前言
本章主要讲解JAVA中怎么进行PDF合并
并响应给前端 前端进行预览操作
IO实战代码 主要是记录一些常用 但是很容易忘记的IO流操作
欢迎查看👉🏻👉🏻👉🏻JAVA IO 专栏 查漏补缺 指教一二
虽然你现在用不到 但是未来你一定用得到 🥸
POM依赖
引入下方依赖 后续代码都是在这个版本进行开发 不同版本可能会有些依赖报错
pom
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.16</version>
<type>pom</type>
</dependency>
java代码
文档合并
java
/**
* 将pdf文档转换成字节数组
*
* @return 返回对应PDF文档的字节数组
*/
private static byte[] getPdfBytes(InputStream inputStream) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] data = new byte[2048];
int len;
while ((len = inputStream.read(data)) != -1) {
out.write(data, 0, len);
}
return out.toByteArray();
}
/**
* 基于内存中的字节数组进行PDF文档的合并
*
* @param firstPdf 第一个PDF文档
* @param secondPdf 第二个PDF文档
*/
private static byte[] mergePdfBytes(byte[] firstPdf, byte[] secondPdf) {
try {
if (firstPdf != null && secondPdf != null) {
// 创建字节数组,基于内存进行合并
ByteArrayOutputStream bass = new ByteArrayOutputStream();
PdfDocument destDoc = new PdfDocument(new PdfWriter(bass));
// 合并的pdf文件对象
PdfDocument firstDoc = new PdfDocument(new PdfReader(new ByteArrayInputStream(firstPdf)));
PdfDocument secondDoc = new PdfDocument(new PdfReader(new ByteArrayInputStream(secondPdf)));
// 合并对象
PdfMerger merger = new PdfMerger(destDoc);
merger.merge(firstDoc, 1, firstDoc.getNumberOfPages());
merger.merge(secondDoc, 1, secondDoc.getNumberOfPages());
// 关闭文档流
merger.close();
firstDoc.close();
secondDoc.close();
destDoc.close();
return bass.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
log.error("合并PDF文件失败 {}", e.getMessage());
}
return null;
}
调用
参数 List<InputStream> inputStreamList
自行将pdf转换 是需要合并的pdf流
例如: // xxx.pdf 填入pdf 路径路径 InputStream fileInputStream = new FileInputStream(new File("xxx.pdf"));
java
/**
* @param response 响应
* @param inputStreamList 文件流列表
* @throws Exception 异常处理
*/
private void handleResponse(HttpServletResponse response,
List<InputStream> inputStreamList) throws Exception {
if (CollUtil.isNotEmpty(inputStreamList)) {
// 处理响应
int size = inputStreamList.size();
byte[] pdfData = getPdfBytes(inputStreamList.get(0));
for (int i = 1; i < size; i++) {
pdfData = mergePdfBytes(pdfData, getPdfBytes(inputStreamList.get(i)));
}
if (pdfData != null) {
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=merged.pdf");
try (OutputStream outputStream = response.getOutputStream()) {
outputStream.write(pdfData);
outputStream.flush();
}
}
}
}
代码直接复制后段合并逻辑就处理完成了
前端接收
因为请求方式不同所有自行修改 只是给一个例子
请求一定要带上 responseType: "blob"
js
export function expressService(waybillNoList) {
return request({
url: 'xxx' ,
method: 'get',
responseType: "blob"
})
}
预览打印
js
async expressServiceData() {
try {
this.buttonLoading = true;
const response = await expressService(this.expressServicelist);
this.buttonLoading = false;
const pdfBlob = new Blob([response.data], {
type: "application/pdf",
});
const blobUrl = URL.createObjectURL(pdfBlob);
const printWindow = window.open(blobUrl, "_blank");
// 等待新窗口加载完成后触发打印
printWindow.onload = function () {
printWindow.print();
};
} catch (error) {
this.buttonLoading = false;
console.error("Error calling expressService:", error);
}
},