Skill 方案导入1375 字·2026/11/14·被检索 0 次

Skill 方案 S5 · 文档与表格批量转换

先按magic bytes认格式再谈转换,抽出图片到assets、公式统一$与1552并留待核对标记、合并单元格拆表说明,最后用表数/行列/图数/公式数四项机器对账。5批转换的0.32亿token可压到0.05亿。

挂靠在《二、重复操作与 Skill 方案》之下

版本
使用说明
v1reused-preview2026/11/14 11:16:48

Skill 方案 S5 · 文档与表格批量转换

一句话:给一个目录,自动认格式、抽正文、提图片、转公式、保住表格结构,并用行列数与公式数做机器校验;5 次大批量转换消耗的 0.32 亿 token 可压到 0.05 亿。

一、为什么需要它

两个月里五类转换反复出现,单次成本都极高,因为每一次都是"边转边试、转完再逐页核对"。

任务来源token主要难点
D01 PDF→MD2026 考研数学(一)真题解析651 万公式有上下标、分式、跨页续表
D02 CSV→可视化B 站 UP 主全量视频清单915 万播放量含"万"、分类靠语义判断
D13 Word 表格→MD表格法.doc,202 次工具调用2130 万合并单元格、边框、图片混排
表格 grid↔Markdown笔记站编辑器双向转换含在上面对齐、转义竖线、代码围栏内不转
零散 docx/pdf各类资料其余格式识别靠猜
指标数值
转换批次5 次
累计 token0.32 亿
平均每批640 万
平均工具调用60–200 次
一次通过率接近零

核心问题不是"转不出来",而是没有验收口径:D01 转完没有一处标记"这题公式可能识别错",用户只能自己逐题验;D13 的 21M token 里,很大一部分花在反复回读原文件比对表格边框。

二、触发词与边界

触发词不适用场景
「把这个 PDF 转成 Markdown」「转 md」只读不转、只要摘要 → 用 pdf skill 直读
「Word 表格转 Markdown」「表格提取」要生成新 xlsx → 走 sheet-generation
「CSV 做成可视化」「出图」要改现有表结构 → 走 sheetagent
「图片里的表格」「扫描件」纯图片 OCR 且无文字层 → 先声明降级
「grid 转 md」「md 转 grid」超大表(> 5000 行)→ 分片处理

边界:转换不改语义。数字、单位、题号一律原样保留;识别不确定的内容加 [待核对·第X页] 标记,绝不"顺手修正"。

三、输入与前置检查

先认格式,不要看扩展名。 改过后缀的 .doc 其实是 docx、.pdf 其实是图片扫描件,这两种在本机都出现过:

node -e "
const fs=require('fs');
for(const f of process.argv.slice(1)){
  const b=Buffer.alloc(8); const fd=fs.openSync(f,'r'); fs.readSync(fd,b,0,8,0); fs.closeSync(fd);
  const hex=b.toString('hex');
  const kind = hex.startsWith('25504446')?'pdf' : hex.startsWith('504b0304')?'zip/docx/xlsx' : hex.startsWith('d0cf11e0')?'ole/doc(xls)':'unknown';
  console.log(f, kind, hex);
}" "C:/Users/cag/xwechat_files/.../表格法.doc"
判定处理
pdf先看有没有文字层;没有则按扫描件降级,逐页转图 + OCR
zip/docx/xlsx用 docx / xlsx skill 抽取,按 XML 结构取表
ole/doc(xls)老格式,先另存为 docx/xlsx 再转,不要强解
unknown停下来问,不猜

三项环境检查:目标目录可写、可用磁盘 > 2 GB(图片提取最占空间)、notes 下的 TS 工具链可用(表格转换依赖 lib/md-tables.ts,跑 npx tsx --version 验证)。

四、执行步骤

步骤 1 · 建工作目录,固定产物结构。

mkdir -p out/<docname>/{assets,raw}

raw/ 放抽取的中间文本,assets/ 放提取的图片,最终 md 与 assets/ 同级,保证 Typora 打开即见。

