产品粑粑说业务负责人要求所有的表格数据都能够导出···
对,所有···
不是说某一个列表···mlgb···
所以首先排除在页面一个个加导出功能··· 会累死爹爹的···
方案二通过一个方法导出el-table数据 ?
实践是检验真理的唯一标准,伟人们都这么说···
经过一番深思熟虑 拍脑袋 决定使用 XLSX 和 FileSaver 配合我们完成此项艰巨的任务···
first step :让el-table具有双击事件功能
还好 elementPlus 提供各种事件,基于我们目前的需求我选择了header-contextmenu;当操作 ‘ 导出excel ’ 时做下载功能;
具体代码如下:
<template>
<el-table
id="el-t"
:data="tableData"
style="width: 100%"
@header-contextmenu="handleRightClick" />
<div
v-if="contextMenuVisible"
class="context-menu"
:style="contextMenuStyle">
<div class="context-menu-option" @click="exportExcelFun">导出为excel</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { exportExcel } from "eltable-as-xlsx";
interface User {
date: string;
name: string;
address: string;
}
const tableData: User[] = [];
const contextMenuVisible = ref(false);
// 右键菜单的位置
const contextMenuStyle = ref({
left: "0",
top: "0",
});
//
function handleRightClick(column: any, event: any) {
event.preventDefault();
// 获取鼠标位置
let x = event.pageX;
let y = event.pageY;
contextMenuVisible.value = true;
contextMenuStyle.value = {
left: `${x}px`,
top: `${y}px`,
};
// 三秒不操作就自动取消
setTimeout(() => {
contextMenuVisible.value = false;
}, 3000);
}
function exportExcelFun() {
exportExcel({
id: "el-t", // DOM id
fileName: `file-${new Date().getTime()}`, // xlsx文件名
excludeColumns: ["操作"], // 要过滤的列
});
contextMenuVisible.value = false;
}
</script>
<style>
.context-menu {
position: fixed;
background-color: #fff;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
z-index: 999;
border: 1px solid #ccc;
}
.context-menu-option {
padding: 4px 15px;
white-space: nowrap;
cursor: pointer;
font-size: 12px;
}
.context-menu-option:hover {
background-color: #f5f5f5;
}
</style>
second step :如何把dom信息转成流信息
本来我想长话短说,但是说来话长 ··· 所以具体操作就不写了,毕竟好不容易在代码中写一次备注··· 不能浪费···
反正就是先这样再那样,就好了···
/*
*导出函数
* id :操作的el-table DOMID
* fileName :导出的文件命名
* excludeColumns :要过滤的列 (比如 操作列 一般是不用导出的)
*/
export const exportExcel = ({ id, fileName, excludeColumns = [] }: any) => {
// 获取表头和数据行的 DOM 元素
const theads = document.querySelectorAll(`#${id} table > thead > tr th`);
const rows = document.querySelectorAll(`#${id} table > tbody > tr`);
// 初始化一个空数组,用于存储表格数据
let data = [];
// 遍历每一行数据
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
let rowData = [];
const cells = row.cells;
// 遍历每一列数据
for (let j = 0; j < cells.length; j++) {
const cell = cells[j];
const columnTitle = theads[j].innerText;
const colspan = Number(theads[j].getAttribute("colspan"));
// 判断该列是否需要排除,如果需要排除,则跳过
if (!excludeColumns.includes(columnTitle) || colspan > 1) {
const cellValue = cell.innerText;
rowData.push(cellValue);
}
}
// 将该行数据添加到 data 数组中
data.push(rowData);
}
// 初始化一个空数组,用于存储表头数据
const headers = [];
// 遍历表头数据
for (let i = 0; i < theads.length; i++) {
const columnTitle = theads[i].innerText;
// 如果该列不需要排除,则将该列添加到 headers 数组中
if (!excludeColumns.includes(columnTitle)) {
headers.push(columnTitle);
}
}
// 将表头数据添加到数据数组的第一项
data.unshift(headers);
// 将数据转换为工作表
const worksheet = XLSX.utils.aoa_to_sheet(data);
// 计算每列的宽度
const columnWidths = computeColWidths(rows);
// 将列宽度设置到工作表中
worksheet["!cols"] = columnWidths.map((w) => ({ width: w / 6.4 }));
// 创建工作簿,将工作表添加到工作簿中
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
// 将工作簿转换为二进制数据流并下载
const wbout = XLSX.write(workbook, { bookType: "xlsx", type: "array" });
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
`${fileName}.xlsx`
);
};
在github上有完整的demo栗子, 可以CC哈。
最后附上npm包地址:www.npmjs.com/package/elt… github地址:github.com/yaozoo/elta…