CSV成绩单按班级自动拆分成多文件(附完整脚本+实测记录)

老师场景的刚需:教务导出一个大CSV,全班混在一起,要分发给各班班主任,就得按班级拆成多个文件。手动复制粘贴又慢又容易漏行。下面这份脚本 30 行搞定,本文所有数字都是实际运行结果。

脚本要处理的真实脏数据

完整脚本

import csv, os
from collections import defaultdict

def read_csv_auto(path):
    raw = open(path, 'rb').read()
    for enc in ('utf-8-sig', 'gbk'):
        try:
            return list(csv.reader(raw.decode(enc).splitlines())), enc
        except UnicodeDecodeError:
            pass
    raise ValueError(path + ": 无法识别编码")

HEADER = ["姓名", "班级", "语文", "数学", "英语"]
groups = defaultdict(list)
header = None

for fn in sorted(os.listdir('in')):
    data, enc = read_csv_auto('in/' + fn)
    if data[0] != HEADER:
        print(f"跳过 {fn}: 表头不符")
        continue
    if header is None:
        header = data[0]
    for r in data[1:]:
        cls = r[1].strip()          # 关键:班级名去空格
        if not cls:
            print(f"跳过 {fn} 空班级行: {r[0]}")
            continue
        groups[cls].append(r)

os.makedirs('out', exist_ok=True)
for cls, rs in sorted(groups.items()):
    with open(f'out/{cls}.csv', 'w', newline='', encoding='utf-8-sig') as f:
        w = csv.writer(f)
        w.writerow(header)
        w.writerows(rs)
    print(f"out/{cls}.csv: {len(rs)} 人")

实跑结果(本文数据当场生成、当场拆分核对)

输入 3 个文件共 43 条学生记录:

输出:

out/一班.csv: 10 人
out/三班.csv: 15 人
out/二班.csv: 18 人
合计 43

10 + 15 + 18 = 43,与输入条数完全一致;"二班 "那行已正确归入out/二班.csv(逐文件 grep 验证),没有被拆成假班级。

三个实测踩过的坑

  1. 编码写死必崩:open(path, encoding='gbk') 遇到带BOM的UTF-8文件抛 UnicodeDecodeError。先读二进制,按 utf-8-sig → gbk 顺序尝试解码。
  2. 班级名不 strip 会静默分错:"二班 "≠"二班",字典里多出一个键,输出多一个残缺文件,没人会注意到少了一个人。一行 .strip() 修复。
  3. 拆完必须做合计核对:输出各班人数之和必须等于输入数据行数。43=43 才能确认没有行被吞掉。这一步不能省——CSV解析不会丢行,但你的过滤逻辑会。

改成按其他列拆

把 r[1] 换成任意列的下标(0 起)就能按科目、按年级、按部门拆。要拆 Excel(.xlsx)而不是 CSV,加一行 pip install openpyxl,把读取部分换成 openpyxl.load_workbook(path).active 遍历行即可,拆分逻辑完全不变。

需要代写这类批量脚本(按你的真实表结构调整、加异常处理、交付可运行文件),可以在喵窝资源铺下单「脚本代写」档(¥19.9),或先在客服对话框聊聊需求。