如何在HTML表格循环多级数据时实现单元格合并
解决方案:三级嵌套数据生成带合并单元格的动态HTML表格
要实现三级嵌套数据的合并单元格表格,核心是提前计算每一级单元格需要合并的行数(rowspan),然后在循环渲染时控制仅在第一行渲染带rowspan的父级单元格,后续行跳过该列的单元格渲染。
步骤1:预处理数据,计算各级rowspan
先遍历原始数据,给每个学科(subject)和班级(class)添加对应的rowspan值:
- 学科的rowspan = 该学科下所有班级的学生数量总和
- 班级的rowspan = 该班级下的学生数量
// 预处理函数:给数据添加rowspan信息 const processData = (data) => { return data.map(subject => { // 计算当前学科的总行数(所有班级的学生数之和) const totalRowspan = subject.class.reduce((sum, cls) => sum + cls.results.length, 0); // 给每个班级添加rowspan(当前班级的学生数) const processedClasses = subject.class.map(cls => ({ ...cls, rowspan: cls.results.length })); return { ...subject, totalRowspan, class: processedClasses }; }); }; // 处理后的数据 const processedMyData = processData(myData);
步骤2:动态渲染合并单元格表格
以React为例,通过多层循环渲染表格,仅在每组的第一行渲染带rowspan的父级单元格:
import React from 'react'; const MergedTable = ({ data }) => { const processedData = processData(data); return ( <table border="1" cellPadding="8" cellSpacing="0"> <thead> <tr> <th>Subject</th> <th>Class</th> <th>Student</th> <th>Score</th> </tr> </thead> <tbody> {processedData.map((subject, subjectIndex) => ( // 遍历每个学科下的班级 subject.class.map((cls, classIndex) => ( // 遍历每个班级下的学生 cls.results.map((result, resultIndex) => ( <tr key={`${subjectIndex}-${classIndex}-${resultIndex}`}> {/* 仅在当前学科的第一行第一列渲染Subject单元格,带totalRowspan */} {resultIndex === 0 && classIndex === 0 && ( <td rowSpan={subject.totalRowspan}>{subject.subject}</td> )} {/* 仅在当前班级的第一行第二列渲染Class单元格,带rowspan */} {resultIndex === 0 && ( <td rowSpan={cls.rowspan}>{cls.name}</td> )} {/* 学生和分数每行都渲染 */} <td>{result.student}</td> <td>{result.score}</td> </tr> )) )) ))} </tbody> </table> ); }; // 使用组件 <MergedTable data={myData} />
关键逻辑说明
- Subject列:只有当当前是该学科下第一个班级的第一个学生时,才渲染带
rowSpan={subject.totalRowspan}的单元格,后续行自动跳过该列。 - Class列:只有当当前是该班级下的第一个学生时,才渲染带
rowSpan={cls.rowspan}的单元格,后续行跳过该列。 - Student和Score列:每行都正常渲染,不需要合并。
这种方式完全动态适配任意行数的三级嵌套数据,不管学科、班级、学生数量怎么变,都能自动计算合并行数并正确渲染表格。
内容的提问来源于stack exchange,提问作者Sun
相关产品推荐
相关产品推荐

