在之前项目有个功能中需要做多个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