Vue项目导出PDF(可修改样式|指定分页)

3,205 阅读1分钟

使用html2canvas+jsPDF

html2canvas文档
html2canvas-GitHub

jsPDF文档
jsPDF文档-GitHub

  • 安装 npm install html2canvas jsPDF
  • 在目标文件中引入 import html2canvas from "html2canvas"; import jsPDF from "jspdf";
  • 在需要导出pdf的部分,指定ref

主要思想

分页:生成多canvas

修改样式:生成canvas之前修改

  • 此方法目前稍微臃肿,有待简化
changeStyle(){
    //...样式变动
},
recoverStyle(){
    //...还原样式
},
exportPdf() {
    //此处可按需做样式变动(如:this.$refs.xxx.style.xx(内联样式))
    //注意:此处样式变动会反映到页面上,如需原样式显示,需在生成canvas后还原样式
    //!!!修改样式怎么样不反馈在页面呢... copy dom后绝对定位到视口外,取消对视口内样式更改,改为对绝对定位的dom进行更改。
    //!!或者直接写好导出所需样式,此时setTimeout也不需要了
    //只不过有个问题就是增加了代码量...
    this.changeStyle();
    //发现生成一页时,修改的样式未被捕捉,因此在外层使用setTimeout()
    setTimeout(()=>
        html2canvas(that.$refs.exportPdf, {
            scale: 2.0, //提高清晰度
            backgroundColor: "#fff", //canvas背景色 可根据需要设置
            //allowTaint: true
          }).then(function(canvas) {
            //此处还原样式
            this.recoverStyle();
            //console.log(canvas); //可查看下生成canvas画布信息 (宽高)
            //目标打印html页面实际宽高(即canvas宽高)
            let contentWidth = canvas.width;
            let contentHeight = canvas.height;
            //一页pdf显示的 html页面生成的canvas高度;
            let pageHeight = (contentWidth / 595.28) * 841.89; // 根据缩放比例确定一页html高 参考A4纸尺寸
            let pdf = new jsPDF("", "pt", "a4");
            let imgWidth = 555.28; //因为留了外边距
            if (pageHeight >= contentHeight) {
              /**直接导出(一页)**/
              let imgHeight = (555.28 / contentWidth) * contentHeight;
              let pageData = canvas.toDataURL("image/jpeg", 1.0);
              pdf.addImage(pageData, "JPEG", 20, 30, imgWidth, imgHeight); //20、50是x、y边距
              pdf.save("exportPdf.pdf");
            } else {
              /** 导出多页
              *** 因为分页是直接截断canvas,容易导致文字图片被切割,此时可指定分页处
              *** 主要思想是生成多canvas进行pdf排版
              **/
              //此处可按需做样式变动(如:this.$refs.xxx.style.xx(内联样式))
              //注意:此处样式变动会反映到页面上,如需原样式显示,需在生成canvas后||导出pdf前/后还原样式
              this.changeStyle();
              html2canvas(that.$refs.exportPdf1, {
                // dpi: window.devicePixelRatio,
                scale: 2.0,
                backgroundColor: "#fff"
              }).then(function(canvas) {
                let contentWidth2 = canvas.width;
                let contentHeight2 = canvas.height;
                if (pageHeight >= contentHeight2) {
                  let imgHeight = (555.28 / contentWidth2) * contentHeight2;
                  var pageData2 = canvas.toDataURL("image/jpeg", 1.0);
                  pdf.addImage(pageData2, "JPEG", 20, 30, imgWidth, imgHeight);
                }
                html2canvas(that.$refs.exportPdf2, {
                  scale: 2.0,
                  backgroundColor: "#fff"
                }).then(function(canvas) {
                //此处还原样式
                  this.recoverStyle();
                  let contentWidth3 = canvas.width;
                  let contentHeight3 = canvas.height;
                  if (pageHeight >= contentHeight3) {
                    let imgHeight = (555.28 / contentWidth3) * contentHeight3;
                    let pageData3 = canvas.toDataURL("image/jpeg", 1.0);
                    pdf.addPage();
                    pdf.addImage(pageData3, "JPEG", 20, 30, imgWidth, imgHeight);
                    pdf.save("exportPdf.pdf");
                  }
                });
                //...若还有多页,增加以上逻辑块,最后pdf.save("name.pdf")即可
              });
            }
            })
        ,50)
}