网页中,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