发工资条怕串部门?20行Python按部门列拆成独立文件

2026-10-14 · 喵窝资源铺

一张工资总表按部门拆开再分发,是工资条保密的基本动作——最忌把生产部的条发进质检部的群。手工筛选复制粘贴,部门一多必出错。这篇给一个 20 行脚本:自动识别「部门」列 → strip 后归组 → 每部门一个独立 xlsx(保留表头),空部门行带行号挑进报告,绝不混进任何文件。代码实跑验证,真实输出贴在下面。

输出长什么样

构造 96 条测试数据:3 个部门(生产部/质检部/仓储部)× 12 个月的工资条,并故意在部分行的部门列尾部注入空格("仓储部 "),模拟从各部门 Excel 拼表时的常见脏数据。跑完:

拆分完成:3 个部门,共 96 条
  仓储部: 36 条 -> out/仓储部工资条.xlsx
  生产部: 36 条 -> out/生产部工资条.xlsx
  质检部: 24 条 -> out/质检部工资条.xlsx

逐文件回读核对:每个文件里的部门列去重后有且只有本部门一个值(36/36/24 与分组计数一致),注入的带空格部门全部被 strip 归组——没有出现 仓储部 .xlsx 这种脏文件,96 条一条不少。

完整脚本

# -*- coding: utf-8 -*-
"""按部门拆分工资条为独立工作簿:自动识别「部门」列,strip 后分组,
每个部门一个 xlsx(保留表头)。空部门行单独挑进报告。
用法: python payslip_split_dept.py 工资条.xlsx 输出目录
"""
import sys, os, re
from openpyxl import load_workbook, Workbook

src, outdir = sys.argv[1], sys.argv[2]
DEPT_KEY = re.compile(r'部\s*门|dept', re.I)

wb = load_workbook(src)
ws = wb.active
rows = list(ws.iter_rows(values_only=True))
if not rows:
    sys.exit("空表")
header = [str(c).strip() if c is not None else "" for c in rows[0]]
dept_idx = next((i for i, h in enumerate(header) if DEPT_KEY.search(h)), None)
if dept_idx is None:
    sys.exit(f"找不到部门列,表头={header}")

os.makedirs(outdir, exist_ok=True)
groups, bad = {}, []
for i, row in enumerate(rows[1:], 2):
    if not any(c is not None and str(c).strip() for c in row):
        continue  # 整行空白跳过
    d = row[dept_idx]
    d = str(d).strip() if d is not None else ""
    if not d:
        bad.append(f"第{i}行 {row[1] if len(row)>1 else ''}: 部门为空,跳过")
        continue
    groups.setdefault(d, []).append(row)

made = []
for d, rs in groups.items():
    wbo = Workbook(); wso = wbo.active; wso.title = "工资条"
    wso.append(header)
    for r in rs:
        wso.append(r)
    path = os.path.join(outdir, f"{d}工资条.xlsx")
    wbo.save(path)
    made.append((d, len(rs), path))

print(f"拆分完成:{len(groups)} 个部门,共 {sum(n for _, n, _ in made)} 条")
for d, n, p in sorted(made):
    print(f"  {d}: {n} 条 -> {p}")
for b in bad:
    print("  !", b)

用法:python payslip_split_dept.py 工资条.xlsx 输出目录。拆完后每个文件只发给对应部门负责人即可。

踩到的 2 个真坑

  1. 部门列不 strip,会拆出 仓储部 .xlsx 这种脏文件。各部门 Excel 拼起来的总表,部门值经常带尾随空格或全角空格——同一个部门会被拆成两个文件,发的时候漏掉一半人。实测注入的 "仓储部 " 若去掉 strip 那一行,就会多出一个带空格后缀的文件。归组前统一 str(d).strip() 是这一步唯一的防线。顺带说:文件名不要做「清洗成拼音/去特殊字符」的花活,部门名原样最稳,谁认得谁的部门。
  2. 别按列位置硬编码 col=3,一换模板就拆错列。有的表第一列是工号、有的是姓名,「部门」可能在第 2~5 列任何位置。按表头文本正则匹配(部门|dept)自动定位,匹配不到就把完整表头打印出来退出——宁可停下来让人看,也不要拆出一堆按错误列命名的文件。同理,部门为空的行(合并单元格遗忘、漏填)必须挑进报告而不是默认塞进"未分组":工资条发错人的事故大多发生在这类被默认处理的行上。

口径提醒:本脚本只做拆分。金额核对(实发=应发-扣款)是另一道独立工序,别指望拆分脚本顺便发现算错工资——两个检查混在一起,出了错反而查不清是哪一环。

懒得自己跑?把工资总表发我(后台留言),AI 拆分+逐文件核对后把整包部门文件发回给你,9.9 元/次,虚拟物品交付后不退款、结果不符免费重做。更多现成脚本与代做服务 →

相关阅读:工资条按部门拆分进阶(含校验位核对) · 工资条批量发邮件(缺邮箱/格式错自动挑出) · 邮箱列清洗去重(发错人的源头治理) · 工资表全量核对