一、问题
遇到一个需求,就是要把整个看板页面导出成PDF用在汇报,也就是要把整个DOM生成一个PDF保存到本地。
二、解决方法
1、解决思路:使用插件 jspdf 和 html2canvas,我用的版本如下图
2、代码实现
import { jsPDF } from 'jspdf'
import html2canvas from 'html2canvas'
// 封装成一个公共的方法(核心代码)
export const htmlToPDF = async (htmlId: string, title: string, bgColor = "#fff") => {
const pdfDom = document.getElementById(htmlId) as HTMLElement | null;
if (!pdfDom) {
console.error('Element not found');
return '';
}
const scale = window.devicePixelRatio || 1; // 使用设备像素比来提高清晰度
const canvas = await html2canvas(pdfDom, {
scale: scale,
useCORS: true,
backgroundColor: bgColor,
});
const imgProps = canvas.toDataURL('image/png'); // 使用PNG格式提高质量
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'px',
format: [595.28, 841.89], // A4尺寸(以像素为单位)
});
const imgPropsObj = pdf.getImageProperties(imgProps);
const pdfWidth = 576; // A4宽度减去一些边距
// 控制页面展示 调整这个98 防止出现空白页
const pdfHeight = (imgPropsObj.height * pdfWidth) / imgPropsObj.width - 98;
const pageHeight = 841.89; // A4页面的高度
let heightLeft = pdfHeight; // 剩余高度
let y = 0; // 当前Y坐标
// 处理分页逻辑
while (heightLeft > 0) {
const imgHeight = Math.min(heightLeft, pageHeight); // 当前图像可显示的高度
pdf.addImage(imgProps, 'PNG', 0, y, pdfWidth, imgHeight); // 添加图像
heightLeft -= imgHeight; // 减去已添加的高度
y += imgHeight; // 移动Y坐标
if (heightLeft > 0) {
pdf.addPage(); // 如果还有内容,则添加新页面
}
}
// 生成并返回PDF文件
pdf.save(title + '.pdf');
const pdfUrl = window.URL.createObjectURL(new Blob([pdf.output('blob'), { type: 'application/pdf' }]));
return pdfUrl;
};
// 页面中调用 box:要转成pdf文件的盒子
<div id="box">
// 此处为你的页面内容
</div>
// 点击如下方法保存pdf
<button @click="fn">生产pdf</button>
// htmlToPDF 第一个参数:要生成pdf文件的盒子id 第二个参数:生成pdf的文件名
const fn = ()=> {
const pdfUrl = htmlToPDF("box", 'xxx.pdf')
}