excel-data-pipelinelisted
Install: claude install-skill 1231Johnny/claude-skills
# Excel 台账 → 可辩护的 JSON
源表结构、脚本产出与自检输出(示例数据):

## 为什么单独有这一步
凡是要拿数据做汇报、做看板,**数字能不能被追问**决定了整个成果的价值。而实践中出错的地方几乎从来不是算法,是这三类:
1. **看错列**——台账被人删了两列,后续列整体前移,脚本还按老索引取数,取出来的东西形状对、含义完全错;
2. **算错口径**——父子层级里,父级数据该是"自己那一行"还是"所有子级之和",两种都常见,弄反了总量就错;
3. **漏了脏数据**——`#N/A`、`/`、空白、文本格式的数字混在列里,静默变成 `NaN` 或被当成 0。
这个 skill 就是对着这三类问题来的。
---
## 第 1 步:先探结构,不要先写代码
```bash
python inspect_excel.py <工作簿路径> [输出文件]
```
它把每个 sheet 的真实结构写进一个文本文件:
- sheet 名单与各自的尺寸;
- 逐列的列号(Excel 字母 + 0 起索引)、表头文字、若干样例值;
- 表头可能不在第 1 行时,它会跳过前几行空行再找;
- 检测到的合并单元格区域。
**输出写成文件而不是打印到终端**——中文在 Windows 终端下经常乱码,写文件再读比调编码省事得多。
拿到这份结构后,把列位置**显式写死**进提取脚本顶部的配置区。不要用"自动找表头"这类小聪明:台账的表头文字常年微调,自动匹配会在某次微调后悄悄匹配到错误的列上,静默出错。
---
## 第 2 步:列契约校验
在提取脚本开头加一道断言:读表头行,与预期的列名逐个比对,对不上就**报错退出**。
```python
COL_SPEC = [
(0, '编号'), (1, '名称'), (2, '级别'), (3, '地址'),
(9, '供水量'), (10, '售水量'), (11, '漏损量'), (12, '产销差'),
]
def verify_header(ws, spec, header_row=1):
actual = [str(c.value or '').strip() for c in ws[header_row]]
bad = [(i, name, actual[i] if i < len(actual) else '空')
for i, name in spec if i >= len(actual) or actual[i] != name]
if bad:
for i, want, got in bad:
print(f' 第 {i+1} 列:期望「{want}」,实际「{got}」')
raise SystemExit('表头校验未通过——表结构可能被改过,先跑 inspect_excel.py 看清现状')
```
这道校验的价值在**生成阶段就拦住错误**,而不是等材料发出去之后被人发现。一次真实的事故就是台账删掉了"上月底数""本月读数"两列,后面所有列前移两位,脚本默默取到了错误的数据,直到有人对着原始表格核对才发现。
---
## 第 3 步:数值清洗
```python
def safe_num(v):
"""把 Excel 里各种'空'与错误值统一压成 Non