Отсутствующие невыбранные элементы отображения в начале списка (iTextSharp)
Я получаю нежелательные результаты в Adobe Reader DC при создании или восстановлении списка со множественным выбором с помощью iTextSharp в документе Acroform PDF.
Проблема: в PDF-форме отсутствуют невыбранные элементы отображения в начале списка при просмотре измененного PDF-файла в Adobe Reader DC. Например: "Один", "Два", "Три", "Четыре", "Пять" - это элементы списка; и "Два" и "Четыре" выбраны; тогда предыдущие элементы, такие как "Один", отсутствуют в верхней части списка. И первый элемент, отображаемый в списке, начинается с первого выбора, в данном случае "Два". (См. Скриншот Adobe Reader DC)
К сведению: с помощью Adobe Reader DC, когда я выбираю различные варианты выбора полей в списке и затем щелкаю за пределами списка, поле списка возвращается к обычному виду со всеми отображаемыми элементами. Я не могу воспроизвести это поведение при открытии измененного PDF в Adobe Acrobat Professional 8, и все элементы поля видны и правильно выбраны. Такое поведение недостающих элементов списка также можно воспроизвести в GhostScript при преобразовании PDF в BMP или PNG.
Пожалуйста, ответьте на мой вопрос: не могли бы вы предоставить мне решение этой проблемы, если это проблема iTextSharp или мой синтаксис неверен. Не могли бы вы также сообщить мне, можно ли воспроизвести это поведение с помощью Adobe Reader DC?
Спасибо за поддержку!
Измененный документ Acroform PDF с выпуском: http://www.nk-inc.com/listbox-error.pdf
Снимок экрана Adobe Reader DC: http://www.nk-inc.com/listbox-error-reader.gif
ADDITIONAL INFORMATION:
iTextSharp.dll Version: 5.5.6.0
Adobe Reader DC Version: 2015.008.20082
Adobe Acrobat Pro Version: 8.x
Form Type: Acroform PDF
VB.NET CODE (v3.5 - Приложение для Windows):
Imports iTextSharp.text.pdf
Imports iTextSharp.text
Imports System.IO
Public Class listboxTest
Private Sub RunTest()
Dim cList As New listboxTest()
Dim fn As String = Application.StartupPath.ToString.TrimEnd("\") & "\listbox-error.pdf"
Dim b() As Byte = cList.addListBox(System.IO.File.ReadAllBytes(fn), New iTextSharp.text.Rectangle(231.67, 108.0, 395.67, 197.0), "ListBox1", "ListBox1", 1)
File.WriteAllBytes(fn, b)
Process.Start(fn)
End Sub
Public Function addListBox(ByVal pdfBytes() As Byte, ByVal newRect As Rectangle, ByVal newFldName As String, ByVal oldfldname As String, ByVal pg As Integer) As Byte()
Dim pdfReaderDoc As New PdfReader(pdfBytes)
Dim m As New System.IO.MemoryStream
Dim b() As Byte = Nothing
Try
With New PdfStamper(pdfReaderDoc, m)
Dim txtField As iTextSharp.text.pdf.TextField
txtField = New iTextSharp.text.pdf.TextField(.Writer, newRect, newFldName)
txtField.TextColor = BaseColor.BLACK
txtField.BackgroundColor = BaseColor.WHITE
txtField.BorderColor = BaseColor.BLACK
txtField.FieldName = newFldName 'ListBox1
txtField.Alignment = 0 'LEFT
txtField.BorderStyle = 0 'SOLID
txtField.BorderWidth = 1.0F 'THIN
txtField.Visibility = TextField.VISIBLE
txtField.Rotation = 0 'None
txtField.Box = newRect '231.67, 108.0, 395.67, 197.0
Dim opt As New PdfArray
Dim ListBox_ItemDisplay As New List(Of String)
ListBox_ItemDisplay.Add("One")
ListBox_ItemDisplay.Add("Two")
ListBox_ItemDisplay.Add("Three")
ListBox_ItemDisplay.Add("Four")
ListBox_ItemDisplay.Add("Five")
Dim ListBox_ItemValue As New List(Of String)
ListBox_ItemValue.Add("1X")
ListBox_ItemValue.Add("2X")
ListBox_ItemValue.Add("3X")
ListBox_ItemValue.Add("4X")
ListBox_ItemValue.Add("5X")
txtField.Options += iTextSharp.text.pdf.TextField.MULTISELECT
Dim selIndex As New List(Of Integer)
Dim selValues As New List(Of String)
selIndex.Add(CInt(1)) ' SELECT #1 (index)
selIndex.Add(CInt(3)) ' SELECT #3 (index)
txtField.Choices = ListBox_ItemDisplay.ToArray
txtField.ChoiceExports = ListBox_ItemValue.ToArray
txtField.ChoiceSelections = selIndex
Dim listField As PdfFormField = txtField.GetListField
If Not String.IsNullOrEmpty(oldfldname & "") Then
.AcroFields.RemoveField(oldfldname, pg)
End If
.AddAnnotation(listField, pg)
.Writer.CloseStream = False
.Close()
If m.CanSeek Then
m.Position = 0
End If
b = m.ToArray
m.Close()
m.Dispose()
pdfReaderDoc.Close()
End With
Return b.ToArray
Catch ex As Exception
Err.Clear()
Finally
b = Nothing
End Try
Return Nothing
End Function
End Class
1 ответ
Причина, по которой видимый список начинается со второй записи, заключается в том, что iTextSharp начинает рисовать список с первой выбранной записи.
Это оптимизация для списков, которые имеют больше (возможно, намного больше) записей, чем может быть отображено в области фиксированного текстового поля, так что отображаемые записи содержат по крайней мере одну интересную, т.е. выбранную, одну.
К сожалению, эта оптимизация не учитывает, означает ли это, что некоторые строки остаются пустыми внизу, а в случае списков, которые полностью помещаются в текстовое поле, даже нет полос прокрутки или чего-либо еще.
Но iTextSharp также предлагает способ отключить эту оптимизацию: вы можете явно установить первый видимый элемент вручную:
txtField.ChoiceSelections = selIndex
txtField.VisibleTopChoice = 0 ' Top visible choice is start of list!
Dim listField As PdfFormField = txtField.GetListField
Добавление этой средней строки приводит к тому, что сгенерированный внешний вид начинается с первого значения списка.