中文教程:https://github.com/rockboom/SheetJS-docs-zh-CN/
英文详解:https://www.npmjs.com/package/xlsx
安装引用
npm install xlsx
import * as XLSX from "xlsx";
导出文件
let title ="结果.xlsx"; //标题
let aoa = [["序号", "工号", "姓名", "排序", "结果"]]; //表头
// 每行数据
tableData.forEach((item, index) => {
aoa.push([
index + 1,
item.id,
item.name,
item.rank * 1,
item.level,
]);
});
let worksheet = XLSX.utils.aoa_to_sheet(aoa); // 工作表对象
let workbook = XLSX.utils.book_new(); // 文件对象
XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
XLSX.writeFile(workbook, title); // 导出文件
设置列宽和行高
设置列宽,可将数字算为1个字符宽,中文算为2字符宽,导出结果较为美观
worksheet["!cols"] = [{ wch: 10 }, { wch: 20 },...];
列属性,wpx、width、wch任选一个设置列宽即可
- hidden ?: boolean ; // 如果为真,则隐藏列
- wpx ?: number ; // 屏幕像素
- width ?: number ; // Excel 的“最大数字宽度”中的宽度,width*256 是整数
- wch ?: number ; // 字符宽度
- level ?: number ; // 0 索引大纲/组级别
- MDW ?: number ; // Excel 的“最大数字宽度”单位,总是整数
设置行
worksheet["!rows"] = [{...},...]
行属性 ,hpx、hpt任选一
- hidden ?: boolean ; // 如果为真,则隐藏行
- hpx ?: number ; // 屏幕像素高度
- hpt ?: number ; // 高度
- level ?: number ; // 0 索引大纲/组级别
设置单元格
单元格属性
- v 原始值
- w 格式化文本
- t 类型: b布尔值, e错误, n数字, d日期, s文本, z存根
- f 单元格公式
- F 如果公式是数组公式,则封闭数组的范围
- D 如果为真,则数组公式是动态的
- r 富文本编码
- h 富文本的 HTML 呈现(
- c 与单元格相关的评论
- z 与单元格关联的数字格式字符串
- l 单元格超链接对象 ( .Target持有链接, .Tooltip是工具提示)
- s 单元格的样式/主题。 ps: 从文件读取时默认不提取行和列属性,写入文件时默认不保留。 选项 cellStyles: true 必须传递给相关的读取或写入函数。
单个单元格——设置注释
直接获取:worksheet[“A1”]
worksheet["A1"].c = [
{ a: "SheetJS", t: "注释内容" }
];
worksheet["A1"].c.hidden = true; // 隐藏注释
单元格范围——设置数字类型
通过行号列号获取:worksheet[XLSX.utils.encode_cell({ r: R, c: C })]
// D2到E6范围
let range = {
s: { c: 3, r: 1 },
e: { c: 4, r: 5 },
};
for (let R = 0; R <= range.e.r; ++R) {
for (let C = 0; C <= range.e.c; ++C) {
let cell = worksheet[XLSX.utils.encode_cell({ r: R, c: C })];
cell.t = "n";
}
}
基于elementPlus的文件上传
直接在前端处理Excel处理,不上传至后端。因此借助
before-upload
获取原生文件,再经由XLSX.read
读取文件的数据。
<el-form :inline="true" class="operate">
<el-form-item label="通过文件上传数据" style="width: 100%">
<el-upload
ref="upload"
class="upload"
action=""
accept=".xlsx"
:limit="1"
:before-upload="handleBeforeUpload"
:auto-upload="false"
>
<template #trigger>
<el-button type="info" size="small" @click.stop="download"
>样表下载</el-button
>
<el-button type="warning" size="small">文件选择</el-button>
</template>
<el-button
type="success"
size="small"
@click="submitUpload"
style="margin-left: 12px"
>数据读取</el-button
>
</el-upload>
</el-form-item>
</el-form>
const upload = ref<UploadInstance>();
// 点击【数据获取】后读取数据
const handleBeforeUpload: UploadProps["beforeUpload"] = (rawFile) => {
// console.log(rawFile);
const fileReader = new FileReader();
fileReader.onload = (files) => {
try {
const data = files.target.result;
const workbook = XLSX.read(data, { type: "binary" });
const wsname = workbook.SheetNames[0];
const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]);
...
} catch (e) {
console.log(e);
}
};
fileReader.readAsBinaryString(rawFile);
return false;//读取后不上传文件至后端
};
// 点击【数据获取】
const submitUpload = () => {
upload.value!.submit();
};
// 点击【样表下载】
const download = async () => {
let title = "样表.xlsx";
let aoa = [["序号", "工号", "姓名"]];
users.forEach((item, index) => {
aoa.push([index + 1, item.id, item.username]);
});
let worksheet = XLSX.utils.aoa_to_sheet(aoa);
let workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
XLSX.writeFile(workbook, title);
};