你有没有遇到过这种情况?
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文件") return print(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) continue if 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文件") return print(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("❌ 没有成功读取任何文件") 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 __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: 文件太多,想知道每个数据来自哪个文件。解决方案:自动添加"来源文件"列,方便追溯。
还能怎么玩