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

如何让嵌套HTML表格中指定列实现水平滚动?(Angular 14)

Angular 14 实现固定列+货币列水平滚动表格

需求回顾

  • 表格前6列为固定列,占父表格宽度的80%
  • 剩余20%宽度分配给PDO货币列,每个货币列最小宽度为父表格宽度的10%:
    • 1个货币列:占满20%宽度
    • 2个货币列:各占10%宽度
    • 3个及以上货币列:各占10%宽度,且该区域支持水平滚动
  • 表格为嵌套结构,按pdoName、advocacy、program分组

具体实现步骤

1. 模板结构拆分(HTML)

将表格拆分为固定列容器和可滚动货币列容器,保持两个容器内的分组行结构完全同步,确保行高对齐:

<div class="table-container">
  <!-- 固定列区域(前6列) -->
  <div class="fixed-columns">
    <table class="table">
      <thead>
        <tr>
          <th>PDO名称</th>
          <th>倡导项</th>
          <th>项目</th>
          <th>列4</th>
          <th>列5</th>
          <th>列6</th>
        </tr>
      </thead>
      <tbody>
        <ng-container *ngFor="let pdo of pdoGroups">
          <tr class="group-row">
            <td colspan="6">{{ pdo.pdoName }}</td>
          </tr>
          <ng-container *ngFor="let advocacy of pdo.advocacies">
            <tr class="subgroup-row">
              <td colspan="6">{{ advocacy.advocacyName }}</td>
            </tr>
            <ng-container *ngFor="let program of advocacy.programs">
              <tr>
                <td></td>
                <td></td>
                <td>{{ program.programName }}</td>
                <td>{{ program.col4 }}</td>
                <td>{{ program.col5 }}</td>
                <td>{{ program.col6 }}</td>
              </tr>
            </ng-container>
          </ng-container>
        </ng-container>
      </tbody>
    </table>
  </div>

  <!-- 可滚动货币列区域 -->
  <div class="scrollable-columns">
    <table class="table">
      <thead>
        <tr>
          <th *ngFor="let currency of currencies" style="width: {{ tableWidth * 0.1 }}px;">
            {{ currency }}
          </th>
        </tr>
      </thead>
      <tbody>
        <ng-container *ngFor="let pdo of pdoGroups">
          <tr class="group-row">
            <td colspan="{{ currencies.length }}"></td>
          </tr>
          <ng-container *ngFor="let advocacy of pdo.advocacies">
            <tr class="subgroup-row">
              <td colspan="{{ currencies.length }}"></td>
            </tr>
            <ng-container *ngFor="let program of advocacy.programs">
              <tr>
                <td *ngFor="let currency of currencies">
                  {{ program[currency] }}
                </td>
              </tr>
            </ng-container>
          </ng-container>
        </ng-container>
      </tbody>
    </table>
  </div>
</div>

2. CSS布局设置

通过Flex布局实现两容器并排,固定列占80%宽度,滚动列容器占20%并开启横向滚动,同时统一表格样式保证对齐:

.table-container {
  display: flex;
  width: 100%;
  overflow: hidden;
}

.fixed-columns {
  width: 80%;
  flex-shrink: 0;
  border-right: 1px solid #ddd;
}

.scrollable-columns {
  width: 20%;
  overflow-x: auto;
}

.table {
  width: 100%;
  border-collapse: collapse;
  margin: 0;
}

.table th, .table td {
  padding: 8px 12px;
  border-bottom: 1px solid #ddd;
  text-align: left;
}

.group-row, .subgroup-row {
  background-color: #f5f5f5;
  font-weight: bold;
}

3. 组件逻辑处理(TS)

计算父表格宽度并动态绑定货币列宽度,同时监听窗口 resize 事件更新宽度:

import { Component, OnInit, HostListener } from '@angular/core';

@Component({
  selector: 'app-reports-table',
  templateUrl: './reports-table.component.html',
  styleUrls: ['./reports-table.component.css']
})
export class ReportsTableComponent implements OnInit {
  pdoGroups: any[] = []; // 替换为你的分组数据
  currencies: string[] = ['PHP', 'USD', 'AUD']; // 替换为你的货币列表
  tableWidth = 0;

  ngOnInit(): void {
    this.calculateTableWidth();
    // 这里加载你的业务数据
  }

  @HostListener('window:resize')
  onResize() {
    this.calculateTableWidth();
  }

  private calculateTableWidth(): void {
    const container = document.querySelector('.table-container');
    if (container) {
      this.tableWidth = (container as HTMLElement).offsetWidth;
    }
  }
}

关键逻辑说明

  • 当货币列数量≤2时,列总宽度为10%×N ≤20%,滚动容器不会触发滚动,自动占满20%宽度
  • 当货币列数量≥3时,列总宽度为30%>20%,滚动容器自动显示横向滚动条
  • 两个容器内的分组行结构必须完全同步,避免出现行高错位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 04:35:36