小题分排版
0. 什么时候用
老师手上有一份阅卷系统导出的小题分表(每行一个学生、每列一个小题),想让每个学生
拿到一张清晰的小纸条:哪一题、得了多少分、哪题丢分了。本技能把它排成 A4 竖排 · 两栏 ·
每页 6 人 的 Excel,直接 Ctrl+P 打印,裁开即可分发。
不适用场景:只要汇总统计/排名分析(那是分析任务,不是排版);只要一份普通明细表。
1. 三步走
> 下文 <skill> 指本技能的安装目录(即 SKILL.md 所在文件夹),脚本在其 scripts/ 下。
> Python 用系统 python 或任意 3.9+ 解释器均可。路径一律给绝对路径。
步骤 1 — 探测源表,生成配置
python "<skill>/scripts/probe.py" "<源文件绝对路径>" --sheet 0 \
--config "<工作目录>/config.json" --out "<输出 xlsx 绝对路径>"
输出:列结构报告 + 推断出的题组列表 + config.json(含 layout 默认值)。
必须核对三件事(打印出来让老师一眼看懂的关键):
1. 题组标签对不对(13~16 / 1~6 / 7~12 / 17 …)——不对就直接改 groups[].label;
2. 满分合计是否等于卷面总分(源表满分 150 就应显示 150);
3. 考号/姓名/班级/总分列有没有认错(认错时改 id_col / name_col / class_col / total_col)。
步骤 2 — 生成 xlsx
python "<skill>/scripts/build_print.py" --config "<工作目录>/config.json"
可调参数都在 config.json 的 layout 段(见 §3)。改完重跑本步即可。
步骤 3 — 重算 + 核验分页(不可跳过)
powershell -ExecutionPolicy Bypass -File "<skill>/scripts/recalc.ps1" ^
-Workbook "<输出 xlsx>" -Pdf "<工作目录>/preview.pdf" -Report "<工作目录>/pagecheck.txt"
读 pagecheck.txt:
- HPageBreaks = 人数/每页人数 - 1 且 VPageBreaks = 0 → 通过;
- HPageBreaks 偏大 → 每页装不下,压 row_h.data 或减小 row_gap_pt 后回步骤 2;
- PDF 的 /MediaBox 个数即页数,应为 0 0 595.2 841.8(A4 纵向)。
2. 输出长什么样
┌─────────────────────────────────────────────┐
│ 孟想 考号 130122 总分 116 │ ← 抬头(加粗,可配字段)
├─────┬───┬───┬───┬───┬───┬───┬─────┬─────┤
│ 题号│ ① │ ② │ ③ │ ④ │ ⑤ │ ⑥ │ 小计│ 满分│
├─────┼───┼───┼───┼───┼───┼───┼─────┼─────┤
│13~16│ 4 │ 4 │ 0 │ 5 │ — │ — │ 13 │ 18 │
│ 1~6 │ 4 │ 4 │ 4 │ 4 │ 4 │ 4 │ 24 │ 24 │
│ 7~12│ 5 │ 5 │ 5 │ 0 │ 5 │ 0 │ 20 │ 30 │
│ 17 │ 6 │ 8 │ — │ — │ — │ — │ 14 │ 14 │
│ 18 │ 6 │ 8 │ — │ — │ — │ — │ 14 │ 14 │
│ 19 │ 3 │ 8 │ — │ — │ — │ — │ 11 │ 14 │
│ 20 │ 4 │ 6 │ 6 │ — │ — │ — │ 16 │ 18 │
│ 21 │ 4 │ 0 │ 0 │ — │ — │ — │ 4 │ 18 │
├─────┼───┴───┼───────┴───┼─────┼─────┤
│ 合计│得分率│ 77.3% │名次 │ 20 │116 │150 │
└─────┴──────┴────────────┴─────┴─────┴────┘
- 题号行给真实题号区间,①~⑥ 是该组第几小题,学生一眼对得上号。
- 0 分红底红字、部分得分黄底 —— 薄弱题不用找。
- 小计 / 总分 / 得分率全是公式,改一个小题分,抬头和合计自动跟着变。
3. layout 参数(改这里调版式)
| 键 | 默认 | 说明 |
|---|---|---|
per_page / per_col |
6 / 3 | 每页人数 = per_col × 2(两栏) |
margin_lr_cm / margin_tb_cm |
1.0 / 2.0 | 左右 / 上下页边距(cm) |
col_gap |
2.0 | 横向两栏间距(间隔列宽,原 1.0 的 2 倍) |
row_gap_pt |
28 | 上下两个区块的间距(pt,原 14 的 2 倍) |
row_h |
title 22 / header 16 / data 19 / total 20 | 区块内各行高(pt) |
col_w |
label 7.9 / sub 4.4 / subtotal 5.7 / full 5.7 | 列宽 |
title_fields |
["name","id","total"] |
抬头字段,可选 name/id/class/total/rank |
show_rate / show_rank |
true / true | 合计行是否显示得分率 / 名次 |
highlight |
true | 是否用色块标注失分 |
常见改法
- 抬头要「总分」而不是「班名」:title_fields 用 ["name","id","total"];要班名就用 "rank"。
- 上下页边距加大(如 2 cm)后每页掉人 → 同步把 row_h.data 调小(22→19 这类)。
- 间距要翻倍:col_gap 与 row_gap_pt 各乘 2。
4. 题组识别原理(排错用)
表头形如 单选13(4.0分)、1-6_1(4.0分)、1-6(24.0分)、17_1(6.0分)、17(14.0分):
- 带
_的是小题列,key 取_前部分(1-6_1→1-6,17_1→17); - 不带
_且满分等于某组小题满分之和的,判为小计列(1-6(24.0分)、17(14.0分)); - 剩下的不带
_列(单选13~单选16)按去掉末位数字后的前缀归为一组; - 题组按首列位置排序,标签由
make_label()生成(纯数字→该数字,a-b→a~b,其余→首~尾)。
若某份源表识别错乱,直接手改 config.json 的 groups(label / cols / fulls)最省事。
5. 依赖、权限与隐私(投稿/分发前请如实对外声明)
依赖(仅两个,且都是可选自动安装)
| 包 | 用途 | 版本要求 |
|---|---|---|
openpyxl |
读写 xlsx、建表、设打印参数 | ≥ 3.1.0 |
xlrd |
读取旧版 .xls 源表 |
≥ 2.0.1 |
两个脚本都用 try: import … except ImportError: 兜底,只有在你机器上确实没装时才执行
python -m pip install --quiet <包>,装到当前使用的那个解释器;已装则完全不触发、不联网。
若不想让它动全局环境,可先建虚拟环境再用该环境的 python 运行,或直接手工
pip install openpyxl xlrd 后再跑(装好后脚本不会再尝试安装)。
权限声明
| 能力 | 用到什么 | 说明 |
|---|---|---|
| 读本地文件 | 学生小题分源表(xls/xlsx/csv) | 只读,绝不回写、不修改源文件 |
| 写本地文件 | 输出的打印版 xlsx、可选预览 PDF | 路径由你指定 |
| 启动本机应用 | recalc.ps1 通过 COM 调用本机已安装的 Excel |
仅用于重算公式缓存值与导出 PDF;Visible=false,不显示窗口,用完即 Quit() |
| 网络 | 完全不使用 | 无任何联网、上报、遥测行为 |
隐私说明:全部处理在本机完成,学生姓名、考号、成绩不会上传到任何服务器;
技能内不含任何密钥、账号或硬编码地址。
6. 参考
references/layout_spec.md—— 行高预算公式、列宽换算、分页核验方法、已知坑scripts/probe.py—— 结构探测 + 生成配置scripts/build_print.py—— 建表落盘scripts/recalc.ps1—— Excel COM 重算回写缓存值 + 导出 PDF + 分页报告