Vue项目中如何实现表格选中数据的 Excel 导出
一、安装
npm install xlsx
二、核心代码
<template><div class="statistics-container"><el-button type="primary" @click="handleExportSelected">导出选中</el-button><el-table:data="tableData"borderstyle="width: 100%"@selection-change="handleSelectionChange"><el-table-column type="selection" width="55" /><el-table-column prop="index" label="序号" width="90" /><el-table-column prop="nickName" label="昵称" width="170" /><el-table-column prop="username" label="账号名" width="150" /></el-table></div>
</template><script lang="ts" setup>
import * as XLSX from "xlsx";
// 表格数据
const tableData = ref([]);// 选中项
const selectedRows = ref<any[]>([]);
const handleSelectionChange = (val: any[]) => {selectedRows.value = val;
};
// 导出选中
const handleExportSelected = () => {if (selectedRows.value.length === 0) {ElMessage.warning("请先选择要导出的数据");return;}// 准备导出数据const exportData = selectedRows.value.map((item) => {return {用户ID: item.userId,客户昵称: item.nickName,账号名: item.username,};});// 创建工作簿const ws = XLSX.utils.json_to_sheet(exportData);const wb = XLSX.utils.book_new();XLSX.utils.book_append_sheet(wb, ws, "列表数据");// 导出文件const fileName = `列表数据_选中_${new Date().getTime()}.xlsx`;XLSX.writeFile(wb, fileName);ElMessage.success(`成功导出${selectedRows.value.length}条数据`);
};
</script>
三、设置表头样式、实现列宽自适应
安装xlsx-js-style,设置单元格样式
npm install xlsx-js-style
import XLSX from "xlsx-js-style";
// 导出选中
const handleExportSelected = () => {if (selectedRows.value.length === 0) {ElMessage.warning("请先选择要导出的数据");return;}// 准备导出数据const exportData = selectedRows.value.map((item) => {return {用户ID: item.userId,客户昵称: item.nickName,账号名: item.username,};});// 创建工作簿const ws = XLSX.utils.json_to_sheet(exportData);// 设置表头样式const headerStyle = {font: {name: "Arial",sz: 12,bold: true,color: { rgb: "000000" },},fill: {fgColor: { rgb: "f3fff1" },},alignment: {horizontal: "center",vertical: "center",},border: {top: { style: "thin", color: { rgb: "000000" } },bottom: { style: "thin", color: { rgb: "000000" } },left: { style: "thin", color: { rgb: "000000" } },right: { style: "thin", color: { rgb: "000000" } },},};// 应用表头样式const range = XLSX.utils.decode_range(ws["!ref"]);for (let col = range.s.c; col <= range.e.c; col++) {const cell = ws[XLSX.utils.encode_cell({ r: 0, c: col })];if (cell) {cell.s = headerStyle;}}// 设置列宽自适应const colWidths = [];for (let col = range.s.c; col <= range.e.c; col++) {let maxWidth = 10;for (let row = range.s.r; row <= range.e.r; row++) {const cell = ws[XLSX.utils.encode_cell({ r: row, c: col })];if (cell && cell.v) {const cellLength = cell.v.toString().length;if (cellLength > maxWidth) {maxWidth = cellLength;}}}// 限制最大宽度为50,最小宽度为20colWidths.push({ wch: Math.min(Math.max(maxWidth + 2, 20), 50) });}ws["!cols"] = colWidths;const wb = XLSX.utils.book_new();console.log(ws);XLSX.utils.book_append_sheet(wb, ws, "列表数据");// 导出文件const fileName = `列表数据_选中_${new Date().getTime()}.xlsx`;XLSX.writeFile(wb, fileName);ElMessage.success(`成功导出${selectedRows.value.length}条数据`);
};