XLS 文件解析

预计阅读时间: 4 分钟

XLS 文件解析插件:zxkv-excel-json「👈 点击查看」

「🚀」场景需求

  前边文章已经对“XLSX 转 JSON”做了相应的处理,早期需求比较紧张,就优先考虑了目前主流的“xlsx”格式的 Excel 文件解析。但是投入使用后发现有一部分用户的操作系统偏老旧,他们办公处理文档还是基于早期的“office”办公软件进行工作的;为了支持“xls”文档的解析,寻找了好多方案进行处理;处理时不仅要考虑兼容性还要考虑插件包的内存大小、兼容性、使用是否便捷等一系列因素,最终采用“xlsx.js”来实现解析“xls”文件。 在处理 Demo 案例过程中发现,“xlsx.js”对“xlsx”格式文件和“xls”格式文件均支持,相对之前处理“xlsx”格式文件时,需要对文件流进行加载处理,具体方法可以参考如下代码案例。

「🚢」功能实现

提示「🔔」:

  前端解析 Excel 文件是基于 sheetjs 的xlsx包实现文件解析的,接下来是具体的实现步骤和注意事项「注:支持 xlsx 和 xls 及其它格式文件的解析」

  • 安装方式一:
npm
yarn
pnpm
bun
1npm install xlsx --save
  • 安装方式二:
npm
yarn
pnpm
bun
1npm install  https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz
  • 读取 XLS 文件
读取文件
1// 引入解析excel文件解析包
2import { read, utils } from "xlsx";
3// 引入转换解析数据的包
4import ConvertToJson from "read-excel-file/schema";
5
6/**
7 * @description Xls文件转JSON数据
8 * @param {Object} file xls文件对象
9 * @param {Object} keyProps 表头和属性值对应关系:{'用户名':{prop:'username',type:String}...}
10 * @param {Object} emptyItem 数据项默认值对象
11 * @param {Number} titleRows 表头说明所占用行数
12 * @return {Object} 解析异常时返回值为null,正常情况下返回Array数组
13 **/
14export const XlsToData = (file, keyProps, emptyItem, titleRows = 0) => {
15	return new Promise((resolve, reject) => {
16		// 初始化FileReader对象实例
17		const FR = new FileReader();
18
19		// 读取成功
20		FR.addEventListener("loadend", evt => {
21			// 文件对象
22			const FB = evt.target.result;
23
24			// 读取数据
25			const WB = read(FB);
26
27			// 转换二维数组数据
28			let fileXls = utils.sheet_to_json(WB.Sheets[WB.SheetNames[0]], { header: 1 });
29
30			// 判断解析的数据是否是二维数组
31			if (!(Array.isArray(fileXls) && fileXls.length)) return resolve([]);
32
33			// 赋值默认数据对象
34			let emptyStmp = { ...emptyItem };
35
36			// 截取数据体
37			let xlsData = fileXls.splice(titleRows);
38
39			// 转换后的数据
40			const { rows } = ConvertToJson(xlsData, keyProps);
41
42			// 处理后的数据
43			let list = rows?.map((row, index) => Object.assign({ index }, emptyStmp, row));
44			resolve(list);
45		});
46
47		// 读取失败
48		FR.addEventListener("error", () => reject(null));
49
50		// 读取数据
51		FR.readAsArrayBuffer(file);
52	});
53};
  • xlsx 使用文档-sheetjs

SheetJS 文档「👈 点击查看文档」

  • 要读取的 XLS 文件源数据

    账号密码姓名
    A000110001STU_10001
    A000210002STU_10002
    A000310003STU_10003
    A000410004STU_10004
    A000510005STU_10005
  • 解析 xls 文件数据

读取数据
1[
2	["账号", "密码", "姓名"],
3	["A0001", 10001, "STU_10001"],
4	["A0002", 10002, "STU_10002"],
5	["A0003", 10003, "STU_10003"],
6	["A0004", 10004, "STU_10004"],
7	["A0005", 10005, "STU_10005"]
8]
  • 转换数据「将解析生成的二维数组转换成后端所需的 JSON 数组对象,此处需要借助 “schema” 包进行解析处理」
  • 数据转换只转数据体,所以 XLS 文件的标头无需处理,故在进行转换数据之前需将标头该一组数据移除掉
解析数据
1[
2	["A0001", 10001, "STU_10001"],
3	["A0002", 10002, "STU_10002"],
4	["A0003", 10003, "STU_10003"],
5	["A0004", 10004, "STU_10004"],
6	["A0005", 10005, "STU_10005"]
7]
  • 转换数据所需参数配置
转换参数
1// 匹配转换的数据字段
2let keyProp = {
3	账号: {
4		prop: "username",
5		type: String
6	},
7	密码: {
8		prop: "password",
9		type: String
10	},
11	姓名: {
12		prop: "studentname",
13		type: String
14	}
15};
16
17// 空值数据
18let emptyItem = {
19	username: "",
20	password: "",
21	studentname: ""
22};
  • 转换后的 JSON 数据
JSON 数据格式
1[
2	{
3		"index": 0,
4		"username": "A0001",
5		"password": 10001,
6		"studentname": "STU_10001"
7	},
8	{
9		"index": 1,
10		"username": "A0002",
11		"password": 10002,
12		"studentname": "STU_10002"
13	},
14	{
15		"index": 2,
16		"username": "A0003",
17		"password": 10003,
18		"studentname": "STU_10003"
19	},
20	{
21		"index": 3,
22		"username": "A0004",
23		"password": 10004,
24		"studentname": "STU_10004"
25	},
26	{
27		"index": 4,
28		"username": "A0005",
29		"password": 10005,
30		"studentname": "STU_10005"
31	}
32]

「🚄」效果展示

XLS 文件上传前的文件展示效果区域

上传前的文件展示效果区域

XLS 文件解匹配后的数据展示效果

文件解匹配后的数据展示效果

「🚗」分析总结

  上述笔记是对 Excel 文件的 XLS 格式的文件进行解析处理的;对比 XLSX 文件的解析,XLS 格式的解析多了文件流读取这一步骤。XLSX 格式文件也可以用过上述方式来解析生成 JSON 格式的数据,已在实际开发中使用和验证。

  若需整合支持 Excel 文件数据的解析,可以直接使用 “xlsx” 包进行解析,也可以使用 “read-excel-file” 包进行解析,两种方式均可,相对来说 “xlsx” 包支持的文件种类比较多些;“read-excel-file” 包比较小,仅支持 “xlsx” 一种数据格式文件的解析。可以根据自己开发过程中实际场景需求来选取符合自己要求的方案。