def generate_html_table(data, merged_regions=None, is_header=False):
"""
根据二维数组和合并区域生成HTML表格
参数:
data: 二维列表,表示表格数据
merged_regions: 列表,每个元素是(row_min, col_min, row_max, col_max)表示合并区域
is_header: 布尔值,是否为表头行(使用th标签)
返回:
HTML表格字符串
"""
if not data:
return ""
rows = len(data)
cols = len(data[0]) if rows > 0 else 0
# 初始化标记数组,标记哪些单元格已被合并
merged_cells = [[False] * cols for _ in range(rows)]
# 构建HTML
html = '<table border="1" cellspacing="0" cellpadding="5">\n'
for i in range(rows):
html += ' <tr>\n'
for j in range(cols):
# 如果这个单元格已被合并,跳过
if merged_cells[i][j]:
continue
# 检查这个单元格是否在某个合并区域内
merged = False
rowspan = 1
colspan = 1
if merged_regions:
for region in merged_regions:
row_min, col_min, row_max, col_max = region
# 如果当前单元格是这个合并区域的左上角单元格
if i == row_min and j == col_min:
merged = True
rowspan = row_max - row_min + 1
colspan = col_max - col_min + 1
# 标记被合并的单元格
for r in range(row_min, row_max + 1):
for c in range(col_min, col_max + 1):
if r != row_min or c != col_min: # 跳过左上角单元格
merged_cells[r][c] = True
break
# 生成单元格标签
tag = 'th' if is_header else 'td'
cell_content = data[i][j] if data[i][j] is not None else ''
# 添加rowspan和colspan属性
attributes = ''
if rowspan > 1:
attributes += f' rowspan="{rowspan}"'
if colspan > 1:
attributes += f' colspan="{colspan}"'
html += f' <{tag}{attributes}>{cell_content}</{tag}>\n'
html += ' </tr>\n'
html += '</table>'
return html
# 表格数据
data = [
["学期", "科目", "成绩", None, None], # 注意:合并的单元格用None填充
[None, None, "平时成绩", "考试成绩", "总评"],
["2023秋季", "数学", "85", "90", "88"],
[None, "语文", "88", "92", "90"],
[None, "英语", "90", "85", "87"],
["2024春季", "物理", "82", "88", "85"],
[None, "化学", "85", "90", "88"]
]
# 定义合并区域
# 格式: (起始行, 起始列, 结束行, 结束列)
merged_regions = [
(0, 0, 1, 0), # "学期"单元格合并第0行第0列到第2行第0列
(0, 1, 1, 1), # "科目"单元格合并第0行第1列到第1行第1列
(0, 2, 0, 4), # "成绩"单元格合并第0行第2列到第4列
(2, 0, 4, 0), # "2023秋季"单元格合并第2行第0列到第4行第0列
(5, 0, 6, 0) # "2024春季"单元格合并第5行第0列到第6行第0列
]
def generate_html_table_optimized(data, merged_regions=None, is_header=False):
"""
优化版本:根据二维数组和合并区域生成HTML表格
参数:
data: 二维列表,表示表格数据
merged_regions: 列表,每个元素是(row_min, col_min, row_max, col_max)表示合并区域
is_header: 布尔值,是否为表头行(使用th标签)
返回:
HTML表格字符串
"""
if not data:
return ""
rows = len(data)
cols = len(data[0]) if rows > 0 else 0
# 初始化数据结构
merged_cells = [[False] * cols for _ in range(rows)] # 标记哪些单元格已被合并(非起始位置)
merge_cells_start = {} # 字典,key为(row,col),value为(rowspan, colspan)
# 预处理合并区域
if merged_regions:
for region in merged_regions:
row_min, col_min, row_max, col_max = region
rowspan = row_max - row_min + 1
colspan = col_max - col_min + 1
# 标记起始位置
merge_cells_start[(row_min, col_min)] = (rowspan, colspan)
# 标记被合并的单元格(非起始位置)
for r in range(row_min, row_max + 1):
for c in range(col_min, col_max + 1):
if r != row_min or c != col_min: # 跳过起始单元格
merged_cells[r][c] = True
# 构建HTML
html = '<table border="1" cellspacing="0" cellpadding="5">\n'
for i in range(rows):
html += ' <tr>\n'
for j in range(cols):
# 如果这个单元格已被合并(非起始位置),跳过
if merged_cells[i][j]:
continue
# 生成单元格标签
tag = 'th' if is_header else 'td'
cell_content = data[i][j] if data[i][j] is not None else ''
# 检查是否是合并区域的起始位置
attributes = ''
if (i, j) in merge_cells_start:
rowspan, colspan = merge_cells_start[(i, j)]
if rowspan > 1:
attributes += f' rowspan="{rowspan}"'
if colspan > 1:
attributes += f' colspan="{colspan}"'
html += f' <{tag}{attributes}>{cell_content}</{tag}>\n'
html += ' </tr>\n'
html += '</table>'
return html
html_table = generate_html_table_optimized(data, merged_regions)
print(html_table)