一、需求来源:把可视化展示HTML页面打印成PDF文件报表
二、html2canvas+jsPDF导出pdf原理:通过html2canvas将遍历页面元素,并渲染生成canvas,然后将canvas图片格式添加到jsPDF实例,生成pdf。
三、代码
1 var title = 'RFM'
2 this.overflow = 'visible'; 3 let self = this; 4 let targetDom = document.querySelector('#pdfDom'); // 获取打印的元素
5 this.$nextTick(()=>{ // 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
6 html2Canvas(targetDom, { 7 allowTaint: true, 8 height: targetDom.scrollHeight 9 }).then(function (canvas) { // 通过promise返回canvas元素
10 let contentWidth = canvas.width 11 let contentHeight = canvas.height 12 let pageHeight = contentWidth / 592.28 * 841.89 // 每页高度:a4纸的尺寸
13 let leftHeight = contentHeight 14 let position = 0
15 let imgWidth = 590.28 // 图片宽度
16 let imgHeight = 592.28 / contentWidth * contentHeight 17 let pageData = canvas.toDataURL('image/jpeg', 1.0) // 保存canvas图像
18 // 参数:方向(l:横向,p:纵向)| 测量单位("pt","mm", "cm", "m", "in" or "px")| 格式(默认a4,也可通过大小数组[595.28, 841.89])
19 let PDF = new JsPDF('p', 'pt', 'a4') 20 // 按照a4规格分页操作
21 if (leftHeight < pageHeight) { 22 PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) 23 } else { 24 while (leftHeight > 0) { 25 PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) 26 leftHeight -= pageHeight 27 position -= 841.89
28 if (leftHeight > 0) { 29 PDF.addPage() // 添加页
30 } 31 } 32 } 33 PDF.save(title + '.pdf') // 保存pdf文档,本地下载pdf文件
34 }) 35 }) 36 this.timeout = setTimeout(() => { 37 self.overflow = 'auto'; 38 }, 1000);
pageHeight计算公式:
四、遇到的坑
1、打印元素中overflow属性值不能为auto
解决方案为在打印前把overflow值设置为visible,打印完之后重新设置为auto。
注意:
(1)把auto修改成visible,要考虑页面渲染时间,所以要用 nextTick 等页面渲染完再执行操作
(2)把visible再修改成auto要考虑到打印时间,所以要用到 settimeout 延迟执行
2、要设置height高度为打印元素的 滚动高度 scrollHeight ,若元素没有滚动条,scrollHeight 值 = 元素真实高度 (测试是如此的)
拓展:
原生js使DIV滚动到最底部 : ele.scrollTop = ele.scrollHeight