filereader 必须用 readasarraybuffer,chrome 98+/firefox 100+ 已弃用 readasbinarystring;xlsx.read() 需传入 arraybuffer 并指定 { type: 'array' };sheet_to_json 要加 { defval: null, blankrows: true, range: worksheet['!ref'] } 才能保留空行和合并结构;日期处理应设 { celldates: true, datenf: 'yyyy-mm-dd' } 并用 xlsx.ssf.parse_date_code 转换;多 sheet 须通过 workbook.sheetnames[0] 安全获取首表。

FileReader 必须用 readAsArrayBuffer,不能用 readAsBinaryString
Chrome 98+、Firefox 100+ 已弃用 readAsBinaryString,调用后会抛出 DOMException: Failed to execute 'readAsBinaryString' on 'FileReader': The method is deprecated.。SheetJS 的 XLSX.read() 要求输入为 Uint8Array 或 ArrayBuffer,否则解析失败或日期/公式全乱。
正确做法是:
- 用
reader.readAsArrayBuffer(file)读取 - 传入
XLSX.read(data, { type: 'array' }),type必须显式指定为'array' - 别信老教程里
readAsBinaryString + { type: 'binary' }的写法,它在新版浏览器里根本跑不通
SheetJS 的 sheet_to_json 默认不保留空行和合并单元格
直接调用 XLSX.utils.sheet_to_json(worksheet) 会跳过全空行,且把合并单元格(如 Excel 里 A1:B1 合并)拆成多个独立单元格,值只填在左上角,其余为空 —— 这和你在 Excel 里看到的结构完全不一致。
要还原原始布局,得加参数:
-
{ defval: null }:让空单元格显式输出null,而不是被过滤掉 -
{ blankrows: true }:保留全空行 -
{ range: worksheet['!ref'] }:强制按实际范围读取,避免自动截断 - 合并单元格信息存在
worksheet['!merges']里,需单独提取,sheet_to_json不处理它
日期字段默认转成 JS Date 对象,但 Excel 序列号容易错位
Excel 里日期本质是浮点数(如 44927 表示 2023-01-01),SheetJS 默认转成 Date,但时区处理有坑:如果 Excel 文件没带时区信息,XLSX.read() 会按本地时区解释,导致 UTC+8 用户看到的日期比 Excel 里少一天。
稳妥做法是:
- 读取时加
{ cellDates: true, dateNF: 'yyyy-mm-dd' } - 后续用
cell.w(显示文本)或cell.v(原始数值)判断类型,避免依赖cell.t === 'd' - 真要算日期差,用
XLSX.SSF.parse_date_code(val)手动转,别直接 new Date(val)
多 Sheet 时不要硬写 workbook.Sheets['Sheet1']
workbook.Sheets 是个对象,键名来自 Excel 文件实际命名(可能叫“销售数据”“2024Q3”,甚至含空格或中文),不是固定字符串。硬编码 'Sheet1' 在用户上传非默认命名文件时直接报 undefined 错误。
安全获取第一张有效 Sheet 的方式:
const firstSheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[firstSheetName];- 检查
worksheet && worksheet['!ref']是否存在,再继续解析 - 若要支持用户选 Sheet,用
<select></select>动态渲染workbook.SheetNames
workbook.SheetNames、worksheet['!merges'] 和 worksheet['!ref'] 这三个字段。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











