前言
本人是前端菜鸟一枚,写这个文章的目的是为纯粹是为了以后遇到同样的问题后能粘贴复制,毕竟为了实现这个功能到处看网上大佬的文章,还有leader帮助才能把这个功能完成。如果能帮助到有需要的人那我很开心,因为我很多问题都是靠网上的大佬分享的文章解决的。文字功底有限,直接开撸。
//获取canvas配置项
getCanvasOption(shareContent){
let canvasEle = document.querySelector('canvas');
if(canvasEle){
document.getElementById('dialog').removeChild(canvasEle)
}
let width = shareContent.offsetWidth; //获取dom 宽度
let height = shareContent.offsetHeight; //获取dom 高度
let canvas = document.createElement("canvas"); //创建一个canvas节点
let scale = 2; //定义任意放大倍数 支持小数
canvas.getContext("2d").scale(scale, scale); //获取context,设置scale
canvas.width = width * scale; //定义canvas 宽度 * 缩放
canvas.height = height * scale; //定义canvas高度 *缩放
canvas.style.cssText = 'width: '+ width +'px; height: '+ height +'px';
let opts = {
scale: scale, // 添加的scale 参数
canvas: canvas, //自定义 canvas
// logging: true, //日志开关,便于查看html2canvas的内部执行流程
width: width, //dom 原始宽度
height: height,
useCORS: true // 【重要】开启跨域配置
};
return opts;
},
downloadFile(content, fileName) { //下载base64图片
let base64ToBlob = function(code) {
let parts = code.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
});
};
let aLink = document.createElement('a');
let blob = base64ToBlob(content); //new Blob([content]);
let evt = document.createEvent("HTMLEvents");
evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为
aLink.download = fileName;
aLink.href = URL.createObjectURL(blob);
aLink.click();
},
//下载图片
downLoadPic() {
let shareContent = document.getElementById('cert');//需要截图的包裹的(原生的)DOM 对象
let opts = this.getCanvasOption(shareContent);
this.html2canvas(shareContent,opts).then((canvas) =>{
// document.getElementById('dialog').appendChild(canvas);
let context = canvas.getContext('2d');
// 【重要】关闭抗锯齿
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
let MIME_TYPE = "image/png";
let imgURL = canvas.toDataURL(MIME_TYPE);
this.downloadFile(imgURL,'文件名')
});
},
//下载pdf
downLoadPdf() {
let shareContent = document.getElementById('cert');//需要截图的包裹的(原生的)DOM 对象
let opts = this.getCanvasOption(shareContent);
this.html2canvas(shareContent,opts).then((canvas) =>{
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new this.JsPDF('', 'pt', 'a4')
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save('文件名' + '.pdf')
});
},
},
mounted(){
//此项目是服务端渲染故,因为引入的中两个包里面有window,故需在页面加载后再调用这两个包
import('html2canvas').then((html2canvas)=>{
this.html2canvas = html2canvas.default;
});
import('jspdf').then((JsPDF)=>{
this.JsPDF = JsPDF.default;
});
}
此功能是在vue服务端渲染nuxt下实现的,实现这个在代码编写的时候特别要注意this的指向问题,我实习这个功能的过程中就因为this指向问题栽了坑,在method方法里面嵌套的回调最好是用箭头函数。不足之处,欢迎指正。
参考文章
https://segmentfault.com/a/1190000011478657