我在尝试使用Apache PDFBOX(1.8.5)从字段中设置一些时出现问题。我有几个不同的静态PDF用于测试。使用以下代码,我可以设置表单字段的值,并保存生成的PDF。然后,我可以在Adobe Reader中打开此PDF并查看结果:
PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
pdfTemplate.setAllSecurityToBeRemoved(true);
PDAcroForm acroForm = docCatalog.getAcroForm();
List fields = acroForm.getFields();
Iterator fieldsIter = fields.iterator();
while( fieldsIter.hasNext())
{
PDField field = (PDField)fieldsIter.next();
if(field instanceof PDTextbox){
((PDTextbox)field).setValue("STATIC PDFBOX EDIT");
}
}
然后我最终保存了表格。对于静态PDF:
这很好用。我可以在Adobe Reader XI中打开文档,并在表单中查看正确的值。
对于静态PDF:
这似乎不起作用。当我在Adobe Reader XI中打开生成的表单时,字段似乎不会填充。但是,如果我在我的Firefox或Chrome浏览器的PDF查看器中打开PDF,则字段显示为填充在那里。
如何设置这些字段,以便在Adobe Reader XI中查看时显示值?
编辑:示例PDF可在此处找到:https://github.com/bamundson/PDFExample
答案 0 :(得分:15)
您的PDF之间的主要区别在于使用的表单技术:
Test_9.pdf
使用优质的 AcroForm 表单; Test_10.pdf
和Test_10.pdf
使用带有 AcroForm 表示和 XFA 的混合表单(Adobe XML Forms Architecture)表示。支持XFA的PDF查看器(即最重要的Adobe Reader和Adobe Acrobat)使用文件中的 XFA 信息,而XFA不知情的查看者(即大多数其他人)使用 AcroForm 信息。
PDFBox主要是XFA不知道的。这尤其意味着PDField
返回的PDAcroForm.getFields()
对象仅代表 AcroForm 信息。因此,您的((PDTextbox)field).setValue("STATIC PDFBOX EDIT")
来电只会影响表单的 AcroForm 表示。
这解释了你的观察
当我在Adobe Reader XI中打开生成的表单时,这些字段似乎没有填充。但是,如果我在我的Firefox或Chrome浏览器的PDF查看器中打开PDF,则字段显示为填充在那里。
(据我所知,Firefox和Chrome集成的PDF查看器是XFA不知道的。)
所以,
如何设置这些字段,以便在Adobe Reader XI中查看时显示值?
基本上有两种方式:
从 AcroForm 词典中删除 XFA 条目:
acroForm.setXFA(null);
如果没有 XFA ,Adobe Reader也会使用 AcroForm 表单信息。
编辑 AcroForm 和 XFA 信息。您可以使用
检索XFA信息PDXFAResource xr = acroForm.getXFA();
使用
提取底层XMLxr.getDocument()
然后,您可以编辑XML,将生成的XML放入流中,然后将其包装在PDXFAResource
中,然后使用AcroForm.setXFA(...)
进行设置。
虽然选项1当然更容易实现,但它仅适用于混合文档。如果您还需要编辑纯XFA表单,则需要实现选项2。
使用最新版本的iText
可以为这些PDF编写新的字段值
iText对XFA表单有一定程度的明确支持。
答案 1 :(得分:4)
您需要为acrofields设置NeedAppearances标志为true。 请尝试以下代码段。它将正确显示字段中的值。
COSDictionary acroFormDict = new COSDictionary();
acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);
acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());
// add a new AcroForm and add that to the document
PDAcroForm acroForm = new PDAcroForm(document, acroFormDict);