此项目以vue为例,引用方式是
cnpm install html2canvas -s
// 在用到的地方引用
import html2canvas from 'html2canvas'
不是 vue 的可以直接引用 js 文件,不多说话,直接上代码(注释都在里面了)
printSeat() {
this.$store.commit("updatePageLoading", ++this.$store.state.pageLoading)
// 下面是这边需求,需要对打印出来的东西做一些样式调整,写的代码,可根据自己业务需求进行修改
document.querySelectorAll('#chartList')[0].style.top = 0;
document.querySelectorAll('#chartList')[0].style.left = 0;
try {
document.querySelectorAll('.group-area-right')[0].style.right = '180px';
} catch (error) {
}
try {
document.querySelectorAll('.group-area-left')[0].style.left = '180px';
} catch (error) {
}
try {
document.querySelectorAll('.area-class')[0].style.left = '180px';
} catch (error) {
}
// 这边就是我们的业务代码了,也可以不用 document.createElement("canvas"), 直接进行html2canvas 进行生成图片,我这边因为图片过大,生成出来的图片很模糊,就进行了处理
let canvas2 = document.createElement("canvas");
let _canvas = document.querySelectorAll('#seatPrint')[0];
let w = parseInt(window.getComputedStyle(_canvas).width);
let h = parseInt(window.getComputedStyle(_canvas).height);
//将canvas画布放大若干倍,然后盛放在较小的容器内,就显得不模糊了
canvas2.width = w * 1.9;
canvas2.height = h * 1.6;
//可以按照自己的需求,对context的参数修改,translate指的是偏移量
let context = canvas2.getContext("2d");
context.scale(2, 2);
// context.translate(100, 0);
document.querySelectorAll('#seatPrint')[0].style.transform = 'scale(.8)';
document.querySelectorAll('#seatPrint')[0].style.marginLeft = '-10%';
document.querySelectorAll('#seatPrint')[0].style.width = '120%';
let that = this
// { canvas: canvas2 } 不处理的话是不用穿的,直接传第一个参数就行(需要生成的dom区域)
html2canvas(document.querySelectorAll('#seatPrint')[0], { canvas: canvas2 }).then((canvas) => {
// canvas.toDataURL() 输出的 base64
const blob = this.convertBase64UrlToBlob(canvas.toDataURL()); // 转成bolb
// 下载的文件名称
const fileName = this.$route.query.planName + '座次图'
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName);
} else {
// 创建 a 标签,开始下载
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
//此写法兼容可火狐浏览器
document.body.appendChild(link);
const evt = document.createEvent("MouseEvents");
evt.initEvent("click", false, false);
link.dispatchEvent(evt);
document.body.removeChild(link);
// 样式恢复
setTimeout(() => {
this.$store.commit("updatePageLoading", --this.$store.state.pageLoading)
// 下面注释的代码,火狐浏览器不支持(苦恼,奈何客户用的是火狐,继续采坑)
// document.querySelectorAll('.list-box')[0].style.zoom = 1;
document.querySelectorAll('#seatPrint')[0].style.transform = 'scale(1)';
document.querySelectorAll('#seatPrint')[0].style.marginLeft = 0;
document.querySelectorAll('#seatPrint')[0].style.width = '100%';
try {
document.querySelectorAll('.group-area-right')[0].style.right = '30px';
} catch (error) {
}
try {
document.querySelectorAll('.group-area-left')[0].style.left = '30px';
} catch (error) {
}
try {
document.querySelectorAll('.area-class')[0].style.left = '0px';
} catch (error) {
}
}, 100)
}
}).catch(err => {
this.$store.commit("updatePageLoading", --this.$store.state.pageLoading)
});
convertBase64UrlToBlob(base64) {
let parts = base64.split(";base64,");
let contentType = parts[0].split(":")[1];
let raw = window.atob(parts[1]);
let rawLength = raw.length;
let uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; i++) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
在中间遇到了一个奇怪的问题,就是chrome浏览器生成图片大约要3秒钟左右,而火狐浏览器能加载一分钟,提示显示
image
刚开始以为打印的dom元素比较多,然后就尝试了打印部分dom,都没有问题,只要已使用外层的dom就会提示,后来我改了dom元素的层级结构,然后就快了很多,中间尝试过直接后端生成,但是我觉得前端应该也没问题,网上查了说chrome 和 火狐浏览器都挺好用的,然后就开始改层级了
网友评论