【问题标题】:Merge documents to create TOC in iText (Java)合并文档以在 iText (Java) 中创建目录
【发布时间】:2015-08-04 01:08:16
【问题描述】:

当使用 iText 创建需要目录的文档时,我通常使用的过程是在内存中创建主文档,在内存中将 TOC 创建为单独的文档(使用虚拟链接),将它们合并为第三个文档,然后使用 PdfStamper 将链接协调到文档中并将其写入文件。

这适用于除最新版本 (5.5.6) 之外的所有 iText 版本。我将包含一个执行此过程的简单程序(实际程序要复杂得多)。当使用 iText 5.5.5 或更早版本运行它时,它会创建所需的文档(2 页,第一页包含提供打开第二页链接的文本)。在 5.5.6 中,对 makeRemoteNamedDestinationsLocal 的调用会导致异常 com.itextpdf.text.pdf.PdfDictionary cannot be cast to com.itextpdf.text.pdf.PdfArray.

由于这一直有效,直到最新版本,我怀疑这可能是最新版本中的错误。这是一个错误,还是我做错了什么?如果它不是错误,我应该如何执行此任务?此外,通常如何为 iText 提交错误报告?从网站上看,他们似乎希望将问题作为报告提交到此处。

import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.*;
import java.io.*;

// WORKS CORRECTLY USING itext version 5.5.5
// FAILS WITH 5.5.6
// CAUSES AN EXCEPTION 
// "com.itextpdf.text.pdf.PdfDictionary cannot be cast to com.itextpdf.text.pdf.PdfArray"
// with makeRemoteNamedDestinationsLocal()
public class testPdf {
    public static void main (String[] args) throws Exception {
        // Create simple document
        ByteArrayOutputStream main = new ByteArrayOutputStream();
        Document doc = new Document(new Rectangle(612f,792f),54f,54f,36f,36f);
        PdfWriter pdfwrite = PdfWriter.getInstance(doc,main);
        doc.open();
        doc.add(new Paragraph("Testing Page"));
        doc.close();

        // Create TOC document
        ByteArrayOutputStream two = new ByteArrayOutputStream();
        Document doc2 = new Document(new Rectangle(612f,792f),54f,54f,36f,36f);
        PdfWriter pdfwrite2 = PdfWriter.getInstance(doc2,two);      
        doc2.open();
        Chunk chn = new Chunk("<<-- Link To Testing Page -->>");
        chn.setRemoteGoto("DUMMY.PDF","page-num-1");
        doc2.add(new Paragraph(chn));
        doc2.close();

        // Merge documents
        ByteArrayOutputStream three = new ByteArrayOutputStream();
        PdfReader reader1 = new PdfReader(main.toByteArray());
        PdfReader reader2 = new PdfReader(two.toByteArray());
        Document doc3 = new Document();
        PdfCopy DocCopy = new PdfCopy(doc3,three);
        doc3.open();
        DocCopy.addPage(DocCopy.getImportedPage(reader2,1));
        DocCopy.addPage(DocCopy.getImportedPage(reader1,1));
        DocCopy.addNamedDestination("page-num-1",2,new PdfDestination(PdfDestination.FIT));
        doc3.close();

        // Fix references and write to file
        PdfReader finalReader = new PdfReader(three.toByteArray());
        // Fails on this line
        finalReader.makeRemoteNamedDestinationsLocal();
        PdfStamper stamper = new PdfStamper(finalReader,new FileOutputStream("Testing.pdf"));
        stamper.close();    
    }
}

【问题讨论】:

  • 它看起来像一个错误。我会将它归档在我们的问题跟踪器中,以便我们的开发人员可以查看。感谢您提供重现问题的示例。太棒了!
  • 感谢您的转发。我怀疑是一个错误,但我认为总是有可能我只是在做一些不应该工作的愚蠢事情,最终不再起作用。当然,我提供了一个示例 - 我不希望任何人尝试修复像 iText 这样复杂的项目中的任何内容,而没有任何东西可以指出问题可能出在哪里,并且重现错误的代码总是比我的更清晰错误的解释。
  • 与此同时,我认为它已在问题跟踪器中修复。

标签: java pdf-generation itext tableofcontents


【解决方案1】:

您检测到 iText 5.5.6 中引入的错误。这已在我们的存储库中修复:

感谢您报告此错误。你可以在 github 上找到修复:https://github.com/itext/itextpdf/commit/eac1a4318e6c31b054e0726ad44d0da5b8a720c2

【讨论】:

  • 使用该补丁从源代码重建后,我可以确认这确实解决了问题。重建这有点技巧,因为我总是使用 Ant 并且从未接触过 maven,并且缺少一些测试所需的东西(例如 ghostscript)。我本可以构建一个快速的 Ant 构建来完成它,但不确定是否需要设置任何不寻常的选项,并且无法很好地读取 pom 文件来确定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-28
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 2012-08-24
  • 1970-01-01
相关资源
最近更新 更多