网页中,html2canvas + jspdf 前端如何准确把指定 Dom 区域为 pdf 文件导出呢?
使用 html2canvas + jspdf 组合就可以了。
低层原理盲猜【有空也不会去看源码哈】,把 Dom 转 Image 再构建 pdf。Dom 转 Image 如何转?svg 的 forignObject 支持把 Dom 内嵌到 svg 里,然后可以通过给图片对象写入 base64 编码的 svg 流来实现。即:const image = new Image();,image.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(mySvgXmlByHtml))),两行搞了
言归正转,使用方式如下:
try {
await html2Canvas(document.querySelector('#myTargetDomId'), {
allowTaint: true, // 开启跨域
scale: 2, // 提升画面质量,但是会增加文件大小
}).then(canvas => {
const contentWidth = canvas.width;
const contentHeight = canvas.height;
const pageHeight = (contentWidth / 592.28) * 841.89;
let leftHeight = contentHeight;
let position = 0;
// a4 纸的尺寸[595.28,841.89],html 页面生成的 canvas 在 pdf 中图片的宽高
const imgWidth = 595.28;
const imgHeight = (592.28 / contentWidth) * contentHeight;
const pageData = canvas.toDataURL('image/jpeg', 1.0);
const pdf = new JsPDF('', 'pt', 'a4');
// 有两个高度需要区分,一个是 html 页面的实际高度,和生成 pdf 的页面高度(841.89)
// 当内容未超过 pdf 一页显示的范围,无需分页
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
} else {
// 分页
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
// position += 841.89;
// 避免添加空白页
if (leftHeight > 0) {
pdf.addPage();
}
}
}
const now = new Date();
const date = now.toLocaleDateString().replace(/\//g, '-');
const time = now.toLocaleTimeString().replace(/:/g, '-');
pdf.save(`我的文件名${date}_${time}.pdf`);
});
} catch (err) {
// eslint-disable-next-line no-console
console.warn(err);
} finally {
// finally
}
参考引用:
https://www.cnblogs.com/eide/p/14234798.html
https://blog.csdn.net/weixin_44833875/article/details/117065423