我有一个问题,来自 iText 7.0.4.0(.NET 4.5.1)的 PdfWriter 会为某些输入 PDF 文件生成损坏的 PDF 文档。
详细说明,带有 well-formed 段的 PDF 文件没有问题。但是,如果输入 PDF 包含不规则内容(缺少更好的单词;请参阅谷歌驱动器中的示例),PdfWriter 会生成损坏的 PDF 文件;由于损坏,我的意思是该文件可以打开,但它显示一个具有极高缩放率的空白页(在 Adobe Reader XI 中)。上述 Google 驱动器链接中也提供了损坏的样本。
示例代码:
using (var pdfReader = new PdfReader("sample1_input.pdf"))
{
PdfDocument pdfDoc = new PdfDocument(pdfReader, new PdfWriter("sample1_corrupted_output.pdf"));
// Trying to highlight a part of PDF by referencing this example:
// https://developers.itextpdf.com/examples/stamping-content-existing-pdfs/clone-highlighting-text
// Commented out for now because PdfWriter is producing corrupted PDF documents for the samples and similar PDF files.
//PdfCanvas canvas = new PdfCanvas(pdfDoc.GetFirstPage());
//canvas.SetExtGState(new PdfExtGState().SetFillOpacity(0.1f));
//canvas.SaveState();
//canvas.SetFillColor(Color.YELLOW);
//canvas.Rectangle(100, 100, 200, 200);
//canvas.Fill();
//canvas.RestoreState();
pdfDoc.Close(); // Corrupted PDF file is produced, even without highlighting.
}
我注意到的一个“有趣”的事情是,如果我提供“new StampingProperties().UseAppendMode()”作为 PdfDocument 的第三个参数(没有突出显示代码),PdfWriter 会吐出原始文件(尽管由于某种原因比原始文件大几 kb)。但是,当突出显示代码为 un-commented 时,PdfWriter 会返回生成损坏的 PDF。
链接到示例文件:https://drive.google.com/open?id=0B3NPOZswWocQV09KMW5fbFVyUm8 sample1_input.pdf(输入样本#1) - > sample1_corrupted_output.pdf(损坏的输出)sample2_input.pdf(输入样本#2) - > sample2_corrupted_output.pdf(损坏的输出)
请提出一些建议。
1 回答
这种损坏的原因是所讨论的 PDF 页面树的一个不寻常的结构:
它有两种不同寻常的方式:
它有一个没有任何页面对象的子树(字典 17 和 21)。
它有一个具有混合子节点类型的节点(字典 10 有一个Page子 3 和一个Pages子 17)
如果删除 page-less 子树(通过从对象 10 的Kids中删除对象 17),则删除两个怪癖并且代码不再失败。
虽然两个怪怪都很怪异,但我没有在 ISO 32000-1 中看到任何内容(遗憾的是我还没有 ISO 32000-2 的副本),表明明确禁止这些不寻常的结构。因此,我认为这是一个 iText 错误。
我可以使用 iText 7.0.4 for Java 重现问题,但不能重现 7.0.5 的当前开发 SNAPSHOT。
实际上,有一个提交日期 2017-09-19 10:03:37 [3]被描述为“修复页面树重建中的错误”,代码块中
PdfPagesTree
类的差异被描述为“PdfPage 和 PdfPages 的句柄混合”。因此,该问题似乎已知并已得到修复。您可以等待 7.0.5 版本或查找修补程序 7.0.4.x。