XLSX 文件解析

预计阅读时间: 5 分钟

XLSX 文件解析插件:zxkv-xlsx「👈 点击查看」

「🚀」场景需求

  工作中,最初解析 Excel 文件数据是通过后端开发来对上传的文件内容进行解析的;此时的前端只需能保证把 Excel 文件成功传递到后端即可;然后后端通过编程语言将收到的 File 文件流解析成想要的 JSON 数据格式返回给前端进行数据展示。前期想法很好,最初的方案也是按照后端解析的思路进行设计实现的。最后为了减轻服务端的压力,最终将 Excel 文件解析的工作提前放置在前端解析,最初的一步上传就搞定的逻辑,到如今基于“前端”实现 Excel 转 JSON,犹如晴天霹雳似的打的我一头雾水,还需要重新梳理逻辑,确定前端实现转换的方案。

  「 无 奈 」确定方案后,就尝试寻找现有的方案来满足当前的业务需求;穿梭于各大开发博客论坛网站之间,愣是没找到符合自己需求的方案;最后在翻阅 Githubnpm 时候无意间找到一个能解析 Excel 文件的开源包,犹如一道金光照射在我的眼前,脑门瞬间灵光一闪,就它了,历经千山万水,终于达到了技术 leader 的要求,终于可以松一口气了。「 開 心 😆」

「🚢」功能实现

注意「👀」:

  前端解析 Excel 文件是基于 read-excel-file 包实现文件解析的,接下来是具体的实现步骤和注意事项「注:该包仅支持 xlsx 格式的文件解析,xls格式的文件无法解析」

  • 安装所需依赖包「选其一」
npm
yarn
pnpm
bun
1npm install read-excel-file
  • 读取 XLSX 文件
读取数据
1// 引入解析xlsx文件数据的包
2import ReadXlsxFile from "read-excel-file";
3// 引入转换解析数据的包
4import ConvertToJson from "read-excel-file/schema";
5
6/**
7 * @description Xlsx文件转JSON数据
8 * @param {Object} file xlsx文件对象
9 * @param {Object} keyProps 表头和属性值对应关系
10 * @param {Object} emptyItem 数据项默认值对象
11 * @param {Number} titleRows 表头说明所占用行数
12 * @return {Object} 解析异常时返回值为null,正常情况下返回Array数组
13 **/
14export const XlsxToData = async (file, keyProps, emptyItem, titleRows = 0) => {
15	try {
16		// 通过安装的插件包进行解析文件
17		let fileXlsx = await ReadXlsxFile(file);
18
19		// 判断解析出来的数据是否是 Array
20		if (!(Array.isArray(fileXlsx) && fileXlsx.length)) return [];
21
22		// 处理数据项的默认值
23		let emptyStmp = { ...emptyItem };
24
25		// 截取数据体
26		let xlsxData = fileXlsx.splice(titleRows);
27
28		// xlsx转换JSON数据
29		const { rows } = ConvertToJson(xlsxData, keyProps);
30
31		// 转换后的数据
32		let list = rows?.map((row, index) => Object.assign({ index }, emptyStmp, row));
33
34		// 返回解析处理后的数据
35		return list;
36	} catch (error) {
37		// 文件解析失败,返回 null
38		return null;
39	}
40};
  • 要读取的 XLSX 文件源数据

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

解析数据
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”包进行解析处理」
  • 数据转换只转数据体,所以 XLSX 文件的标头无需处理,故在进行转换数据之前需将标头该一组数据移除掉
转换数据
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 数据
转换后的数据
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]

「🚄」效果展示

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

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

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

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

「🚗」分析总结

  需求场景构想的宏伟蓝图,需要一步一步的去学习和探索,以至于达成最终想要的效果。每一次的功能开发都是一次挑战,在面对挑战时,要静下心来,好好分析本次功能所需的技术点,然后一点一点剖析,最终会发现,卡脖子的往往是那关键的一小步,解决了那关键的一小步,接下来基本就可以一帆风顺,后续功能所有的场景和所需的技术点都会梳理的明明白白,在不断的思考和探索中稳步前行。(ง•_•)ง