本教程详细讲解如何在Web前端使用JavaScript和SheetJS(xlsx库)直接解析Excel文件,涵盖环境准备、ArrayBuffer读取、工作簿对象解析、转换为JSON及日期处理等完整实践。
JavaScript前端读取Excel文件:SheetJS基础用法教程
时间:2026-10-30
浏览:564
文章目录
在前端交互场景中,用户常需要导入本地的 Excel 表格(如 .xlsx 或 .xls 格式)并快速在页面上进行数据校验、预览或图表展示。如果将解析工作完全交由后端服务器处理,不仅会产生额外的网络请求延迟,还会增加服务端的计算负载与临时存储成本。通过在浏览器端运行 JavaScript 直接读取与解析 Excel 文件,能够让数据流在客户端即时成型。SheetJS(npm 包名为 xlsx)是目前 JavaScript 生态中应用最为广泛的表格解析工具库。本文将以清晰的步骤说明其底层运行机制、环境引入方式、数据流转逻辑以及核心 API 的具体用法,并提供可直接运行的完整代码示例。
一、前端解析 Excel 的核心机制与数据流转
浏览器无法像桌面应用那样直接打开本地文件,它受制于浏览器的安全沙箱机制。用户必须通过页面上的文件上传控件(<input type="file">)或拖拽区域明确授权并选择文件。选择后,JavaScript 获得的是一个标准 File 对象。前端解析的核心在于:利用浏览器的 FileReader 或 File.prototype.arrayBuffer() 将物理文件转化为二进制内存流,再将该字节数组交由 SheetJS 解析为结构化的抽象工作簿对象(Workbook),最终提取为前端日常使用的 JSON 数组。
二、环境准备与依赖引入
要在项目中使用 SheetJS,可根据工程环境选择 CDN 直链引入或基于构建工具的 npm 依赖安装。
1. CDN 引入(原生 HTML 页面)
对于不需要复杂构建工具的原生页面或教学实验,直接在 HTML 的 <head> 或 <body> 底部引入官方构建的独立脚本最为快捷。加载后,全局对象 window.XLSX 便立即可用:
<!-- 引入 SheetJS 稳定版本脚本 -->
<script src="https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js"></script>
2. npm 依赖安装(现代工程化项目)
在基于 Vue、React 或 Vite/Webpack 的前端工程中,建议使用包管理器安装:
npm install xlsx
在业务模块中通过 ES Module 语法按需导入:
import * as XLSX from 'xlsx';
三、核心解析步骤详解
掌握 SheetJS 并不需要死记硬背庞杂的配置。完成一次标准的文件读取,只需依次执行以下六个关键步骤。
1. 捕获文件对象
在 HTML 中声明 <input type="file" id="excelFileInput" accept=".xlsx, .xls">。为该元素绑定 change 事件监听器:
const inputElement = document.getElementById('excelFileInput');
inputElement.addEventListener('change', async (event) => {
const file = event.target.files[0];
if (!file) return;
// 此时已经安全取得 File 对象
console.log(`已选择文件: ${file.name}, 大小: ${file.size} 字节`);
});
2. 将文件读入 ArrayBuffer
现代浏览器支持直接调用 file.arrayBuffer(),返回一个 Promise,这比传统 FileReader 的事件回调更加直观:
const arrayBuffer = await file.arrayBuffer();
const reader = new FileReader(); reader.readAsArrayBuffer(file); 并在 reader.onload 中处理。现代前端项目推荐直接使用 file.arrayBuffer()。
3. 解析为 Workbook 对象
调用 XLSX.read(),将刚才读取的 arrayBuffer 传入。第二个参数中必须指明数据格式类型 type: 'array':
const workbook = XLSX.read(arrayBuffer, { type: 'array' });
4. 提取工作表并转为 JSON
一个 Excel 文件可能包含多个 Sheet。SheetJS 会把所有表名存放在 workbook.SheetNames 数组中,具体的数据存放在 workbook.Sheets 对象中。我们通常取第一个表:
// 获取第一个工作表的名称
const firstSheetName = workbook.SheetNames[0];
// 根据名称获取具体的工作表对象
const worksheet = workbook.Sheets[firstSheetName];
// 调用工具函数,将工作表转换为对象数组
const jsonData = XLSX.utils.sheet_to_json(worksheet);
console.log('解析后的数据结果:', jsonData);
四、SheetJS 的核心数据模型
为了在实际业务中更灵活地处理表格,理解 SheetJS 内部的对象结构至关重要。SheetJS 将电子表格组织为三层模型:Workbook(工作簿)、Worksheet(工作表)和 Cell(单元格)。
如上图所示,当我们在 JavaScript 中访问某个单元格(如 worksheet['A1'])时,它并不是一个普通的字符串,而是一个对象:
v(Value):存储单元格的真实解析值,如数字100、字符串"姓名"或布尔值true。t(Type):标明单元格的数据类型,常见包括's'(字符串)、'n'(数值)、'b'(布尔)、'd'(日期)。w(Formatted Text):单元格在 Excel 视图中渲染出来的格式化文本,例如加入千分位符号或货币符号后的"$100.00"。
五、完整可运行的前端实操代码
下面是一个完整的、包含界面与样式的独立 HTML 文件代码。你可以将它直接保存为本地 .html 文件,在任何现代浏览器中双击打开测试。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>SheetJS 前端读取 Excel 示例</title>
<!-- 引入 SheetJS -->
<script src="https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js"></script>
<style>
body { font-family: sans-serif; padding: 24px; color: #17324D; }
.upload-card { border: 2px dashed #659B9B; padding: 20px; border-radius: 8px; width: 480px; }
#output { margin-top: 20px; background: #EEF4F7; padding: 12px; border-radius: 6px; max-height: 300px; overflow-y: auto; }
</style>
</head>
<body>
<h3>选择 Excel 文件解析</h3>
<div class="upload-card">
<input type="file" id="excelInput" accept=".xlsx, .xls, .csv" />
</div>
<h4>解析结果预览 (JSON):</h4>
<pre id="output">等待选择文件...</pre>
<script>
const excelInput = document.getElementById('excelInput');
const output = document.getElementById('output');
excelInput.addEventListener('change', async (event) => {
const file = event.target.files[0];
if (!file) return;
output.textContent = '正在读取解析中...';
try {
// 1. 读取文件的 ArrayBuffer
const buffer = await file.arrayBuffer();
// 2. 转换成 Workbook 对象
const workbook = XLSX.read(buffer, {
type: 'array',
cellDates: true // 自动将日期单元格转为 JS Date 对象
});
// 3. 取出首个 Sheet
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
// 4. 转换为 JSON 数组
const jsonData = XLSX.utils.sheet_to_json(worksheet, {
defval: '' // 空单元格填充空字符串,防止属性缺失
});
// 5. 渲染展示
output.textContent = JSON.stringify(jsonData, null, 2);
} catch (error) {
output.textContent = '文件解析失败:' + error.message;
}
});
</script>
</body>
</html>
六、高频实际问题与处理策略
在真实业务场景中,由于 Excel 本身的数据存储特性,直接使用默认配置常会遇到以下问题:
1. Excel 日期变成五位数字的问题
Excel 底层将日期存储为距离 1900 年 1 月 0 日的天数(即“日期序列号”)。默认情况下,SheetJS 会直接输出该数值(例如 45200)。解决方式是在调用 XLSX.read 时开启日期解析开关:
const workbook = XLSX.read(buffer, {
type: 'array',
cellDates: true // 自动解析为 JavaScript 标准 Date 实例
});
2. 防止空单元格导致字段缺失
默认使用 sheet_to_json 时,若某行的某一列为空,输出的 JavaScript 对象中将直接缺少该键名。这可能导致后续代码访问 item.telephone 时出现非预期的 undefined。通过配置 defval 可以统一空值占位:
const jsonData = XLSX.utils.sheet_to_json(worksheet, {
defval: '' // 缺失列自动填充空字符串,也可设为 null
});
3. 读取非首行表头或无规则表格
某些 Excel 文件的第一行是“报表标题”或说明文字,真正的字段名从第二行甚至第三行才开始。此时可以通过 header: 1 获取纯粹的二维数组:
// 获取行数组构成的二维矩阵 [ [A1, B1], [A2, B2], ... ]
const rawRows = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
// 手动截取有效表头与数据行
const headers = rawRows[1]; // 假设第二行是表头
const dataRows = rawRows.slice(2);
七、总结
前端利用 SheetJS 解析 Excel 的核心逻辑非常纯粹:通过 HTML5 File 接口获取用户授权的文件,以 ArrayBuffer 二进制形式载入内存,借助 XLSX.read 构造出 Workbook 数据树,再利用 XLSX.utils.sheet_to_json 完成到 JavaScript 业务对象的转换。对于大多数常见表格导入需求,配合 cellDates: true 与 defval: '' 参数即可稳定工作;若遇到数万行的大型数据表,则推荐将解析代码放入 Web Worker 中执行,从而保证界面的响应速度与用户体验。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。