有一个心理测评项目,测评结束后,要使用echarts图表展示出来,并且可以下载/打印图表。项目中需要处理数据的比较复杂,这篇只对关键部分进行摘要说明
1、获取到echarts并复制
let echarts = document.getElementsByTagName("canvas")[0];
let echartsCanvas = echarts.cloneNode(true); // 避免修改属性影响到页面上的图表
echartsCanvas.style.background = "#FFFFFF";
2、创建画布
let canvas = echartsCanvas.getContext("2d"); //创建画布
3、创建img
let img = new Image();
img.src = echarts.toDataURL();
4、在onload中绘制图形、位置、文字等
img.onload = () => {
echartsCanvas.setAttribute("width", img.width);
echartsCanvas.setAttribute("height", img.height+50);
echartsCanvas.setAttribute("style", "background:#ffffff;");
canvas.fillStyle = "rgba(255, 255, 255, 1)"; // 填充背景色
canvas.fillRect(0, 0, img.width, img.height+50); // 制"已填充"的矩形
// 绘制图片,drawImage(要绘制的图像, 在画布上放置图像的x坐标位置, 在画布上放置图像的y坐标位置, 要使用的图像的宽度, 要使用的图像的高度)
canvas.drawImage(img, 0, 50, img.width, img.height); // 上方留出信息空白
// 图片标题文字绘制
canvas.font = "32px Arial";
canvas.fillStyle = "black";
let tittext = "测评结果";
let titLength = tittext.length*32; // 文字整体宽度
let position = echartsCanvas.width/2 - titLength/2;
canvas.fillText(tittext, position, 30); // (要绘制的文字, 开始绘制文本的x坐标位置, 开始绘制文本的y坐标位置)
// 绘制下划线
canvas.beginPath(); // 开始一条路径
canvas.moveTo(position, 40); // 开始绘制的位置, (开始绘制的X坐标, 开始绘制的y坐标)
canvas.lineTo(position+titLength, 40); // 结束绘制的位置, (结束绘制的X坐标, 结束绘制的y坐标)
canvas.strokeStyle = 'black'; // 下划线颜色
canvas.stroke(); // 绘制下划线
// 合成图片
const synthesisUrl = echartsCanvas.toDataURL("image/png");
// 下载图片
downloadImg(synthesisUrl)
// 打印图片
printImg(synthesisUrl)
}
4.1、下载图片
downloadImg(synthesisUrl) {
const alink = document.createElement("a"); // 创建a标签
alink.href = synthesisUrl;
alink.download = "测评结果"; // 重命名文件
alink.click();
URL.revokeObjectURL(synthesisUrl); // 释放内存
}
下载下来的图片,如图所示(没有给图表填充数据,仅做示例测试):
4.2、打印图片
打印内容,通常我是调起浏览器的打印(比如在浏览器空白处右键→点击打印,看到的那个效果),然后在浏览器打印中,由客户自己去设置要打印的纸张等设置
printImg(synthesisUrl) {
const iframe = document.createElement("iframe");
iframe.onload = () => {
iframe.style.display = "none";
let doc = iframe.contentWindow.document;
doc.write(`
<div style="display:flex; justify-content:center; align-items:center; flex-direction:column;">
<div class="height" style="width:100%; height:20px;"></div>
<img src="` + synthesisUrl + `" alt="Canvas Image" style="width: 100%;">
</div>
`);
// 动态添加CSS以控制打印样式,隐藏页眉页脚
let style = doc.createElement('style');
style.type = 'text/css';
style.innerHTML = `
/* 只在火狐浏览器下生效的CSS */
@-moz-document url-prefix() {
@media print {
.height {
height: 20px;
}
}
}
@media print {
@page {
margin: 0;
}
body, html {
display:flex;
justify-content: center;
align-items: center;
}
}
`;
doc.head.appendChild(style);
setTimeout(() => {
iframe.contentWindow.print()
},1000);
}
iframe.type = "application/pdf"
document.body.appendChild(iframe);
调起浏览器打印如图所示: