前段时间遇到了这么个需求,需要根据后端返回的多个pdf流(如下图),整合成一个pdf文件并打印,在这里分享一下我使用的方法
使用到的工具:
pdf.js:教程站内有,可以查看一下,
pdf-poppler:使用以下代码下载依赖
$ npm install pdf-poppler
代码:
<script>
export default {
data() {
return {
tableNowSelectionData:[],//el-table多选选中的数据
allPrintData:[],//点击print时深拷贝el-table多选选中的数据
testData:[],//用于保存返回后的pdf流
}
},
watch:{
testData(newVal, oldVal) {
if (newVal.length == this.allPrintData.length) {
//利用侦听器,如果testData的数据长度等于allPrintData的长度,说明所有的pdf流文件都拿到了,将他们传入batchPrintPDF函数
this.batchPrintPDF(newVal);
}
},
},
methods:{
print(){
this.testData = [];//清空保存的pdf流
this.allPrintData = JSON.parse(
JSON.stringify(this.tableNowSelectionData)
);//点击print时深拷贝el-table多选选中的数据
for (let item of this.tableNowSelectionData) {//循环选中的数据发送请求
let obj = {
id:item.id,
};//obj为根据需求需要传给后端的数据
axios({//这是使用原生axios是因为使用封装后的axios拿到的pdf会莫名变成空白,但是原生axios就不会有这个问题
url: downloadUrl,//请求地址,如果跨域需要做反向代理配置
method: "post",
data: obj,
responseType: "arraybuffer",
})
.then(async (res) => {
console.log(res);//返回的数据如下图,res.data才是我们需要的数据
this.testData.push(res.data);//将返回的pdf流push进testData
})
.catch((err) => {
this.$message.error("打印失败", err);
});
}
},
batchPrintPDF(pdfList) {
let arr = [];
pdfList.map((item, index) => {
const binaryData = [];
binaryData.push(item);
let url = window.URL.createObjectURL(
new Blob(binaryData, {
type: "application/pdf"
})
);
arr.push(url); //将pdf流文件转为blob并存入数组
});
const PDFMerger = require("pdf-merger-js"); //引入合并pdf插件
let merger = new PDFMerger();
let pdfUrl = "";
arr.map(async (item, index) => {
await merger.add(item); //添加需要合并的pdf地址
if (index == arr.length - 1) {
//最后一个pdf地址添加完成后向下执行
const binaryData = [];
let str = await merger.saveAsBuffer(); //拿到合并后的二进制文件
binaryData.push(str.buffer);//转buffer格式
pdfUrl = await window.URL.createObjectURL(
new Blob(binaryData, {
type: "application/pdf"
})
);//将buffer格式转为blob格式
let printData = await [pdfUrl];
printJS({
printable: printData,
type: "pdf",
}); //调用浏览器打印
}
});
}
},
}
</script>
(此图为上方print函数发送请求返回的数据例字,data为需要使用的数据)