2013-07-22 92 views
4

我正在使用pdfbox来操作PDF内容。我有一个很大的PDF文件(比如500页)。我还有一些其他单页PDF文件,其中只包含单个图像,每个文件最大大小为8-15kb。我需要做的是将这些单页PDF导入到大PDF文件的特定页面上。PDFBox LayerUtility - 将图层导入到现有PDF中

我已经尝试了pdfbox的LayerUtility,我已经成功了,但它创建了一个非常大的文件作为输出。源代码pdf在处理之前大约为1MB,并且在添加较小的pdf文件时,大小可以达到64MB。有时我需要将两个较小的PDF包含在较大的PDF中。

有没有更好的方法来做到这一点,或者我只是做这个错误?下面张贴尝试添加两层到单个页面代码:

... 
... 
.. 
overlayDoc[pCounter] = PDDocument.load("data\\" + overlay + ".pdf"); 
outputPage[pCounter] = (PDPage) overlayDoc[pCounter].getDocumentCatalog().getAllPages().get(0); 

LayerUtility lu = new LayerUtility(overlayDoc[pCounter]); 
form[pCounter] = lu.importPageAsForm(bigPDFDoc, Integer.parseInt(pageNo)-1); 
lu.appendFormAsLayer(outputPage[pCounter], form[pCounter], aTrans, "OVERLAY_"+pCounter); 
outputDoc.addPage(outputPage[pCounter]); 

mOverlayDoc[pCounter] = PDDocument.load("data\\" + overlay2 + ".pdf");      
mOutputPage[pCounter] = (PDPage) mOverlayDoc[pCounter].getDocumentCatalog().getAllPages().get(0); 

LayerUtility lu2 = new LayerUtility(mOverlayDoc[pCounter]); 
mForm[pCounter] = lu2.importPageAsForm(outputDoc, outputDoc.getNumberOfPages()-1); 
lu.appendFormAsLayer(mOutputPage[pCounter], mForm[pCounter], aTrans, "OVERLAY_2"+pCounter); 

outputDoc.removePage(outputPage[pCounter]); 
outputDoc.addPage(mOutputPage[pCounter]); 
... 
... 
+0

您的代码不幸的是,有些不完整。如何将其他页面放入outputDoc并不明显。 'pCounter'变量似乎表明您对每个页面执行类似于上面的操作,在这种情况下,文件大小爆炸并不奇怪,因为涉及一些深度副本可能会使共享资源倍增。 – mkl

+0

是的,pCounter是理想的页面总数。我唯一的选择是使用数组,因为上面的代码在循环中运行,直到保存outputDoc,我需要将每个页面的数据存储在单独的地方,或者我碰到COSVisitor异常。有没有更好的方法来做到这一点?我怎样才能限制资源?我无法使用叠加类,因为它没有选择性叠加页面的功能。任何帮助表示赞赏! –

回答

3

随着像下面的我没有看到大小的任何unepected增长代码:

PDDocument bigDocument = PDDocument.load(BIG_SOURCE_FILE); 
LayerUtility layerUtility = new LayerUtility(bigDocument); 
List bigPages = bigDocument.getDocumentCatalog().getAllPages(); 

// import each page to superimpose only once 
PDDocument firstSuperDocument = PDDocument.load(FIRST_SUPER_FILE); 
PDXObjectForm firstForm = layerUtility.importPageAsForm(firstSuperDocument, 0); 

PDDocument secondSuperDocument = PDDocument.load(SECOND_SUPER_FILE); 
PDXObjectForm secondForm = layerUtility.importPageAsForm(secondSuperDocument, 0); 

// These things can easily be done in a loop, too 
AffineTransform affineTransform = new AffineTransform(); // Identity... your requirements may differ 
layerUtility.appendFormAsLayer((PDPage) bigPages.get(0), firstForm, affineTransform, "Superimposed0"); 
layerUtility.appendFormAsLayer((PDPage) bigPages.get(1), secondForm, affineTransform, "Superimposed1"); 
layerUtility.appendFormAsLayer((PDPage) bigPages.get(2), firstForm, affineTransform, "Superimposed2"); 

bigDocument.save(BIG_TARGET_FILE); 

正如你看到的我叠加第一页FIRST_SUPER_FILE两页的目标文件但我只有导入页面一次。因此,该导入页面的资源也只能导入一次。

此方法也是循环打开的,但不会多次导入同一页面!相反,将所有必需的模板页面作为表单一次性导入,并在后面的循环中一次又一次地引用这些表单。

(我希望这能解决您的问题。如果不是,提供更多的代码和样品PDF文件重现您的问题。)

+0

感谢您的帮助MKL。非常感谢。我已经尝试了上述方法(有点不同),但是这里的问题在于,导入FIRST_SUPER_FILE,SECOND_SUPER_FILE的窗体显示在原始页面上,并且不作为叠加层。该图层覆盖原始页面的内容。这就是我需要使用FIRST_SUPER_FILE然后从BIG_SOURCE_FILE顶部导入页面的原因。有没有其他方法可以做到这一点?是否有可以为图层设置的索引级别?如果有的话,这会让我的生活更轻松! –

+1

如果你想干净地做(即不扩大文件大小),你必须稍微改进'LayerUtility'。该实用程序类只知道如何追加**表单('appendFormAsLayer'),这意味着该表单处于前台。您需要一种方法来**预先填写**表格。由于在现有方法中使用的'PDPageContentStream'构造函数也只知道如何替换或追加,所以您或者必须改进该类,或者创建一个类似工作的辅助方法,但预先添加新的内容流而不是追加。 – mkl

相关问题