美文网首页让前端飞Web前端之路
html2canvas+jspdf踩坑之路

html2canvas+jspdf踩坑之路

作者: 穆熙沐 | 来源:发表于2019-12-13 15:12 被阅读0次

             最近刚完成了项目中所有模块的详情页导出pdf功能。本来开始后端接了这个活,前端只要传过去单号就好,可是做到最后一直实现不来,页面总是显示一半,于是,后端把活让给了我😢
             还好,同组的其他伙伴项目中有用到过,给了我些帮助。
    具体实现思路是:html2canvas 截屏页面快照,然后把照片插入到pdf页面内。
    遇到的问题有:
    1)快照是空白的
             首先页面DOM布局很重要,如果布局比较乱,很容易打印出空白页面。我们要知道html2canvas 截屏的元素是相对body元素定位的,所以我这里把要截屏的DOM元素copy了一份,放在body元素里。

                let targetDom = document.querySelector('#pdfWrap');
                let copyDom = targetDom.cloneNode(true);
                copyDom.classList.add("copydom");
                document.body.appendChild(copyDom);
    

    但是这样也有问题,所以要从新缕清布局,尽量不要copy元素,因为cloneNode(true)无法copy echarts画出的图表~


    image.png

    2)pdf宽度很大,在a4纸打印不够
             打印出来的PDF是等比例的缩放字体大小,如果宽度很宽,字体就会变得很小很小。这个时候就要和PM沟通协商,看看想怎么解决。
    3)快照图片不显示
    原因是跨域请求了图片资源,html2canvas 默认是不跨域的,所以在这里要设置下可跨域。

    <img :src="item.path+'?'+new Date().getTime()" crossOrigin="anonymous"/>
            html2canvas(copyDom, {
                useCORS: true
            })
    

    4)快照截屏是当前可视窗口大小,没法滚动
             我们页面比较长,有滚动条,所以会出现当前问题。设置当前要截屏的DOM元素的宽度和高度都为目标元素的滚动高度。

                copyDom.style.height = targetDom.scrollHeight  + "px";
                copyDom.style.width = targetDom.scrollWidth  +  "px";
    

    5)页面表格内容超出用省略号显示的解决办法
             和PM沟通,需要把省略掉掉内容折行展示出来。html2canvas 的截图原则是所见即所得,所以页面是什么样子,打印出来是什么样子。因此,我需要在新的copy DOM元素下改变折行样式。(增加这行类名:export-mulit-line)

     let recordDom = copyDom.getElementsByClassName('approval-records')[0];
    let recordTableDom = recordDom.getElementsByClassName('data-table')[0];
    recordTableDom.classList.add("export-mulit-line");
    

    ⚠️:这里涉及到了折行,页面高度会有所改变,所以要增加copyDOM元素的高度~(appendHeight即为变化的高度)

    copyDom.style.height = targetDom.scrollHeight + appendHeight + "px";
    

    总体实现代码:

            // 判断是否多行
            isMultiline(arr, num) {
                return arr.some(e => {
                    return e.remark && e.remark.length > num;
                });
            },
            getPdf(dom, title) {
                this.loading = true;
                let targetDom = document.querySelector('#pdfWrap');
                let copyDom = targetDom.cloneNode(true);
                copyDom.classList.add("copydom");
                // 多行展示预算信息
                let appendHeight = 0;//折行增加的高度
               copyDom.style.height = targetDom.scrollHeight + appendHeight + "px";
                copyDom.style.width = targetDom.scrollWidth  +  "px";
                document.body.appendChild(copyDom);
                utils.exportPDF(copyDom, this.orgInfo.orgName).then(v => {
                    this.loading = v;
                });
            }
    }
    

    utils.js

     // 导出PDF
        async exportPDF(copyDom, activityName) {
            await html2canvas(copyDom, {
                useCORS: true
            })
                .then(canvas => {
                    let contentWidth = canvas.width;
                    let contentHeight = canvas.height;
                    let pageHeight = contentWidth / 592.28 * 841.89;
                    let leftHeight = contentHeight;
                    let position = 0;
                    let imgWidth = 555.28;
                    let imgHeight = 555.28 / contentWidth * contentHeight;
                    console.log(contentHeight);
                    let pageData = canvas.toDataURL('image/jpeg', 1.0);
                    let PDF = new JsPDF('', 'pt', 'a4');
                    if (leftHeight < pageHeight) {
                        PDF.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight);
                    } else {
                        while (leftHeight > 0) {
                            PDF.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight);
                            leftHeight -= pageHeight;
                            position -= 841.89;
                            if (leftHeight > 0) {
                                PDF.addPage();
                            }
                        }
                    }
                    PDF.save(activityName + '.pdf');
                });
            return false;
        }
    

    html2canvas官网

    相关文章

      网友评论

        本文标题:html2canvas+jspdf踩坑之路

        本文链接:https://www.haomeiwen.com/subject/laryiftx.html