注意一、
使用jspdf将图片(jpg/jpeg/png/bmp)转pdf(记为pdfA),得到的pdf(pdfA)和需要合并的pdf(记为pdfB)类型不一致,需要将pdfA转为pdfB类型,才能合并,使用arraybuffer转,具体如下
// pdf--pdfA--是使用jspdf将图片生成的pdf
// file--pdfB--是合并pdf需要的pdf格式
const jsPdfBytes = pdf.output('arraybuffer');
const file = await PDFDocument.load(jsPdfBytes);
注意二、
jspdf 可转pdf的图片类型有jpg、jpeg、png、bpm,
不支持 tif 和 tiff 图片类型
.tif和.tiff格式的文件需要通过安装依赖
“tiff.js”: “^1.0.0”,
也是使用arrayBuffer,将图片格式转为base64,(jpg/jpeg格式,然后将该格式通过jspdf转为pdf文件)
if(x.FILE_TYPE == '.tif' || x.FILE_TYPE == '.tiff' ){
const response = await fetch(imgUrl);
const buffer = await response.arrayBuffer();
const Tiff = require("tiff.js");
const tiff = new Tiff({ buffer });
imgUrl = tiff.toDataURL();
}
注意三、
async/await 和 new Promise 控制异步任务顺序执行,执行完imgToPdf()方法,再执行合并pdf 方法
注意四、
jspdf 将图片转为pdf,注意图片大小的自适应,可以通过设置图片的最大宽度来控制图片自适应的大小
const imageWidth = 100;
注意五、
因为异步任务执行可能导致批量选择文件的顺序与实际获得的文件顺序不一致,所以获取到的this.pdfFileArr,需要通过id 调整为正确的pdf文件打印顺序
图片转pdf代码:
async imgToPdf(arr) {
const promises = [];
arr.forEach(async (x)=>{
const promise = new Promise(async (resolve,reject)=>{
//jsPdf 仅支持JPG/JPEG/PNG/BMP格式,不支持tif
let id = x.ID
let imgUrl = window.URL.createObjectURL(x.FILE)
//如果是tif或者tiff文件,需要转化后再进行 图片转pdf操作
if(x.FILE_TYPE == '.tif' || x.FILE_TYPE == '.tiff' ){
const response = await fetch(imgUrl);
const buffer = await response.arrayBuffer();
const Tiff = require("tiff.js");
const tiff = new Tiff({ buffer });
imgUrl = tiff.toDataURL();
}
const pdf = new jsPDF();
//添加header
//pdf.text('PDF Header', 10, 10);
// 将图片绘制到pdf中
const imageWidth = 100; // 设定图片的最大宽度
const imageHeight = 0; // 设置为 0,将根据宽度等比例计算高度
const img = new Image();
img.src = imgUrl
let finalWidth = imageWidth;
let finalHeight = imageHeight;
img.onload = function () {
const width = img.width;
const height = img.height;
// 计算图片适应 PDF 页面的尺寸
const aspectRatio = width / height;
if (finalHeight === 0) {
finalHeight = finalWidth / aspectRatio;
} else if (finalWidth === 0) {
finalWidth = finalHeight * aspectRatio;
}
};
// 添加图片到 PDF
pdf.addImage(imgUrl, 'JPEG', 10, 10, finalWidth, finalHeight, null, 'SLOW')
const jsPdfBytes = pdf.output('arraybuffer');
const file = await PDFDocument.load(jsPdfBytes);
//const blob = new Blob([file], { type: 'application/PDF' })
let obj = {
ID: id,
FILE: file
}
console.log("执行了------imgToPdf")
resolve(obj)
}).then((obj)=>{
this.pdfFileArr.push(obj)
}).catch((error)=>{
this.loadLoading = false
alert('错误信息为:'+error)
})
promises.push(promise);
})
return Promise.all(promises)
},
合并pdf代码
async mergePdf(sortList) {
console.log('最终需要合并的pdf数组', sortList)
let files = sortList
// 创建一个新的PDF文档
const mergedPdf = await PDFDocument.create();
// 遍历选择的每个文件
for (let i = 0; i < files.length; i++) {
/**
这里为.pdf 文件的遍历操作
通过FileReader 读取.pdf文件,转为合并pdf所需要的pdf类型
const file = files[i];
const url = window.URL.createObjectURL(file)
const reader = new FileReader();
// 读取文件内容
const fileContents = await new Promise((resolve, reject) => {
reader.onload = function (event) {
resolve(event.target.result);
};
reader.onerror = function (event) {
reject(new Error("文件读取错误。"));
};
reader.readAsArrayBuffer(file); //blob
});
// 将PDF文件添加到合并的PDF文档中
const pdf = await PDFDocument.load(fileContents);
console.log("合并pdf---", pdf)
**/
const pdf = files[i];
const copiedPages = await mergedPdf.copyPages(
pdf,
pdf.getPageIndices()
);
copiedPages.forEach((page) => {
mergedPdf.addPage(page);
});
}
const uint8Array = await mergedPdf.save();
let mergeBuffer = Buffer.from(uint8Array);
const url = window.URL.createObjectURL(new Blob([mergeBuffer], { type: 'application/pdf;charset=utf-8' }));
this.mergePdfUrl = url
console.log("pdf合并完成")
console.log("新合并的pdf--", url)
console.log("新合并的pdf--", mergedPdf)
},
将获得的pdf文件url给iframe即可预览,iframe 自带toolbar工具栏打印
<iframe ref="printPdf" id="printIframe"
style="overflow:hidden;filter: Chroma(Color=white);border: none;width: 100%; height: 100%"
:src="item.url + '#toolbar=0'"></iframe>
<!-- #view=FitH,top -->
如果自己编写打印接口,可以通过id获取到该iframe,
调起 contentWindow.print() 即可打印该dom元素
document.getElementById('printIframe').contentWindow.print();