美文网首页工作生活
基于 Vue 页面导出 PDF与html2canvas受污染的解

基于 Vue 页面导出 PDF与html2canvas受污染的解

作者: Nic_Y | 来源:发表于2019-07-04 16:58 被阅读0次

    基于 Vue 页面导出 PDF

    首先引入两个模块

    //将页面html转换成图片
    yarn add html2canvas -s
    //将图片生成pdf
    yarn add jspdf -s
    

    template 代码

    <div id="pdf">
      内容
      <img :src="imgUrl" alt="" />
    </div>
    <el-button
      type="primary"
      icon="el-icon-download"
      @click="ExportPdf"
      :loading="ExportPdfloading"
      >导出PDF</el-button
    >
    

    原理

    1. 通过 html2Canvas 将 html 中指定区域转化为 canvas
    2. 使用 canvas.toDataURL("image/jpeg", 1.0);将 canvas 转为 base64
    3. 再通过 jspdf 导出 pdf

    js 代码

    import html2Canvas from "html2canvas";
    import JsPDF from "jspdf";
    export default {
      name: "pdf",
      data() {
        return {
          ExportPdfloading: false,
          imgUrl: ""
        };
      },
      methods: {
        ExportPdf() {
          html2Canvas(document.querySelector("#pdf"), {
            allowTaint: true,
            dpi: 400 //据说是清晰度,改了也看不出啥变化
          }).then(function(canvas) {
            let contentWidth = canvas.width;
            let contentHeight = canvas.height;
            // A4纸宽度 592.28
            let pageHeight = (contentWidth / 592.28) * 841.89;
            let leftHeight = contentHeight;
            let position = 30;
            let imgWidth = 592.28;
            let imgHeight = (592.28 / contentWidth) * contentHeight;
            let pageData = canvas.toDataURL("image/jpeg", 1.0); //最后将canvas转换成base64  1.0是转换成base64的清晰度
            let PDF = new JsPDF("", "pt", "a4");
            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;
                if (leftHeight > 0) {
                  PDF.addPage();
                }
              }
            }
            // 浏览器自动下载pdf文件
            PDF.save("pdf.pdf");
          });
        }
      }
    };
    

    使用 html2canvas 无法渲染网络图片

    注意

    1. 服务器的图片,必须是已经设置了允许跨域的
    2. 如果服务器端的图片不允许跨域访问,使用一下方法也无法解决

    解决思路

    1. 将网络图片转为 base64,在页面中使用 base64 渲染
    2. 通过 html2Canvas 将 html 中指定区域转化为 canvas
    3. 使用 canvas.toDataURL("image/jpeg", 1.0);将 canvas 转为 base64
    4. 再通过 jspdf 导出 pdf

    js 代码

    首先定义一个方法

    getBase64(url, ext, callback) {
        var canvas = document.createElement("canvas"); //创建canvas DOM元素
        var ctx = canvas.getContext("2d");
        var img = new Image();
        img.crossOrigin = "Anonymous";//说是可以跨域,但还是要看服务端是否允许跨域
        img.src = url;
        img.onload = function() {
        canvas.width = img.width; //指定画板的宽度,自定义
        canvas.height = img.height; //指定画板的高度,自定义
        ctx.drawImage(img, 0, 0, img.width, img.height); //参数可自定义
        var dataURL = canvas.toDataURL("image/" + ext);
        callback.call(this, dataURL); //回掉函数获取Base64编码
        canvas = null;
        };
    }
    

    使用方法

    let temp =
      "https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80";
    this.getBase64(imgUrl, "png", function(base64) {
      // 给原生img对象的src属性赋值
      this.imgUrl = base64;
    });
    

    在通过上面ExportPdf()方法导出 PDF

    相关文章

      网友评论

        本文标题:基于 Vue 页面导出 PDF与html2canvas受污染的解

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