PDFBox在指定页码处拆分为3(插入pdf)

时间:2016-03-12 23:33:02

标签: java pdfbox

我已阅读帖子How to split a PDF using Apache PDFBox?How to merge two PDF files into one in Java?但是,它只展示了如何在每个页面或相同的chucks中拆分它,而addSource()的合并apis似乎只有文件字符串 InputStream PDDocument。

我想将一页pdf文件插入指定页码的较大pdf文件(比如100页)的3个位置,例如因此,我需要在第3页,第7页,第10页拆分较大的文档,然后插入一页pdf doc,然后将所有拆分部分合并到一个新的pdf文件中。

我试图做如下:

        PDDocument doc;
        PDDocument onePage;
        Splitter splitDoc = new Splitter();
        PDFMergerUtility mergedDoc = new PDFMergerUtility();

        onePage = PDDocument.load("/path/onepage.pdf");
        doc = PDDocument.load("/path/hundredpages.pdf");
        splitDoc.setSplitAtPage(1); // inefficient
        // is there a better solution for split?
        List<PDDocument> splitDocs = splitDoc.split(doc);

        for (int i=0; i<splitDocs.size(); i++) {

            if (i==2 || i==7 || i==10) { // only to demonstrate

                mergeFiles.addSource(onePage); // see comment below

            } else {

                // doesn't accept PDDocument 
                // what's the alternative without resorting to InputStream
                mergeFiles.addSource(splitDocs.remove(0)); 

            }


        }

        mergedDoc.setDestinationFileName("/path/mergeddoc.pdf");
        mergedDoc.mergeDocuments();

我哪里出错或有更好的方法?

1 个答案:

答案 0 :(得分:1)

这个答案是关于你真正想要达到的目标,即

  

我想将一页pdf文件插入到指定页码的较大pdf文件(例如100页)的3个位置,例如第3,7和10页。

而不是你认为你必须做的事情,即

  

因此,我需要在第3页,第7页,第10页拆分较大的文档,然后插入一页pdf doc,然后将所有拆分部分合并到一个新的pdf文件中。 < / p>

此外,我假设您仍在使用PDFBox版本1.8.x,而不是2.0.0版本候选版本。

要将页面插入文档(由PDDocument实例表示),您实际上不必拆分和重新合并该文档,只需在给定索引处添加页面即可。因此,我们可以简化方法。

但与此同时,您的任务中还有一个细节再次使其复杂化:您无法多次将相同的页面对象插入到同一目标文档中,至少需要创建一个浅层副本。 / p>

考虑到这一点,你可以将一页pdf文件插入3个更大的pdf 的位置:

PDDocument document = ...;
PDDocument singlePageDocument = ...;
PDPage singlePage = (PDPage) singlePageDocument.getDocumentCatalog().getAllPages().get(0);

PDPageNode rootPages = document.getDocumentCatalog().getPages();
rootPages.getKids().add(3-1, singlePage);
singlePage.setParent(rootPages);
singlePage = new PDPage(new COSDictionary(singlePage.getCOSDictionary()));
rootPages.getKids().add(7-1, singlePage);
singlePage = new PDPage(new COSDictionary(singlePage.getCOSDictionary()));
rootPages.getKids().add(10-1, singlePage);
rootPages.updateCount();

document.save(...);

InsertPages.java方法testInsertPages

小心, 但是,此代码假设是一个平面页面树。如果页面树更深,则必须以不同方式遍历页面列表:要将页面作为第n个文档页面插入,您不能简单地将其添加到位置n-1到页面根目录,而是必须检查它的孩子一个接一个,如果来到内部PDPageNode对象,你必须读取它的Count值来检查它包含的页数;如果此数字暗示要插入的位置包含在其中,则必须递归到该内部PDPageNode对象。