需求:纯前端导出表格,设置列宽单元格内容左对齐
1. 首先安装xlsx和xlsx-js-style
npm install xlsx --save
npm install xlsx-js-style --save
- 关于xlsx-js-style和xlsx-style
首先说明本人不建议使用xlsx-style
在使用xlsx-style发现会报错Could not resolve "./cptable"
解决方法:
需要在vite.config.js进行配置,个人认为完全没必要多此一举!!!
当然以下也给出解决方法
configureWebpack: {
externals: { './cptable': 'var cptable' }
}
2. 在HTML中给table添加id或class名
这里给需要导出的表格设置id 'xlsx-table'
<el-table :data="tableData" id="xlsx-table">
<el-table-column property="stcd" label="测站编码" />
<el-table-column property="stnm" label="测站名称" />
<el-table-column property="dataTime" label="监测时间" />
<el-table-column property="dictLabel" label="所属机构" />
</el-table>
3. 自行创建js文件copy以下内容
注释中有各个函数的介绍,这里不展开一一说明了
import * as XLSX from "xlsx";
import XLSX_STYLE from 'xlsx-js-style';
// 参数介绍
// id:表格的id
// name:保存的文件名
// col_W:列宽
// style:单元格样式
export async function exportTableToExcel({id, name, col_W = 20, style = {alignment: { horizontal: 'left' }}}) {
const ws = XLSX.utils.table_to_sheet(document.querySelector(id));
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
const count = splitRange(ws["!fullref"])
// 遍历单元格
for (let c = 0; c <= count.col; c++) {
// 设置列宽
ws["!cols"].push({ wch: col_W })
for (let r = 0; r <= count.row; r++) {
const cellAddress = XLSX.utils.encode_cell({ r, c });
if (ws[cellAddress]) {
// 给每个单元格添加样式
ws[cellAddress].s = style;
}
}
}
const wbout = XLSX_STYLE.write(wb, { type: 'binary', bookType: 'xlsx' });
saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), name + '.xlsx');
}
const s2ab = (s) => {
// 将二进制字符串转换为ArrayBuffer
const buf = new ArrayBuffer(s.length);
const view = new Uint8Array(buf);
for (let i = 0; i < s.length; i++) {
view[i] = s.charCodeAt(i) & 0xFF;
}
return buf;
}
// 文档没找到列数,只找到一个“A1:F14”代表A-F列,思路是转换成ascii码 F-A 就是列数 14-1 就是行数
function splitRange(rangeStr) {
// 拆分范围字符串为起始和结束部分
const [start, end] = rangeStr.split(':');
// 提取字母和数字
const extractParts = (str) => ({
letters: str.match(/[A-Za-z]+/)[0],
numbers: parseInt(str.match(/\d+/)[0], 10)
});
// 返回结构化的数组
return {
col: extractParts(end).letters.charCodeAt(0) - extractParts(start).letters.charCodeAt(0),
row: extractParts(end).numbers - extractParts(start).numbers - 1 // 减掉标题行
}
}
4. 在需要的地方引入exportTableToExcel方法并使用即可
例如点击按钮导出id为xlsx-table的表格
<el-button
@click="exportTableToExcel({id: '#xlsx-table', title: '全省-各政区总览'})"
type="primary"
>
导出
</el-button>