Java 将页面添加为第n页

Java 将页面添加为第n页,java,pdf,itext,Java,Pdf,Itext,我有两个PDF文件: Master.pdf:包含带有书签、大纲(目录)的页面 Child.pdf:只有一页的文件 Child.pdf页面需要作为第n页(在我的示例中为第10页)附加到Master.pdf 生成的PDF应该为新页面提供一个新的大纲项(一个新书签)。此外,现有的书签应该可以正常工作。实际上:应该重构现有的大纲树 我可以通过iTextAPI实现这一点吗?有什么有用的样品吗 public class ConcatenateBookmarks { public static fin

我有两个PDF文件:

  • Master.pdf:包含带有书签、大纲(目录)的页面
  • Child.pdf:只有一页的文件
  • Child.pdf页面需要作为第n页(在我的示例中为第10页)附加到Master.pdf

    生成的PDF应该为新页面提供一个新的大纲项(一个新书签)。此外,现有的书签应该可以正常工作。实际上:应该重构现有的大纲树

    我可以通过iTextAPI实现这一点吗?有什么有用的样品吗

    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);
        }
    }
    
    公共类连接电子书标记{
    公共静态最终字符串SRC1=“C:\\C\\spring in action.pdf”;
    公共静态最终字符串SRC2=“C:\\C\\SPD-DUAL DS.pdf”;
    公共静态最终字符串DEST=“C:\\C\\final.pdf”;
    /**
    *操作PDF文件src,结果为文件dest
    * 
    *@param src
    *原始PDF
    *@param dest
    *生成的PDF
    *@抛出异常
    *@DocumentException
    */
    public void manipulatedpf(String[]src,String dest)抛出IOException,DocumentException{
    int点=3;
    文档=新文档();
    PdfSmartCopy copy=新的PdfSmartCopy(文档,新文件输出流(dest));
    document.open();
    PDF阅读器;
    int page_offset=0;
    int n;
    //为书签创建一个列表
    ArrayList bookmarks=新建ArrayList();
    列出tmp;
    对于(int i=0;i<1/*src.length*/;i++){
    读卡器=新的PDF读卡器(src[i]);
    PdfReader reader2=新的PdfReader(src[1]);
    int pageScont=reader2.getNumberOfPages();
    页面偏移量=页面浏览量;
    如果(i==0){
    HashMap map=SimpleNamedDestination.getNamedDestination(读取器,false);
    exportToXML(映射,新文件输出流(dest),“ISO8859-1”,false);
    复制.addNamedDestinations(映射,0);
    }
    tmp=SimpleBookmark.getBookmark(阅读器);
    //这一水平必须提高
    //分居到
    //换衣服
    //应该转移
    SimpleBookmark.shiftPageNumbers(tmp,页码偏移,
    新的int[]{POINT,reader.getNumberOfPages()+PageScont});
    bookmarks.addAll(tmp);
    //添加页面
    n=reader.getNumberOfPages();
    第u页偏移量+=n;
    对于(int page=0;page
    请看一下示例。我使用了
    PdfStamper
    而不是
    PdfCopy
    ,但是您真正需要的代码是适应
    PdfOutline
    的代码

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

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

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

    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
    实例中获取大纲树,您可以创建自己的
    条目
    ,将其添加到
    大纲
    中,然后可以使用
    setOutlines()
    方法将更新的大纲放回
    PdfStamper
    实例中。(您已经为
    PdfCopy
    PdfSmartCopy
    类找到了类似的方法):


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

    向我们展示您已经尝试过的内容。给我们看看你的密码。请原谅。现在就添加代码。谢谢布鲁诺。我试试这个,然后告诉你。非常感谢你的合作。
    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);
    
    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);
    }