一、需求背景:
最近在做一个项目,在后台管理系统中,将查询到的信息以类似报告的形式展示给用户,用户可以查看,或者下载。下载采用图片的形式进行。
二、选择技术实现背景
由于查询的信息是从后端获取的,拿到前端以HTML的形式布局并展示,所以技术实现考虑过直接后端生成图片,前端负责展示并下载,或者前端负责编排布局并生成图片下载。最终由于时间有限,暂时由后端采用模板的方式,将内容生成为图片文件流给前端进行下载。
但是,心里始终有点放不下,所以今天尝试了在前端进行图片的生成并下载。
三、涉及部分
1、页面部分
仅作展示,div里面内容可以自行编辑,里面的内容就是想要生成图片的内容
<el-dialog title="" :visible.sync="detailFlag" width="600px" center>
<div style="width:100%;" ref="downQR">
<div v-html="htmlTitle" style="text-align:center;"></div>
<div style="padding: 5px;">
<h3 style="padding:0 10px;">【患儿信息】</h3>
<div class="item" v-text="'姓名:'+patientName"></div>
<div class="item" v-text="'法定监护人:'+realName"></div>
<div class="item" v-text="'联系方式:'+phone"></div>
<div v-html="htmlBody"></div>
<div class="item" style="width:100%;height:50px;"><p>患者/患儿监护人签名:<img v-if="imageUrl" :src="imageUrl" style="width:160px;height:50px;display:inline-block"/></p>
</div>
<div class="item" style="margin-top:50px;" v-text="'签字日期:'+recordTime"></div>
</div>
</div>
<el-button type="primary" size="default" @click="downloadTest(realName)">保存图片</el-button>
</el-dialog>
2、代码部分引入的实现类
我在此处用的html2canvas这个工具类,具体安装可以使用npm或者直接本地引用。
不管怎么引用,此处都需要根据路径导入
import html2canvas from "html2canvas";
3、代码实现的主体部分
这段代码就是核心了,包含了两步:第一步,将标记的HTML部分画到画布上,并生成图片;第二步,根据生成的图片url和设置的图片名称,将图片下载到本地
downloadTest(realName) {
let element = this.$refs.downQR;
html2canvas(element, {
allowTaint: true,
useCORS: true,
tainttest: true, // 检测每张图片都已经加载完成
logging: true,
//backgroundColor: `rgb(143,40,37)`, // 转换图片可能会有白色底色,你可根据你的页面或者PM要求设置一下背景色,不要的话就null
}).then((canvas) => {
// 转成图片,生成图片地址
let imgUrl = canvas.toDataURL("image/jpeg");
this.downloadIamgeTest(imgUrl, realName);
});
},
downloadIamgeTest(imgsrc, name) {
// 下载图片地址和图片名
var image = new Image();
// 解决跨域 Canvas 污染问题
image.setAttribute("crossOrigin", "anonymous");
image.onload = function () {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
var url = canvas.toDataURL("image/png"); // 得到图片的base64编码数据
var a = document.createElement("a"); // 生成一个a元素
var event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "photo"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
};
image.src = imgsrc;
},
总结:目前,通过这种方法,能够实现几乎全部HTML内容生成图片,但是,我遇到一个问题,假如HTML内容中有网络图片,我这里是没有被画出来的,也就是canvas没把网络图片渲染出来,所以这是个问题,后续待解决。