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

Angular中用SheetJS读取Excel并渲染Material表格失败求助

Angular Excel读取与Material表格渲染问题排查

我是新手开发者,正在用Angular开发组件:通过XLSX库解析Excel/CSV外部数据源,展示到Angular Material表格。但调试发现文件根本无法读取,调整逻辑、尝试标签加载文件仍未解决。以下是项目相关代码,恳请协助排查!


table.component.ts

// dashboard.component.ts
// import { MatTableModule } from '@angular/material/table';
import { MatTableDataSource } from '@angular/material/table';
import * as xlsx from 'xlsx';
import { read, utils, writeFile } from 'xlsx';
import { Component, OnInit } from '@angular/core';
import { FileService } from '../../Services/FileServices';


@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-data.component.css'],
  templateUrl: 'table-data.component.html',
  standalone: false,
  // imports: [MatTableModule],
})
export class TableBasicExample implements OnInit {
  ExcelData: any[] = []; // 用于表格数据

  constructor(private fileService: FileService) {}

  ngOnInit(): void {
    // 组件初始化时调用文件读取函数
    this.loadExcelData();
  }

  loadExcelData(): void {
    const filePath = 'assets/data.xlsx'; // Excel文件路径

    this.fileService.readExcel(filePath)
      .then((data) => {
        // 读取成功
        console.log('读取的数据:', data);
        this.ExcelData = data;
      })
      .catch((error) => {
        // 错误处理
        console.error('文件读取错误:', error);
      });
      
  }
}

table.component.html

<div class="container m-5">
  <!-- <h1 class="text-primary text-center">读取Excel文件并展示到表格</h1>
  <input type="file" class="form-control w-50" (change)="ReadExcelFile($event)" > -->
  <table mat-table [dataSource]="ExcelData" *ngIf="ExcelData && ExcelData.length > 0" class="mat-elevation-z8">

    <!--- 注意:列定义顺序不影响实际渲染,渲染列由行定义的属性决定 -->
  
    <!-- 日期列 -->
    <ng-container matColumnDef="data">
      <th mat-header-cell *matHeaderCellDef> 日期 </th>
      <td mat-cell *matCellDef="let element"> {{element.data}} </td>
    </ng-container>
  
    <!-- 平均温度列 -->
    <ng-container matColumnDef="tempMedia">
      <th mat-header-cell *matHeaderCellDef> 平均温度 °C </th>
      <td mat-cell *matCellDef="let element"> {{element.tempMedia}} </td>
    </ng-container>
  
     <!-- 最低温度列 -->
     <ng-container matColumnDef="tempMin">
      <th mat-header-cell *matHeaderCellDef> 最低温度 °C </th>
      <td mat-cell *matCellDef="let element"> {{element.tempMin}} </td>
    </ng-container>

    <!-- 最高温度列 -->
    <ng-container matColumnDef="tempMax">
      <th mat-header-cell *matHeaderCellDef> 最高温度 °C </th>
      <td mat-cell *matCellDef="let element"> {{element.tempMax}} </td>
    </ng-container>
  
    <!-- 相对湿度列 -->
    <ng-container matColumnDef="umiditaRelativa">
      <th mat-header-cell *matHeaderCellDef> 相对湿度 % </th>
      <td mat-cell *matCellDef="let element"> {{element.umiditaRelativa}} </td>
    </ng-container>
  
      <!-- 能见度列 -->
      <ng-container matColumnDef="visibilitaKm">
        <th mat-header-cell *matHeaderCellDef> 能见度 km </th>
        <td mat-cell *matCellDef="let element"> {{element.visibilitaKm}} </td>
      </ng-container>

        <!-- 平均风速列 -->
    <ng-container matColumnDef="ventoMediaSpeed">
      <th mat-header-cell *matHeaderCellDef> 平均风速 km/h </th>
      <td mat-cell *matCellDef="let element"> {{element.ventoMediaSpeed}} </td>
    </ng-container>

      <!-- 最大风速列 -->
      <ng-container matColumnDef="ventoMaxSpeed">
        <th mat-header-cell *matHeaderCellDef> 最大风速 km/h </th>
        <td mat-cell *matCellDef="let element"> {{element.ventoMaxSpeed}} </td>
      </ng-container>

        <!-- 海平面气压列 -->
    <ng-container matColumnDef="pressioneSlm">
      <th mat-header-cell *matHeaderCellDef> 海平面气压 mb </th>
      <td mat-cell *matCellDef="let element"> {{element.pressioneSlm}} </td>
    </ng-container>

      <!-- 降雨量列 -->
      <ng-container matColumnDef="pioggiamm">
        <th mat-header-cell *matHeaderCellDef> 降雨量 mm </th>
        <td mat-cell *matCellDef="let element"> {{element.pioggiamm}} </td>
      </ng-container>

        <!-- 辐射量列 -->
    <ng-container matColumnDef="irraggiamento">
      <th mat-header-cell *matHeaderCellDef> 辐射量 [Wh/m²]  </th>
      <td mat-cell *matCellDef="let element"> {{element.irraggiamento}} </td>
    </ng-container>


    <!-- <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> -->
    <!-- <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> -->
  </table>

排查解决方案

1. 修复Material表格渲染配置

模板中注释掉了表头和数据行的核心渲染代码,且组件未定义列名数组,导致表格无法渲染:

  • 在组件类中添加列名数组:
displayedColumns: string[] = ['data', 'tempMedia', 'tempMin', 'tempMax', 'umiditaRelativa', 'visibilitaKm', 'ventoMediaSpeed', 'ventoMaxSpeed', 'pressioneSlm', 'pioggiamm', 'irraggiamento'];
  • 取消模板中两行关键代码的注释:
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

2. 补全FileService的Excel读取逻辑

你调用了fileService.readExcel()但未提供Service实现,这是文件读取失败的核心原因。以下是正确的Service代码:

// src/app/Services/FileServices.ts
import { Injectable } from '@angular/core';
import * as xlsx from 'xlsx';

@Injectable({ providedIn: 'root' })
export class FileService {
  async readExcel(filePath: string): Promise<any[]> {
    try {
      // 发起请求获取assets中的Excel文件
      const response = await fetch(filePath);
      if (!response.ok) throw new Error(`请求状态异常: ${response.status}`);
      // 转换为ArrayBuffer用于XLSX解析
      const arrayBuffer = await response.arrayBuffer();
      // 解析Excel工作簿
      const workbook = xlsx.read(arrayBuffer, { type: 'array' });
      // 获取第一个工作表
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];
      // 将工作表转换为JSON数组(表头作为对象键名)
      return xlsx.utils.sheet_to_json(worksheet);
    } catch (error) {
      console.error('文件读取失败:', error);
      throw error;
    }
  }
}

3. 修正依赖与模块配置

  • 确保已安装XLSX依赖:执行npm install xlsx
  • 由于组件非standalone,需在所属NgModule的imports中添加MatTableModule:
// 例如app.module.ts
import { MatTableModule } from '@angular/material/table';

@NgModule({
  imports: [
    // ...其他模块
    MatTableModule
  ]
})
export class AppModule { }

4. 验证文件路径与资产配置

  • 确认src/assets/data.xlsx文件存在
  • 检查angular.json中assets配置是否包含src/assets:
"assets": [
  "src/favicon.ico",
  "src/assets"
]

5. 调试建议

  • 在loadExcelData的catch块中打印完整错误栈,区分是网络请求错误还是文件解析错误
  • 在FileService的readExcel方法中添加console.log,跟踪请求、解析各步骤的执行情况

内容的提问来源于stack exchange,提问作者detommaso.engine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:41:02