文章目录
一、安装xlsx
执行命令:npm i xlsx file-saver --save
二、报错及解决
使用时:import XLSX from "xlsx";
发现如下报错信息
报错原因:xlsx版本不兼容。
解决也很简单:
1)先移除已安装的xlsx: npm uninstall xlsx
2)安装低版本:npm i xlsx@0.17.0
三、编写公共方法
javascript
// exportExcel.js
import { saveAs } from "file-saver";
import XLSX from "xlsx";
function datenum(v, date1904) {
if (date1904) v += 1462;
const epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data) {
let ws = {};
let range = {
s: {
c: 10000000,
r: 10000000
},
e: {
c: 0,
r: 0
}
};
for (let R = 0; R != data.length; ++R) {
for (let C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
let cell = {
v: data[R][C]
};
if (cell.v == null) continue;
const cell_ref = XLSX.utils.encode_cell({
c: C,
r: R
});
if (typeof cell.v === "number") cell.t = "n";
else if (typeof cell.v === "boolean") cell.t = "b";
else if (cell.v instanceof Date) {
cell.t = "n";
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
} else cell.t = "s";
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);
return ws;
}
function s2ab(s) {
let buf = new ArrayBuffer(s.length);
let view = new Uint8Array(buf);
for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
return buf;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
/**
* @description 导出表格数据
* @param {Array} header 表头
* @param {Array} data 数据
* @param {String} filename 文件名
* @param {merges} header 表头
* @param {autoWidth} header 是否自适应表格内容宽度
* @param {bookType} header excel文件后缀名
*/
export function exportJson2Excel({
header = [],
data = [],
filename = "excel",
merges = [],
autoWidth = true,
bookType = "xlsx"
} = {}) {
let dataKeys = [];
// 处理xlsx头部
header = header.map(item => {
dataKeys.push(item.key);
return item.value;
});
// 处理data数据
data = data.map(item => {
const dataOne = dataKeys.map(key => item[key]);
return [...dataOne];
});
header.length > 0 && data.unshift(header);
let ws = sheet_from_array_of_arrays(data);
if (merges.length > 0) {
if (!ws["!merges"]) ws["!merges"] = [];
merges.forEach(item => {
ws["!merges"].push(XLSX.utils.decode_range(item));
});
}
if (autoWidth) {
// 设置worksheet每列的最大宽度
const colWidth = data.map(row =>
row.map(val => {
// 先判断是否为null、undefined
if (val == null) {
return {
wch: 10
};
} else if (val.toString().charCodeAt(0) > 255) {
// 判断是否为中文
return {
wch: val.toString().length * 2
};
} else {
return {
wch: val.toString().length
};
}
})
);
// 以第一行为初始值
let result = colWidth[0];
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]["wch"] < colWidth[i][j]["wch"]) {
result[j]["wch"] = colWidth[i][j]["wch"];
}
}
}
ws["!cols"] = result;
}
const ws_name = "SheetJS";
const wb = new Workbook();
// 将工作表添加到工作簿
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
const wbout = XLSX.write(wb, {
bookType: bookType,
bookSST: false,
type: "binary"
});
saveAs(
new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}),
`${filename}.${bookType}`
);
}
四、方法使用
javascript
<template>
<div class="hello">
<el-button type="primary" @click="handleExport">导出为Excel</el-button>
<el-table :data="tableData" border>
<el-table-column
v-for="item in header"
:key="item.key"
:label="item.value"
:prop="item.key"
>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { exportJson2Excel } from "../utils/exportExcel.js";
export default {
data() {
return {
message: "",
header: [
{
key: "id",
value: "ID"
},
{
key: "title",
value: "名称"
},
{
key: "tag",
value: "标签"
},
{
key: "typeText",
value: "方式"
},
{
key: "cycle",
value: "周期"
},
{
key: "status",
value: "状态"
}
],
tableData: [
{
id: 44,
title: "test111122222",
tag: "",
typeText: "定时任务",
cycle: "每天 9:00",
status: "草稿"
},
{
id: 45,
title:
"名称很长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长",
tag: "hhh",
typeText: "定时任务",
cycle: "每天 12:00",
status: "草稿"
},
{
id: 45,
title: "测试测试测试",
tag: "hhh",
typeText: "定时任务",
cycle: "每天 00:00",
status: "草稿"
},
{
id: 47,
title: "嗯嗯嗯",
tag: "hhh",
typeText: "定时任务",
cycle: "每天 10:00",
status: "草稿"
},
{
id: 48,
title: "test",
tag: "null",
typeText: "循环任务",
cycle: "每天 19:00",
status: "正式"
}
]
};
},
methods: {
handleExport() {
console.log("export");
exportJson2Excel({
data: this.tableData,
header: this.header
});
}
};
</script>
页面页面展示,及导出结果: