我已阅读帖子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();
我哪里出错或有更好的方法?
答案 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
对象。