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

Angular中多次调用Observable函数失效,SheetJS导入Excel用forkJoin无响应

问题根因

  • 重复绑定同一个FileReader实例的onload事件:每次调用getSheet方法都会覆盖fileReader.onload的回调函数,最终只有最后一次绑定的回调(对应index=2的C表读取逻辑)会生效,前两个回调直接被覆盖不会执行。
  • readAsArrayBuffer调用时机过早:你在给fileReader绑定onload回调前就调用了读取方法,若文件体积很小、读取完成时回调还没绑定,后续所有回调都不会触发。
  • 组合后的Observable没有被订阅:RxJS的Observable是冷订阅模式,不调用subscribe方法的话,内部逻辑永远不会执行。
  • 读取格式不匹配:你调用的是readAsArrayBuffer,但XLSX.read里指定的type是binary,格式不对应会导致解析失败。

修复方案

优化逻辑让文件只解析一次,复用解析后的workbook对象分别读取三个sheet的数据,避免重复绑定事件和重复解析资源。

步骤1:封装公共解析方法

// 封装workbook解析方法,整个流程只执行一次文件读取
getWorkbook(file: File): Observable<XLSX.WorkBook> {
  return new Observable((observer) => {
    const fileReader = new FileReader();
    fileReader.onload = (ev: ProgressEvent<FileReader>) => {
      try {
        const binary = ev.target?.result;
        const workbook = XLSX.read(binary, { type: 'binary', cellDates: true, cellStyles: true });
        observer.next(workbook);
        observer.complete();
      } catch (err) {
        observer.error(err);
      }
    };
    fileReader.onerror = (err) => observer.error(err);
    fileReader.readAsBinaryString(file); // 格式和XLSX.read的配置匹配
  });
}

// 从已解析的workbook中提取指定sheet数据
getSheetFromWorkbook<T>(workbook: XLSX.WorkBook, headers: string[], index: number): T[] {
  return XLSX.utils.sheet_to_json<T>(workbook.Sheets[workbook.SheetNames[index]], { header: headers, range: 1 });
}

步骤2:调整业务调用逻辑

getExcel(evt: Event) {
  const input = evt.target as HTMLInputElement;
  const file = input.files?.[0];
  if (!file) return;

  this.getWorkbook(file).pipe(
    map(workbook => ({
      dataA: this.getSheetFromWorkbook<interfaceA>(workbook, this.headerA, 0),
      dataB: this.getSheetFromWorkbook<interfaceB>(workbook, this.headerB, 1),
      dataC: this.getSheetFromWorkbook<interfaceC>(workbook, this.headerC, 2)
    }))
  ).subscribe({
    next: (result) => {
      // 此处可直接获取三个sheet的完整数据
      console.log(result.dataA, result.dataB, result.dataC);
      // 后续业务逻辑
    },
    error: (err) => {
      console.error('Excel解析失败:', err);
    }
  })
}

内容的提问来源于stack exchange,提问作者A-Hsien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:06:07