iTextSharp SetField 用于不同页面上具有相同名称的字段

iTextSharp SetField for fields with same name on different pages

我使用 acroFields.GetTranslatedFieldName() 从 pdf 中获取下一个字段名:

topmostSubform[0].Page1[0].CheckBox2A[0]
topmostSubform[0].Page1[0].CheckBox2A[1]
topmostSubform[0].Page2[0].CheckBox2A[0]
topmostSubform[0].Page2[0].CheckBox2A[1] 
topmostSubform[0].Page3[0].CheckBox2A[0]
topmostSubform[0].Page3[0].CheckBox2A[1] 

我用下一行代码在第二页填CheckBox2A[0]

fields.SetField("topmostSubform[0].Page2[0].CheckBox2A[0]", "1")

检查第一页上的 CheckBox2A[0],而不是第二页上的 CheckBox2A[0]。

iTextSharp(以及 Java 的 iText,已测试 here)未正确关联从 XFA 模板结构派生的引用

topmostSubform[0].Page2[0].CheckBox2A[0]

与一个 XFA 数据集中的匹配条目:

<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" >
  <xfa:data >
    <topmostSubform >
<!-- vvv the incorrect match by iText -->
      <CheckBox2A >0</CheckBox2A >
<!-- ^^^ the incorrect match by iText -->
      <CheckBox2A >0</CheckBox2A >
      <CheckBox2B >0</CheckBox2B >
      <CheckBox2B >0</CheckBox2B >
      <Voorletters />
      <Achternaam />
      <CheckBox2C >0</CheckBox2C >
      <CheckBox2C >0</CheckBox2C >
      <DatumDag />
      <DatumMaand />
      <DatumJaar />
      <TextField1 />
      <HuisNrTekst5 />
      <HuisNrNummer5 />
      <Straat />
      <PostcodeNr1c />
      <PostcodeAlpha1c />
      <Plaats />
      <HuisNrTekst5 />
      <HuisNrNummer5 />
      <TextField1 />
      <PostcodeNr1c />
      <PostcodeAlpha1c />
      <Plaats />
      <TextField1 />
      <CheckBox2D >0</CheckBox2D >
      <CheckBox2D >0</CheckBox2D >
      <IBANREKC_1 />
      <IBANREKB_1 />
      <IBANREKA_1 />
      <IBAN_1 />
      <BurgerserviceNr />
      <Voorletters />
      <Achternaam />
      <CheckBox2E >0</CheckBox2E >
      <CheckBox2E >0</CheckBox2E >
      <HuisNrTekst5 />
      <HuisNrNummer5 />
      <Straat />
      <PostcodeNr1c />
      <PostcodeAlpha1c />
      <Plaats />
      <DatumDag />
      <DatumMaand />
      <DatumJaar />
      <IBANREKC_2 />
      <IBANREKB_2 />
      <IBANREKA_2 />
      <IBAN_2 />
      <Telefoon />
<!-- vvv the correct match -->
      <CheckBox2A >0</CheckBox2A >
<!-- ^^^ the correct match -->
      <CheckBox2A >0</CheckBox2A >
      <CheckBox2B >0</CheckBox2B >
      <CheckBox2B >0</CheckBox2B >
      <IBANREKC_1 />
      <IBANREKB_1 />
      <IBANREKA_1 />
      <IBAN_1 />
      <CheckBox2C >0</CheckBox2C >
      <CheckBox2C >0</CheckBox2C >
      <TextField1 />
      <TextField1 />
      <CheckBox2D >0</CheckBox2D >
      <CheckBox2D >0</CheckBox2D >
      <Telefoon />
      <CheckBox2E >0</CheckBox2E >
      <CheckBox2E >0</CheckBox2E >
      <CheckBox2F >0</CheckBox2F >
      <CheckBox2F >0</CheckBox2F >
      <TextField1 />
      <TextField1 />
      <CheckBox2G >0</CheckBox2G >
      <CheckBox2G >0</CheckBox2G >
      <CheckBox3B >0</CheckBox3B >
      <CheckBox3B >0</CheckBox3B >
      <CheckBox3B >0</CheckBox3B >
      <IBAN_1E_01 />
      <IBAN_1D_01 />
      <IBAN_1C_01 />
      <IBAN_1A_01 />
      <IBAN_1B_01 />
      <IBANREKC_1 />
      <IBANREKB_1 />
      <IBANREKA_1 />
      <IBAN_1 />
      <IBAN_1E_02 />
      <IBAN_1D_02 />
      <IBAN_1C_02 />
      <IBAN_1B_02 />
      <IBAN_1A_02 />
      <CheckBox3D >0</CheckBox3D >
      <CheckBox3D >0</CheckBox3D >
      <CheckBox3D >0</CheckBox3D >
      <CheckBox3A >0</CheckBox3A >
      <CheckBox3A >0</CheckBox3A >
      <CheckBox3A >0</CheckBox3A >
      <CheckBox2A >0</CheckBox2A >
      <CheckBox2A >0</CheckBox2A >
      <CheckBox3B >0</CheckBox3B >
      <CheckBox3B >0</CheckBox3B >
      <CheckBox3B >0</CheckBox3B >
      <DatumDag />
      <DatumMaand />
      <DatumJaar />
      <TextField1 />
      <DatumDag />
      <DatumMaand />
      <DatumJaar />
      <TextField1 />
      <Telefoon />
    </topmostSubform >
  </xfa:data >
</xfa:datasets >

因此,更改了错误的数据集元素。恐怕这必须由 iText 开发人员进行调查,我手头没有解决办法。

不过您可能很幸运:文档中的表单实际上是 AcroForm 和 XFA 表示的混合体。在您的 fields.SetField 调用期间,iText 尝试在两种表示中设置值,实际上,在 AcroForm 表示中它设置了正确的值。

因此,如果结果 PDF 不再需要携带该 XFA 结构,您可以简单地删除 XFA 结构:

using (var pdfReader = new PdfReader(file))
using (FileStream output = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, output))
{
    AcroFields fields = pdfStamper.AcroFields;
    fields.SetField("topmostSubform[0].Page2[0].CheckBox2A[0]", "1");
    fields.RemoveXfa();
}

这样做,您会在第 2 页上打勾: