格式忠实度
单元格显示文本经过一层补偿,修复一组引擎缺陷——每一条都经实测验证并由单元测试锁定。本页说明哪些是精确还原、哪些是近似。
内置数字格式:Excel 实际行为表
ECMA-376 把内置 id 14 定义为 mm-dd-yy,但 Excel(en-US)渲染成 m/d/yyyy。引擎返回的是 ECMA 标准串,且 loadFormatTable 覆盖在结构上不可能生效(内置表恒优先于自定义表查表)。因此预览器自带 Excel 行为表,覆盖随区域变化的 id——0–22 与 37–49(14 → m/d/yyyy、18 → h:mm AM/PM、46 → [h]:mm:ss……),先把 id 解析成格式串再进入格式化;23–36(国际货币占位,现实中罕见)不提供行为表,回退引擎的 ECMA 标准串。
数字段的字面量补偿
引擎会丢弃数字段内的字面量:¥#,##0.00 渲染成 1,234.50(货币没了)、#,##0.00;-#,##0.00 对 -1234.5 渲染成 1,234.50(负号没了)、"neg"0 渲染成 5(引号文本没了)。补偿层抽取两侧"可安全回注"的字面量(引号串、转义、货币符号、-、(、)、空格),把数字中段以绝对值交给引擎,再拼回——顺带精确还原了 Excel 的符号语义(负段没有 - 就不显示负号,与 Excel 一致)。
还原:货币前后缀、单位(0.0" kg")、文本前缀("Total: "@)、负号、会计括号。
近似:数字之间交错的字面量(电话号码式 000-0000)与千分位缩放逗号(#,##0,)仍会丢失;_ 宽度填充与 * 重复填充有意丢弃。
日期与时间:整体自实现
两个引擎缺陷使整体重写成为必要(引擎把 h 后面的 mm 当月份——0.5 配 h:mm 显示 12:12 而非 12:00;dddd 渲染成日号):
mm分钟/月份邻接消歧(前邻 h、后邻 s → 分钟)- 星期名(
ddd/dddd)、月份名(mmm/mmmm)、12 小时制 +AM/PM - 累计时长
[h]:mm:ss、[m]:ss、[s](引擎全坏) - 无括号
mm:ss(引擎误读为"月:秒")按当日时间的"分:秒"渲染——累计分钟在 Excel 里是带括号[m]:ss的语义,两者区分开 - 小数秒(
ss.0,内置 47)按显示精度四舍五入 - date1904 工作簿:格式化前序列号 +1462 天平移
- 引号字面量(
yyyy"年"m"月"d"日")与 1900 幽灵日(serial 60)均已处理
时间计算全程用 UTC 分量(规避夏令时重叠/空隙的业界标准做法),任何时区下渲染一致。
General
General 为自实现:15 位有效数字去尾零(引擎会输出 16 位浮点尾迹)、布尔大写 TRUE/FALSE、文本原样。
主题色与 indexed 色
引擎读取侧把 theme/tint/indexed 颜色解析为 null——真实文件的默认字体色(theme 1)与所有主题色填充会整体丢失。覆盖层只解压 styles.xml + theme1.xml(各几 KB),拿回原始颜色规格并解析(主题调色板含 0/1・2/3 下标交换、ECMA tint 的 HSL 亮度公式、indexed 调色板),按数组下标合并。显式 RGB 优先;覆盖层失败时优雅降级为 RGB-only。
自闭合样式元素(真实 Excel 文件的 id 对齐)
真实 Excel 文件把默认边框写成自闭合 <border/>(<font/>/<fill/> 偶见自闭合)。引擎解析会跳过自闭合元素,其 fonts/fills/borders 数组各少一项、cellXfs 的 id 引用整体错位:borderId=0 拿到文件中 border #1 的样式、末位引用悬空(手工 OOXML 实测——引擎自家写产物是展开形态,经导出包往返的文件不会触发)。覆盖层因此按 styles.xml 文档序完整重建这三个集合(自闭合空项照常占位),id 与 cellXfs 严格对齐;引擎数组仅在 styles.xml 本身读不出来时兜底。
格式码颜色段
[Red] / [Blue] / [Color 3] 段颜色会被抽出并以内联颜色应用到单元格(引擎的 formatCell 遇到颜色段会整体输出错乱串)。