• 使用 html2canvas 和 jspdf 将页面转 pdf,同时解决当页面过长时,页面白屏问题


    代码如下,直接粘贴复制即可,代码中 jspdf 是全局引入,你可以自己局部引入

    别人使用标签的方式来显示 base64,但是当页面过长时,base64 大小过大会导致页面解析异常,显示白屏

    import html2canvas from 'html2canvas';
    
    export function printPdf(dom: HTMLElement | null) {
      // 1 dom 存在
      if (!dom) return;
      // 2 生成 canvas
      html2canvas(dom, { useCORS: true, allowTaint: true }).then(function (canvas) {
        // document.body.appendChild(canvas);
        // return;
        // 1 canvas 宽高
        const contentWidth = canvas.width;
        const contentHeight = canvas.height;
        console.log('contentWidth contentHeight', contentWidth, contentHeight);
    
        // 2 一页 pdf 显示 html 页面生成的 canvas 高度
        const pageHeight = (contentWidth / 592.28) * 841.89;
        // 3 未生成 pdf 的 html 页面高度
        let leftHeight = contentHeight;
        // 4 pdf 页面偏移
        let position = 0;
        // 5 a4纸的尺寸 [595.28, 841.89],html 页面生成的 canvas 在 pdf 中图片的宽高
        const imgWidth = 595.28;
        const imgHeight = (592.28 / contentWidth) * contentHeight;
        const img = canvas.toDataURL('image/jpeg', 1.0);
        const pdf = new jspdf.jsPDF('', 'pt', 'a4');
        // 有两个高度需要区分,一个是html页面的实际高度,和生成 pdf 的页面高度(841.89)
        // 当内容未超过 pdf 一页显示的范围,无需分页
        if (leftHeight < pageHeight) {
          pdf.addImage(img, 'JPEG', 0, 0, imgWidth, imgHeight);
        } else {
          while (leftHeight > 0) {
            console.log(imgWidth, imgHeight, position, leftHeight);
            pdf.addImage(img, 'JPEG', 0, position, imgWidth, imgHeight);
            leftHeight -= pageHeight;
            position -= 841.89;
            // 避免添加空白页
            if (leftHeight > 0) {
              pdf.addPage();
            }
          }
        }
        // 6 挂载至页面
        const blob = dataURLtoBlob(pdf.output('datauristring'));
        console.log(blob);
        const url = window.URL.createObjectURL(blob); //获得一个pdf的url对象
        location.href = url;
        // window.open(url, '_blank')//打开一个新窗口
        // console.log(url);
        // URL.revokeObjectURL(url) //释放内存
        // const base64String = btoa(pdf.output());
        // const embed = ``;
        // document.documentElement.style.overflow = 'hidden';
        // document.body.innerHTML = embed;
      });
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    dataURLtoBlob 函数如下:

    // 当 base64 过大时会导致页面无法加载,需要转化成 blob 格式
    function dataURLtoBlob(dataurl: any) {
      const arr = dataurl.split(',');
      // 注意base64的最后面中括号和引号是不转译的
      const _arr = arr[1].substring(0, arr[1].length - 2);
      const mime = arr[0].match(/:(.*?);/)[1];
      const bstr = atob(_arr);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], {
        type: mime,
      });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    数据结构之二叉树(前提知识)
    每日4道算法题——第020天
    flink1.15.0消费kafka 报错 The coordinator is not available.
    web期末网站设计大作业:基于HTML+CSS+JavaScript制作新能源汽车企业网站
    2022阿里巴巴云栖大会
    蓝桥杯(3.11)
    【python】内置函数——isinstance()/issubclass()判断参数1是否是参数2类型
    黑马JVM总结(二十九)
    Telnet
    EN 13967防水用柔性薄板—CE认证
  • 原文地址:https://blog.csdn.net/SiShen654/article/details/133640355