iText 7.0.4.0 - PdfWriter为某些PDF文件输入生成损坏的PDF

时间:2017-09-28 22:56:26

标签: c# itext itext7

我遇到一个问题,即iText 7.0.4.0(.NET 4.5.1)中的PdfWriter会为某些输入PDF文件生成损坏的PDF文档。

详细说明,具有格式良好的段落的PDF文件没有问题。但是,如果输入PDF包含不规则内容(缺少更好的单词;请参阅Google drive中的示例),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)由于某种原因比原来的)。但是,当突出显示代码未注释时,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 个答案:

答案 0 :(得分:2)

这种损坏的原因是所讨论的PDF页面树的一个不寻常的结构:

structure of page tree

这在两个方面很不寻常:

  • 它有一个没有任何页面对象的子树(字典17和21)。
  • 它有一个具有混合子节点类型的节点(字典10有一个页面子项3和一个页面子项17)

如果删除无页面子树(通过从对象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 [c0b35f0]描述为“修复页面树重建中的错误”,代码块中 onOpenDialog : function () { var oView = this.getView(); var oDialog = oView.byId("helloDialog"); // create dialog lazily if (!oDialog) { // create dialog via fragment factory oDialog = sap.ui.xmlfragment(oView.getId(), "sap.ui.demo.wt.view.HelloDialog"); oView.addDependent(oDialog); } oDialog.open(); } 类的差异描述为“处理PdfPage和PdfPages的混合“。因此,这个问题似乎已为人所知并已经解决。

您可以等待7.0.5版本,也可以查找修补程序7.0.4.x。