需求
项目中打印使用的是print.js,但是printjs在打印pdf时一次只能打印一个pdf,需要支持打印多个pdf
解决方式
将多个pdf合并成一个,然后打印
实现
1、安装依赖
npm install print-js
npm install pdf-lib
2、代码
import printJS from 'print-js'
import * as pdfLib from 'pdf-lib'
// 打印方法
async print() {
// 创建一个pdf文档用来保存合并后的文件
const pdfDocument = await pdfLib.PDFDocument.create()
// 循环pdf数据,这里后端返回的文件是base64格式
for (const data of pdfBase64Data) {
// 将base64格式转换成二进制
// 格式转换的时候,记得把data:application/pdf;base64,去掉
const arrayBuffer = await this.base64ToArrayBuffer(data) // 得到二进制格式数据
// 复制pdf中的页面到新pdf中
const pdfDoc = await pdfLib.PDFDocument.load(arrayBuffer)
const copyPage = await pdfDocument.copyPages(pdfDoc, pdfDoc.getPageIndices())
copyPage.forEach(item => {
pdfDocument.addPage(item)
})
}
// 保存合并后的pdf文件,得到的是一个二进制数据
const pdf = await pdfDocument.save()
// 将二进制的数据转换为base64,因为打印pdf时用的是base64格式
const pdfFile = await this.arrayBufferToBase64(pdf)
// 如果文件太大,打开的预览页面有可能会出现是空白的情况,加个setTimeout可以解决
printJS({
printable: pdfFile,
type: 'pdf',
base64: true
})
}
// base64转二进制
base64ToArrayBuffer(base64) {
let binaryString = ''
if (base64.indexOf('data:') === 0) {
const arr = base64.split(',')
binaryString = window.atob(arr[1])
} else {
binaryString = window.atob(base64)
}
const len = binaryString.length
const bytes = new Uint8Array(len)
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i)
}
return bytes.buffer
},
// 二进制转base64
arrayBufferToBase64(buffer) {
let binary = ''
const bytes = new Uint8Array(buffer)
const len = bytes.byteLength
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i])
}
// 对二进制字符串进行Base64编码
return window.btoa(binary)
},
其他
1、printjs提供了一个回调,在预览弹窗关闭时触发,不闲弹窗多的情况下也可以用这种方式实现批量打印
2、如果批量打印时的数据有图片也有pdf,就可以使用onPrintDialogClose去分别调用
printJS({
printable: pdf,
type: 'pdf',
base64: true,
onPrintDialogClose: this.LoopPrintPdf // 需要传参就写成箭头函数() => this.LoopPrintPdf(data)
})