html2canvas实现html转图片(逐行解析!)

html2canvas实现html转图片(逐行解析!)

背景:

​ 有这样一个需求,要求前端这边把某人的资料生成名片的样式然后作为图片下载到本地

介绍:

​ 该脚本允许你直接在用户浏览器上对网页或部分网页进行“截图”。截图是基于 DOM 的,因此可能不能100% 准确地表示实际情况,因为它没有制作实际的截图,而是基于页面上可用的信息构建截图。该脚本遍历它所加载的页面的 DOM。它收集有关所有元素的信息,然后使用这些信息构建页面的表示形式。换句话说,它实际上并不采用页面的屏幕快照,而是基于从 DOM 读取的属性构建页面的表示形式。

代码解析:

// 引入相关的依赖
import html2canvas from "html2canvas";
  function savePicture() {
    // 拿到id为'bussiness-card'元素的DOM
    let htmlDom = document.querySelector('#bussiness-card');
    // html2canvas()第一个参数为需要被打印的dom元素,第二个参数是html2canvas的一些配置项
    html2canvas(htmlDom, {
      useCORS: true
    }).then((canvas) => {
      let type = 'png';
      // 打印后的imgData','后的是base64数据
      let imgData = canvas.toDataURL(type);
        
      function base64ToBlob(img) {
        // 拿到格式为base64的图片
        let imgBase64 = imgData.split(';base64,')[1];
        // 照片格式
        let contentType = imgData.split(';base64,')[0].split(':')[1];
        // 解码base64
        let raw = window.atob(imgBase64);
        let rawLength = raw.length;
        // 转为8 位无符号整型数组
        let uInt8Array = new Uint8Array(rawLength);
        for (let i = 0; i < rawLength; ++i) {
          // 返回i位置的字符Unicode编码
          uInt8Array[i] = raw.charCodeAt(i)
        }
        return new Blob([uInt8Array], { type: contentType });
      }

      // 下载后的文件名
      let filename = '个人名片' + (new Date()).getTime() + '.' + type;
      const blob = base64ToBlob(imgData);
      // 创建一个事件,evt就是被创建的Event对象
      let evt = document.createEvent("HTMLEvents");
      // 初始化一个点击事件
      evt.initEvent("click", true, true);
      // 创建a标签,加上download属性实现下载
      let aLink = document.createElement("a");
      aLink.download = filename;
      aLink.href = URL.createObjectURL(blob);
      aLink.click();
    })
  }

注意!!

​ 本人在手机端下载图片的过程中,发现需要被下载的dom中的图片却不见了。类似这样

image-20220712154504050

​ 但是这个照片在电脑上却正常显示。

​ 这个问题有两个原因可能会造成:1. 浏览器的跨域问题;2. 浏览器的缓存问题

​ 一. 针对上述问题1,因为我是用 标签里面的src属性进行照片的渲染的,但是如果照片的域名和当前网页域名不一致的话,http协议可能会禁止请求照片,就会导致照片获取不到。所以就要允许跨域。html2canvas里面的useCORS设置为true就可以跨域请求了。

​ 二. 针对上述问题2,因为浏览器的机制是先访问缓存的内容,这样就会导致我们实际上没有请求到照片的url,禁止使用浏览器缓存即可。给照片url地址带上参数?prevent_cache

<img src={`${doctorInfo?.avatarUrl}?prevent_cache`}  crossOrigin="anonymous" /> 

参考:

canvas导出为图片并用JS下载_Lingfeng928的博客-CSDN博客

(33) 为什么canvas.toDataURL获取图片是空白。 - SegmentFault 思否

https://segmentfault.com/q/1010000008648867

js base64和图片 相互转换_oneyJiang的博客-CSDN博客_base64转图片 js

将URL图片链接转换成base64__dalianmiao的博客-CSDN博客_链接转base64

跨源相关机制综述(三):crossorigin属性 - 知乎 (zhihu.com)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值