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

如何用docutils为Sphinx覆盖率表格创建两行表头

实现Sphinx表格的分组表头(多行表头)

要实现带分组的两行表头,你只需要利用docutils中nodes.entry节点的colspan属性——它和HTML里的colspan作用完全一致,用来指定单元格跨列数。下面提供两种修改方案:

方案1:重构表头生成逻辑(推荐)

重新设计_PrepareTable方法,让它直接支持分组表头的定义,代码更易维护:

def _PrepareTable(self, column_groups: List[Tuple[str, int, List[Tuple[str, int]]]], identifier: str, classes: List[str]) -> Tuple[nodes.table, nodes.tgroup]:
    table = nodes.table("", identifier=identifier, classes=classes)
    
    # 计算总列数
    total_cols = sum(num_cols for _, num_cols, _ in column_groups)
    tableGroup = nodes.tgroup(cols=total_cols)
    table += tableGroup
    
    # 批量添加列宽配置
    for _, _, columns in column_groups:
        for col_title, width in columns:
            tableGroup += nodes.colspec(colwidth=width)
    
    # 构造两行表头
    thead = nodes.thead()
    
    # 第一行:分组标题(带跨列)
    group_row = nodes.row()
    for group_title, span, _ in column_groups:
        entry = nodes.entry("", nodes.paragraph(text=group_title), colspan=span)
        group_row += entry
    thead += group_row
    
    # 第二行:具体列标题
    col_row = nodes.row()
    for _, _, columns in column_groups:
        for col_title, _ in columns:
            col_row += nodes.entry("", nodes.paragraph(text=col_title))
    thead += col_row
    
    tableGroup += thead
    
    return table, tableGroup

然后修改_GenerateCoverageTable的调用逻辑,用分组结构定义表头:

def _GenerateCoverageTable(self) -> nodes.table:
    # 定义表头分组:(分组名称, 跨列数, [(列标题, 列宽), ...])
    column_groups = [
        ("Module", 1, [("Module", 500)]),
        ("语句覆盖", 4, [
            ("Total Statements", 100),
            ("Excluded Statements", 100),
            ("Covered Statements", 100),
            ("Missing Statements", 100)
        ]),
        ("分支覆盖", 4, [
            ("Total Branches", 100),
            ("Covered Branches", 100),
            ("Partial Branches", 100),
            ("Missing Branches", 100)
        ]),
        ("Coverage in %", 1, [("Coverage in %", 100)])
    ]
    
    table, tableGroup = self._PrepareTable(
        identifier=self._packageID,
        column_groups=column_groups,
        classes=["report-doccov-table"]
    )
    tableBody = nodes.tbody()
    tableGroup += tableBody
    
    # 后续添加表格数据行的逻辑保持不变
    return table

方案2:小幅度修改现有代码

如果不想大幅重构_PrepareTable,可以在_GenerateCoverageTable中手动替换原有的单行表头:

def _GenerateCoverageTable(self) -> nodes.table:
    columns = {
        "Module": 500,
        "Total Statements": 100,
        "Excluded Statements": 100,
        "Covered Statements": 100,
        "Missing Statements": 100,
        "Total Branches": 100,
        "Covered Branches": 100,
        "Partial Branches": 100,
        "Missing Branches": 100,
        "Coverage in %": 100
    }
    
    table, tableGroup = self._PrepareTable(
        identifier=self._packageID,
        columns=columns,
        classes=["report-doccov-table"]
    )
    
    # 移除原有的单行表头
    tableGroup.remove(tableGroup.children[-1])
    
    # 构造新的两行表头
    thead = nodes.thead()
    
    # 第一行:分组标题行
    group_row = nodes.row()
    group_row += nodes.entry("", nodes.paragraph(text="Module"), colspan=1)
    group_row += nodes.entry("", nodes.paragraph(text="语句覆盖"), colspan=4)
    group_row += nodes.entry("", nodes.paragraph(text="分支覆盖"), colspan=4)
    group_row += nodes.entry("", nodes.paragraph(text="Coverage in %"), colspan=1)
    thead += group_row
    
    # 第二行:原有的列标题行
    col_row = nodes.row()
    for title in columns.keys():
        col_row += nodes.entry("", nodes.paragraph(text=title))
    thead += col_row
    
    tableGroup += thead
    
    tableBody = nodes.tbody()
    tableGroup += tableBody
    
    # 后续添加表格数据行的逻辑保持不变
    return table

两种方案的核心都是通过给nodes.entry设置colspan参数,实现表头单元格的跨列合并,最终生成符合需求的两行分组表头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:35:14