首页 > 解决方案 > Apache PDFBox - 无法读取 PDF 中的所有字段

问题描述

我们正在尝试读取 PDF 并动态填充其中的值。根据传入的请求,我们运行一些规则并派生要使用的 PDF,然后动态填充值。我们使用的是 Apache PDFBox 2.0.11 版,出于某种原因,我们遇到了特定 PDF 模板的问题。我们无法读取此特定模板的某些字段,并且生成的 PDF 不完整。想知道是否与原始 PDF 本身有关。这是我们用来读取字段并填充它的代码片段。

PDDocument pdfTemplate = PDDocument.load(inputStream);
PDDocumentCatalog docCatalog = pdfTemplate.getDocumentCatalog();
PDAcroForm  acroForm = docCatalog.getAcroForm();
acroForm.setXFA(null);
COSArrayList<PDField> list = (COSArrayList<PDField>) acroForm.getFields();
for (PDField field : list) {
     field.setReadOnly(true);
      logger.debug("Field name "+field.getFullyQualifiedName())))
      //use logic to populate value by calling field.setValue();
}

当我们尝试打印每个字段名称时,我们观察到超过 30% 的字段丢失。任何人都可以帮助解决它吗?PDF 有 15 页,有不同的问题。如果问题出在原始 PDF 本身,那么可能是什么原因导致无法阅读某些字段?

标签: javaapachepdfpdf-generationpdfbox

解决方案


您可能在该表单上有分层字段。尝试类似下面的代码...

PDDocument pdfTemplate = PDDocument.load(inputStream);
PDDocumentCatalog docCatalog = pdfTemplate.getDocumentCatalog();    
PDAcroForm  acroForm = docCatalog.getAcroForm();
PDFieldTree fieldTree = acroForm.getFieldTree();
Iterator<PDField> fieldTreeIterator = fieldTree.iterator();
while (fieldTreeIterator.hasNext()) {
    PDField field = fieldTreeIterator.next();
    if (field instanceof PDTerminalField) {
        String fullyQualifiedName = field.getFullyQualifiedName();
        logger.debug("Field name "+fullyQualifiedName);
    }
}

PDAcroForm.getFields() 只获取根字段,而不是它们的子字段。PDAcroForm.getFieldTree() 获取所有字段,但是您需要在设置值之前测试它们是否是终端。非终端字段不能有值,也没有与之关联的小部件(页面上的表示)。如果完全限定名称中有句点,您就会知道这是问题所在。句点代表层次结构。


推荐阅读