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](https://s2.loli.net/2022/07/12/UBd2ZGehfK96RnQ.png)
但是这个照片在电脑上却正常显示。
这个问题有两个原因可能会造成: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