报表行类型

BaskReport 中行(Row)是报表纵向排列的基本单元,每一行由若干单元格(Cell)组成。系统通过行的 band(带区) 属性来区分「行类型」,用于控制分页时该行的重复行为。

说明:很多人会把「标题行 / 表头行 / 明细行 / 表尾行」称为行类型,但在 BaskReport 里它们不是独立的行类型枚举,而是用户在报表布局上的位置概念——通过单元格之间的父格关系(左父格 / 上父格)数据展开方式来表达。真正的「行类型」只有下面三种(由 band 枚举决定),其余行均为普通行。

一、行类型总览

行类型 band 值 说明 分页行为
普通行 none(band 为 null 默认行类型 随数据自然分页,不重复
重复表头 headerrepeat 作为「表头」固定区域 每页顶部重复显示
重复表尾 footerrepeat 作为「表尾」固定区域 每页底部重复显示

后台枚举位置:com.basksoft.report.core.model.ReportBand.Bandnone / headerrepeat / footerrepeat)。设计器中未设置行类型时,bandnull,等价于 none

二、普通行(none)

最常见的行类型,也是所有新建行的默认值。

  • 行为:随数据展开自然分页,不会在后续页重复。
  • 适用:明细数据行、普通内容行。
  • 当报表出现分页时,普通行只会按内容顺序出现在某一页,不会跨页重复。

三、重复表头(headerrepeat)

将某一行(或多行)标记为重复表头,在每一页的顶部都会重复渲染该区域。

典型用途:报表的列标题行(表头)。当明细数据跨越多页时,希望每一页都能看到列名,就把列标题行设为「重复表头」。

实现要点

  • 后台在分页构建(PagingBuilder)时会收集所有 band == headerrepeat 的行,形成 headerRows,在每一页开头插入。
  • 重复表头行本身的高度不计入该页数据区高度的累加(分页时其原始行号被记录但占位高度单独处理),保证每页数据区可用高度一致。

设计器操作

  1. 选中目标行(通常是列标题行)。
  2. 右键 → 重复表头(或勾选行属性中的「重复表头」)。
  3. 如需取消,再次右键选择 取消行类型 / 普通行

注意:要区分「重复表头(headerrepeat,分页每页重复)」与「标题行(报表最顶部的报表标题)」。标题行通常只出现在第一页,不属于重复表头;若希望报表标题也每页显示,可将其设为 headerrepeat,但一般场景下标题只需首页出现。

四、重复表尾(footerrepeat)

将某一行(或多行)标记为重复表尾,在每一页的底部都会重复渲染该区域。

典型用途:报表的页脚、合计提示、版权说明等希望每页底部都出现的内容。

实现要点

  • 后台收集所有 band == footerrepeat 的行,形成 footerRows,在每一页末尾插入。
  • 与重复表头同样,其高度为独立占位,不计入数据区累加高度。

设计器操作

  1. 选中目标行。
  2. 右键 → 重复表尾
  3. 取消:右键 → 取消行类型 / 普通行

重复表尾与「报表页脚(page footer)」不同:本系统的 headerrepeat / footerrepeat行级的重复区域,跟随数据分页每页出现;而全局页眉页脚由页面设置控制。请按实际需求选择。

五、重复行(表头 / 表尾)的使用限制

重复表头 / 表尾在分页时,每一页都是把原行「按当前值拷贝一份」后再固定显示在页头 / 页尾,因此它是固定区域,不支持依赖数据集的多条数据展开绑定,也不支持动态行高。

5.1 不支持多条数据的展开绑定

在重复表头 / 表尾区域内的单元格,即使配置了 down(纵向)/ right(横向)展开,也不会在每页重复区域里展开成多条数据。

原因是:每页的重复区并不是重新执行展开,而是直接复制原行当时的单元格值。因此重复区内只会显示原行「单次求值」的结果,不会产生由数据集驱动的多行 / 多列展开。

正确做法

  • 重复表头 / 表尾只放静态文本、固定值、或固定聚合表达式(如 =sum(...) 这类不依赖展开的结果)。
  • 明细数据的向下 / 向右展开,请放在普通行(none)区域,通过单元格的父子格(上父格 / 左父格)驱动。

