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

Angular mat-table动态列与行表头实现需求,求对应表格HTML代码

第一步:组件TS代码预处理数据

你需要先把嵌套的表格数据处理为适配mat-table的扁平化数据源:

import { Component } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';

interface TableGroupItem {
  salesHist: number[];
  sales: number[];
  forecastHist: number[];
  forecast: number[];
  group: string;
  recordCount: string;
  rows: {key: string, title: string}[];
}

interface FlatTableRow {
  group: string;
  isFirstRowOfGroup: boolean;
  groupRowCount: number;
  rowTitle: string;
  rowKey: string;
  values: number[];
}

@Component({
  selector: 'app-table-demo',
  templateUrl: './table-demo.component.html',
  styleUrls: ['./table-demo.component.css']
})
export class TableDemoComponent {
  displayedColumns: string[] = ['group','row','0','1','2'];
  dataSource = new MatTableDataSource<FlatTableRow>();

  // 你提供的原始数据
  tableData: TableGroupItem[] = [{
    salesHist: [1, 2, 3, 4],
    sales: [1, 2, 3, 4],
    forecastHist: [1, 2, 3, 4],
    forecast: [1, 2, 3, 4],
    group: "000",
    recordCount: "1234",
    rows: [{
      key: "forecast",
      title: "Forecast"
    }, {
      key: "sales",
      title: "Sales"
    }, {
      key: "salesHist",
      title: "Sales History"
    }]
  }];

  ngOnInit() {
    // 扁平化数据
    const flatRows: FlatTableRow[] = [];
    this.tableData.forEach(groupItem => {
      const groupRowCount = groupItem.rows.length;
      groupItem.rows.forEach((row, index) => {
        flatRows.push({
          group: groupItem.group,
          isFirstRowOfGroup: index === 0,
          groupRowCount: groupRowCount,
          rowTitle: row.title,
          rowKey: row.key,
          // 取对应key的数值数组,对应0/1/2列的索引
          values: groupItem[row.key as keyof TableGroupItem] as number[]
        })
      })
    })
    this.dataSource.data = flatRows;
  }
}

第二步:表格HTML代码

<table
  mat-table
  matSort
  [dataSource]="dataSource"
  class="w-100"
>
  <!-- group列:实现跨行效果 -->
  <ng-container matColumnDef="group">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Group</th>
    <td 
      mat-cell 
      *matCellDef="let row" 
      [attr.rowspan]="row.isFirstRowOfGroup ? row.groupRowCount : null"
      [style.display]="row.isFirstRowOfGroup ? 'table-cell' : 'none'"
    >
      {{ row.group }}
    </td>
  </ng-container>

  <!-- row列:展示行标题 -->
  <ng-container matColumnDef="row">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let row">
      {{ row.rowTitle }}
    </td>
  </ng-container>

  <!-- 动态数值列:0/1/2 -->
  <ng-container *ngFor="let col of ['0','1','2']" [matColumnDef]="col">
    <th mat-header-cell *matHeaderCellDef>{{ col }}</th>
    <td class="sim-row-cell" mat-cell *matCellDef="let row">
      {{ row.values[+col] }}
    </td>
  </ng-container>

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

实现说明

  • group列只在每个分组的第一行渲染,通过rowspan属性设置跨行数,非首行的group列单元格隐藏,实现跨行效果
  • 每行直接绑定对应行标题和对应索引的数值,不需要额外的嵌套循环,符合mat-table的渲染逻辑
  • 不需要使用multiTemplateDataRows属性,扁平化数据源的实现方式性能更优,维护更简单

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:09:04