你有没有遇到过这种情况?
12个月销售报表,每个表都有几十列数据——产品名称、规格、型号、单价、数量、折扣、运费、备注、销售人员、客户名称、客户电话、客户地址、订单编号、付款方式、发货日期、签收日期、售后状态、评价分数……但你只需要其中的「产品名称」和「销售额」两列。
你一个一个打开Excel,找到这两列,Ctrl+C复制,打开汇总表,Ctrl+V粘贴,再打开下一个……重复12遍。好不容易合完了,发现列名对不齐,又要重新来。
如果这样的表有几十个呢?一下午就没了。
更崩溃的是,领导临时说:"再加一列「销售日期」。"你又得把几十个表重新打开一遍。
我让AI写了30行代码,做了一个事:批量从多个Excel中提取指定列,自动合并成一个表。列名对不齐?自动匹配。想加列?改一下输入就行。
原来:打开文件 → 找到列 → 复制 → 粘贴 → 关闭 → 下一个 → 重复N遍 → 一下午没了现在:运行脚本 → 输入文件夹路径 → 输入要保留的列名 → 几秒钟搞定
效果展示
你的文件夹里是这样的(12个报表 × 20列):
你只需要两列:产品名称 和 销售额
运行脚本,输入列名:产品名称,销售额
几秒钟后,得到这个汇总表:
12个报表、240列数据,只提取你需要的2列,一键汇总。 还自动添加了"来源文件"列,方便追溯数据来自哪个报表。
完整代码
import osimport pandas as pddef merge_specific_columns(folder_path, columns_to_keep, output_file="合并结果.xlsx", include_subfolders=False):"""从多个Excel文件中提取指定列并合并columns_to_keep: 要保留的列名列表,如 ['产品名称', '销售额']include_subfolders: 是否包含子文件夹"""# 收集所有Excel文件excel_files = []if include_subfolders:for root, dirs, files in os.walk(folder_path):for f in files:if f.lower().endswith(('.xlsx', '.xls')):excel_files.append(os.path.join(root, f))else:excel_files = [os.path.join(folder_path, f) for f in os.listdir(folder_path)if f.lower().endswith(('.xlsx', '.xls'))]if not excel_files:print("❌ 未找到Excel文件")returnprint(f"📂 找到 {len(excel_files)} 个Excel文件")print(f"📋 要提取的列: {', '.join(columns_to_keep)}")all_data = []skipped_files = []missing_columns = []for file_path in excel_files:file_name = os.path.basename(file_path)print(f" 📄 {file_name}")try:df = pd.read_excel(file_path)df_columns_lower = [col.lower() for col in df.columns]# 查找匹配的列(不区分大小写)matched_columns = []for col in columns_to_keep:col_lower = col.lower()if col_lower in df_columns_lower:original_col = df.columns[df_columns_lower.index(col_lower)]matched_columns.append(original_col)else:missing_columns.append((file_name, col))print(f" ⚠️ 缺少列: {col}")if not matched_columns:print(f" ⚠️ 未找到任何匹配列,跳过")skipped_files.append(file_name)continue# 提取指定列df_extracted = df[matched_columns].copy()# 添加来源列df_extracted.insert(0, '来源文件', file_name)all_data.append(df_extracted)print(f" ✅ 已提取 {len(matched_columns)} 列,{len(df)} 行")except Exception as e:print(f" ❌ 读取失败: {str(e)[:30]}")skipped_files.append(file_name)continueif not all_data:print("❌ 没有成功读取任何数据")if missing_columns:print("\n⚠️ 缺失列信息:")for file_name, col in missing_columns[:10]:print(f" {file_name}: 缺少列「{col}」")return# 合并所有数据merged_df = pd.concat(all_data, ignore_index=True)# 保存结果output_path = os.path.join(folder_path, output_file)merged_df.to_excel(output_path, index=False)print(f"\n✅ 完成!成功合并 {len(all_data)} 个文件")print(f"📊 总行数: {len(merged_df)} 行")print(f"📁 保存至: {output_path}")if skipped_files:print(f"\n⚠️ 跳过 {len(skipped_files)} 个文件(格式异常或无匹配列)")if missing_columns:print(f"\n⚠️ {len(missing_columns)} 个文件缺少指定列")def merge_by_keyword(folder_path, keyword, output_file="按关键词合并.xlsx"):"""按文件名关键词筛选后合并"""excel_files = [os.path.join(folder_path, f) for f in os.listdir(folder_path)if f.lower().endswith(('.xlsx', '.xls')) and keyword.lower() in f.lower()]if not excel_files:print(f"❌ 未找到文件名包含「{keyword}」的Excel文件")returnprint(f"📂 找到 {len(excel_files)} 个匹配文件")all_data = []for file_path in excel_files:file_name = os.path.basename(file_path)try:df = pd.read_excel(file_path)df.insert(0, '来源文件', file_name)all_data.append(df)print(f" ✅ {file_name} ({len(df)} 行)")except Exception as e:print(f" ❌ {file_name} 读取失败: {str(e)[:30]}")if not all_data:print("❌ 没有成功读取任何文件")returnmerged_df = pd.concat(all_data, ignore_index=True)output_path = os.path.join(folder_path, output_file)merged_df.to_excel(output_path, index=False)print(f"\n✅ 完成!共合并 {len(all_data)} 个文件")print(f"📊 总行数: {len(merged_df)} 行")print(f"📁 保存至: {output_path}")if __name__ == "__main__":print("=" * 50)print("📊 批量合并Excel指定列")print("=" * 50)print("从多个Excel中提取指定列合并成一个表")print()path = input("请输入Excel文件夹路径: ").strip()if path.startswith('"') and path.endswith('"'):path = path[1:-1]path = path.replace('\\', '/')if not os.path.exists(path):print("❌ 路径不存在")input("按回车键退出...")exit()print("\n1. 按指定列合并(提取指定列)")print("2. 按关键词筛选后合并(如只合并文件名含「销售」的表)")choice = input("请选择(1或2,默认1): ").strip() or "1"if choice == "2":keyword = input("请输入关键词(如 销售): ").strip()if not keyword:print("❌ 关键词不能为空")input("按回车键退出...")exit()merge_by_keyword(path, keyword)else:print("\n请输入要保留的列名(多个列名用英文逗号分隔)")print("例如: 产品名称,销售额,日期")columns_input = input("列名: ").strip()columns_to_keep = [c.strip() for c in columns_input.split(',') if c.strip()]if not columns_to_keep:print("❌ 至少输入一个列名")input("按回车键退出...")exit()# 询问是否包含子文件夹sub = input("是否包含子文件夹?(y/n,默认n): ").strip().lower()include_sub = sub == 'y'merge_specific_columns(path, columns_to_keep, include_subfolders=include_sub)input("\n按回车键退出...")
使用步骤
安装依赖:
pip install pandas openpyxl把上面的完整代码复制到一个文本文件里,保存为
merge_columns.py把所有需要合并的Excel文件放在同一个文件夹里,比如
C:/销售报表打开终端,运行
python merge_columns.py输入文件夹路径
C:/销售报表选择模式1(按指定列合并)
输入要保留的列名,例如
产品名称,销售额等待几秒钟,打开同目录下的
合并结果.xlsx
踩坑记录
坑1: 不同文件的列名大小写不一样(有的"产品名称",有的"产品名")。解决方案:代码加了大小写自动匹配,只要文字对得上就能识别。
坑2: 有些文件缺少指定列,程序直接崩溃。解决方案:加了错误处理,自动跳过缺少列的文件,并提示用户。
坑3: 文件太多,想知道每个数据来自哪个文件。解决方案:自动添加"来源文件"列,方便追溯。
还能怎么玩
按关键词筛选:只合并文件名包含"销售"的报表
包含子文件夹:扫描所有子文件夹中的Excel文件
动态添加列:想加列就加列,改一下输入就行
数据追溯:自动添加"来源文件"列,知道每行数据从哪来
夜雨聆风