需求:将dom转成图片,下载到本地。
在实际项目中,有可能会出现这种需求,比如用某字符串生成二维码,然后将二维码打包下载到本地。因为二维码可以是前端来生成(使用插件qrcode.js),所以没有图片链接给到前端,但是页面的二维码实际已经生成,在这种情况下,可以使用dom-to-image来下载。
dom-to-image可以下载多种格式的图片:
例如,将需要下载的dom最外层标签设置id="ecodeHtml",需要下载的html部分设置class="print-html",获取要下载的dom为$("#ecodeHtml").find(".print-html")[0],因为笔者这里要下载的是png格式的图片,所以需要使用domtoimage.toPng(printingSpaceDiv),该函数是一个promise,完成后,返回的内容就是我们要下载的图片base64编码,再利用a标签的href和download标签,触发点击事件,图片下载成功啦!
import $ from 'jquery'
import domtoimage from 'dom-to-image';
loadImages(event) {
let fileName = 'image.jpg';
let printingSpaceDiv =$("#ecodeHtml").find(".print-html")[0];
domtoimage.toPng(printingSpaceDiv)
.then(function (dataUrl) {
let evt = document.createEvent("HTMLEvents");
let aLink = document.createElement('a');
evt.initEvent("click", true, true);
aLink.download = fileName;
aLink.href = dataUrl;
aLink.click();
})
.catch(function (error) {
console.log(error);
});
}
在vue前端下载——jszip压缩和解压,结合file-saver导出图片zip,每20个图片分一个目录一文中,笔者记录了jszip和file-saver打包下载的具体实现,这里的不同之处在于图片的链接不是一个url,而是通过dom-to-image生成图片的base64编码数据进行下载。
具体实现如下:
import $ from 'jquery'
import JSZip from 'jszip'
import saveAs from 'file-saver';
import domtoimage from 'dom-to-image';
//...
async validateImage(pathImg) { // 验证图片地址是否有效
var ImgObj = new Image();
ImgObj.src = pathImg;
return ImgObj.fileSize > 0 || (ImgObj.width > 0 && ImgObj.height > 0);
},
async getQrcodeDom(data, appendDom) {
let failure = [];
let dom = `<div class="load-all-image">`;
data.forEach((item, index) => {
if (!this.validateImage(item.qrcodeUrl)) {
failure.push(index + 1);
} else {
dom += `<div class="print-html">
<div class="info">
<div class="imgName">${item.name}</div>
</div>
</div>`;
}
});
dom += `</div>`;
$('.' + appendDom).append(dom);
let imgBase64 = [];
let imgsName = [];
let nameTemp = [];
let zip = new JSZip();
let selectPic = $('.load-all-image .print-html');
let folderObj = {};
for (let j = 0; j < selectPic.length; j++) {
let item = selectPic[j];
let addr = $(item).find(".imgName").text();
imgsName.push(addr);
let dataUrl = await domtoimage.toPng(item);
imgBase64.push(dataUrl.substring(22));
}
for (let i = 0; i < imgsName.length; i++) {
let name = imgsName[i].trim();
if (nameTemp.includes(name)) {
zip.file(name + '_' + i + '.jpg', imgBase64[i], {base64: true});
} else {
zip.file(name + '.jpg', imgBase64[i], {base64: true});
nameTemp.push(name)
}
}
zip.generateAsync({type: "blob"}).then((content) => {
saveAs(content, `images.zip`);
$('.load-all-image').remove();
});
},
本篇纪录了使用dom-to-image将html转成png的具体实现,包含单张图片下载和打包下载,如有其他方法,欢迎讨论!