ADR-0032:语义表格列合并与标准 DOCX 网格跨度
- 日期:2026-10-16
- 状态:已采纳;验收证据单独记录
背景
组件 GridTable 的跨行/跨列能力不属于语义 Table。后者原来把源单元格列表下标与物理列号等同,DOCX、模板、字段和外链因此没有共同的合并表达。仅增加 gridSpan 标签会让布局或来源访问越界,不能形成完整能力。
决策
TableCell 增加正整数 columnSpan,默认 1;TableRow.cells 保留真实锚点,不填占位格。每行跨度必须完整覆盖物理列网格。TableRow.columnCount 安全求和,cellAtColumn 返回覆盖指定物理列的真实锚点,越界失败。缺省列按首行覆盖数推导等比例列,推断最多 4,096 列,避免巨大跨度隐式分配;显式列另受布局预算。
固定/比例列合并按覆盖宽度之和测量一次,只扣一次内边距;IR CellFragment.columnIndex 保留物理起始列,矩形覆盖整个宽格。整行分页、完整行拆分及短区域游标共享这一规则。拆行状态按当前源行锚点数量维护,行切换后重新创建,允许相邻行有不同合并结构。源文字/图片只计真实锚点一次;maxCells 继续计覆盖网格槽,重复表头计输出行。
本批拒绝覆盖任何 Auto 列的合并格;未合并 Auto 格及其他位置的 Auto 列保留。跨列首选宽度的约束分配以后另行设计,不把约束全部归首列或跳过探测。单向 StreamingTable 仍明确拒绝合并。
最终字段沿用 IR 网格起始列与格内 UTF-16;外链经统一物理列定位取得源锚点。Java 动态行与普通绑定复制跨度;XML cell 使用固定正十进制 column-span,静态、表头和动态原型均校验完整覆盖。
DOCX 一个真实锚点写一个 w:tc,span > 1 写标准 w:tcPr/w:gridSpan,tblGrid 保存物理列网格。导入验证容器、唯一属性/元素、正整数、上限与行覆盖;无 tblGrid 时按真实跨度推断。vMerge、hMerge、省略槽及嵌套表格维持明确损失边界;错误几何不能由允许损失模式猜测修复。重复表头 PAGE 仍拒绝,Word 与 PDF 同分页不承诺。
兼容性
保留既有 TableCell 的 2/3/4/5 参数构造器、工厂和访问器,默认跨度 1。新增 toBuilder 保存全部行内内容及跨度。record components 从 5 增至 6;旧 record 解构模式和反射形状需要调整,不能声称所有源码或二进制完全兼容。项目尚未正式发布,坐标不变,隔离调用方重新编译验收。
未引入模型到布局/字体/后端的反向依赖,没有新增依赖。rowSpan 和递归格内容各需覆盖模型、分页与 OOXML 的独立设计,列合并完成不能关闭整个 GAP-12。
验证要求
覆盖交替锚点数量、窄覆盖列、整行/拆行/短区、表头字段、末锚点图文外链、UTF-16 与结构预算。Java/XML 绑定及原生 gridSpan 往返必须同批验证。独立解析 OOXML、PDF 几何、双引擎渲染与全部新页复查;本机 Word 可用时只更新生成样例并回读保存结果。旧完整/单向长表和隔离坐标调用方回归保持。