需求:
先附上效果图:
由图可知用nz-table 的单元格合并和滚动可以实现该效果
以下是代码:
<div class="table-area">
<nz-table style="width: 1500px;" #goupTable
[nzData]="groupFakeData" nzBordered [nzScroll]="{ x: '1500px' }"
>
<thead>
<tr>
<th [nzWidth]="tableWidth" rowspan="2" nzLeft [nzFilters]="filterName" [nzFilterFn]="nameFilterFn">Group</th>
<ng-container *ngFor="let data of groupFakeData[0].data;let i = index">
<th [nzWidth]="tableWidth" colspan="4">{{ data.date }}</th>
</ng-container>
</tr>
<tr>
<ng-container *ngFor="let data of groupFakeData[0].data">
<th [nzWidth]="tableWidth">Lent Hours(h)</th>
<th [nzWidth]="tableWidth">Lent Staff</th>
<th [nzWidth]="tableWidth">Borrowed Hours(h)</th>
<th [nzWidth]="tableWidth">Borrowed Staff</th>
</ng-container>
</tr>
</thead>
</nz-table>
</div>
const groupFakeData = [
{
groupName: 'Group 1',
data:[
{
date: '2019-01-01',
keys:{
lentHours: 8,
lentStaff: 8,
borrowedHours: 8,
borrowedStaff: 8
}
},
{
date: '2019-01-02',
keys:{
lentHours: 8,
lentStaff: 8,
borrowedHours: 8,
borrowedStaff: 8
}
},
{
date: '2019-01-03',
keys:{
lentHours: 8,
lentStaff: 8,
borrowedHours: 8,
borrowedStaff: 8
}
}
.
.
.
]//data的长度为8
}
.
.
.
];
可以看到,跟我们理想的样子大相径庭,为什么会出现这样的效果?
接下来找原因。
打开调试我们可以发现:表格只生成了8个col,也就是上面的代码中:
<ng-container *ngFor="let data of groupFakeData[0].data;let i = index">
<th [nzWidth]="tableWidth" colspan="4">{{ data.date }}</th>
</ng-container>
groupFakeData[0].data的长度,结合table的相关知识,我们得出结论:由于table会根据第一行的th元素生成对应数量的col,也就是说第一行的「表头分组」操作只生成了8个col,并不是生成32个col然后以4个为一组合并,并且每个col的宽度是tableWidth的宽度。
开启滚动后,由于col的数量与表头数量不匹配,会造成样式混乱。
要解决这个问题,我们从表格结构出发思考,既然table会根据第一行的th元素生成相应数量的col,那我们给它一个隐藏的tr,改造后的代码如下:
<nz-table style="width: 1500px;" #goupTable
[nzData]="groupFakeData" nzBordered [nzScroll]="{ x: '1500px' }"
>
<thead>
<tr style="display: none;">
<th [nzWidth]="tableWidth" *ngFor="let item of colNum">
</th>
</tr>
<tr>
<th [nzWidth]="tableWidth" rowspan="2" nzLeft [nzFilters]="filterName" [nzFilterFn]="nameFilterFn">Group</th>
<ng-container *ngFor="let data of groupFakeData[0].data;let i = index">
<th [nzWidth]="tableWidth" colspan="4">{{ data.date }}</th>
</ng-container>
</tr>
<tr>
<ng-container *ngFor="let data of groupFakeData[0].data">
<th [nzWidth]="tableWidth">Lent Hours(h)</th>
<th [nzWidth]="tableWidth">Lent Staff</th>
<th [nzWidth]="tableWidth">Borrowed Hours(h)</th>
<th [nzWidth]="tableWidth">Borrowed Staff</th>
</ng-container>
</tr>
</thead>
</nz-table>
其中colNum是个长度为4 * groupFakeData[0].data长度的数组,里面的元素无所谓。
上面我们提到,每个col的宽度会根据第一行th的宽度来生成,那么我们可以简化一下,只在第一行th写宽度就可以了
<nz-table style="width: 1500px;" #goupTable
[nzData]="groupFakeData" nzBordered [nzScroll]="{ x: '1500px' }"
>
<thead>
<tr style="display: none;">
<th [nzWidth]="tableWidth" *ngFor="let item of colNum">
</th>
</tr>
<tr>
<th rowspan="2" nzLeft [nzFilters]="filterName" [nzFilterFn]="nameFilterFn">Group</th>
<ng-container *ngFor="let data of groupFakeData[0].data;let i = index">
<th colspan="4">{{ data.date }}</th>
</ng-container>
</tr>
<tr>
<ng-container *ngFor="let data of groupFakeData[0].data">
<th>Lent Hours(h)</th>
<th>Lent Staff</th>
<th>Borrowed Hours(h)</th>
<th>Borrowed Staff</th>
</ng-container>
</tr>
</thead>
</nz-table>
最开始我的思路是:创建日期表头 * 4,但是始终无法做到数据和表头对应,于是就放弃了转换其他思路,如果有更好的实现思路请在评论区告诉我