当前位置:首页>python>Python与办公自动化--核对两张万行数据表的差异

Python与办公自动化--核对两张万行数据表的差异

  • 2026-09-10 12:21:38
Python与办公自动化--核对两张万行数据表的差异
Python 作为“自动化胶水语言”,非常适合用来处理重复性高、规则明确、数据量大的工作,在涉及大量excel、word等操作的办公流程中效果还挺不错的。
今天我们看一个核对两张万行数据表差异的问题。以财务中的常见场景为例,给定本月销售表.xlsx 和 财务入账表.xlsx。 任务很明确:找出金额不一致的订单,或者找出只在一边出现的“幽灵订单”。

如果是几百行数据,Excel 的 VLOOKUP 或 条件格式 还能应付。但当数据量达到 1 万行、5 万行甚至更多时:

  • Excel 公式计算缓慢,每改一个单元格都要转圈半天;
  • 内存占用飙升,随时可能“未响应”;
  • 人工比对容易漏看,非常容易出错。

而采用Python核对数据的本质,其实是集合运算,主要分为三个步骤:

  1. 对齐(Merge):以“订单号”为唯一键,将两张表像拼图一样拼在一起。
  2. 标记(Indicator):让程序自动标记每一行数据是“两边都有”、“只在左表”还是“只在右表”。
  3. 筛选(Filter):提取出状态异常(缺失或金额不符)的行,生成报告。

整个过程,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("🎉 恭喜!两张表数据完全一致,没有发现差异。")        return    result_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 公式更稳健,主要得益于以下几点设计:

  1. 容错性强:
    • 空格陷阱:很多时候“订单 123"和“订单 123 "(带空格)在 Excel 里看起来一样,但 VLOOKUP 会匹配失败。代码中的 .str.strip() 自动消除了这个隐患。
    • 格式混乱:有些单元格里可能是文本型的数字,代码通过 pd.to_numeric(..., errors='coerce') 强制转换,避免类型不匹配导致的报错。
  2. 逻辑清晰的外连接(Outer Join): 传统的 VLOOKUP 只能查“左边有、右边有没有”,很难反向查“右边有、左边没有”。pd.merge(how='outer') 一次性把三种情况(左独有、右独有、共有)全部拉平,逻辑无死角。
  3. 直观的报告输出: 生成的 Excel 不再是原始数据堆砌,而是直接过滤掉了“一致”的行,只保留问题行,并按错误类型排序。可以直接把这个表发给业务人员去核实,节省沟通成本。
  4. 向量化:相比传统的 for 循环去一行行遍历(那是 Python 的弱点),这里利用了 pandas 的 merge 函数,类似于数据库的 SQL 连接操作,底层由 C 语言优化,处理百万行数据也是秒级响应。


实际使用时只要按照下面步骤操作就可以了(看上去步骤很多,但实际操作起来通常不会超过5分钟)

第一步:文件与代码准备

  1. 创建专属文件夹
    • 在桌面新建一个文件夹,命名为 自动对账工具。
  2. 准备 Excel 数据
    • 将你需要比对的两个 Excel 文件放入该文件夹。
    • 注意:确保两个表中都有唯一的标识列(如:订单号、身份证号、流水号)和需要比对的数值列(如:金额、数量)。
  3. 保存代码
    • 此时你的文件夹结构应该是这样的:
    • 📂 自动对账工具/ 
    • ├── 📄 check_diff.py (你的代码) 
    • ├── 📊 本月销售表.xlsx (你的数据 1) 
    • └── 📊 财务入账表.xlsx (你的数据 2)
    • 新建一个文本文档,将你提供的代码完整复制进去。
    • 将文件另存为 check_diff.py(注意后缀名必须是 .py,不能是 .txt)。
    • 将这个 .py 文件也放入 自动对账工具 文件夹中。

第二步:定制化配置(最关键一步)

找到这两行(94/95行),把引号里的名字改成你实际的 Excel 文件名(必须包含后缀 .xlsx):
# 修改前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

    过往文章/合集

    合集

    文章

    Python编程小技巧

    Python编程小技巧--用Python查询天气

    Python编程小技巧--‌自制简易系统监控

    Python--数据/图像可视化

    Python编程小技巧--雷达图

    报表"不直观"?20行Python代码做出高颜值KPI仪表盘,惊艳全场!

    Python数据可视化--绘制树状图(电商品类销售分析)

    Python编程基础算法

    Python编程基础算法--斐波那契数列的矩阵算法

    Python编程基础算法--LeetCode编辑距离问题

    细数那些经典教材

    细数那些经典教材--算法与数据结构

    细数那些经典教材--编程竞赛

    细数那些经典教材--机器学习入门就劝退?这几本“神书”帮你少走弯路!

    Python库巡礼

    Python库巡礼--PySpark

    Python 库巡礼--matplotlib:数据可视化的基石

    Python与数学之美

    Python与数学之美--黄金螺线

    Python与数学之美--可视化理解导数本质

    Python与数学之美--星形线(来自300年前的"完美曲线")

    Python与办公自动化
    Python与办公自动化--批量生成报告/通知
    月底加班到10点?Python 30秒搞定100个Excel的合并/拆分(附完整代码)
    Python与办公自动化--PDF的合并与拆分
    计算机科学人物志
    计算机科学人物志--图灵(理论起源)

    最新文章

    随机文章