首页 > 解决方案 > 使用 Itext 链接 Portable Collection 的 pdf

问题描述

我有便携式集合,总共有两个 pdf 文档。我的要求是,如果我打开一个 pdf 文档并单击链接或任何文本,它应该重定向到该便携式集合的另一个 pdf。

例如:考虑在可移植集合中有两个 pdf,即 Programming.pdf 和 Java.pdf。如果我单击 Programming.pdf 中的任何特定文本或变量,它应该重定向到 Java.pdf。可能吗...?。

标签: pdfitext

解决方案


要在可移植集合中的文档之间导航,您必须使用Embedded Go-To actions。它们特别包含一个T目标字典,它实际上可以作为目标字典链的开始,以在具有任意嵌入深度的集合成员之间导航。要在同级文档之间导航,您需要一个目标字典上升到包含另一个目标字典的父文档,该目标字典再次从该父级下降到所需的同级。有关详细信息,请参阅。ISO 32000-2 第 12.6.4.4 节“嵌入式 Go-To 操作”。

在 iText 5.x 中,您可以构建这样的嵌入式 goto 操作:

PdfTargetDictionary sibbling = new PdfTargetDictionary(true);
sibbling.setEmbeddedFileName(linkId);
PdfTargetDictionary parent = new PdfTargetDictionary(sibbling);
Chunk chunk = new Chunk("Go to " + linkId + ".");
PdfDestination dest = new PdfDestination(PdfDestination.XYZ, -1, -1, 0);
dest.addFirst(new PdfNumber(0));
PdfAction action = PdfAction.gotoEmbedded(null, parent, dest, false);
chunk.setAction(action);
document.add(chunk);

(来自EmbeddedLinks助手createPage

例如,以下测试创建了一个包含四个文档 A、B、C 和 D 的投资组合,它们都包含彼此的链接:

public void testLinkToSibblingInPortfolio() throws IOException, DocumentException {
    Files.write(new File("portfolio-with-embedded-gotos.pdf").toPath(), createPdf(new String[] {"A", "B", "C", "D"}));
}

public byte[] createPdf(String[] allIds) throws DocumentException, IOException {
    Document document = new Document();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfWriter writer = PdfWriter.getInstance(document, baos);
    document.open();
    document.add(new Paragraph("This document contains a collection of PDFs."));

    PdfCollection collection = new PdfCollection(PdfCollection.HIDDEN);
    PdfCollectionSchema schema = getCollectionSchema(); 
    collection.setSchema(schema);
    PdfCollectionSort sort = new PdfCollectionSort("TITLE");
    collection.setSort(sort);
    collection.setInitialDocument("A");
    writer.setCollection(collection);

    PdfFileSpecification fs;
    PdfCollectionItem item;
    for (String id : allIds) {
        fs = PdfFileSpecification.fileEmbedded(writer, null,
            String.format("%s.pdf", id),
            createPage(id, allIds));
        fs.addDescription(id, false);

        item = new PdfCollectionItem(schema);
        item.addItem("TITLE", id);
        fs.addCollectionItem(item);
        writer.addFileAttachment(fs);
    }

    document.close();
    return baos.toByteArray();
}

public byte[] createPage(String id, String[] allIds) throws DocumentException, IOException {
    Document document = new Document();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfWriter.getInstance(document, baos);
    document.open();

    Paragraph p = new Paragraph(id,
        FontFactory.getFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED, 48));
    document.add(p);

    for (String linkId : allIds) {
        if (!id.equals(linkId)) {
            PdfTargetDictionary sibbling = new PdfTargetDictionary(true);
            sibbling.setEmbeddedFileName(linkId);
            PdfTargetDictionary parent = new PdfTargetDictionary(sibbling);
            Chunk chunk = new Chunk("Go to " + linkId + ".");
            PdfDestination dest = new PdfDestination(PdfDestination.XYZ, -1, -1, 0);
            dest.addFirst(new PdfNumber(0));
            PdfAction action = PdfAction.gotoEmbedded(null, parent, dest, false);
            chunk.setAction(action);
            document.add(chunk);
        }
    }

    document.close();
    return baos.toByteArray();
}

private static PdfCollectionSchema getCollectionSchema() {
    PdfCollectionSchema schema = new PdfCollectionSchema();

    PdfCollectionField size = new PdfCollectionField("File size", PdfCollectionField.SIZE);
    size.setOrder(2);
    schema.addField("SIZE", size);

    PdfCollectionField filename = new PdfCollectionField("File name", PdfCollectionField.FILENAME);
    filename.setVisible(false);
    schema.addField("FILE", filename);

    PdfCollectionField title = new PdfCollectionField("Title", PdfCollectionField.TEXT);
    title.setOrder(0);
    schema.addField("TITLE", title);

    return schema;
}

EmbeddedLinks测试testLinkToSibblingInPortfolio和帮助程序createPdfcreatePagegetCollectionSchema

这实际上从 iText 示例KubrickBoxKubrickCollectionKubrickMovies中借鉴了很多。


使用当前的 iText 5 开发版本 5.5.14-SNAPSHOT 进行测试。


推荐阅读