以下代码演示了一个非常奇怪的错误。一旦“源”文件关闭,“目标”文件无法保存和关闭,它将抛出“java.io.IOException:COSStream已关闭且无法读取。可能其封闭的PDDocument已关闭?”
如果我们注释掉保存源文件,那么目标将正确保存和关闭。这似乎清楚地表明源文件包含一个COSStream对象,该对象也存在于目标文件中。当我们关闭源文件然后无法保存目标时,源文件COSStream似乎已关闭。
如果我们注释掉展平源文件AcroForm,那么目标将正确保存和关闭。
这个简单的示例是尝试将表单的一个副本与其自身合并,如果您替换某些其他PDF文件(所有政府表单曾经是XFA文档),则错误将重现。大多数PDF都适用于这种情况。我们将XFA文档向下转换为普通PDF,以将其作为变量消除,并且错误仍然存在。
PDFBox 2.0.8及更早版本中存在问题
@Test
public void testMergeGovernmentForms() throws Exception {
File file = new File("GeneralForbearance.pdf");
PDDocument destination = PDDocument.load(file);
PDDocument source = PDDocument.load(file);
source.getDocumentCatalog().getAcroForm().flatten(); //comment out just this line and the destination.save will pass
PDFMergerUtility appender = new PDFMergerUtility();
appender.appendDocument(destination, source);
source.close(); //comment out just this line and the destination.save will pass
destination.save(File.createTempFile("PrintMergeIssue", ".pdf"));
destination.close();
}
从HERE
下载GeneralForbearance.pdf此外,如果您“预先展平”政府表格并保存,您可以使用更简单的代码获得相同的行为。
@Test
public void testMerge() throws Exception {
PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
PDDocument src = PDDocument.load(new File("C:/temp/GovFormPreFlattened.pdf"));
PDDocument dest = PDDocument.load(new File("C:/temp/GovFormPreFlattened.pdf"));
pdfMergerUtility.appendDocument(dest, src);
src.close(); //if we don't close the src then we don't have an error
dest.save(File.createTempFile("MergeIssue",".PDF"));
dest.close();
}
可以找到预先扁平的政府表格HERE
答案 0 :(得分:0)
PDFMergerUtility合并标记文档中存在一些问题,我将其修复,修补并作为问题PDFBOX-3999提交回Apache,如果需要,可以从那里下载补丁。此修补程序适用于2.0.8版