html2Canvas生成图片展示,下载图片或下载为PDF格式文件

介绍

html2Canvas生成图片展示,下载图片或下载为PDF格式文件。

html2Canvas使用方法

npm i html2canvas

npm i jspdf

import html2canvas from "html2canvas";

import JsPDF from "jspdf";

代码段

str:pdf标题; eles:需要下载的标签


      const title = str;
      const ele = document.querySelector(eles);
      html2canvas(ele, {
        allowTaint: true,
      }).then((canvas) => {
        //展示图片
        const imgBlobData=canvas.toDataURL("image/png");
        this.picUrl = window.URL.createObjectURL(imgBlobData)
        
        //直接下载图片
        const link = document.createElement('a'); // 创建一个超链接对象实例
        const event = new MouseEvent('click'); // 创建一个鼠标事件的实例
        link.download = 'Button.png'; // 设置要下载的图片的名称
        link.href = canvas.toDataURL(); // 将图片的URL设置到超链接的href中
        link.dispatchEvent(event); // 触发超链接的点击事件

        //下载为PDF文件
        const PDF = new JsPDF("p", "mm", "a4"); // A4纸,纵向
        const ctx = canvas.getContext("2d");
        const a4w = 190;
        const a4h = 277; // A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
        // eslint-disable-next-line no-mixed-operators
        const imgHeight = Math.floor((a4h * canvas.width) / a4w); // 按A4显示比例换算一页图像的像素高度
        let renderedHeight = 0;

        while (renderedHeight < canvas.height) {
          const page = document.createElement("canvas");
          page.width = canvas.width;
          page.height = Math.min(imgHeight, canvas.height - renderedHeight); // 可能内容不足一页

          // 用getImageData剪裁指定区域,并画到前面创建的canvas对象中
          page
            .getContext("2d")
            .putImageData(
              ctx.getImageData(
                0,
                renderedHeight,
                canvas.width,
                Math.min(imgHeight, canvas.height - renderedHeight)
              ),
              0,
              0
            );
          // 添加图像到页面,保留10mm边距
          // eslint-disable-next-line no-mixed-operators
          PDF.addImage(
            page.toDataURL("image/jpeg", 1.0),
            "JPEG",
            10,
            10,
            a4w,
            Math.min(a4h, (a4w * page.height) / page.width)
          );

          renderedHeight += imgHeight;
          if (renderedHeight < canvas.height) {
            PDF.addPage();
          } // 如果后面还有内容,添加一个空页
        }
        PDF.save(`${title}.pdf`);
     });

html2Canvas可能遇到的部分问题

1、图片跨域

解决方案:

  • 设置配置项 allowTaint: false

    canvas 的 CanvasRenderingContext2D 属于浏览器的对象,如果渲染过跨域资源,浏览器就认定 canvas 已经被污染了 Taint:污点

  • 设置配置项 useCORS: false

    表示允许跨域资源共享,注意不能与 allowTaint 同时配置为 true

  • img 标签中添加 crossOrigin = "anonymous"

    anonymous:如果使用这个值的话就会在请求 header 中带上 Origin 属性,但请求不会带上 cookie 和客户端 ssl 证书等其他的一些认证信息

  • 图片服务器配置 Access-Control-Allow-Origin: *

    重要的配置项,是跨域问题的根本源泉,需要后端配合

2、截图锯齿

解决方案:根据设备像素比进行缩放

// 设置放大倍数
const scale = window.devicePixelRatio;

3、截图不全

解决方案:截图之前将页面滚动到顶部

document.body.scrollTop = document.documentElement.scrollTop = 0;
const imgBlobData = await convertToImage(element);

4、对 css3 支持不好

html2canvas 暂不支持的 CSS 样式属性:

background-blend-mode、background-clip: text、box-decoration-break、repeating-linear-gradient()、font-variant-ligatures、mix-blend-mode、writing-mode、writing-mode、border-image、box-shadow、filter、zoom、transform

解决方案:

对于一些必要的样式,可以选择使用图片做兜底实现

box-shadow 可以参考 这个pr,修改源码解决,但是,实际效果也不是太理想……

5、svg 标签

问题原因:vue-lottie 动画库渲染的标签是 svg(也可能是你自己写的 svg 标签)

html2canvas 对于 svg 标签的支持也不尽人意,解决办法同样是用图片做兜底

在项目中,我们是用 svg 做动画,截图的时候把动画换成一张静态图,这样只要设置要静态图的样式,截图效果还是可以接受的

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值