SheetJS是浏览器中解析Excel文件最可靠方案,支持.xlsx/.xls、公式、多sheet、合并单元格等;需用readAsArrayBuffer读取并指定{type:'array'},再用sheet_to_json转换,注意header、defval及日期格式处理。
浏览器里直接解析 .xlsx 文件,别折腾自己写解析器——SheetJS(xlsx npm 包)是目前唯一稳定、兼容主流 Excel 特性的方案。它不依赖后端,纯前端解析,支持公式、多 sheet、合并单元格、日期格式等,连 Excel 2007+ 的二进制结构(.xlsx)和旧版 .xls 都能啃下来。
常见误区是试图用 FileReader + XMLHttpRequest 手动解析 XML 结构,结果卡在命名空间、共享字符串表、日期序列号转换上,半天跑不出一行数据。
正确做法是:引入 xlsx,用 read 或 readFile 加载文件,再用 utils.sheet_to_json 转成数组。
用户点击上传按钮,选中一个 .xlsx 文件,立刻拿到 JSON 格式的数据表(默认第一张 sheet):
立即学习“前端免费学习笔记(深入)”;
<input type="file" id="excel-file" accept=".xlsx,.xls"><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js"></script><script> document.getElementById('excel-file').addEventListener('change', function(e) { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { const data = new Uint8Array(e.target.result); const workbook = XLSX.read(data, { type: 'array' }); const firstSheet = workbook.Sheets[workbook.SheetNames[0]]; const jsonData = XLSX.utils.sheet_to_json(firstSheet, { header: 1, // 返回二维数组(适合表格渲染),不设则返回对象数组 defval: '' // 空单元格填空字符串,避免 undefined }); console.log(jsonData); // 如 [[ "姓名", "年龄" ], [ "张三", 25 ]] }; reader.readAsArrayBuffer(file); });</script>
注意三点:
readAsArrayBuffer 是必须的——xlsx 内部依赖二进制精度,readAsText 会破坏结构{ type: 'array' } 告诉 XLSX.read 输入是 Uint8Array,类型错会导致静默失败或乱码sheet_to_json 的 header: 1 和 defval 不设容易让空列变成 undefined,后续 map 或渲染出错真实 Excel 往往不止一张表、首行是标题、日期显示为数字(如 44926)。这些不是 bug,是 Excel 底层存储方式决定的:
workbook.SheetNames,对每个名字调用 workbook.Sheets[name]
header: 1,改用 sheet_to_json(sheet, { header: 1 }) 得到二维数组,再手动取第 0 行作 key;或直接用 sheet_to_json(sheet) 让库自动把首行当字段名(前提是首行全为字符串且无空值)44926 ≈ 2022-12-30),sheet_to_json 默认会转成 JS Date 对象,但需确保单元格格式在 Excel 里确实是「日期」而非「常规」——否则它当普通数字读,输出仍是 44926
若发现日期没转,检查原始 Excel 中该列是否右键→「设置单元格格式」→「日期」;也可手动用 XLSX.SSF.format('yyyy-mm-dd', value) 强制格式化数值型日期。
大文件(>10MB)或含大量公式/图表的 Excel 在浏览器里解析可能卡顿甚至 OOM。这不是代码问题,是限制:
FileReader 的 ArrayBuffer 支持较弱,建议加 try/catch 并提示“请用 Chrome 或 Edge”xlsx.full.min.js 含加密/图表支持,体积约 700KB;若只读数据,用 xlsx.min.js(~200KB),但不支持 .xlsxlsx 官方支持;如必须兼容,得降级到 xlsx 0.14.x 并配合 core-js polyfillonChange 里直接 console.log(workbook)——整个 workbook 对象极大,Chrome 控制台展开时会卡死真正麻烦的从来不是“怎么读出来”,而是“怎么判断这行是不是有效数据”“空行怎么跳过”“合并单元格怎么还原”。这些得靠业务逻辑补足,SheetJS 只负责把二进制翻译成结构化数据。