2013-07-22 42 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

相關問題