【问题标题】:iTextSharp Form Field Not Displaying ampersands, &, with SetFieldiTextSharp 表单字段不显示 & 与 SetField
【发布时间】:2011-06-27 00:27:23
【问题描述】:

我在 iTextSharp 和一个 PDF 表单(特别是表单域)方面遇到了问题,我花了将近两天的时间在上面,我非常希望有人能解答。

我有一个 PDF 表单,当我以用户身份打开它时,我可以在表单字段中输入 & 符号。但是,当我使用 iTextSharp 使用 .SetField 填写表单字段值时,& 符号会消失。我尝试过使用 &(这实际上导致字段中的所有文本显示为空白)、& 的 unicode 表示、不展平表单、展平表单等都无济于事。我不确定问题可能是什么,因为我提到表单字段当然可以接受带有默认编码的逗号和&符号。

我有什么遗漏吗?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'Using iText 4.1.2.0
    GeneratePDF2()
End Sub

Private Sub GeneratePDF2()
    ''//The directory to output files to
    Dim WorkingFolder = My.Computer.FileSystem.SpecialDirectories.Desktop

    Dim FormFileName = Path.Combine(WorkingFolder, "testfile.pdf")
    Dim FinalFileName = Path.Combine(WorkingFolder, "Final.pdf")

    ''//The name of the form field that we are going to create
    Dim TextFieldName = "form1[0].#subform[0].Table3[0].Row2[0].Line2_FullName_and_AddressofEmployer[0]"

    Dim FieldValue As String = "Jonathan & Chris & Mark" ' Does Not Work
    'Dim FieldValue As String = "Jonathan and Chris and Mark" ' Works

    Dim Letter As RandomAccessFileOrArray
    'Create a PDF reader object based on the PDF template
    Dim PDFReader As PdfReader
    'Dim BAOS1 As MemoryStream
    Dim Stamper As PdfStamper


    Dim BAOS As MemoryStream = New MemoryStream()
    Dim Copy As PdfCopyFields = New PdfCopyFields(BAOS)

    Dim FormFilePath As String = FormFileName
    Letter = New RandomAccessFileOrArray(FormFilePath)
    'Create a PDF reader object based on the PDF template
    PDFReader = New PdfReader(Letter, Nothing)

    Dim BAOS1 As MemoryStream = New MemoryStream()
    Stamper = New PdfStamper(PDFReader, BAOS1)

    Dim FormFields As AcroFields = Stamper.AcroFields

    'Set field value
    FormFields.SetField(TextFieldName, FieldValue)

    'Rename field after setting value
    Dim RenamedFormFieldName As String
    RenamedFormFieldName = String.Concat(Guid.NewGuid().ToString, "_", Guid.NewGuid().ToString)

    FormFields.RenameField(TextFieldName, RenamedFormFieldName)

    ' flatten the form to remove editting options, set it to false
    ' to leave the form open to subsequent manual edits
    Stamper.FormFlattening = True
    ' close the pdf
    Stamper.Close()

    'This could be the correct location
    Copy.AddDocument(New PdfReader(BAOS1.ToArray))

    Copy.Writer.CloseStream = False
    Copy.Close()

    PDFReader = New PdfReader(BAOS.ToArray())
    Stamper = New PdfStamper(PDFReader, New FileStream(FinalFileName, FileMode.Create))


    Stamper.FormFlattening = True
    Stamper.Close()

End Sub

