2. 银行流水 Excel 多表合并与字段对齐

任务说明

银行导出的流水常分散在多个 Excel 工作表(或文件)中,列名不一致(如“交易金额”“金额(元)”“发生额”),金额单位也可能混用(元/万元)。本案例用 pandas 把多表纵向合并为一张表,完成列名对齐与金额单位统一(全部换算为“元”),并输出合并结果供后续审计分析。

环境与依赖

pip install pandas openpyxl

实现代码

import pandas as pd

# 1. 列名对齐映射:不同来源列名 -> 统一标准列名
COLUMN_MAP = {
    "交易日期": "date", "日期": "date",
    "交易金额": "amount", "金额(元)": "amount", "发生额": "amount",
    "摘要": "summary", "备注": "summary",
    "对方户名": "counterparty", "对方账户": "counterparty",
}

# 2. 各表金额单位:'yuan' 表示已是元,'wan' 表示万元需 *10000
UNIT_MAP = {"Sheet1": "yuan", "Sheet2": "wan", "Sheet3": "yuan"}

def normalize(df: pd.DataFrame, unit: str) -> pd.DataFrame:
    """对齐列名并统一金额单位为元。"""
    df = df.rename(columns=COLUMN_MAP)
    # 只保留标准列,缺失列补空
    for col in ["date", "amount", "summary", "counterparty"]:
        if col not in df.columns:
            df[col] = pd.NA
    df = df[["date", "amount", "summary", "counterparty"]].copy()
    # 金额转数值并统一单位
    df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
    if unit == "wan":
        df["amount"] = df["amount"] * 10000
    df["date"] = pd.to_datetime(df["date"], errors="coerce")
    return df

def merge_sheets(path: str) -> pd.DataFrame:
    """读取 Excel 所有工作表,合并为一张对齐后的表。"""
    sheets = pd.read_excel(path, sheet_name=None)  # dict: {表名: DataFrame}
    frames = []
    for name, df in sheets.items():
        unit = UNIT_MAP.get(name, "yuan")
        df = normalize(df, unit)
        df["source_sheet"] = name  # 保留来源,便于审计追溯
        frames.append(df)
    merged = pd.concat(frames, ignore_index=True)
    return merged

if __name__ == "__main__":
    result = merge_sheets("bank_flow.xlsx")
    result.to_excel("merged_flow.xlsx", index=False)
    print(result)
    print("总记录数:", len(result))

运行与验证

准备一个 bank_flow.xlsx,包含 Sheet1/Sheet2/Sheet3 三个工作表,列名与单位按上面 COLUMN_MAP、UNIT_MAP 设置(例如 Sheet2 的“发生额”以万元计)。运行脚本后:

  • 控制台打印合并后的表,列应为 date, amount, summary, counterparty, source_sheet;
  • 生成 merged_flow.xlsx,行数等于三张表数据行数之和;
  • 抽查 Sheet2 的记录,其 amount 应等于原值 ×10000,与 Sheet1/Sheet3 的元值口径一致。

判定通过:合并表列名统一、金额单位一致(均为元)、来源可追溯,且无因列名不匹配导致的整列丢失。

关键点

sheet_name=None 一次性读入全部工作表;rename 完成列名对齐,缺失列补 NA 保证结构一致;单位换算在数值化之后进行,避免字符串参与乘法;source_sheet 列保留数据来源,满足审计可追溯要求。