十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python处理Excel从入门到实战:读取、匹配与批量合并

Python处理Excel从入门到实战:读取、匹配与批量合并 这次我们再回到一个很常见的需求用 Python 处理 Excel 表格。很多做办公自动化的人一开始想到的都是 Excel 自带的 VBA 宏。VBA 在单文件、单表格里确实够用但一旦遇到“几十个 Excel 要合并”“每天从系统导出报表后清洗一遍”“要把某个表格里的字段匹配到另一张表”这类任务VBA 的开发和维护成本都会明显上升。Python 的优势在于不用在 Excel 界面里操作一个脚本可以反复执行也能和其他系统、数据库、定时任务直接对接。本文就是一篇面向入门者的 Excel 表格处理基础教程适合刚接触 Python 办公自动化的读者也适合想从 VBA 切到 Python 的办公人员。本次基础篇会演示几个非常高频的操作读取工作表、写入新工作簿、设置单元格样式、把空白单元格自动填充上一行内容、按关键字匹配两张表的数据、批量合并多个 xlsx 文件、按条件拆分数据以及根据 Excel 清单批量重命名 Word 文件。这些场景基本覆盖了日常办公里“反复手工复制粘贴”的典型痛点。环境方面这个主题没有 GPU、显存之类的门槛普通办公电脑能安装 Python 就能运行主要消耗的是 CPU 和内存。下面直接进入正题。1. Python 操作 Excel 的核心能力速览先把整体能力和技术选型表格放在前面方便快速判断自己应该学哪种写法。项目说明操作对象Excel 工作簿、工作表、单元格、区域、图表、公式常见文件格式.xlsx新版 Excel、.xls旧版需额外处理推荐技术方案openpyxl、pandas、xlsxwriter运行环境Python 3.8 及以上版本均可推荐 3.10硬件要求无需 GPU普通 CPU 8GB 内存可满足大部分场景主要使用方式命令行运行脚本、PyCharm / VS Code 运行、定时任务调用是否支持批量任务支持循环读取多个文件并输出即可是否提供接口 API基础操作不涉及可封装成函数供 Web 服务或定时脚本调用适合场景表格合并拆分、数据匹配、格式整理、批量生成报表、重复性办公操作学习难度低掌握读取、遍历、写入三步即可开始不同第三方库的侧重点也不同。建议初学者优先掌握 openpyxl 和 pandas 两套方案方案读取 .xlsx写入 .xlsx批量处理数据分析适用场景openpyxl支持支持支持一般单元格级操作、格式设置、公式写入pandas支持支持很好很强数据清洗、统计、合并、匹配xlsxwriter不支持读取支持支持一般只写不读、生成带图表的报表xlrd只读 .xls不支持一般一般处理旧版 .xls 文件2. 适用场景与使用边界2.1 这个工具适合谁Python 处理 Excel 的典型用户有三类。第一类是运营、人事、财务岗位的办公人员他们经常需要处理系统导出的报表希望减少重复劳动。第二类是 Python 开发者和自动化运维人员他们需要把表格数据接入到脚本或业务系统里。第三类是数据相关岗位例如数据分析师他们需要快速做数据合并、筛选、统计和导出。从熟练度来看只要掌握了“用 Python 读取一个 xlsx 文件、循环每一行、把结果写入新文件”这三步就已经能解决很多基础表格需求。这也是后续做数据清洗、图表自动化、日报自动生成、批量文件重命名等复杂任务的前置条件。2.2 不适合什么场景不过也要说清楚边界。如果只是临时查看一个表格直接打开 Excel 处理反而更快没必要用脚本。如果需要生成带大量复杂交互功能的工作簿例如用户需要在 Excel 里点击按钮做联动、切换视图、执行宏Python 写完后仍然要保留用户交互那么要考虑是否应该用 VBA 或者 Office 插件方案。另外如果文件是非常老旧的 .xls 格式openpyxl 无法直接处理需要先转换格式或改用其他依赖库。2.3 数据安全与合规边界办公自动化处理的大多是工作数据可能有客户名单、工资、合同金额等敏感信息。使用脚本时要注意不要随便把包含个人身份信息或商业机密的表格上传到在线转换工具。本地脚本处理时原始文件先备份输出结果单独放目录。如果涉及他人个人信息应遵守公司数据管理制度和相关法律法规。批量处理前先检查文件来源防止带宏病毒或异常数据的文件进入流程。如果脚本要共享给同事注意隐藏敏感信息路径和内部数据。3. 环境准备与前置条件3.1 检查 Python 环境在开始写 Excel 脚本前先确认电脑上已经安装 Python。打开命令提示符Windows或终端macOS / Linux执行python --version如果显示Python 3.x.x说明环境可用。如果提示找不到命令需要先安装 Python。安装时记得勾选“Add Python to PATH”这样后续在命令行里执行pip install会更省事。建议使用 Python 3.10 及以上版本。Python 3.8 也能运行本教程的代码但新版在性能、依赖兼容性上更好。3.2 安装第三方依赖库本文需要用到 openpyxl 和 pandas。pandas 读取 Excel 时底层依赖 openpyxl所以两个库都要安装pip install openpyxl pandas如果网络较慢可以指定使用国内镜像源pip install openpyxl pandas -i https://pypi.tuna.tsinghua.edu.cn/simple安装后可以在 Python 里写一行代码确认import openpyxl import pandas print(openpyxl 版本:, openpyxl.__version__) print(pandas 版本:, pandas.__version__)能正常打印版本号说明依赖安装完成。如果提示ModuleNotFoundError说明对应库没有安装成功需要回到上一步重新安装。3.3 确认 Excel 文件格式需要注意 .xlsx 和 .xls 的区别。..xlsx 是 Excel 2007 之后的标准格式openpyxl 和 pandas 都能直接读取。.xls 是 Excel 97-2003 的旧格式openpyxl 不支持pandas 需要额外依赖 xlrd。对于旧 .xls 文件最简单的处理方式是用 Excel 打开后另存为 .xlsx或者在代码里用 pandas 指定引擎读取。基础篇里统一以 .xlsx 为例。3.4 准备测试目录为了不把原始数据和脚本混在一起建议新建一个测试目录例如excel-demo/ ├── 原始数据/ │ ├── 销售_1.xlsx │ └── 销售_2.xlsx ├── 输出结果/ └── 脚本/ ├── 01_读取表格.py └── 02_合并文件.py目录可以按自己习惯调整但建议保持三块分离原始数据不动输出结果单独放置脚本统一管理。这样做的好处是批量处理时不会因为脚本输出文件覆盖原始文件而造成数据丢失。4. 快速上手读取 Excel 与写入新表4.1 用 openpyxl 读取单元格先准备一个测试文件演示表格.xlsx内容为人员名单。然后用 openpyxl 读取第一个工作表和指定单元格from openpyxl import load_workbook # 读取工作簿 wb load_workbook(原始数据/演示表格.xlsx) # 获取当前活动的工作表 ws wb.active print(工作表名称:, ws.title) print(A1 单元格内容:, ws[A1].value) print(B2 单元格内容:, ws[B2].value)运行后可以看到工作表名称和单元格内容。这里load_workbook是读取工作簿的入口函数参数支持文件路径。路径里带中文一般没有问题但不建议把文件放在名称有特殊符号的目录下。4.2 遍历工作表中的所有数据实际办公中通常不是只看一个单元格而是要遍历所有行。用iter_rows可以按行返回数据from openpyxl import load_workbook wb load_workbook(原始数据/演示表格.xlsx) ws wb.active for row in ws.iter_rows(min_row1, max_rowws.max_row, max_colws.max_column, values_onlyTrue): print(row)values_onlyTrue表示返回单元格的值而不是单元格对象。这样每行会得到一个元组例如(张三, 研发部, 12000)。后续要做汇总、筛选可以先把这个元组转成列表再按需求处理。4.3 用 pandas 读取表格并进行统计如果只是读取数据openpyxl 完全够用。但要做数据统计和匹配pandas 的 DataFrame 会方便很多import pandas as pd df pd.read_excel(原始数据/销售明细.xlsx, sheet_name1月) print(df.head()) print(总行数:, len(df)) print(列名:, list(df.columns)) print(销售额合计:, df[销售额].sum())这里sheet_name可以传工作表名称也可以传索引例如sheet_name0表示第一个工作表。head()默认显示前 5 行用于快速确认数据是否读取正确。如果读取 .xlsx 文件时遇到Excel file format cannot be determined或Missing optional dependency openpyxl这类错误通常是因为文件格式不一致或者电脑里没有安装 openpyxl。解决办法是先把文件另存为标准 .xlsx 格式再确认安装了 openpyxl。4.4 写入新的 Excel 文件写入一个基本的工作簿非常简单from openpyxl import Workbook wb Workbook() ws wb.active ws.title 员工工资 ws.append([姓名, 部门, 工资]) ws.append([张三, 研发部, 12000]) ws.append([李四, 市场部, 10000]) ws.append([王五, 财务部, 11000]) wb.save(输出结果/工资表.xlsx) print(文件已生成)append会把一行数据追加到工作表末尾。第一次写入时表头会放在第 1 行随后每调用一次append就新增一行。保存后可以用 Excel 打开输出结果/工资表.xlsx检查内容。4.5 设置表头样式如果希望输出文件更接近正式报表可以给表头设置加粗、背景色和居中from openpyxl import Workbook from openpyxl.styles import Font, Alignment, PatternFill wb Workbook() ws wb.active ws.title 员工工资 headers [姓名, 部门, 工资] rows [ [张三, 研发部, 12000], [李四, 市场部, 10000], ] ws.append(headers) header_fill PatternFill(solid, fgColor4472C4) header_font Font(boldTrue, colorFFFFFF) center_alignment Alignment(horizontalcenter, verticalcenter) for cell in ws[1]: cell.fill header_fill cell.font header_font cell.alignment center_alignment for row in rows: ws.append(row) wb.save(输出结果/员工工资_带样式.xlsx)代码里先写入表头再对第 1 行的每个单元格设置填充色和字体然后写入数据。这类样式操作是 openpyxl 的强项后续要加边框、列宽、单元格合并等也都围绕cell对象展开。4.6 写入公式openpyxl 支持在单元格里写 Excel 公式比如计算两列相乘from openpyxl import Workbook wb Workbook() ws wb.active ws[A1] 数量 ws[A1] 10 ws[B1] 20 ws[C1] A1*B1 wb.save(输出结果/带公式.xlsx)需要注意openpyxl 只负责写入公式并不会自己计算结果显示值。用 Excel 打开文件后Excel 会重新计算并显示结果。如果脚本立刻用data_onlyTrue读取 C1得到的可能是None因为文件还没有被 Excel 打开计算过。这是 openpyxl 的一个常见特点后面读取公式单元格值时要特别注意。5. 基础功能案例覆盖办公中最高频的 6 类操作这一部分从常见搜索需求里梳理出 6 个高频案例。每个案例都按“目标、输入、代码、结果判断”来组织可以直接复制改路径使用。5.1 让空白单元格自动填充上一行内容这是一个非常常见的场景原始表里为了可读性同一组的部门名称只在第一行填写后续行都是空值。做统计时这些空单元格会导致筛选和透视出错所以需要把空值补成上一行同列的内容。假设原始表结构如下姓名部门工资张三研发部12000李四10000王五11000赵六市场部9000孙七8500可以看到部门列出现了合并单元格式的纵向省略。目标是从第 2 行开始扫描遇到空值就补上“最近一次非空值”from openpyxl import load_workbook wb load_workbook(原始数据/人员表.xlsx) ws wb.active # 从第2行开始因为第1行通常是表头 for col in range(1, ws.max_column 1): last_value None for row_index in range(2, ws.max_row 1): cell ws.cell(rowrow_index, columncol) value cell.value if value is None or str(value).strip() : # 当前单元格为空用上一行同列的最近非空值填充 if last_value is not None: cell.value last_value else: last_value value wb.save(输出结果/人员表_已填充.xlsx) print(填充完成)运行前记得备份原始文件因为这个脚本会覆盖保存到新路径虽然不会改动原始数据但错误的填充逻辑可能会覆盖有效值。判断成功的标准是输出结果/人员表_已填充.xlsx中所有空部门都被填上了内容。5.2 将多列内容合并到一起并添加符号间隔第二个高频需求是把“省份”“城市”“地区”等多列合成一列中间用横线、逗号或竖线分隔。例如把“北京-研发部-张三”这种格式拼出来。用 pandas 最简单import pandas as pd df pd.read_excel(原始数据/人员表.xlsx) # 处理空值避免出现字符串 nan df df.fillna() df[完整信息] df[城市].astype(str) - df[部门].astype(str) - df[姓名].astype(str) df.to_excel(输出结果/人员表_合并列.xlsx, indexFalse)这里的核心逻辑是通过拼接字符串。如果列里有数字例如工号 1001直接用astype(str)能避免数字和字符串拼接报错。分隔符可以根据需求改成、、,、|等。如果你习惯用 openpyxl也可以逐行拼接已有单元格内容后写入新列from openpyxl import load_workbook wb load_workbook(原始数据/人员表.xlsx) ws wb.active # 假设 G 列是新列 ws[G1] 完整信息 for row_index in range(2, ws.max_row 1): city ws.cell(rowrow_index, column4).value or department ws.cell(rowrow_index, column2).value or name ws.cell(rowrow_index, column1).value or ws.cell(rowrow_index, column7).value f{city}-{department}-{name} wb.save(输出结果/人员表_合并列_openpyxl.xlsx)5.3 两张表按关键字匹配数据类似 VLOOKUP很多办公人员习惯用 VLOOKUP 函数在一张表里匹配另一张表的数据。Python 里对应操作是 pandas 的merge。场景工资表里有员工工号但没有部门信息员工基础表里有工号和部门。目标是把部门匹配到工资表上。import pandas as pd salary_df pd.read_excel(原始数据/工资表.xlsx) base_df pd.read_excel(原始数据/员工基础表.xlsx) # 只保留需要匹配的列 base_subset base_df[[工号, 部门]] # 以工资表为主表按工号匹配 result_df salary_df.merge(base_subset, on工号, howleft) result_df.to_excel(输出结果/工资表_补部门.xlsx, indexFalse) print(匹配完成共, len(result_df), 行)参数说明on工号表示两边共用同一列名。howleft表示保留左边表全部行右边匹配不到的数据用 NaN 填充。如果两张表中关键字段名不一样例如一边叫工号另一边叫员工编号可以改用left_on工号, right_on员工编号。判断成功的标准是查一下输出文件中原来为空或缺失的部门列是否被正确填充。如果有多条记录匹配上数据量可能会变多需要先检查原表是否有一对多关系。5.4 批量合并多个 Excel 文件这个场景在财务、运营汇总时非常常见比如一个文件夹下有多个月份报表想把它们合并成一个总表。import pandas as pd from pathlib import Path folder Path(原始数据/销售数据) output_path 输出结果/销售合并.xlsx frames [] for file in folder.glob(*.xlsx): # 防止读取到已经生成的输出文件 if file.name output_path: continue print(正在读取:, file.name) df pd.read_excel(file) frames.append(df) if frames: merged_df pd.concat(frames, ignore_indexTrue) merged_df.to_excel(output_path, indexFalse) print(合并完成总行数:, len(merged_df)) else: print(没有找到可合并的 Excel 文件)使用glob(*.xlsx)会遍历文件夹下所有 xlsx 文件。ignore_indexTrue的作用是让合并后的行索引重新从 0 开始避免多张表索引重复。如果每张表表头一致这个脚本可以直接使用。需要注意如果文件夹里包含格式不一致的文件例如有的表多一列有的表少一列合并后可能会出现大量空值。建议先打印各文件的列名做一次检查。5.5 按条件把数据拆分到多个文件批量合并的逆操作是按某个字段拆分。比如一个总表包含了三个区域的订单现在要按区域生成三个独立文件import pandas as pd df pd.read_excel(原始数据/订单表.xlsx) output_dir 输出结果/按区域拆分 import os os.makedirs(output_dir, exist_okTrue) for region, group in df.groupby(区域): # 简单清理文件名避免特殊字符导致保存失败 safe_name str(region).replace(/, -).replace(\\, -) file_path os.path.join(output_dir, f订单_{safe_name}.xlsx) group.to_excel(file_path, indexFalse) print(已生成:, file_path)写文件之前先创建输出目录避免因为目录不存在而报错。分组键里的值如果包含\、/、:等 Windows 不支持的符号需要提前替换掉否则保存时会抛异常。5.6 根据 Excel 清单批量重命名 Word 文件这个需求经常出现在文档管理场景Excel 里维护着“原文件名”和“新文件名”两列文件夹里有大量 Word 文档需要按清单统一改名。先安装 python-docx 之外的库实际上这个需求本身不需要解析 Word 内容只需要操作文件名因此不需要 python-docx。但后续如果还需要修改 Word 内部内容那才需要安装 python-docx。下面用 pandas 读取 Excel 清单后用os.rename或Path.rename完成操作import pandas as pd from pathlib import Path df pd.read_excel(原始数据/重命名清单.xlsx) folder Path(原始数据/Word文档) for _, row in df.iterrows(): old_name str(row[原文件名]) .docx new_name str(row[新文件名]) .docx old_path folder / old_name new_path folder / new_name if old_path.exists() and not new_path.exists(): old_path.rename(new_path) print(已将, old_name, 重命名为, new_name) elif not old_path.exists(): print(未找到文件:, old_name) else: print(目标文件已存在跳过:, new_name)这里故意加了一步判断防止目标文件已存在时直接覆盖他人文件。批量重命名属于不可逆操作如果没有提前备份改错后恢复成本很高。最稳妥的做法是先把旧文件名和新文件名都打印出来确认无误后再真正执行。6. 批量化与自动化封装到这里我们已经跑通了多个独立场景。实际办公里这些操作往往不是只跑一次而是每天、每周重复执行。因此要把脚本封装成函数并预留批量入口。6.1 把核心流程封装成函数以批量合并为例封装后的函数应该接收“输入目录”和“输出文件路径”两个参数import pandas as pd from pathlib import Path def merge_excel_files(input_dir: str, output_path: str, pattern: str *.xlsx): frames [] for file in Path(input_dir).glob(pattern): if Path(output_path).name file.name: continue df pd.read_excel(file) frames.append(df) if not frames: print(没有需要合并的文件) return False merged_df pd.concat(frames, ignore_indexTrue) merged_df.to_excel(output_path, indexFalse) print(f合并完成输出文件: {output_path}) return True if __name__ __main__: merge_excel_files(原始数据/销售数据, 输出结果/销售合并.xlsx)这样写的好处是以后在其他项目里只需要import merge_excel_files就能复用脚本文件直接运行时也能完成一次合并任务。6.2 用目录任务批处理多个输入输出如果每天要向几个固定目录输出结果可以再封装一个最简单的“任务字典”import os if __name__ __main__: tasks [ {input_dir: 原始数据/销售A, output: 输出结果/销售A_合并.xlsx}, {input_dir: 原始数据/销售B, output: 输出结果/销售B_合并.xlsx}, ] for task in tasks: success merge_excel_files(task[input_dir], task[output]) if not success: print(任务失败请检查目录:, task[input_dir])这个模式已经接近批量化。后续如果要支持更多任务类型可以把任务配置抽到一个 JSON 文件里脚本启动时读取配置再循环执行。6.3 加入日志与失败重试批量处理最怕脚本跑到一半因为某个文件格式异常而中断。简单处理方式是记录成功和失败的文件名import pandas as pd from pathlib import Path import logging logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s) folder Path(原始数据/销售数据) output_path 输出结果/销售合并.xlsx success_list [] fail_list [] frames [] for file in folder.glob(*.xlsx): if file.name Path(output_path).name: continue try: df pd.read_excel(file) frames.append(df) success_list.append(file.name) logging.info(f成功读取: {file.name}) except Exception as e: fail_list.append(file.name) logging.error(f读取失败: {file.name}原因: {e}) if frames: merged_df pd.concat(frames, ignore_indexTrue) merged_df.to_excel(output_path, indexFalse) logging.info(f成功: {len(success_list)} 个文件失败: {len(fail_list)} 个文件) if fail_list: logging.warning(f失败文件列表: {fail_list})加了try-except后单个文件出错不会导致整个脚本崩溃日志里会记录具体失败原因和文件信息。这也是工程化脚本和一次性脚本的一个重要区别。6.4 后续接 API 或定时任务的思路这个基础主题本身不涉及模型服务或复杂的 Web API但在实际办公自动化落地时脚本能力很容易被二次封装。两个常见方向把函数暴露给 FastAPI 接口让前端页面或业务系统上传 Excel后端处理后返回结果文件。用系统自带的任务计划程序每天定时执行脚本例如每天早上 8 点自动读取指定目录文件处理后输出到共享目录。从基础脚本到 API 服务或定时任务本质是一样的先保证核心处理函数稳定再在外部包装触发入口。建议不要把所有操作都写在一个巨大的脚本里而是拆成“读取、清洗、合并、导出”几个模块后续接任何触发方式都会更轻松。7. 资源占用与性能观察7.1 Excel 处理对硬件的需求Excel 自动化不是模型推理任务不需要 GPU也不存在显存占用问题。主要关注的是CPU脚本在读取、遍历、拼接数据时消耗 CPU。内存openpyxl 和 pandas 都会把数据加载到内存中。文件越大内存占用越明显。磁盘输出文件需要足够空间批量处理时注意不要把大量文件写到系统盘。对普通办公场景几千到几万行数据、几十个文件以内的批量任务一般办公电脑都能流畅处理。对于几十万行以上或上百MB 级别的超大文件需要小心内存占用可能需要改用逐行读取或数据库方案。7.2 怎么观察脚本资源占用可以在脚本运行时打开操作系统的任务管理器找到对应的python进程。要更精确地记录可以使用 psutilpip install psutil然后在处理过程中打印当前进程内存import psutil import os def print_memory_usage(): process psutil.Process(os.getpid()) memory_mb process.memory_info().rss / 1024 / 1024 print(f当前内存占用: {memory_mb:.1f} MB)这个数字会随数据读取量变化。如果你发现批处理跑到一半内存快速上涨说明代码可能把多个大文件同时保留在内存里了需要调整处理策略。7.3 大文件处理优化使用 openpyxl 只读模式openpyxl 在读取大型文件时可以通过read_onlyTrue进入只读模式逐行读取而不是一次性加载整个工作表from openpyxl import load_workbook wb load_workbook(原始数据/超大文件.xlsx, read_onlyTrue) ws wb.active for row in ws.iter_rows(values_onlyTrue): # 逐行处理 print(row) wb.close()只读模式适合快速遍历数据但会牺牲部分单元格对象能力。如果你只是做求和、统计、内容拼接这种模式非常合适。7.4 pandas 读取大文件时的注意事项pandas 没有直接的“流式读取 Excel”模式它是把整个文件的解析结果载入内存。面对超大文件可以通过参数降低开销import pandas as pd df pd.read_excel( 原始数据/超大文件.xlsx, usecols[姓名, 部门, 工资], # 只读取需要的列 dtype{工号: str}, # 指定列类型避免数字误读 )usecols可以明显减少内存占用如果只需要某几列做匹配建议只保留必要列。dtype可以避免工号、身份证号等长数字变成浮点或科学计数法。7.5 批量任务如何降低出问题概率批量处理时建议做到“读一个文件、处理一个文件、释放一个文件”不要让所有 DataFrame 都累计在一个变量里。比如需要把多个文件中的某几列汇总到一张新表可以每读取一个文件就计算一次结果最后只保存汇总值。另一个策略是控制同时读取的文件数量。如果实在需要并行处理也要考虑 CPU 核数和文件大小直接开 100 个线程去读 Excel 并不一定能提速反而容易把内存占满。8. 常见问题与排查方法问题现象可能原因排查方式解决方案导入 openpyxl 时报 ModuleNotFoundError依赖库没有安装执行pip list查看包列表运行pip install openpyxlpandas 读取 xlsx 报 Missing optional dependency openpyxl缺少读取 Excel 的引擎按报错提示安装依赖运行pip install openpyxl提示 PermissionErrorExcel 文件正被 WPS 或 Excel 打开关闭文件窗口检查是否有进程占用释放文件后重新执行或把输出路径改为新文件openpyxl 无法打开 .xls 文件格式是旧版 Excel查看文件后缀是否真的是 .xls用 Excel 另存为 .xlsx文件显示“外部表不是预期的格式”文件后缀与实际格式不一致或文件损坏用 Excel 打开后另存新 xlsx确认文件是标准 xlsx 格式用 data_onlyTrue 读取公式单元格返回 Noneopenpyxl 不自己计算公式结果判断文件是否曾被 Excel 打开保存过写入公式后用 Excel 打开一次或让生成端使用计算后的缓存值读出的数字变成科学计数法单元格存为文本或 pandas 自动推断类型打印 dtypes 检查类型读取时指定 dtype 或转成字符串中文路径导致读不到文件系统编码或路径写法问题打印绝对路径确认是否存在使用 pathlib.Path 拼接路径避免直接用\\手写路径输出文件名覆盖原始文件脚本保存路径设置错误检查save()和to_excel()路径输出单独放 output 目录避免和输入目录相同批量合并后数据条数翻倍两张表存在一对多关系或重复读取了输出文件打印 文件列表检查是否有重复来源排除输出文件匹配前先 remove 重复项这里特别强调“外部表不是预期的格式”。这个报错不只出现在 Python 中很多办公软件在连接 Excel 时也可能出现。最常见原因是文件扩展名是 .xlsx但实际内容是 CSV 或旧格式文本或者文件是从某个系统直接导出、头信息不完整。解决思路不是强行让 Python 读取而是先打开文件确认格式另存为规范 .xlsx 后重试。9. 最佳实践与使用建议9.1 原始数据永远备份处理 Excel 前先复制一份原始文件。批量重命名、批量覆盖、按条件拆分这类操作一旦跑错结果文件很难手工恢复。最简单的方法是建立输入目录后只做读操作所有结果写到输出结果/目录。这样即使脚本写得有问题原始文件也不会被破坏。9.2 第一次用少量数据验证不要一上来就跑整个文件夹。先用一个只有几行数据的小文件测试确认读取字段、输出格式、保存逻辑都正确后再扩大到全量数据。全量运行前可以打印文件数量、总行数、列名等统计信息防止读错文件或表头不一致。9.3 路径统一管理脚本里的文件路径尽量避免散落在代码各处。更稳妥的方式是在脚本开头定义INPUT_DIR 原始数据 OUTPUT_DIR 输出结果然后用Path(INPUT_DIR) / 销售数据拼接。这样目录变动时只需要改顶部配置不用到处查找。9.4 定期任务要考虑目录是否存在如果脚本要交给任务计划程序每天运行输出目录很可能在某天被清理掉。创建目录时使用os.makedirs(output_dir, exist_okTrue)避免目录不存在时报错。运行日志也不要只输出到控制台建议写入日志文件方便排查“别人反馈脚本没跑”的问题。9.5 加密和只读工作簿的坑如果需要处理带打开密码的 Excel 文件openpyxl 默认不支持解密读取。最简单的方式是先用 Excel 手动解密另存为无密码文件或使用 office 自动化相关模块。只读或共享工作簿也可能出现权限限制建议测试文件使用普通工作簿。9.6 涉及关键业务数据时必须做校验办公自动化脚本的常见风险是代码“能跑”但结果错。批量合并后需要核对总行数是否等于各文件行数之和匹配后需要检查关键列空值数量是否合理拆分后需要查看各组行数之和是否等于原表总行数。这些校验逻辑可以以简单的assert或日志方式放在脚本末尾第一时间发现数据异常。9.7 敏感数据脱敏测试脚本时不要直接使用真实客户名单、工资全表。建议造一批“张三”“李四”或带随机编号的测试数据。如果一定要处理真实数据输出文件不要带上手机号、身份证号等原始信息只保留业务需要的字段。脚本本身也不要提交到公共代码仓库。10. 总结与下一步这一篇重点不是讲复杂算法而是把 Python 处理 Excel 的完整链路走通环境安装、依赖准备、读取、写入、填充、合并、匹配、拆分、批量重命名再到批量化封装和问题排查。对刚接触办公自动化的读者只要能把 5.4 的批量合并、5.3 的数据匹配两个案例跑通就已经具备处理常见表格任务的脚本能力。接下来比较容易踩的坑集中在三类一是旧版 .xls 与 .xlsx 格式转换二是文件被 Excel 占用导致无法写入三是批量输出时路径和文件名不规范。在写任何全量脚本之前先给这三个点打补丁能省下大量调试时间。如果再往下走建议按这个顺序进阶先掌握 pandas 的groupby和merge这是数据匹配和汇总的核心然后学习把清洗结果自动生成图表最后把脚本接入目录监听或定时任务让数据在每天早上自动完成更新。第一个可以练习的自动化项目可以试试“每天合并当天新增的三个报表并生成一份汇总 Excel”这几乎覆盖了办公自动化的全部基础套路。
返回列表