本月销售表.xlsx 和 财务入账表.xlsx。 任务很明确:找出金额不一致的订单,或者找出只在一边出现的“幽灵订单”。如果是几百行数据,Excel 的 VLOOKUP 或 条件格式 还能应付。但当数据量达到 1 万行、5 万行甚至更多时:

而采用Python核对数据的本质,其实是集合运算,主要分为三个步骤:
整个过程,Python 通常只需 2-3 秒。
下面是完整代码
import pandas as pdimport osdef compare_excel_files(file1, file2, key_col, value_col, output_file='差异报告.xlsx'):"""自动核对两个 Excel 文件的差异:param file1: 第一个文件路径 (例如:销售表.xlsx):param file2: 第二个文件路径 (例如:财务表.xlsx):param key_col: 用于匹配的唯一键列名 (例如:订单号):param value_col: 需要核对数值的列名 (例如:金额):param output_file: 结果输出文件名"""print(f"🚀 正在读取 {file1} ...")df1 = pd.read_excel(file1)print(f"🚀 正在读取 {file2} ...")df2 = pd.read_excel(file2)# 1. 数据清洗:去除首尾空格,防止因空格导致匹配失败df1[key_col] = df1[key_col].astype(str).str.strip()df2[key_col] = df2[key_col].astype(str).str.strip()# 2. 合并数据:使用外连接 (outer join),确保两边的数据都在# indicator=True 会生成一列 '_merge',标记数据来源merged_df = pd.merge(df1[[key_col, value_col]],df2[[key_col, value_col]],on=key_col,how='outer',indicator=True,suffixes=('_表 1', '_表 2'))# 3. 定义差异逻辑results = []for index, row in merged_df.iterrows():status = "正常"diff_value = 0# 情况 A: 只在表 1 存在 (表 2 缺失)if row['_merge'] == 'left_only':status = "❌ 仅在表 1 存在"diff_value = row[f'{value_col}_表 1']# 情况 B: 只在表 2 存在 (表 1 缺失)elif row['_merge'] == 'right_only':status = "❌ 仅在表 2 存在"diff_value = -row[f'{value_col}_表 2'] # 负数表示表 2 多出来了# 情况 C: 两边都有,但数值不一致else:val1 = row[f'{value_col}_表 1']val2 = row[f'{value_col}_表 2']# 处理可能的非数字情况,并保留 2 位小数比较try:if abs(float(val1) - float(val2)) > 0.01: # 允许 1 分钱误差status = "⚠️ 金额不一致"diff_value = float(val1) - float(val2)else:status = "✅ 一致"except ValueError:status = "⚠️ 数据格式错误"if status != "✅ 一致":results.append({key_col: row[key_col],'状态': status,f'{value_col}_表 1': row.get(f'{value_col}_表 1', '无'),f'{value_col}_表 2': row.get(f'{value_col}_表 2', '无'),'差异值': diff_value})# 4. 输出结果if not results:print("🎉 恭喜!两张表数据完全一致,没有发现差异。")returnresult_df = pd.DataFrame(results)# 按照差异类型排序,让严重问题排在前面result_df = result_df.sort_values(by='状态')result_df.to_excel(output_file, index=False)print(f"✅ 核对完成!共发现 {len(result_df)} 处差异。")print(f"📄 详细报告已保存至:{os.path.abspath(output_file)}")# ================= 配置区域 (请在此处修改) =================if __name__ == "__main__":# 请将以下文件名替换为你实际的文件名# 确保这两个文件在当前脚本同一目录下,或者填写绝对路径file_sales = '本月销售表.xlsx'file_finance = '财务入账表.xlsx'# 指定哪一列是订单号,哪一列是要对比的金额KEY_COLUMN = '订单号'VALUE_COLUMN = '实付金额'# 检查文件是否存在,避免报错if os.path.exists(file_sales) and os.path.exists(file_finance):compare_excel_files(file_sales, file_finance, KEY_COLUMN, VALUE_COLUMN)else:print("❌ 错误:找不到指定的 Excel 文件,请检查文件名或路径。")
这段代码之所以比 Excel 公式更稳健,主要得益于以下几点设计:
.str.strip() 自动消除了这个隐患。pd.to_numeric(..., errors='coerce') 强制转换,避免类型不匹配导致的报错。pd.merge(how='outer') 一次性把三种情况(左独有、右独有、共有)全部拉平,逻辑无死角。for 循环去一行行遍历(那是 Python 的弱点),这里利用了 pandas 的 merge 函数,类似于数据库的 SQL 连接操作,底层由 C 语言优化,处理百万行数据也是秒级响应。
实际使用时只要按照下面步骤操作就可以了(看上去步骤很多,但实际操作起来通常不会超过5分钟)
自动对账工具。check_diff.py(注意后缀名必须是 .py,不能是 .txt)。.py 文件也放入 自动对账工具 文件夹中。# 修改前file_sales = '本月销售表.xlsx'file_finance = '财务入账表.xlsx'# 修改后 (假设你的文件叫 data_a.xlsx 和 data_b.xlsx)file_sales = 'data_a.xlsx'file_finance = 'data_b.xlsx'
打开你的 Excel 表,看一眼表头第一行的文字是什么,必须完全一致(包括空格)。找到这两行(98/99行)进行修改:
# 修改前KEY_COLUMN = '订单号'VALUE_COLUMN = '实付金额'# 修改后 (假设你的表头分别是 "Order_ID" 和 "Total_Price")KEY_COLUMN = 'Order_ID'VALUE_COLUMN = 'Total_Price'
⚠️ 注意:如果 Excel 表头是 订单号(带空格),而代码写的是 订单号,程序会报错或匹配失败。建议先在 Excel 里把表头空格删干净。
差异报告.xlsx 。python check_diff.py合集 | 文章 |
|---|---|