XFA在PDFBox 1.8.12中构建,而不是在2.0.4中



我尝试从文件中提取XFA,直到我将PDFBox从1.8.12更新到2.0.4之前,它对我来说工作正常。

我有一个文件,我可以使用 1.8.12 但不能使用 2.0.4 提取 XFA。

当我使用 PDFBox 使用 2.0.4 提取它时,我得到了 XFA 的结构,但几乎所有值都丢失了。另一方面,当我尝试使用 1.8.12 提取相同的表单时,结果很好。

我在SO上调查了类似的问题。据说它在 2.0.4 中已修复,但我仍然面临问题。

有什么想法吗?

我已经包含了文件

生成的XFA-1.8.12

生成的 XFA-2.0.4

使用的文件

编辑#1

对于 2.0.4

// returns PDXFA
public static byte[] getParsableXFAForm(File file) {
if (file == null)
return null;
PDDocument doc;
PDDocumentCatalog catalog;
PDAcroForm acroForm;
PDXFAResource xfa;
try {
//            String pass = null;
doc = PDDocument.load(file);
if (doc == null)
return null;
//             flattenPDF(doc);
doc.setAllSecurityToBeRemoved(true);
// System.out.println("Security " + doc.isAllSecurityToBeRemoved());
catalog = doc.getDocumentCatalog();
if (catalog == null) {
doc.close();
return null;
}
acroForm = catalog.getAcroForm();
if (acroForm == null) {
doc.close();
return null;
}
xfa = acroForm.getXFA();
if (xfa == null) {
doc.close();
return null;
}
// TODO return byte[]
byte[] xfaBytes = xfa.getBytes();
doc.close();
return xfaBytes;
} catch (IOException e) {
// handle IOException
// happens when the file is corrupt.
e.printStackTrace();
System.out.println("XFAUtils-getParsableXFAForm-IOException");
return null;
}
}

对于 1.8.12

public static byte[] getParsableXFAForm(File file) {
if (file == null)
return null;
PDDocument doc;
PDDocumentCatalog catalog;
PDAcroForm acroForm;
PDXFA xfa;
try {
doc = PDDocument.loadNonSeq(file, null);
if (doc == null)
return null;
// flattenPDF(doc);
doc.setAllSecurityToBeRemoved(true);
// System.out.println("Security " + doc.isAllSecurityToBeRemoved());
catalog = doc.getDocumentCatalog();
if (catalog == null) {
doc.close();
return null;
}
acroForm = catalog.getAcroForm();
if (acroForm == null) {
doc.close();
return null;
}
xfa = acroForm.getXFA();
if (xfa == null) {
doc.close();
return null;
}
// TODO return byte[]
byte[] xfaBytes = xfa.getBytes();
doc.close();
return xfaBytes;
} catch (IOException e) {
// handle IOException
// happens when the file is corrupt.
//          e.printStackTrace();
System.out.println("XFAUtils-getParsableXFAForm-IOException");
return null;
}
}

乍一看

您的PDF中有6个修订版,在此过程中,XFA表格的填写越来越多。您的 1.8.12 代码提取最新版本的 XFA,而您的 2.0.4 代码提取它的最旧版本。

我使用 PDFBox 版本 2.0.4、2.0.5 和当前的开发快照 2.1.0-SNAPSHOT 运行了您的 2.0.4 代码。在 2.0.4 版本中,我确实可以重现加载 XFA 表单的最旧修订版,但使用 2.0.5 或 2.1.0-SNAPSHOT 加载了当前修订版。

这似乎是PDFBox 2.0.0...2.0.4中的一个缺点,该缺陷已在2.0.5中修复。

仔细检查

由于PDFBox 2.0.4中的一个错误从错误的文件修订版中读取XFA表单似乎非常难以置信,我对此进行了更多研究。

特别是我仔细研究了PDF文件本身。事实上,事实证明,该文件在实际的 PDF 文件标题之前有 10 个垃圾字节!

这些额外的垃圾字节使得相对于文件启动的交叉引用和偏移量都是错误的。因此,PDFBox无法以常规方式解析文件,而是必须进行某种修复。

查看 2.0.4 和2.0.5 之间的差异,特别是代码发生了重大变化,以修复带有损坏的交叉引用和偏移的 PDF。虽然PDFBox 2.0.4只能部分修复文件(仅找到最初的XFA修订版),因此,PDFBox 2.0.5成功地进行了更完整的修复,特别是找到了最新的XFA修订版。


修复了OP的PDF(即删除了前导垃圾字节,参见XFA-File-fixed.pdf),我也可以使用PDFBox版本2.0.0...2.0.4成功提取当前的XFA表单修订版。

因此,这不是我最初假设的PDFBox错误,而只是一个损坏的PDF文件,在PDFBox 2.0.5改进之前,PDFBox文件修复功能无法正确修复。

最新更新