You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript如何将Excel读取函数正确改写为async/await形式

问题根源

你的代码核心问题是没有正确将回调式的FileReader异步逻辑封装为Promise,导致async/await无法等待执行完成:

  • 你在onload事件回调里写的return jsonObj,只是回调函数自身的返回值,不会作为外层Get_DataXls函数的返回结果
  • 外层Get_DataXls在调用readAsBinaryString、注册完onload事件后就直接执行结束,默认返回值是undefined,根本等不到文件读取、Excel解析的流程走完,不管你在函数内哪个位置加await都会出现报错、拿不到结果的问题
  • 基于事件/回调的异步API必须手动包装为Promise实例,才能被async/await正确捕获结果、等待执行完成。
修正后可运行代码
// 点击事件回调也可以直接加async,用await写法替代.then链式调用
document.getElementById('uploadBud').addEventListener('click', async () => {
  const selectedFile = document.getElementById('importBUDid').files[0];
  const arreglo = await Get_DataXls(selectedFile);
  alert('Ready');
});

async function Get_DataXls(selectedFile) {
  if (!selectedFile) return null;
  // 将FileReader逻辑包装为Promise
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    // 增加错误捕获,避免文件读取异常时出现未捕获错误
    fileReader.onerror = () => reject(new Error('Excel文件读取失败'));
    fileReader.onload = (event) => {
      const binaryData = event.target.result;
      const workbook = XLSX.read(binaryData, { type: "binary" });
      let parseResult = null;
      workbook.SheetNames.forEach(sheetName => {
        // 原写法sheet_to_row_object_array是旧版别名,官方推荐直接用sheet_to_json
        parseResult = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
      });
      console.log(parseResult);
      // 读取解析完成后,通过resolve把结果返回给外层
      resolve(parseResult);
    }
    fileReader.readAsBinaryString(selectedFile);
  })
}
额外注意事项
  • 原代码存在逻辑缺陷:如果Excel包含多个工作表,forEach遍历过程中parseResult会被后一个工作表的内容覆盖,最终只返回最后一个工作表的解析结果。如果需要获取所有工作表内容,可以把parseResult定义为对象,用工作表名作为key存储每个表的解析结果
  • 必须给FileReader增加onerror异常处理,否则文件损坏、格式不支持等场景会抛出未捕获的全局错误
  • 如果要进一步优化读取性能,可以把readAsBinaryString替换为readAsArrayBuffer,配合XLSX的type: 'array'配置,解析大文件时速度更快、内存占用更低。

内容的提问来源于stack exchange,提问作者madison_sg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:36:25