【问题讨论】:

    标签: pdf encoding itextsharp itext


    【解决方案1】:

    我无法重现您的问题,我使用的是 5.1.1.0 版本。下面是创建 PDF、向其中添加字段然后将字段的值设置为 This & that 的示例代码。 (它分三个步骤,因为我不知道如何在初始 PDF 创建期间添加字段。)我还尝试在 Acrobat 中手动创建 PDF,并且我也可以将字段设置为 & 符号。您是在 iTextSharp 或其他程序中创建表单域吗?你能把那个 PDF 贴在某个地方让我们看看吗?

    Option Explicit On
    Option Strict On
    
    Imports iTextSharp.text
    Imports iTextSharp.text.pdf
    Imports System.IO
    
    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ''//The directory to output files to
            Dim WorkingFolder = My.Computer.FileSystem.SpecialDirectories.Desktop
    
            ''//This sample code creates a base PDF, then adds a text field to it and finally sets the field value.
            ''//These filenames represent those three actions
            Dim BaseFileName = Path.Combine(WorkingFolder, "Base.pdf")
            Dim FormFileName = Path.Combine(WorkingFolder, "Form.pdf")
            Dim FinalFileName = Path.Combine(WorkingFolder, "Final.pdf")
    
            ''//The name of the form field that we are going to create
            Dim TextFieldName = "Text1"
    
            ''//Create our base PDF
            Using FS As New FileStream(BaseFileName, FileMode.Create, FileAccess.Write, FileShare.Read)
                Using Doc As New Document(PageSize.LETTER)
                    Using W = PdfWriter.GetInstance(Doc, FS)
                        Doc.Open()
                        Doc.NewPage()
                        Doc.Add(New Paragraph("This is my form"))
                        Doc.Close()
                    End Using
                End Using
            End Using
    
            ''//Add our form field
            Using FS As New FileStream(FormFileName, FileMode.Create, FileAccess.Write, FileShare.Read)
                Dim R1 = New PdfReader(BaseFileName)
                Using S As New PdfStamper(R1, FS)
                    Dim F As New TextField(S.Writer, New Rectangle(50, 50, 500, 100), TextFieldName)
                    S.AddAnnotation(F.GetTextField(), 1)
                    S.Close()
                End Using
            End Using
    
            ''//Set the field value to text with an ampersand
            Using FS As New FileStream(FinalFileName, FileMode.Create, FileAccess.Write, FileShare.Read)
                Dim R2 = New PdfReader(FormFileName)
                Using S As New PdfStamper(R2, FS)
                    S.AcroFields.SetField(TextFieldName, "This & that")
                    S.Close()
                End Using
            End Using
    
            Me.Close()
        End Sub
    End Class
    

    编辑

    我刚刚使用您发送的 PDF 进行了尝试,它对我来说工作得很好。下面是我运行的完整代码。 Here's the PDF it made。你确定你没有对 PDF 做其他事情(我不知道是什么。)如果你创建一个全新的 Windows 应用程序并针对 5.1.1.0 使用下面的代码,它对你有用吗?

    Option Explicit On
    Option Strict On
    
    Imports iTextSharp.text
    Imports iTextSharp.text.pdf
    Imports System.IO
    Imports System.Text
    
    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ''//The directory to output files to
            Dim WorkingFolder = My.Computer.FileSystem.SpecialDirectories.Desktop
    
            Dim FormFileName = Path.Combine(WorkingFolder, "testfile.pdf")
            Dim FinalFileName = Path.Combine(WorkingFolder, "Final.pdf")
    
            ''//The name of the form field that we are going to create
            Dim TextFieldName = "form1[0].#subform[0].Table3[0].Row2[0].Line2_FullName_and_AddressofEmployer[0]"
    
            ''//Set the field value to text with an ampersand
            Using FS As New FileStream(FinalFileName, FileMode.Create, FileAccess.Write, FileShare.Read)
                Dim R2 = New PdfReader(FormFileName)
                Using S As New PdfStamper(R2, FS)
                    S.AcroFields.SetField(TextFieldName, "Chris & Mark")
                    S.FormFlattening = True
                    S.Close()
                End Using
            End Using
    
            Me.Close()
        End Sub
    
    End Class
    

    【讨论】:

    • writer.addAnnotation(PdfAnnotation); PdfFormField 派生自 PdfAnnotation。 TextField/RadioCheckField/PushbuttonField 非常适合创建 PdfFormField 实例 Just So。各种列表类型使用 TextField。这在布局期间不会占用空间,但我认为您可以使用带有 no-stroke-no-fill Rectangle 的通用标签。
    • @Mark Storer,我想你会知道答案的!我没有检查作者本身,我试图用它制作一个印模,但显然失败了。
    • 这是我的示例文件,它在感兴趣的特定字段上展示了奇怪的“不能采用 & 符号”行为。 removeblankrows.info/testfile.pdf。尝试将“Chris & Mark”放在名为“form1[0].#subform[0].Table3[0].Row2[0].Line2_FullName_and_AddressofEmployer[0]”的字段中“申请人最近五年的就业情况”下,并将表格然后查看结果。 & 符号对我来说神秘地丢失了,但是当我在字段中输入时,我就可以正常输入了。
    • @AudioFrk,我更新了我上面的帖子,不幸的是(对你来说)你发送的 PDF 对我来说很好。
    • @Chris,我添加了我用问题测试的代码。它是您提供的内容和现有代码的组合,并确认问题仍然存在。我正在使用不同版本的 iText,4.1.2.0,但我想知道它是否是我使用的代码而不是版本。
    【解决方案2】:

    有一个类似的案例,用户在应用程序中输入的德语变音符号没有显示在 PDF 中。原来是字体问题。 必须将我们自己的字体与应用程序一起发布(Liberation 包以获得跨平台的 Arial 风格)并执行此操作(它是 Java):

    BaseFont baseFont = BaseFont.createFont(FONT_FILE, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
    acroFields.setFieldProperty(fieldName, "textfont", baseFont, null);
    

    【讨论】:

      猜你喜欢
      • 2017-11-17
      • 2021-11-10
      • 1970-01-01
      • 2015-08-20
      • 1970-01-01
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多