jsPDF+html2canvas实现html转pdf下载+打印
原理:将页面的dom元素通过html2canvas转成canvas,通过canvas.toDataURL('image/jpeg', 1.0);返回一个包含图片展示的 数据URL,通过JsPDF将调用 addImage用法插入图片数据,JsPDF通过addPage添加页面,pdf.autoPrint()自动打印, pdf.save(`${title}.pdf`)生成pdf文件。
缺陷:通过html2canvas转化后有缩放,无论怎么调整,感觉都不够高清,大多数场景都能满足,但是和手动创建word文档打印,还是有差距,若用在重要文档上,业务审核肯定不通过,这个时候就要求无缩放打印,下一章写如何用JsPDF无缩放打印
pdf.addimage()是一个可用于在PDF文件上插入图片的函数,它提供了控制图片大小、压缩质量、图片旋转度数等属性。pdf.addImage(image, format, x, y, width, height, alias, compression, rotation)
参数
1、image:表示要插入的图片资源,可以是图片文件的路径或者base64编码字符串。2、format:表示要插入的图片格式,包括:‘JPEG’, ‘PNG’, ‘GIF’, ‘BMP’, ‘TIFF’, ‘RAW’, ‘JPEG2000’。
3、x:图片在PDF中的x轴坐标,单位为pt(点)。
4、y:图片在PDF中的y轴坐标,单位为pt(点)。
5、width:图片在PDF中的宽度,单位为pt(点)。
6、height:图片在PDF中的高度,单位为pt(点)。
7、alias(可选):指定图片资源的别名。
8、compression(可选):指定图片的压缩质量,取值为0-1之间的浮点数。
9、rotation(可选):指定图片的旋转角度,取值范围为0-360之间的整数
核心代码如下:
/**
* 生成pdf、pdf打印
* @param {*} ele 页面解析后的dom
* @param {*} printParams 打印配置,内部配置参数如下
* @param {*} title 文件名称
* @param {*} type 打印类型
* @param {*} offset 边距
*/
export const printPreviewPDF = (ele, printParams) => {
const { title, type, offset = 15, iframDom, scale} = printParams;
const newDom = ele.cloneNode(true);
newDom.style.position = 'fixed';
newDom.style.top = 999999;
document.body.appendChild(newDom);
html2canvas(newDom, { dpi: 300, scale: scale || 2 }).then((canvas) => {
const contentWidth = canvas.width;
const contentHeight = canvas.height;
const w = 595.28 - offset * 2;
const h = 841.89 - offset * 2;
// 一页pdf显示html页面生成的canvas高度;
const pageHeight = (contentWidth / w) * h;
// 未生成pdf的html页面高度
let remainHeight = contentHeight;
// pdf页面偏移
let position = 0;
// html页面生成的canvas在pdf中图片的宽高(a4纸的尺寸[595.28,841.89])
const imgWidth = w;
const imgHeight = (w / contentWidth) * contentHeight;
const pageData = canvas.toDataURL('image/jpeg', 1.0);
const pdf = new JsPDF('', 'pt', 'a4');
// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
// 当内容未超过pdf一页显示的范围,无需分页
if (remainHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', offset, offset, imgWidth, imgHeight);
} else {
while (remainHeight > 0) {
pdf.addImage(pageData, 'JPEG', offset, position, imgWidth, imgHeight);
remainHeight -= pageHeight;
position -= 841.89;
// 避免添加空白页
if (remainHeight > 0) {
pdf.addPage();
}
}
}
if (type === PRINT_TYPE.CURRENT_PRINT) {
pdf.autoPrint();
iframDom.src = pdf.output('datauristring'); // 在iframe中显示,实现当前页面打印
// 打印
} else if (type === PRINT_TYPE.DOWNLOAD) {
// 下载
pdf.save(`${title}.pdf`);
} else {
// pdf.autoPrint();
// pdf.output('dataurlnewwindow'); --- 这个方法,导致 超过 3页,第4页的时候 页面空白。弃用。
const link = window.URL.createObjectURL(toBlob(pdf.output('datauristring')));
const myWindow = window.open(link);
myWindow.print();
}
newDom.remove();
});
};