在之前項目有個功能中需要做多個PDF合併,而且可能pdf數量會很多,所以在實現了三種方式後做了一下簡單的時間對比
第一種方法
用的spire.doc.free依賴
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc.free</artifactId>
<version>2.0.0</version>
</dependency>
代碼:
File file = new File("m1.pdf");
//合併PDF文檔法一
PdfDocumentBase doc = PdfDocument.mergeFiles(inputStreams.toArray(new InputStream[inputStreams.size()]));
//保存文檔
doc.save(file.getName(), FileFormat.PDF);
doc.close();
// file轉Bytes,後續要用到bytes
bytes = DownLoadUtils.File2byte(file);
mergeFiles的參數可以是流數組InputStream[],也可以是文件名數組String[]等
第二種方法
使用pdfbox依賴
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
代碼:
// 合併PDF文檔法二
File file1 = new File("m2.pdf");
PDFMergerUtility merger = new PDFMergerUtility();
inputStreams.forEach(merger::addSource);
merger.setDestinationFileName(file1.getName());
try {
// 合併PDF
merger.mergeDocuments(null);
} catch (IOException e) {
logger.error("Pdf Merge error: ", e);
}
// file轉Bytes,後續要用到
bytes = DownLoadUtils.File2byte(file1);
除了merger.setDestinationFileName方法,也可以用它的其他類型的方式
第三種方法
用的itext依賴
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.0.8</version>
</dependency>
代碼:
/**
* pdf合併
* @param inputStreams 要合併的pdf的InputStream數組
* @return 合併後的pdf的二進制內容
*/
private static byte[] mergePdfFiles(List<InputStream> inputStreams) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Document document = new Document();// 創建一個新的PDF
byte[] pdfs = new byte[0];
try {
PdfCopy copy = new PdfCopy(document, bos);
document.open();
for (InputStream is : inputStreams) {// 取出單個PDF的數據
PdfReader reader = new PdfReader(DownLoadUtils.InputStream2byte(is));
int pageTotal= reader.getNumberOfPages();
// logger.info("pdf的頁碼數是 ==> {}",pageTotal);
for (int pageNo=1;pageNo<=pageTotal;pageNo++){
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, pageNo);
copy.addPage(page);
}
reader.close();
}
document.close();
pdfs = bos.toByteArray();
bos.close();
copy.close();
} catch (DocumentException | IOException e) {
throw new CommonException("合併PDF出錯:" + e);
}
return pdfs;
}
方法參數和返回類型可以根據自己需要去轉換
PDF合併個數:4
測試耗時對比(控制變量法):
輪次 | 方法一 | 方法二 | 方法三 |
---|---|---|---|
1 | 2471 | 632 | 296 |
2 | 1199 | 2906 | 589 |
3 | 1127 | 371 | 280 |
4 | 1347 | 1592 | 657 |
5 | 1482 | 865 | 323 |
合併後pdf大小 | 88K | 93K | 91K |
簡單的測試也可以比較明顯感覺方法三的效率更快些,
所以我最後在項目中使用了依賴itext去合併pdf