Java 设置值后PDFBox PDTextField行为不一致
PDFBox setValue()不是为每个PDTextField设置数据。它节省了几块田地。它不适用于在getFullyQualifiedName()中具有类似外观的字段 注意:field.getFullyQualifiedName(){customdutiesa,customdutiesb,customdutiesc}它正在为customdutiesa工作,但不为customdutiesb和customdutiesc等工作Java 设置值后PDFBox PDTextField行为不一致,java,pdf-generation,pdfbox,acrofields,Java,Pdf Generation,Pdfbox,Acrofields,PDFBox setValue()不是为每个PDTextField设置数据。它节省了几块田地。它不适用于在getFullyQualifiedName()中具有类似外观的字段 注意:field.getFullyQualifiedName(){customdutiesa,customdutiesb,customdutiesc}它正在为customdutiesa工作,但不为customdutiesb和customdutiesc等工作 @Test public void testb3Generator(
@Test
public void testb3Generator() throws IOException {
File f = new File(inputFile);
outputFile = String.format("%s_b3-3.pdf", "123");
try (PDDocument document = PDDocument.load(f)) {
PDDocumentCatalog catalog = document.getDocumentCatalog();
PDAcroForm acroForm = catalog.getAcroForm();
int i = 0;
for (PDField field : acroForm.getFields()) {
i=i+1;
if (field instanceof PDTextField) {
PDTextField textField = (PDTextField) field;
textField.setValue(Integer.toString(i));
}
}
document.getDocumentCatalog().getAcroForm().flatten();
document.save(new File(outputFile));
document.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
输入pdf链接:
输出pdf链接:问题在于,在某些情况下,PDFBox不会为字段构造外观,它会设置字段的值,因此在展平过程中会完全忘记字段内容:
// in case all tests fail the field will be formatted by acrobat
// when it is opened. See FreedomExpressions.pdf for an example of this.
if (actions == null || actions.getF() == null ||
widget.getCOSObject().getDictionaryObject(COSName.AP) != null)
{
... generate appearance ...
}
(org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceValue(String)
)
也就是说,如果有一个JavaScript操作用于与字段关联的值格式化,并且还没有出现任何外观流,则PDFBox假定它不需要创建外观(并且可能会出错,因为它不使用该格式化操作)
如果一个用例后来将表单展平,那么PDFBox的假设显然是错误的
要强制PDFBox也为这些字段生成外观,只需在设置字段值之前删除操作:
if (field instanceof PDTextField) {
PDTextField textField = (PDTextField) field;
textField.setActions(null);
textField.setValue(Integer.toString(i));
}
(从test
TestLikeAbakarRemoveAction
)问题在于,在某些条件下,PDFBox不会为字段构造外观,它会设置字段的值,因此在展平过程中完全忘记字段内容:
// in case all tests fail the field will be formatted by acrobat
// when it is opened. See FreedomExpressions.pdf for an example of this.
if (actions == null || actions.getF() == null ||
widget.getCOSObject().getDictionaryObject(COSName.AP) != null)
{
... generate appearance ...
}
(org.apache.pdfbox.pdmodel.interactive.form.AppearanceGeneratorHelper.setAppearanceValue(String)
)
也就是说,如果有一个JavaScript操作用于与字段关联的值格式化,并且还没有出现任何外观流,则PDFBox假定它不需要创建外观(并且可能会出错,因为它不使用该格式化操作)
如果一个用例后来将表单展平,那么PDFBox的假设显然是错误的
要强制PDFBox也为这些字段生成外观,只需在设置字段值之前删除操作:
if (field instanceof PDTextField) {
PDTextField textField = (PDTextField) field;
textField.setActions(null);
textField.setValue(Integer.toString(i));
}
(来自test
testlikeabakarremoveaction
)@Abubakar太棒了!尽管如此,你还是应该把蒂尔曼的建议从删除的评论中考虑到:<代码> ActuFrim.GeFieldSe()/Case>不返回所有字段的直列表,只返回顶级字段。通常,就像在示例文档中一样,只有顶级字段,但有时存在实际的字段层次结构。在这种情况下,您应该使用acroForm.getFieldTree()
或acroForm.getFieldIterator()
来访问所有字段。在当前情况下,我将获取所有正在更新的字段。这真的有点帮助。@Abubakar很棒!尽管如此,你还是应该把蒂尔曼的建议从删除的评论中考虑到:<代码> ActuFrim.GeFieldSe()/Case>不返回所有字段的直列表,只返回顶级字段。通常,就像在示例文档中一样,只有顶级字段,但有时存在实际的字段层次结构。在这种情况下,您应该使用acroForm.getFieldTree()
或acroForm.getFieldIterator()
来访问所有字段。在当前情况下,我将获取所有正在更新的字段。这真的有点帮助。