5.2 不支持动态行高

重复表头 / 表尾区域内的单元格不支持动态行高(即依赖内容自动撑开行高)。

原因是:重复区的高度在分页时按原行固定的高度占位,若运行时按内容动态撑高,会破坏每页已固定的高度占位与分页计算,导致分页错乱。引擎会对重复行动态行高给出告警。

正确做法

  • 重复表头 / 表尾请使用固定行高(在设计器中显式设置行高),确保每页重复区域高度一致。
  • 若确实需要随内容自适应的高度,请将该内容放到普通行区域。

5.3 限制速查

能力 重复表头 / 表尾 普通行(none)
静态文本 / 固定值 ✅ 支持 ✅ 支持
固定聚合表达式(如 sum) ✅ 支持 ✅ 支持
多条数据展开(down / right) ❌ 不支持 ✅ 支持(需父子格驱动)
动态行高(内容自适应) ❌ 不支持 ✅ 支持
每页重复显示 ✅ 支持 ❌ 不重复

六、与设计器右键菜单的对应关系

在报表设计器中选中行后右键,行类型相关菜单项通常为:

  • 普通行:清除行类型,恢复为 none
  • 重复表头:设置 band = headerrepeat
  • 重复表尾:设置 band = footerrepeat

底层均通过 row.setBand(...) 维护,最终序列化到报表定义(*.json / *.xml)的 band 字段中。

七、容易混淆:行「类型」与行「行为属性」

除了 band 行类型外,每行还有若干独立的行为标志,它们不是行类型,但常与行类型一起使用,需要区分:

行属性 含义 是否与 band 冲突
band 行类型(普通 / 重复表头 / 重复表尾)
lock(锁定) 锁定该行,禁止在设计器中被误编辑 / 移动 可与任意 band 共存
hide(隐藏) 运行时该行不参与渲染,行高计为 0 可与任意 band 共存;隐藏的重复表头/表尾同样不显示
fillRemainingPageHeight 自动拉伸填满当前页剩余高度(常用于末页补白) 可与任意 band 共存

后台分页逻辑(PagingBuilder.getRowHeight):当 row.isHide() 为真时行高返回 0;当 row.isFillRemainingPageHeight() 为真时行高取「页面剩余高度」。这些与 band 互不干扰。

示例组合

  • 一个 headerrepeat 行同时设置 hide → 该重复表头在所有页都不显示。
  • 一个普通行设置 fillRemainingPageHeight → 用于末页补白,但其本身仍是普通行,不会跨页重复。

八、快速对照表

我想要的效果 应使用的行类型 / 属性
列名每页都显示 重复表头(headerrepeat
页脚 / 合计提示每页都显示 重复表尾(footerrepeat
只在第一页出现的报表大标题 普通行(none)即可
某行不随数据分页重复,也不跨页 普通行(none)
保护某行不被误改 普通行 + 锁定(lock)
运行时根据条件隐藏某行 普通行 + 隐藏(hide)
末页补满空白 普通行 + 自动填充剩余高度
数据展开的主区域 普通行(none),靠单元格父格与展开方式驱动

九、小结

  • BaskReport 的「行类型」本质是 band 枚举:普通行 / 重复表头 / 重复表尾 三种。
  • 「标题行 / 表头行 / 明细行 / 表尾行」是布局概念,由父子格与展开方式决定,不是行类型枚举。
  • 重复表头 / 表尾用于分页时每页重复显示固定区域(如列标题、页脚)。
  • 限制:重复表头 / 表尾不支持多条数据的展开绑定(down / right),也不支持动态行高;其每页呈现的是原行的值快照,应使用固定行高与固定内容(静态文本 / 固定聚合表达式)。
  • 明细数据展开、动态行高请放在普通行(none)区域,通过父子格驱动。
  • 锁定、隐藏、自动填充剩余高度是独立于 band 的行行为属性,可叠加使用。

results matching ""

    No results matching ""