【问题标题】:Create Index File(TOC) for merged pdf using itext library in java在java中使用itext库为合并的pdf创建索引文件(TOC)
【发布时间】:2014-02-28 04:33:43
【问题描述】:

我正在使用 iText 通过使用 PDFCopy 合并多个 PDF 来创建 单个 PDF。我需要在本文档的开头创建一个 TOC(不是书签),其中包含指向每个源 PDF 第一页的可点击链接。

合并 pdf 的代码

Document PDFJoinInJava = new Document();
PdfCopy PDFCombiner = new PdfCopy(PDFJoinInJava, outputStream);
PdfCopy.PageStamp stamp;
PDFJoinInJava.open();
PdfReader ReadInputPDF;

List<InputStream> pdfs = streamOfPDFFiles;
List<PdfReader> readers = new ArrayList<PdfReader>();
int totalPages = 0;
Iterator<InputStream> iteratorPDFs = pdfs.iterator();
for (; iteratorPDFs.hasNext(); pdfCounter++) {
    InputStream pdf = iteratorPDFs.next();
    PdfReader pdfReader = new PdfReader(pdf);
    readers.add(pdfReader);
    totalPages += pdfReader.getNumberOfPages();
    pdf.close();
}
int number_of_pages;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
Iterator<PdfReader> iteratorPDFReader = readers.iterator();

PdfImportedPage page;
// Loop through the PDF files and add to the output.
int count = 1;

while (iteratorPDFReader.hasNext()) {
    PdfReader pdfReader = iteratorPDFReader.next();
    count++;
    number_of_pages = pdfReader.getNumberOfPages();

    // Create a new page in the target for each source page.
    for (int pageNum = 0; pageNum < number_of_pages;) {
        currentPageNumber++;
        pageOfCurrentReaderPDF++;
        page = PDFCombiner.getImportedPage(pdfReader, ++pageNum);
        ColumnText.showTextAligned(stamp.getUnderContent(),
                        Element.ALIGN_RIGHT, new Phrase(String
                                .format("%d", currentPageNumber),new Font(FontFamily.TIMES_ROMAN,3)),
                        50, 50, 0);
            stamp.alterContents();

        PDFCombiner.addPage(page);
    }
}
PDFJoinInJava.close();

【问题讨论】:

    标签: java pdf itext itextpdf


    【解决方案1】:

    您要求的东西应该是微不足道的,但事实并非如此。请查看MergeWithToc 示例。您会看到合并 PDF 的代码是正确的,但在我的示例中,我添加了一项额外功能:

    chunk = new Chunk(String.format("Page %d", pageNo));
    if (i == 1)
        chunk.setLocalDestination("p" + pageNo);
    ColumnText.showTextAligned(stamp.getUnderContent(),
        Element.ALIGN_RIGHT, new Phrase(chunk), 559, 810, 0);
    

    对于每一页,我都将一个命名的目的地定义为本地目的地。我们使用p 后跟页码作为其名称。

    我们将在一个额外的页面中使用这些命名的目的地作为 TOC:

    PdfReader reader = new PdfReader(SRC3);
    page = copy.getImportedPage(reader, 1);
    stamp = copy.createPageStamp(page);
    Paragraph p;
    PdfAction action;
    PdfAnnotation link;
    float y = 770;
    ColumnText ct = new ColumnText(stamp.getOverContent());
    ct.setSimpleColumn(36, 36, 559, y);
    for (Map.Entry<Integer, String> entry : toc.entrySet()) {
        p = new Paragraph(entry.getValue());
        p.add(new Chunk(new DottedLineSeparator()));
        p.add(String.valueOf(entry.getKey()));
        ct.addElement(p);
        ct.go();
        action = PdfAction.gotoLocalPage("p" + entry.getKey(), false);
        link = new PdfAnnotation(copy, 36, ct.getYLine(), 559, y, action);
        stamp.addAnnotation(link);
        y = ct.getYLine();
    }
    ct.go();
    stamp.alterContents();
    copy.addPage(page);
    

    在我的示例中,我假设目录适合单个页面。您必须跟踪 y 值并在其值低于底部边距时创建一个新页面。

    如果您希望 TOC 成为第一页,则需要重新对页面重新排序。这显示在 MergeWithToc2 示例中:

    reader = new PdfReader(baos.toByteArray());
    n = reader.getNumberOfPages();
    reader.selectPages(String.format("%d, 1-%d", n, n-1));
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(filename));
    stamper.close();
    

    【讨论】:

    • 感谢它工作正常,但 toc 终于生成了。我可以在 pdf 的开头添加 toc 吗?
    • 我为我的答案创建了一个新示例,在创建 PDF 后重新排序页面。
    • 非常感谢您创建完整的示例。您能否提供链接,让我了解更多有关页面重新排序的信息,因为我可能需要重新排序多个页面(当多个索引页面时)。
    • 发布一个新问题,我将使用PdfStamper 的页面重新排序语法来回答。
    • 你好布鲁诺请参考这个链接stackoverflow.com/questions/21600040/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 2015-08-04
    相关资源
    最近更新 更多