> 项目需求及遇见问题:
1、 需要在pc端上下载一个图片(图片要求为:通过qrcode生成的二维码+自定义的样式和文字。
2、最开始利用html2canvas插件实现把html转化为canvas,通过把canvas转化为图片并下载。)
3、html2canvas在滚动后截图会有空白的问题,a标签下载图片浏览器的兼容问题。最大的困难还是因为html2canvas在产生滚动条后截图会有空白的问题放弃了使用html2canvas,使用js自己手动绘制canvas然后再通过a标签下载。
html代码:
<div class="picBox" ref="canvas-main">
<!-- <div style="background-color: #0a76a4;width: 600px;height: 200px;margin-bottom: 100px" ref="canvas-box">-->
<!-- <p>测试打印</p>-->
<!-- <p>99999</p>-->
<!-- </div>-->
<div class="flex" v-for="(item,index) in tableData" :key="index" :id="'canvasBox'+index"
style="height:160px;background:#FEFF00;width:330px;">
<div style="margin-top: 3px;">
<canvas class="canvas" :id="'canvas'+index"></canvas>
</div>
<div style=" color: #000;padding-left:20px">
<div style="margin: 5px 0px 18px; font-size: 18px;font-weight: 600;">{{item.name}}</div>
<div>医卫士医疗废物追溯</div>
<div>yiweishiyiliaofeiwuzhuisu</div>
</div>
</div>
</div>
js代码
downLoadCode(ind, row) {
this.top = this.gettop()
//使用定时器避免二维码绘制重叠
setTimeout(() => {
//先让滚动条滚动到顶部,避免出现滚动条,截图会出现空白问题
const canvas = document.getElementById('canvas' + ind);
QRCode.toCanvas(canvas, row.id, {
width: 50,
height: 50,
margin: 0
}, function (error) {
if (error) throw error
})
/* qrcode vs qrcodejs2 生成二维码的原理不同,
//qrcode:指定canvas盒子上画二维码
//qrcodejs2:指定绘制二维码的盒子,最后通过canvas生成二维码,并把canvas转化为一个img标签,canvas元素display:none 所以在html2canvas上一直报错“ xx promise” ,
原因是因为html2canvas不支持opacity=0|| visibility:hidden ||display:none
const qrcode = new QRCode(canvas, {
width: 50,
height: 50,
text: row.id,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
*/
document.documentElement.scrollTop = 0 //阻止因滚动条滚动带来的html2canvas接口产生空白问题
const canvasBox = document.getElementById('canvasBox' + ind);
// 注意: this.$ref['canvasBox'+i] 获取dom html2canvas会报错 "Element is not attached to a Document" 原因:猜想和v-for动态渲染有关,
html2canvas(canvasBox, {
logging: false,
useCORS: true,
background: null,
}).then(function (canvas) {
// 保存到本地 用FileSaver这个插件
// require导入,在使用时导入,相当于赋值
const fileSaver = require("file-saver")
/* canvas.toBlob 对于各个浏览器有兼容问题. ie会报错没有toBlob对象
* 解决方式:引入canvas-toBlob.js(https://github.com/eligrey/canvas-toBlob.js/blob/master/canvas-toBlob.js)
* */
canvas.toBlob(function (blob) {
fileSaver.saveAs(blob, row.name + ".jpeg");
});
//生成base64图片数据,通过a标签下载,需要考虑兼容问题
// document.documentElement.scrollTop = this.top 滚动条回位不能放在这里 页面会出现闪动,html2canvas 截图是异步
const url = canvas.toDataURL("image/jpeg"),//把canvas转化为base64图片地址(toDataURL:可指定图片格式)
dowmDom = document.createElement("a");
const userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
if (userAgent.indexOf("Trident") > -1) {
//把 base64 路径转化为 blob 对象
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(',');
//注意base64的最后面中括号和引号是不转译的
var _arr = arr[1].substring(0,arr[1].length-2);
var mime = arr[0].match(/:(.*?);/)[1],
bstr =atob(_arr),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime
});
}
//下载图片
navigator.msSaveBlob(dataURLtoBlob(url), row.name + ".jpeg");
}else{
// 创建a标签下载
dowmDom.download = row.name;// 设置下载的文件名,默认是'下载'
dowmDom.href = url;
dowmDom.click();
dowmDom.remove(); // 下载之后把创建的元素删除
}
})
//让滚动条回到原始位置
document.documentElement.scrollTop = this.top
}, 100)
},
单个下载就完成了,经测试,除了ie在滚动条的处理上会出现小问题,别的浏览器暂时没有问题。