当前位置: 首页 > 知识库问答 >
问题:

将页面添加为第n页

微生青青
2023-03-14

我有两个pdf:

  1. 主人。pdf:包含带有书签、大纲(目录)的页面
  2. 孩子。pdf:只有一页的文件

child.pdf页需要作为第n页(在我的情况下为第10页)附加到Master.pdf.

生成的PDF应该为新页面添加一个新的大纲项(一个新的书签)。现有的书签应该保持正常工作。实际上:现有的大纲树应该重构。

我可以通过iText应用编程接口实现这一点吗?有任何有用的示例吗?

public class ConcatenateBookmarks {
    public static final String SRC1 = "C:\\c\\spring-in-action.pdf";
    public static final String SRC2 = "C:\\c\\SPD-DUAL DS.pdf";
    public static final String DEST = "C:\\c\\final.pdf";

    /**
     * Manipulates a PDF file src with the file dest as result
     * 
     * @param src
     *            the original PDF
     * @param dest
     *            the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String[] src, String dest) throws IOException, DocumentException {
        int POINT = 3;
        Document document = new Document();
        PdfSmartCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
        document.open();
        PdfReader reader;
        int page_offset = 0;
        int n;
        // Create a list for the bookmarks
        ArrayList<HashMap<String, Object>> bookmarks = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> tmp;
        for (int i = 0; i < 1/* src.length */; i++) {
            reader = new PdfReader(src[i]);
            PdfReader reader2 = new PdfReader(src[1]);
            int pagesCount = reader2.getNumberOfPages();
            page_offset = pagesCount;
            if (i == 0) {
                HashMap<String, String> map = SimpleNamedDestination.getNamedDestination(reader, false);
                SimpleNamedDestination.exportToXML(map, new FileOutputStream(dest), "ISO8859-1", false);
                copy.addNamedDestinations(map, 0);
            }
            tmp = SimpleBookmark.getBookmark(reader);
            // this level have to
            // separate up to n don't
            // change and after the
            // should shift
            SimpleBookmark.shiftPageNumbers(tmp, page_offset,
               new int[] { POINT, reader.getNumberOfPages() + pagesCount });
            bookmarks.addAll(tmp);
            // add the pages
            n = reader.getNumberOfPages();
            page_offset += n;
            for (int page = 0; page < n;) {
                copy.addPage(copy.getImportedPage(reader, ++page));
                if (page == POINT) // add child pages to nth point
                {
                    for (int page2 = 0; page2 < pagesCount;) {
                        copy.addPage(copy.getImportedPage(reader2, ++page2));
                    }
                }
            }
            copy.freeReader(reader);
            reader.close();
        }
        // Add the merged bookmarks
        copy.setOutlines(bookmarks);
        // step 5
        document.close();
    }
    /**
     * Main method.
     * 
     * @param args
     *            no arguments needed
     * @throws DocumentException
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, DocumentException, SQLException {
        new ConcatenateBookmarks().manipulatePdf(new String[] { SRC1, SRC2 }, DEST);
    }
}

共有1个答案

臧彭亮
2023-03-14

请看看InsertAndAdaptOutline示例,我使用了PdfStamper而不是PdfCopy,但您真正需要的代码是适应PdfOutline的代码。

在我的代码中,我有一个名为bookmarks.pdf的文件:

我插入一个单独的页面“Hello World”,这样它就是第4页(在您的情况下,将第4页更改为第10页),生成一个名为bookmarks_Hello的文件。pdf

插入页面是一件轻而易举的事:

PdfReader insert = new PdfReader(INSERT);
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(DEST));
stamper.insertPage(4, insert.getPageSize(1));
PdfContentByte cb = stamper.getOverContent(4);
cb.addTemplate(stamper.getImportedPage(insert, 1), 0, 0);
...
stamper.close();

最困难的问题是:如何更新大纲树?您可以从PdfReader实例中获取大纲树,您可以创建自己的条目,并将其添加到大纲中,然后您可以使用setOutline()方法将更新的大纲放回PdfStamper实例中。(您已经为PdfCopyPdfSmartCopy类找到了类似的方法):

List<HashMap<String, Object>> outlines = SimpleBookmark.getBookmark(reader);
HashMap<String, Object> entry = new HashMap<String, Object>();
entry.put("Title", "Hello");
entry.put("Action", "GoTo");
entry.put("Page", "4 Fit");
updateOutline(outlines, entry, 4);
stamper.setOutlines(outlines);

我的updateOutline()方法假设现有的大纲树引用使用GoTo操作的页面:

public boolean updateOutline(List<HashMap<String, Object>> outlines, HashMap<String, Object> entry, int p) {
    int index = 0;
    for (HashMap<String, Object> outline : outlines) {
        Object kids = outline.get("Kids");
        if (kids != null) {
            updateOutline((List<HashMap<String, Object>>)kids, entry, p);
        }
        else {
            if (p < getPage(outline)) {
                outlines.add(index, entry);
                return true;
            }
            index++;
        }
    }
    return false;
}

public int getPage(HashMap<String, Object> outline) {
    Object page = outline.get("Page");
    if (page == null) return -1;
    String p = page.toString().substring(0, page.toString().indexOf(" "));
    return Integer.parseInt(p);
}

如果你的轮廓是以不同的方式创建的,你必须调整updateOutline()方法,但是这个例子应该会给你足够的灵感来了解它是如何完成的。您必须循环浏览大纲树中的所有条目,并在适当的位置插入新的条目。然后将新的、经过修改的大纲树放回生成的PDF中。

 类似资料:
  • 页面窗格以缩略图显示仪表板中的所有页面。 添加一个新页面 在仪表板选项卡中,点击页面窗格上的“+”按钮。 将添加一个空白页到仪表板并已选择。 属性 页面的可用属性: 选项 描述 页面大小 自定义仪表板中页面的大小。 背景 设置页面的背景色。如果你选择“图像填充”,则可以选择图像文件和缩放比例选项。 不透明度 设置图像的不透明度。

  • 页面窗格以缩略图显示仪表板中的所有页面。 添加一个新页面 在仪表板选项卡中,点击页面窗格上的“+”按钮。 将添加一个空白页到仪表板并已选择。 属性 页面的可用属性: 选项 描述 页面大小 自定义仪表板中页面的大小。 背景 设置页面的背景色。如果你选择“图像填充”,则可以选择图像文件和缩放比例选项。 不透明度 设置图像的不透明度。

  • 页面窗格以缩略图显示仪表板中的所有页面。 添加一个新页面 在仪表板选项卡中,点击页面窗格上的“+”按钮。 将添加一个空白页到仪表板并已选择。 属性 页面的可用属性: 选项 描述 页面大小 自定义仪表板中页面的大小。 背景 设置页面的背景色。如果你选择“图像填充”,则可以选择图像文件和缩放比例选项。 不透明度 设置图像的不透明度。

  • 主要内容:将页面添加到PDF文档,示例在前一章中,我们已经学习了如何创建PDF文档。 创建PDF文档后,我们需要添加页面。 现在来了解如何在PDF文档中添加页面。 将页面添加到PDF文档 可以通过实例化类并使用类的方法将其添加到PDF文档来创建空白页面。 以下是创建一个空文档并向其中添加页面的步骤。 第1步:创建空白文档 通过实例化类创建一个空的PDF文档,如下所示。 第2步:创建一个空白页面 类表示PDF文档中的一个页面,因此可以通

  • 问题内容: 如何使用itext从html源向pdf添加标头? 当前,我们扩展了PdfPageEventHelper并覆盖了这些方法。工作正常,但是当我进入2个以上页面时,它将引发RuntimeWorkerException。 问题答案: 通常, 禁止 在事件中添加内容。这是 禁止 添加内容到的对象。您应该使用而 不是 文档在方法中添加页眉和页脚。此外:通过一遍又一遍地解析HTML,您正在浪费大量C

  • 需要新增2个页面 第一个是WebContent/page/simple_role.jsp, 这是authority.jsp页面的外框 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.