Python办公01:一键合并多文件夹下百份 Excel 自动汇总至总表

目录

    • [01:一键合并------多文件夹下百份 Excel 自动汇总至总表](#01:一键合并——多文件夹下百份 Excel 自动汇总至总表)
    • 场景引入
    • 技术原理
    • 环境准备
    • 完整代码
    • 代码逐行解析
      • [1. 导入模块](#1. 导入模块)
      • [2. 递归遍历文件夹](#2. 递归遍历文件夹)
      • [3. 文件过滤](#3. 文件过滤)
      • [4. 读取 Excel 并标记来源](#4. 读取 Excel 并标记来源)
      • [5. 合并所有数据](#5. 合并所有数据)
      • [6. 导出结果](#6. 导出结果)
    • 进阶技巧
      • [技巧 1:指定读取的 Sheet 名称](#技巧 1:指定读取的 Sheet 名称)
      • [技巧 2:统一列名后再合并](#技巧 2:统一列名后再合并)
      • [技巧 3:添加进度条(大文件友好)](#技巧 3:添加进度条(大文件友好))
    • 常见问题
      • [Q1:报错 `ModuleNotFoundError: No module named 'openpyxl'`](#Q1:报错 ModuleNotFoundError: No module named 'openpyxl')
      • Q2:合并后列的顺序乱了怎么办?
      • [Q3:某些 Excel 文件读取出来是空的?](#Q3:某些 Excel 文件读取出来是空的?)
      • [Q4:如何合并 .csv 文件?](#Q4:如何合并 .csv 文件?)
    • 总结

专栏导读

🌸 欢迎来到Python办公自动化专栏---Python处理办公问题,解放您的双手
🏳️‍🌈 个人博客主页:请点击------> 个人的博客主页 求收藏
🏳️‍🌈 Github主页:请点击------> Github主页 求Star⭐
🏳️‍🌈 知乎主页:请点击------> 知乎主页 求关注
🏳️‍🌈 CSDN博客主页:请点击------> CSDN的博客主页 求关注
👍 该系列文章专栏:请点击------>Python办公自动化专栏 求订阅
🕷 此外还有爬虫专栏:请点击------>Python爬虫基础专栏 求订阅
📕 此外还有python基础专栏:请点击------>Python基础学习专栏 求订阅
文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
❤️ 欢迎各位佬关注! ❤️

01:一键合并------多文件夹下百份 Excel 自动汇总至总表

第一阶段:Excel / 数据表高效处理(1-8)

场景引入

每月底,财务部门的同事小张总会遇到这样的噩梦:公司下属 12 个分公司各自把报表放在不同的文件夹里,每个文件夹又有 5-10 份 Excel 文件,格式基本一致但文件名五花八门。小张需要手动打开每一份文件,复制粘贴到汇总表里------每次都要花掉整整半天时间。

学完本节,你可以用 不到 30 行 Python 代码,一键遍历所有文件夹、读取所有 Excel 文件,自动合并成一张总表,全程只需 3 秒钟。


技术原理

核心思路分三步:

  1. 遍历目录树 :使用 Python 内置的 os.walk()pathlib 递归扫描所有子文件夹

  2. 读取 Excel 文件 :使用 pandas.read_excel() 将每个 Excel 文件读取为 DataFrame

  3. 纵向拼接 :使用 pandas.concat() 将多个 DataFrame 按行合并,最后导出为新的 Excel 文件

    文件夹结构示意:
    数据源/
    ├── 北京分公司/
    │ ├── 1月报表.xlsx
    │ └── 2月报表.xlsx
    ├── 上海分公司/
    │ ├── Q1汇总.xlsx
    │ └── Q2汇总.xlsx
    └── 广州分公司/
    └── 年度报表.xlsx
    ↓ Python 自动遍历 + 合并

    总表.xlsx(包含所有数据)


环境准备

安装依赖库

bash 复制代码
pip install pandas openpyxl
库名 作用
pandas 数据处理核心,提供 DataFrame 结构和 concat 合并功能
openpyxl pandas 读取 .xlsx 文件的引擎(必须安装)

完整代码

python 复制代码
import os
import pandas as pd
from pathlib import Path

def merge_excel_files(source_dir, output_file="总表汇总.xlsx"):
    """
    遍历指定目录下所有子文件夹中的 Excel 文件,合并为一张总表

    参数:
        source_dir: 包含 Excel 文件的根目录路径
        output_file: 输出汇总文件的文件名
    """
    all_dataframes = []  # 存储所有读取到的 DataFrame
    file_count = 0       # 统计处理的文件数

    # 将路径转为 Path 对象,方便操作
    root_path = Path(source_dir)

    if not root_path.exists():
        print(f"错误:目录 {source_dir} 不存在!")
        return

    # os.walk 递归遍历所有子文件夹
    for dirpath, dirnames, filenames in os.walk(source_dir):
        for filename in filenames:
            # 只处理 .xlsx 和 .xls 文件
            if filename.endswith(('.xlsx', '.xls')) and not filename.startswith('~$'):
                file_path = os.path.join(dirpath, filename)
                file_count += 1

                try:
                    # 读取 Excel 文件(默认读取第一个 sheet)
                    df = pd.read_excel(file_path, engine='openpyxl' if filename.endswith('.xlsx') else 'xlrd')

                    # 可选:添加一列来源信息,记录数据来自哪个文件
                    df['数据来源文件'] = filename
                    df['数据来源路径'] = dirpath

                    all_dataframes.append(df)
                    print(f"[{file_count}] 已读取: {filename}")

                except Exception as e:
                    print(f"[{file_count}] 读取失败 {filename}: {e}")

    if not all_dataframes:
        print("没有找到任何 Excel 文件!")
        return

    # 将所有 DataFrame 纵向拼接(按行合并)
    print("\n正在合并所有数据...")
    merged_df = pd.concat(all_dataframes, ignore_index=True)

    # 导出为新的 Excel 文件
    merged_df.to_excel(output_file, index=False, engine='openpyxl')

    print(f"\n合并完成!")
    print(f"共处理 {file_count} 个文件")
    print(f"总数据行数: {len(merged_df)}")
    print(f"总数据列数: {len(merged_df.columns)}")
    print(f"汇总文件已保存: {output_file}")


# ==================== 使用示例 ====================
if __name__ == "__main__":
    # 修改这里为你的数据文件夹路径
    SOURCE_DIR = r"D:\数据源"

    # 执行合并
    merge_excel_files(SOURCE_DIR, output_file="总表汇总.xlsx")

代码逐行解析

1. 导入模块

python 复制代码
import os
import pandas as pd
from pathlib import Path
  • os:操作系统接口,用于遍历文件夹
  • pandas as pd:数据处理库,核心工具
  • Path:面向对象的路径操作,比字符串拼接更安全

2. 递归遍历文件夹

python 复制代码
for dirpath, dirnames, filenames in os.walk(source_dir):

os.walk() 是 Python 内置的目录遍历函数,它会递归地进入每个子文件夹。每次迭代返回三个值:

变量 含义 示例
dirpath 当前文件夹的完整路径 "D:\\数据源\\北京分公司"
dirnames 当前文件夹下的子文件夹列表 ["1月", "2月"]
filenames 当前文件夹下的文件列表 ["1月报表.xlsx", "2月报表.xlsx"]

3. 文件过滤

python 复制代码
if filename.endswith(('.xlsx', '.xls')) and not filename.startswith('~$'):
  • endswith(('.xlsx', '.xls')):只处理 Excel 文件
  • not filename.startswith('~$'):排除 Excel 的临时锁文件(编辑时自动生成)

4. 读取 Excel 并标记来源

python 复制代码
df = pd.read_excel(file_path, engine='openpyxl')
df['数据来源文件'] = filename
df['数据来源路径'] = dirpath
  • pd.read_excel() 将 Excel 文件读取为 DataFrame(类似表格的数据结构)
  • 添加两列来源信息,方便后续追溯数据出处

5. 合并所有数据

python 复制代码
merged_df = pd.concat(all_dataframes, ignore_index=True)

pd.concat() 是关键函数:

  • 将列表中的所有 DataFrame 纵向拼接(上下连接)
  • ignore_index=True 重置行索引,避免索引重复

6. 导出结果

python 复制代码
merged_df.to_excel(output_file, index=False, engine='openpyxl')
  • index=False 不导出 pandas 自动生成的行号
  • 最终得到一个包含所有数据的汇总 Excel 文件

进阶技巧

技巧 1:指定读取的 Sheet 名称

如果 Excel 文件有多个 Sheet,可以指定读取特定 Sheet:

python 复制代码
df = pd.read_excel(file_path, sheet_name="Sheet1", engine='openpyxl')

或读取所有 Sheet 并合并:

python 复制代码
all_sheets = pd.read_excel(file_path, sheet_name=None, engine='openpyxl')
for sheet_name, sheet_df in all_sheets.items():
    sheet_df['来源Sheet'] = sheet_name
    all_dataframes.append(sheet_df)

技巧 2:统一列名后再合并

如果不同文件的列名不完全一致,可以先做列名映射:

python 复制代码
# 定义统一列名映射
COLUMN_MAP = {
    '姓名': '姓名',
    '员工姓名': '姓名',
    'Name': '姓名',
    '部门': '部门',
    '所属部门': '部门',
    '金额': '金额',
    '金额(元)': '金额',
}

# 读取后统一列名
df = pd.read_excel(file_path)
df.rename(columns=COLUMN_MAP, inplace=True)

技巧 3:添加进度条(大文件友好)

python 复制代码
from tqdm import tqdm

for dirpath, dirnames, filenames in tqdm(os.walk(source_dir), desc="扫描文件夹"):
    for filename in filenames:
        # ... 处理逻辑

常见问题

Q1:报错 ModuleNotFoundError: No module named 'openpyxl'

原因:没有安装 openpyxl 库,pandas 读取 .xlsx 需要此依赖。

解决 :运行 pip install openpyxl

Q2:合并后列的顺序乱了怎么办?

pd.concat() 会自动对齐列名,但列顺序可能不一致。可以手动指定列顺序:

python 复制代码
desired_columns = ['姓名', '部门', '金额', '日期', '数据来源文件', '数据来源路径']
merged_df = merged_df[desired_columns]

Q3:某些 Excel 文件读取出来是空的?

可能原因:

  • 文件本身没有数据(只有表头)
  • 文件被加密
  • 文件格式不是真正的 Excel(如 .csv 改了后缀)

建议在读取后加判断:

python 复制代码
if df.empty:
    print(f"警告: {filename} 为空,跳过")
    continue

Q4:如何合并 .csv 文件?

只需将读取方式改为 pd.read_csv()

python 复制代码
if filename.endswith('.csv'):
    df = pd.read_csv(file_path, encoding='utf-8-sig')

总结

步骤 核心函数 作用
遍历文件夹 os.walk() 递归扫描所有子目录
读取文件 pd.read_excel() 将 Excel 转为 DataFrame
合并数据 pd.concat() 纵向拼接多个 DataFrame
导出结果 to_excel() 保存为新的 Excel 文件

本节掌握了 Python 办公自动化中最常用的技能之一------多文件自动合并。无论是财务报表、销售数据还是调查问卷,只要格式一致,都可以用这套代码一键汇总。

下一节预告:02:精准拆分------按城市/部门将总表数据秒拆成独立文件,学完本节后你会知道如何反向操作,把一张大表按条件拆分成多个文件!

结尾

希望对初学者有帮助;致力于办公自动化的小小程序员一枚
希望能得到大家的【❤️一个免费关注❤️】感谢!
求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍
此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏
此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏
此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