1. 实现方案
- 分别获取
El-Table
的表头和内容的DOM
元素(这里考虑El-Table
是可滚动的内容区域) - 使用
html2canvas
库将DOM
元素转化为Canvas
- 创建一个新的
Canvas
将上述两个Canvas
进行拼接 - 将最终的
Canvas
转换为图片并下载
2. 具体实现
import html2canvas from 'html2canvas';
/**
* ElTable 导出为图片
* @param {String} selector el-table 的自定义选择器
* @param {String} fileName 文件名
*/
export function elTableExportToImage(selector, fileName) {
const tableHeaderDom = document.querySelector(
`${selector}.el-table .el-table__header`
);
const tableBodyDom = document.querySelector(
`${selector}.el-table .el-table__body`
);
let headerCanvas = null;
let bodyCanvas = null;
html2canvas(tableHeaderDom)
.then((canvas) => {
headerCanvas = canvas;
return html2canvas(tableBodyDom);
})
.then((canvas) => {
bodyCanvas = canvas;
const imageCanvas = _mergeCanvases(headerCanvas, bodyCanvas);
_downloadCanvasAsImage(imageCanvas, fileName);
});
}
/**
* 合并两个 Canvas
* @param {HTMLCanvasElement} canvasOne
* @param {HTMLCanvasElement} canvasTwo
* @returns {HTMLCanvasElement} 合并后的 Canvas
*/
function _mergeCanvases(canvasOne, canvasTwo) {
const mergedCanvas = document.createElement('canvas');
const ctx = mergedCanvas.getContext('2d');
// 设置合并后的 Canvas 大小
mergedCanvas.width = Math.max(canvasOne.width, canvasTwo.width);
mergedCanvas.height = canvasOne.height + canvasTwo.height;
// 将第一个 Canvas 内容绘制到合并的 Canvas
ctx.drawImage(canvasOne, 0, 0);
// 将第二个 Canvas 内容绘制到合并的 Canvas,紧接着第一个 Canvas
ctx.drawImage(canvasTwo, 0, canvasOne.height);
return mergedCanvas;
}
/**
* 下载 canvas 为图片
* @param {HTMLCanvasElement} canvas
* @param {String} fileName 文件名,默认为时间戳
*/
function _downloadCanvasAsImage(canvas, fileName = Date.now()) {
const image = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = fileName + '.png';
link.href = image;
link.click();
link.remove();
}
3. 食用文档
- 安装
html2canvas
库
npm install html2canvas
-
为
El-Table
自定义一个类名或者 ID 名 -
将 类/ID 的选择器做为第一个参数传入
elTableExportToImage
函数
<template>
<el-button
type="success"
@click="elTableExportToImage('#unit-report-table-master', '文件名')">
导出图像
</el-button>
<el-table id="unit-report-table-master" :data="[]"> .... </el-table>
</template>
<script setup>
import { elTableExportToImage } from 'xxxx';
</script>