Excel 表格合并拆分
规矩(每次都要遵守)
- 原文件只读。 脚本只读用户的表,合并结果、拆出来的文件一律另存新文件;重名自动加 _1、_2,绝不覆盖。不要用任何别的办法去改、移动、删除用户的原表。
- 先体检,再动手。 第一次拿到文件夹或文件,先跑
check,把体检结果用大白话一条条告诉用户,再合并或拆分。特别是:
- 认出来的合计行、制表人备注行要念给用户听(第几行、写的什么),问一句「这些不算数据,合并时去掉,对吗?」用户说要保留才加--keep-total。
- 名字相像但没对齐的列(比如「金额」和「金额(元)」)要问用户是不是同一列;是的话用--map对齐。注意单位不同(元 / 万元)的不能硬对齐,要提醒用户。
- 不是每个表都有的列、数字存成文本、跳过的文件都要说清楚。
- 去不去重、按哪几列算重复,由用户定。 - 拆分前先预览。 拆成很多个文件前先跑一次
--preview,把会拆成几份、每份多少行告诉用户,用户点头再正式拆。 - 数字以脚本输出为准,不要心算行数、不要自己改。
- 组件缺了只提示,不自动装。 脚本会告诉用户缺什么、怎么装,由用户自己决定。
- 说人话。 跟用户说「按部门拆开」「把各部门的表合成一张」「去掉重复的行」,不说命令参数和程序里的名字;但用户问起在运行什么,就如实告诉他:在用本机的 Python 脚本读表、生成新文件。
- 全部在本机处理,不联网、不上传。
用法
脚本:python {baseDir}/scripts/excel_merge.py <子命令> ...,路径有空格要整个加引号。
| 子命令 | 做什么 | 会不会动原文件 |
|---|---|---|
check 文件夹或文件… |
体检:每个表的表头位置、行数、标题行、合计行、空行、数字存成文本、合并单元格;多个表时给列名对照;一个表时列出适合拆分的列 | 只读,不生成文件 |
merge 文件夹或文件… |
上下合并成一个新的 xlsx(「合并结果」+「合并说明」两页) | 只读,另存新文件 |
split 文件 --by 列名 |
按这一列的值拆成多个文件(或多个工作表) | 只读,另存新文件 |
split 文件 --rows N |
每 N 行拆一份 | 只读,另存新文件 |
check / merge 共用的选项:
| 选项 | 意思 |
|---|---|
| (不写) | 给的是文件夹或多个文件 → 每个文件取第一个有数据的工作表;只给一个 Excel 文件 → 合并它的所有工作表(隐藏的不算) |
--all-sheets |
每个文件的所有工作表都合并 |
--first-sheet |
只给一个文件时也只取第一个工作表 |
--sheet 名称 |
每个文件只取这个名字的工作表 |
--exclude 词1,词2 |
文件名或工作表名里带这些字的不要(如「说明」「汇总」) |
--recursive |
连子文件夹里的表一起 |
--header-row N |
表头在第 N 行(自动找错了才用) |
--map 名字=姓名,金额(元)=金额 |
手动指定哪些列名是同一列(左边并到右边) |
merge 另外的选项:
| 选项 | 意思 |
|---|---|
--no-source |
不加「来源文件」「来源sheet」列(默认:多个文件就加来源文件,多个工作表就加来源sheet) |
--keep-total |
保留各表自带的合计行、表尾备注行(默认跳过) |
--dedup |
去掉完全重复的行(来源列不算) |
--dedup-by 工号 |
按这几列判断重复,保留第一次出现的 |
--to-number |
把存成文本的数字改成真正的数字(工号、电话、身份证号这类列不动) |
--renumber |
「序号」列重新从 1 编 |
--out 路径 |
保存位置(不能和原文件同名;已存在就加 _1) |
split 的选项:
| 选项 | 意思 |
|---|---|
--by 列名 / --rows N |
按哪一列拆 / 每多少行一份,二选一 |
--to sheets |
拆成一个文件里的多个工作表(默认拆成多个文件) |
--sheet 名称 |
拆哪个工作表 |
--prefix 9月工资_ |
文件名 / 工作表名前面加的字 |
--no-title |
不带表头上面的标题行 |
--preview |
只看会拆成哪几份,不生成文件 |
--max N |
最多拆多少份,默认 500 |
--out 路径 |
拆成文件时是文件夹位置,拆成工作表时是文件位置 |
大白话 → 怎么做
| 用户说 | 怎么做 |
|---|---|
| 「各部门交上来的表在一个文件夹里,帮我合成一张」 | 先 check 文件夹,念体检结果、确认合计行;再 merge 文件夹 |
| 「这个 Excel 有 12 个月的 sheet,合到一起」 | check 文件 → merge 文件(自动合并所有工作表并加来源sheet列);有「说明」「汇总」页就加 --exclude 说明,汇总 |
| 「有的表写『名字』有的写『姓名』」 | 常见同义列名会自动对齐;没对上的用 --map 名字=姓名 |
| 「合并后去掉重复的人」 | --dedup-by 工号(没有工号就问用户按哪几列算重复);整行一样才算重复就用 --dedup |
| 「金额求和不对」 | 多半是数字存成了文本:合并时加 --to-number |
| 「不要来源那一列」 | 加 --no-source |
| 「合计行也要留着」 | 加 --keep-total |
| 「序号乱了」 | 加 --renumber |
| 「按部门拆开,分别发给各部门」 | split 文件 --by 部门 --preview 给用户看 → 点头后去掉 --preview 正式拆 |
| 「拆成一个文件里的多个 sheet」 | 加 --to sheets |
| 「每 500 行拆一个文件」 | split 文件 --rows 500 |
| 「文件名前面加上『9月工资_』」 | 加 --prefix 9月工资_ |
| 「表头认错了」「标题有两行」 | 问清表头在第几行,加 --header-row N |
一步一步教用户(截图式说明)
- 把文件夹位置告诉我:在文件夹上按住键盘 Shift 键,再点鼠标右键 → 选「复制为路径」→ 粘贴到对话框里发给我。
- .xls 读不了时:双击用 Excel 打开 → 点左上角「文件」→「另存为」→ 下面「保存类型」选「Excel 工作簿(*.xlsx)」→ 保存,再把新文件给我。WPS 也一样:左上角「文件」→「另存为」→ 选 .xlsx。
- 结果文件打不开 / 提示被占用:先把 Excel 里打开着的同名文件关掉,再让我重新生成一次。
- 找到结果:合并结果默认放在文件夹旁边,名字是「文件夹名_合并.xlsx」;拆分结果是原文件旁边的「原文件名_按部门拆分」文件夹。
结果里有什么
- 合并结果页:第一行是表头(灰底加粗,冻结、可筛选);来源列浅蓝;不是每个表都有的列表头标橙色、带批注写明几个表有;日期保持日期格式,原表的数字格式(千分位、百分比)照搬;CSV 里 0 开头的工号、11 位以上的手机号身份证号保持原样不变形。
- 合并说明页:每个表的表头行、跳过的标题行、取了多少行、跳过的合计行和备注行(行号+内容)、中间空行、数字存成文本的列、补齐的合并单元格;列名对照表(每个表里原来叫什么);名字相像没对齐的列;没合并的文件和原因;去重删掉了哪几行、和哪一行重复。
- 拆分结果:每份都带原表的标题行、表头格式、列宽、单元格格式;部门那列如果是竖着合并的单元格,会把值补到每一行再拆;空白值归到「(空白)」;原表的合计行不拆进去(合计是整张表的,拆开后不对)。
需要的组件
- 必须:Python 3.8+、openpyxl(读写 Excel)。缺了脚本会提示
pip install openpyxl。 - 可选:xlrd(读老版本 .xls)。没装就提示用户把 .xls 另存为 .xlsx,不影响其他文件。
不做什么
- 不修改、不覆盖、不删除、不移动用户的原文件;不在原表里加 sheet。
- 不联网、不上传,不调用任何在线服务,不运行其他程序。
- 不自动安装任何组件。
- 不做左右拼接(按某列把两个表的信息对到一行,类似查找匹配);不做按类别求和的汇总统计。
- 不破解有密码的文件;不读 WPS 的 .et 格式(请另存为 .xlsx)。
- 两行表头、表头里有合并单元格的,只用一行当列名,会提醒用户先整理成一行表头。