前端工作中经常会用到把一些元素导出,比如表格,正好项目有遇到导出为excel和导出为图片,就都封装实现了一下,以供其他需求的开发者使用:
1.导出为文档
这个说白了就是下载的功能,传过去检索参数,按照结果下载下来,没啥说的,先上伪代码
...
.then(blob => {
// 创建一个临时的URL,用于下载文件
console.log("blob", blob)
const url = window.URL.createObjectURL(new Blob([blob]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `${xxx}.xls`); //设置文件名字
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
success() //callback
dialog.close() //close modal
})
.catch((err) => {})
记得请求添加 responseType: ‘blob’,或者headers设置Accept:‘application/vnd.ms-excel’
2.导出为图片
先说一下最终的方案,最后使用了html2canvas的方案,后面我会说一下我的实现思路
// let element = 'ant-table'
const table = document.querySelector('.xxx-table');
console.log("table :", table )
html2canvas(table , { scale: 1 }).then(canvas => { //scale是图片大小
const dataUrl = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = dataUrl;
link.download = 'table.png';
link.click();
});
如果一个页面导出多个相同的元素,比如一个页面有2个table,将上方传入html2canvas的参数的table换成secondTable即可,如下
var tables = document.getElementsByClassName('ant-table');
var secondTable = tables[1]
多个元素是不能使用querySelector了, 因为querySelector只能选择单个元素,这里需要用其他的元素选择器,最好是class或者tagname等.
再先说一下我一开始实现的思路
- 一开始我用的是原生的canvas,创建canvas画布,设置大小等,
- 选择目标元素并cloneNode(true)深度拷贝目标节点下的全部后代元素
- 渲染元素到画布: 使用drawImage方法将克隆元素渲染到画布上。
- 元素被渲染到画布上后就可以使用toDataURL方法将画布内容导出为图片。
const imageUrl = canvas.toDataURL('image/png');
最后创建链接节点,自动点击,移除节点:
const downloadLink = document.createElement('a');
downloadLink.href = imageUrl;
downloadLink.download = 'element-image.png';
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
这种方案肯定是正常的一个思路,但是一直报cloneNode()函数有问题,undefined还是找不到,不记得了,我以为不支持这个es比较新的函数,其实想解决还是可以,用原生非方法递归子节点和节点元数据。 另外还报canvas的问题。
项目太赶了,我直接pass了,使用了html2canvas的方案,有兴趣的可以去试试。