在项目开发过程中,经常会有图片导出的需求,尤其是带有图表类的应用,通常需要将图表下载导出,虽然 echarts 在图表中提供了下载组件,但是具体项目中难免遇到在图表容器外部调用此保存图片方法的需求
以下是解决方案:
方案一、使用 echarts 官方接口
使用 echarts 官方提供的 getDataURL()方法可以返回一个 base64 的 URL 地址,我们可以利用此地址在 echarts 图表容器外部来实现图片另存和下载。
先看一下官方 API
echartsInstance.getDataURL Function
(opts: {
// 导出的格式,可选 png, jpeg
type?: string,
// 导出的图片分辨率比例,默认为 1。pixelRatio?: number,
// 导出的图片背景色,默认使用 option 里的 backgroundColor
backgroundColor?: string,
// 忽略组件的列表,例如要忽略 toolbox 就是 ['toolbox']
excludeComponents?: Array.<string>
}) => string
示例:var img = new Image();
img.src = myChart.getDataURL({
pixelRatio: 2,
backgroundColor: '#fff'
});
在 chrome 等新版浏览器中实现 base64 图片的下载还是比较容易的:
- 创建一个 a 标签
- 将 a 标签的 href 属性赋值为图片的 base64 编码
- 指定 a 标签的 download 属性,作为下载文件的名称
- 触发 a 标签的点击事件
但是这套逻辑在 IE 下是不行的,这样写会直接报错。
所以 IE 下需要单独处理,这里 IE 在处理这种文件的时候给提供了一个单独的方法:window.navigator.msSaveOrOpenBlob(blob, download_filename)调用这个方法可以直接触发 IE 的下载,还是比较方便的。具体做法如下:
saveImg(){
// 获取画布图表地址信息
const imgUrl = this.dataChart.getDataURL({
type:'jpeg',
pixelRatio: 1,
backgroundColor: '#fff'
});
// 如果浏览器支持 msSaveOrOpenBlob 方法(也就是使用 IE 浏览器的时候),那么调用该方法去下载图片
if (window.navigator.msSaveOrOpenBlob) {
// 截取 base64 的数据内容(去掉前面的描述信息,类似这样的一段:data:image/png;base64,)并解码为 2 进制数据
let bstr = atob(imgUrl.split(',')[1])
// 获取解码后的二进制数据的长度,用于后面创建二进制数据容器
let n = bstr.length
// 创建一个 Uint8Array 类型的数组以存放二进制数据
let u8arr = new Uint8Array(n)
// 将二进制数据存入 Uint8Array 类型的数组中
while (n--) {u8arr[n] = bstr.charCodeAt(n)
}
// 创建 blob 对象
let blob = new Blob([u8arr])
// 调用浏览器的方法,调起 IE 的下载流程
window.navigator.msSaveOrOpenBlob(blob, 'echarts 下载' + '.jpg')
}else{// 类似 chrome 浏览器创建一个 a 标签并使用 a 标签的 href 属性下载
let tempA = document.createElement("a");
tempA.download = 'echarts 下载' +'.jpg';
tempA.href = imgUrl;
document.body.appendChild(tempA);
tempA.click();
tempA.remove();}
}
方案二、使用 canvas 画布
echarts 图表本身是绘制在 canvas 元素中的,所以我们获取到 canvas 对象然后将其画布信息转换为地址即可
以下是实现代码
// 获取画布信息
let canvas = document.getElementsByTagName("canvas");
if(canvas&&canvas.length>0){
// 创建标签
let tempA = document.createElement("a");
// 设置下载名称
tempA.download = "echarts 下载" +".png";
// 设置地址以及文件类型
tempA.href = canvas[0].toDataURL("image/png");
document.body.appendChild(tempA);
// 触发下载事件
tempA.click();
// 移除标签
tempA.remove();}
以上