
Excel 转 Markdown 报 A 级,日期却是一串 46209
一份考勤台账 xlsx 丢给 tri-xlsx2md,四道门跑完门D 交的账是单元格覆盖率 99.1%、工作表数 2/2、置信度 A 级直接可用。可我拿结果表去填当月报表时,日期列全是一串 46209、合计行的工时停在一个旧缓存值、部门列一格空一格。这篇记录我用 tri-xlsx2md 转这份 2026-07 考勤台账的全过程,以及我后来怎么理解「A 级只管覆盖、不看语义」这件事。
这份台账是什么来头
要转的是「考勤台账-2026-07.xlsx」,做考勤的小系统导出来的,37KB 出头。两个工作表:一个「考勤明细」5 列 23 行,另一个「汇总」1 行。文件不大,也没加密,按路径直接丢给 tri-xlsx2md 就行。它不是自己写解析引擎,是个编排车间:先体检、再选刀、干完活必须交一份账。
门A:预检直接给 L0
第一步跑 preflight.py:
bash
python scripts/preflight.py --xlsx 考勤台账-2026-07.xlsx --json
它先读文件头几个字节做魔数判定:PK\x03\x04 开头是 OOXML 的 .xlsx,D0CF11E0 开头才是旧式 .xls。这份是标准的 .xlsx,没加密,2 个工作表,估出来一百多个单元格,直接给 L0 快速档,风险列表空的:
json
{
"detected_type": "xlsx",
"encrypted": false,
"sheet_count": 2,
"cell_estimate": 132,
"grade_suggestion": "L0",
"risks": []
}
那个 encrypted:false 不是摆设,真遇到带加密标记的 .xlsx 它会直接 BLOCK,提示你手动解密,绝不做破解。tri-xlsx2md 在这点很老实。
门B:刀库里 openpyxl 上了首选
门B 跑 detect_backends.py,把五个后端在本地探一遍,import 和 CLI 双路:
bash
python scripts/detect_backends.py --grade L0 --type xlsx --json
结果都装着:
| 后端 | 档位 | 本地状态 | 许可证 |
|---|---|---|---|
| openpyxl | L0 | ✅ import 可用 | MIT |
| markitdown | L0 | ✅ import 可用 | MIT |
| xlrd | L0(xls) | ✅ import 可用 | BSD-3-Clause |
| pandas | L1 | ✅ import 可用 | BSD-3-Clause |
| LibreOffice | L1 | ✅ CLI 可用 | MPL-2.0 |
L0 档首选 openpyxl,降级链 markitdown。这台机器齐全,没到降级那步。
门C:openpyxl 转完我扫了一眼就想归档
按手册里的命令用 openpyxl 转,产出的 Markdown 长这样:
markdown
## Sheet 考勤明细
| 姓名 | 部门 | 日期 | 打卡 | 出勤时长 |
|------|------|------|------|----------|
| 王垚 | 研发部 | 46209 | 正常 | 8 |
| 李菁 | | 46210 | 正常 | 8 |
| 赵磊 | | 46211 | 迟到 | 7.5 |
| ... | | ... | ... | ... |
## Sheet 汇总
| 指标 | 值 |
|------|-----|
| 出勤总工时 | 168 |
表格语法是齐的,竖线、分隔行都在。我心想这活干得漂亮,正要往知识库里放,突然觉得「46209 是啥日子」不太对劲。
门D:交账说 A 级,我没多想就信了一半
门D 交账:
bash
python scripts/quality_check.py --xlsx 考勤台账-2026-07.xlsx --md 考勤台账-2026-07.md --backend openpyxl --grade L0 --json
报告核心数据:
| 关键数据 | 数值 |
|---|---|
| 单元格覆盖率 | 99.1% |
| 工作表数对比 | 2/2 吻合 |
| 行数对比 | 明细 23/23、汇总 1/1 |
| 异常清单 | 空 |
| 置信度 | A(直接可用) |
判定原因:单元格覆盖 ≥95% 且工作表数吻合且无异常,直接 A。看数字确实漂亮,可它就是看不出来三个坑。
坑1:日期列是一串序列号
表里「日期」那列全是 46209、46210 这种。这不是转换丢的,是这份台账的日期列根本没设日期格式。Excel 里日期本质就是整数序列号(2026-07-06 对应 46209),要不要显示成「2026-07-06」全看单元格格式。源文件那列是纯数字,导出时 openpyxl 忠实地把数字原样搬进 Markdown,一个没改。
工具没错,错在源数据把日期当裸数字,而 A 级分级只数格子不辩语义,这一列照样全绿。
坑2:合计行的工时是缓存值
「汇总」表里「出勤总工时 168」,openpyxl 拿到的是 Excel 缓存的那个 168。它是 =SUM(各明细) 的缓存值,公式语义已经丢了。仓库里这份台账停留在某个时刻求出来的 168,后面明细改过工时时,缓存没重算,168 就跟着旧数据走。
转换本身不重算、也不报错,反正在 A 级的表里它就是个普通数字。
坑3:部门列一格空一格
明细表里「研发部」在源文件是合并单元格,跨了好几行。tri-xlsx2md 按规则展开成「左上角值 + 其余留空」,所以 Markdown 里部门列只有第一行有字,下面全是空格格。数据量大了你根本分不清是「真没值」还是「合并展开了」。
覆盖率照样 99.1%,因为这些空格本来就不算源非空单元格,分级压根不关心。
踩完这趟我认了几条理
- A 级只管覆盖,不管语义。算的是「源非空单元格被 MD 占了多大比例」,日期该不该显示成日期、公式是不是旧缓存、合并区展开成空算不算错,它一律不问。
- 固定复核项清单才是真账。tri-xlsx2md 的报告再高,固定那 6 项复核项(合并单元格、公式 vs 值、多行表头、.xls 兼容、超大截断、日期数字格式)一条都不能跳。我以前 A 级就扫一眼,吃过这亏。
- 转换前先看源。日期没格式、公式没重算、大合并区,这类种子在 Excel 里就该处理,转完再来补更费劲。
- 入库的 Excel 台账要过一遍日期与公式。别被 99.1% 和 A 级劝退,把日期列格式化、把公式重算值核一遍、把合并区决定是补全还是保留空格,再当数据用。
顺带一提,我在做「雷达鸭」的案例库时,常有人把统计用的 Excel 直接当知识源丢进来。用这套「覆盖率 + 置信度 + 固定复核项」的口径,至少能一眼看出哪些表「格子很齐但语义存疑」,省得入库后返工。
收尾
Excel 转 Markdown 真难的不是调用哪个库,是你以为 A 级报告就能闭眼入库。tri-xlsx2md 这套「质检车间」把人引到「先体检、再选刀、干完活必须交验」的正道上,但交验不等于完事,A 级下面还压着日期、公式、合并这三层看不见的账。这次我最该记住的,是那句复核项说明:单项数字好看,不等于每个格子都对。
我是老三,10+ 年软件开发经验,软件设计师、人工智能应用工程师,专注鸿蒙应用开发(ArkTS)北向开发与 Web 前端,探索 AI 自动化,不定期在 CSDN 分享鸿蒙 / AI 方向技术文章。
本文遵循 MIT 协议,转载请注明出处。
这个系列的文章都来自开源的 tri 技能库。整套 tri-xxx 技能都能在 skillhub 找到并安装,一条命令装完即用,比如本文用到的 tri-xlsx2md:skillhub install tri-xlsx2md。装完每个技能都有 README,想摸清它到底能干嘛,读那个就够了。