步骤 2 · 抽取正文与图片。 用对应 skill 完成,不手写临时解析脚本:PDF 走 pdf skill,Word/Excel 走 docx / xlsx skill。抽取时同步导出图片到 assets/,命名统一为 img-<页码或序号>-<原文件名>,并在正文原位置插入 ![](assets/img-001.png)。

步骤 3 · 公式处理。 PDF 的文字层会打散公式结构,这是 D01 花掉 651 万 token 的直接原因。规则三条:

  1. 行内统一 $...$,独立公式统一 $$...$$,不混用(用户原话给的是"$$ 或者 $$$$",二选一等于没规定,必须收敛成一条)。
  2. 分式一律写 \frac{}{},不要用 a/b 冒充。
  3. 识别不出的公式原样保留文本并加 [待核对·第3页],不许编一个看起来合理的式子。

步骤 4 · 表格保真。 Markdown 管道表无法表达合并单元格,遇到就拆:跨行合并拆成重复值,跨列合并写成 列A / 列B 并在表下加一行说明。转换用现成函数,不要另写:

cd "C:/Users/cag/WorkBuddy/2026-10-11-06-00-16/notes" && npx tsx scripts/md-tables.test.ts

这个单测覆盖基本表、无首尾竖线、对齐、转义竖线、跳过代码围栏与引用块、多表偏移、grid 转换七类场景,跑通说明 scanPipeTables / pipeTableToGrid 可用。

步骤 5 · 机器校验。 转完必须用数字对账,不靠眼睛:

node -e "
const fs=require('fs'); const md=fs.readFileSync(process.argv[1],'utf8');
const rows=(md.match(/^\|.*\|$/gm)||[]).length;
const seps=(md.match(/^\|[\s:|-]+\|$/gm)||[]).length;
const inline=(md.match(/\\\$[^\\\$\\n]+\\\$/g)||[]).length;
const block=(md.match(/\\\$\\\$/g)||[]).length/2;
const imgs=(md.match(/!\\\[[^\\\]]*\\\]\\([^)]+\\)/g)||[]).length;
console.log(JSON.stringify({tableLines:rows, tables:seps, inlineMath:inline, blockMath:block, images:imgs}));
" out/<docname>/<docname>.md

把结果与原文件的表数、图数、公式数逐项对照;任何一项差超过 1,回到步骤 2 定位是哪一页丢的。

五、输出与验收

{"file":"D13.md","pages":42,"tables":17,"tableRows":386,"images":63,"inlineMath":0,"blockMath":0,"pendingCheck":4}

三条硬断言:

  1. 表格数与原文件一致,且每张表的列数一致;行列数不符必须标出具体表序号。
  2. 图片数 == assets/ 下实际文件数,正文里不得有指向不存在文件的链接。
  3. [待核对] 标记数必须写进最终报告;为 0 时要能说明"确实全部识别成功",不能默认没有。

六、失败处理与回滚

现象根因动作
转出来全是图PDF 无文字层降级 OCR,并在报告首行声明
公式变成乱码字体子集缺 ToUnicode该页转图,人工补,正文留 [待核对]
表格错列合并单元格拆表 + 表下说明,不强行塞进一行
图片丢失抽取时未导出重跑步骤 2,只补图片不动正文
转换后打不开编码不是 UTF-8统一 -Encoding utf8 重写

回滚:转换是全量重生成,不留中间态;原始文件只读,永不修改。产物出错就删 out/<docname>/ 重跑——这里用 Move-Item 挪到 _trash,避开 safe-delete 钩子。

七、收益测算

项目现状改造后
单批 token640 万100 万
批次5 次5 次
累计0.32 亿0.05 亿
核对方式逐页人工比对行列数/图数/公式数对账
返工几乎每批都返差异定位到页

省的是"回读原文件比对"这一层:D13 的 202 次工具调用里,超过一半是在反复读原文档确认表格边界。节省 0.27 亿,约 84%。