html2canvas+jsPDF实现对指定滚动的dom元素转成pdf并分页调打印机打印
问题描述
原生的window.print()无法打印多页,也无法打印超出屏幕的元素,但是我现在需要打印的元素是滚动的,一屏显示不下,并且需要分页打印。于是只能另辟蹊径。
实现思路
- 使用
html2canvas库将指定的 DOM 元素转换为 canvas 图像。 - 对canvas 图像按照每一页进行裁剪。
- 使用
jspdf库对裁剪好的图像贴到pdf中。 - 调用浏览器自带的 PDF 文件打印。
代码实现
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
// 定义打印函数
const printDomToPdf = async () => {
const printDom = document.getElementById('printDom');
if (!printDom) {
console.error('未找到 id 为 printDom 的元素');
return;
}
try {
// 将 DOM 元素转换为 canvas
const canvas = await html2canvas(printDom, {
scale: 2, // 放大比例,提高图像清晰度
useCORS: true, // 允许跨域请求图片
logging: true, // 开启日志记录
scrollY: 0, // 垂直滚动偏移量
scrollX: 0, // 水平滚动偏移量
windowWidth: printDom.scrollWidth, // 窗口宽度,确保捕获整个 DOM 宽度
windowHeight: printDom.scrollHeight // 窗口高度,确保捕获整个 DOM 高度
});
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'mm', 'a4');
const imgProps = pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth(); // 获取 PDF 页面宽度
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; // 根据宽度比例计算 PDF 页面高度
const pageHeight = pdf.internal.pageSize.getHeight(); // 获取 PDF 单页高度
let position = 0; // 当前图像裁剪的起始位置
while (position < pdfHeight) {
if (position !== 0) {
pdf.addPage(); // 如果不是第一页,添加新页面
}
// 计算当前页需要显示的图像高度,取单页高度和剩余高度的最小值
const sliceHeight = Math.min(pageHeight, pdfHeight - position);
// 计算图像在 Y 轴上的裁剪起始位置
const clipY = (position * imgProps.height) / pdfHeight;
// 计算图像在 Y 轴上的裁剪结束位置
const clipHeight = (sliceHeight * imgProps.height) / pdfHeight;
// 创建裁剪后的 canvas
const croppedCanvas = document.createElement('canvas');
const croppedCtx = croppedCanvas.getContext('2d');
croppedCanvas.width = imgProps.width;
croppedCanvas.height = clipHeight;
croppedCtx.drawImage(canvas, 0, clipY, imgProps.width, clipHeight, 0, 0, imgProps.width, clipHeight);
const croppedImgData = croppedCanvas.toDataURL('image/png');
// 使用 9 个参数的 addImage 函数
pdf.addImage(croppedImgData, 'PNG', 0, 0, pdfWidth, sliceHeight, undefined, 'FAST', 0);
position += pageHeight; // 更新裁剪起始位置
}
// 保存并打印 PDF
// pdf.save('printDom.pdf');
pdf.autoPrint();
window.open(pdf.output('bloburl'), '_blank');
} catch (error) {
console.error('打印失败:', error);
}
};

浙公网安备 33010602011771号