跳转到主要内容

xl3 会保留什么,不会保留什么

xl3 是否适合你的模板,最终归结为一个问题:工作簿能原样出来吗? 这一页按功能逐项回答。

下面的内容都是规范层面的决定,而不是某个实现的偶然行为。标为推迟的项是有意 推迟的,并且有 ADR 记录了这件事 —— 这和「没人检查过」不是一回事。

三种判定

判定含义
保留输出与模板完全一致。任何符合规范的实现都必须做到。
保留,但范围不扩展功能本身会留下来,但范围仍是模板给它的那些坐标。即使 @repeat 把工作表从 1 行扩到 50 行,范围也只覆盖那 1 行。每一项都有模板侧的应对办法。
推迟XTL 0.1 不作任何保证。它可能留下,也可能被丢弃,两个符合规范的实现给出不同结果也是允许的。1.1 之前不要依赖它。

布局与格式

功能判定说明
单元格格式 —— 字体、填充、边框、对齐保留
数字与日期格式保留@repeat 扩展出的每一行都会继承,而不只是第一行 —— 见重复块内的格式
行高、列宽保留
合并单元格保留模板里的和源数据行里的都算 (ADR-0033、ADR-0035)。
图片及其锚点保留@repeat 在上方插入行时锚点不会跟着移动。请把图片放在页眉、页脚或侧边 —— 也就是数据块之外。
冻结窗格与拆分保留
单元格批注保留写在 {{ [列] }} 单元格上的批注会留在渲染后的单元格上。
工作表保护、单元格级锁定/隐藏标记保留引擎写入的单元格继承模板单元格的锁定状态,而不是合成一个默认值。
工作簿属性 —— 主题、文档属性保留fixture 120-workbook-properties-preserved
静态单元格里的原生 Excel 公式保留不是 xl3 生成的公式会原样通过 (ADR-0046)。凡是 Excel 打开时能算的,都建议交给它 —— 见 Cookbook 16

带范围的规则

这些会留下来,但范围停在模板放它的位置。引擎不会悄悄把一条规则扩大到它从未提到 的行 —— 一条自动扩展的条件格式,可能会渗到作者刻意排除的合计行上。

功能判定模板侧的应对办法
条件格式保留,但范围不扩展在模板里把规则挂到整列 ($A:$A)。实测:1 行的块扩到 3 行后,规则仍停在 A2:A2
数据验证(下拉、约束)保留,但范围不扩展同样的办法。实测:设在 B2 上的验证,扩展后仍只在 B2
名称定义保留,但范围不扩展工作簿级和工作表级都会留下,但引用不会被重新指向扩展后的区域。
打印区域、打印标题保留,但范围不扩展把打印区域设为整列 ($A:$Z),或设为重复的标题行 ($1:$1)。

推迟到 1.1

有四个功能在 1.0 中被有意留作实现自定义 (ADR-0076)。下面记录参考实现当前的行为, 方便你据此规划,但其中任何一条都不是承诺 —— 这正是「推迟」的含义。

功能参考实现的当前行为
数据透视表不会通过。既不能创作也不能保留。
迷你图同样不会通过。
结构化表格 (ListObject)表格本身会留下,但 ref 不会扩展:跨着 @repeat 行创建的表格,之后仍只覆盖它原本覆盖的那些行。请在模板里把 ref 放宽到整列。
分页符会丢失。 概念上看着紧挨「打印区域」,但并不在其覆盖范围内。请在转换之后由宿主一侧设置。
图表由实现自定义 (ADR-0036 第 3 项)。参考实现通过 ExcelJS 读写,而它的图表支持并不完整 —— 不要指望图表能留下来。

有意移除的部分

功能行为
宏 (VBA、XLM)始终被剥离。 .xlsm 输入会被当作「已移除宏的 XLSX」接受,并发出一条警告。宏永远不会执行,在 1.x 期间宿主和模板都无法把它开回来。见 SECURITY.md

重复块内的格式

范围和单元格级格式的行为方向相反,这个差别最容易让人踩坑。

模板里锚在 A2:A2 的范围,即使输出了十行,依然是 A2:A2。而那十行全都带着 A2 的数字格式和单元格样式 —— 引擎写入的单元格采用模板单元格的格式,并且是每一行, 不只是第一行。

后半句比听起来更重要。第 2..N 行丢掉格式属于无声的数据损失:一列里第一行显示 1,234.50、其余显示 1234.5,看起来就像一次格式失手,并且和真的失手无法区分。 带 data-loss 标签的九条 fixture 就是为了防止这种回归而存在的。

体积上限

上限数值
内存规模上去之后每个输出单元格约 2.2 KB,再加上约 130 MB 的底座。200 万单元格大致需要 4.2 GB 的峰值 RSS。
单次转换的单元格数端到端验证到约 200 万;2 GB 的宿主大约能放 50 万。在假定更大的任务能跑之前,请按每单元格 2.2 KB 估算宿主规格。
单元格字符串长度xl3 原样写出你给的内容。Excel 在读取时会拒绝超过 32,767 个字符的单元格,而 xl3 不做预先校验 —— 如果输出必须能在 Excel 中打开,请在传入前检查长度 (ADR-0032)。

超出可用内存时,表现为宿主层面的 out-of-memory,而不是一个 xl3 错误 —— xl3 无法 捕获它。耗时较长的转换支持 AbortSignal

其中有多少是机器校验过的

一部分。而且值得知道是哪一部分。

  • 123-feature-preservation 用 Stage 1 的单元格值比较,确认名称定义和单元格批注 能经过渲染留存下来。
  • 170-data-loss-numfmt-preserved-across-expansion 在 Stage 2 确认数字格式能越过 @repeat 的展开保持住 —— 就是上面说的那个坑。
  • 对上面表格中每一行都做 Stage 2 规范化比较,仍在等 ADR-0006 的 canonicalizer 工作。

也就是说,没有 fixture 支撑的行是规范层面的承诺,而不是机器校验过的结论。所有实现 都跑同一套适合性语料库,所以被校验的部分处处都被校验;但语料库还 没有覆盖这张表的全部 —— 这一页宁愿把这件事说出来,而不是让人以为不是这样。

这些决定写在哪里

这一页是把规范文档换成平实说法的版本。两边有冲突时,以规范为准。

  • spec/evaluation.md § Styles and Workbook Structure —— 规范性规则
  • ADR-0036 —— 九项功能的保留矩阵,以及为什么每一项都定为「原样保留」而不是「保留并扩展」
  • ADR-0076 —— 把数据透视表 / 迷你图 / ListObject / 分页符推迟到 1.1 的决定,附实测行为
  • ADR-0046 —— 静态单元格中的原生 Excel 公式
  • ADR-0032 —— 字符串长度等边缘上限
  • ADR-0022 —— Excel 版本兼容性
  • SECURITY.md —— 关于宏、网络与文件系统的立场