背景:
最近碰到一个需求是:前端上传 .xlsx / .csv 等 excel 表格文件,读取解析文件内容后再发给后端同学
还用的是 amis 速搭平台,因为用的是老版本 amis(1.5.3),Excel 上传组件 无法解析上传的 excel 文件,它会提示你 t.WorkBook is not a constructor 惊不惊喜~
🦙
Emmmmm......
那试试就
shi shi~吧(这里以原生js为例)
首先,我们需要一个
<input>元素来上传我们的excel文件,拿到我们的文件内容,比如:html<input type="file" accept=".xlsx,.csv,.xls" autocomplete="off" onchange="onInpChange" /> <!-- xlsx: 用于解析 excel buffer 内容为 json 数据 --> <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js" defer />拿到 file 文件内容并读取解析为 json:
ts// input 选中文件 change 事件 const onInpChange = (ev: Event) => { // 选中的文件 const file = ev.target?.files?.[0]; readExcel(file); clearFile(ev.target); }; // 读取 excel 文件内容 const readExcel = (file: File) => { return new Promise((resolve, reject) => { if (!file) return; const fileReader = new FileReader(); // 读为二进制流 fileReader.readAsBinaryString(file); // 读取完毕会触发此方法 (any 大法) fileReader.onload = (ev: any) => { try { const workbook = XLSX.read(ev.target.result, { type: "binary" }); workbook.SheetNames.forEach((sheetName) => { /** 每行数据解析为,对象格式 [ { 奖品序列号: 1001, 快递公司: "天天快递", 快递单号: 1001001 }, { 奖品序列号: 1002, 快递公司: "EMS", 快递单号: 1001002 }, { 奖品序列号: 1003, 快递公司: "顺丰快递", 快递单号: 1001003 }, ... ] */ const rowObject = XLSX.utils.sheet_to_row_object_array( workbook.Sheets[sheetName], ); if (rowObject.length > 0) { resolve(rowObject); } }); } catch (error) { console.error(error); reject(error); } }; }); }; // 清除选中文件 const clearFile = (target: Event.Target) => { if (!Array.isArray(target?.files)) return; target.files.length = 0; };
🦠
此方案仅用作对小文件去解析处理,当直接上传一个 100M 乃至更大的文件的时候,内存就会被极速消耗,可能导致你的浏览器直接卡死(因而,此方案的使用范围很窄) 慎用!!!
