前言
在实现将页面部分元素生成图片并下载的需求过程中,我发现了html2canvas插件
html2canvas是一款javaScript插件,它的原理是通过遍历DOM树,将网页上的HTML元素转化为Canvas对象,从而可以将网页截图输出为图片或者pdf文件,
本文主要讲述转化为图片并下载的功能实现,至于输出为pdf文件我会在文后进行简单补充说明。
下载
//npm 下载
npm install --save html2canvas
//yarn 下载
yarn add html2canvas
引用
import html2canvas from "html2canvas";
需要下载的元素部分,因为我要实现的是一个告示牌样式的图片下载,所以我画的页面如下:
<div class="board" ref="imageDom">
<div class="center">
<p class="title">绿色公示牌 ( A类 )</p>
<p>
根据有关规定,该项目被主管部门评定为A类!悬挂绿牌,请项目全体从业人员继续保持项目良好安全生产状态,同时接受社会监督!
</p>
<div
style="margin-top: -14px; position: absolute; bottom: 0px"
></div>
<span>监督机构:</span
><strong style="font-weight: 550"
>建筑工程质量安全监督服务站</strong
><br />
<span>监督电话:0564—50221111</span>
</div>
</div>
//点击下载按钮
<div style="width: 100%; text-align: right; padding-right: 30px">
<el-button
size="mini"
type="text"
icon="el-icon-download"
@click="downloadFn"
>下载</el-button
>
</div>
其中需要给最外面的盒子一个ref(本文imageDom),用来后面获取容器
点击下载做的事
创建画布,利用html2canvas将HTML元素输出为图片地址,再将图片地址转化为Base64在进行下载
downloadFn() {
const clientWidth = this.$refs.imageDom.offsetWidth;//获取容易的宽高
const clientHeight = this.$refs.imageDom.offsetHeight;
let canvas = document.createElement("canvas");//创建Canvas对象
var scale = 2;//用于渲染的比例。默认为浏览器设备像素比率
canvas.width = clientWidth * scale;
canvas.height = clientHeight * scale;
const ops = {
scale: scale,
width: clientWidth,//画布的宽度
height: clientHeight,//画布的高度
// 跨域配置
useCORS: true, // 使用跨域
allowTaint: true, // 允许使用跨域资源
tainTest: false,
backgroundColor: null,
};
html2canvas(this.$refs.imageDom, ops).then((canvas) => {
// 转成图片,生成图片地址
this.imgUrl = canvas.toDataURL("image/png");
this.download(this.imgUrl, [canvas.width, canvas.height]);
});
},
download(imgUrl, kh) {
this.getUrlBase64(imgUrl, kh).then((base64) => {
const link = document.createElement("a");
link.href = base64;
link.download = `图片.png`;
link.click();
});
},
getUrlBase64(url, kh) {
return new Promise((resolve) => {
let canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
img.crossOrigin = "Anonymous"; // 允许跨域
img.src = url;
img.onload = () => {
// eslint-disable-next-line prefer-destructuring
canvas.height = kh[1];
// eslint-disable-next-line prefer-destructuring
canvas.width = kh[0];
ctx.drawImage(img, 0, 0, kh[0], kh[1]);
const dataURL = canvas.toDataURL("image/png");
canvas = null;
resolve(dataURL);
};
});
},
以上就是完成将元素转化为图片下载的步骤。
补充(转化为pdf文件)
既然都说了html2canvas插件可以实现将HTML元素转化为pdf文件,那应该怎么实现呢,我搁网上搜了下,码友大大们给我指了条明路,结合jspdf插件可以实现
下载
npm install jspdf --save
引用
import jsPDF from "jspdf";
点击转化按钮做的事
调用方法this.downloadPDF(this.$refs.imageDom)
downloadPDF(imageDom) => {
html2canvas(imageDom, {
useCORS: true, //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
allowTaint: true, //允许跨域
scale: 1, 设置放大倍数
}).then((canvas)=> {
canvas2PDF(canvas);
})
};
canvas2PDF(canvas){
// 新建JsPDF对象
const PDF = new jsPDF({
orientation: 'p', //参数: l:横向 p:纵向
unit: 'mm', //参数:测量单位("pt","mm", "cm", "m", "in" or "px")
format: 'a4', //A4纸
})
const ctx = canvas.getContext('2d')
const a4w = 190
const a4h = 277 //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
const imgHeight = Math.floor(a4h * canvas.width / a4w) //按A4显示比例换算一页图像的像素高度
let renderedHeight = 0
while (renderedHeight < canvas.height) {
let page = document.createElement("canvas");
page.width = canvas.width;
page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页
//用getImageData剪裁指定区域,并画到前面创建的canvas对象中
page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);
// canvas转图片数据保留10mm边距
PDF.addImage(page.toDataURL('image/jpeg', 0.2), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width));
renderedHeight += imgHeight;
//判断是否分页,如果后面还有内容,添加一个空页
if (renderedHeight < canvas.height) {
PDF.addPage()
}
}
PDF.save("导出.pdf");
};
在这基础上,如果你还直接转化文本为pdf文件,会有乱码,没有自动换行的问题。这些码友大大们自己再研究研究。