Отсутствующие невыбранные элементы отображения в начале списка (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

Добавление этой средней строки приводит к тому, что сгенерированный внешний вид начинается с первого значения списка.

Другие вопросы по тегам