作为每天和 Excel 打交道的打工人,最烦的莫过于处理一堆零散的 Excel 文件。比如每周各门店报上来的销售表、各部门提交的费用明细,要把这些文件合并成一个总表,手动打开、复制、粘贴不仅费时间,还容易漏行、错行,尤其是遇到带合并单元格、公式的表格,简直是噩梦。
之前我用 pandas 处理过,但 pandas 对 Excel 的格式支持不算友好,合并后经常丢格式、公式失效;后来试了 Free Spire.XLS for Python 免费库,发现它对 Excel 原生格式的支持特别好,合并后的表格能完整保留原有的样式、公式和合并单元格,今天就把这个超实用的方法分享给大家。
方案概述
Free Spire.XLS for Python 是一个无需安装 Microsoft Excel 即可读写 Excel 文件的纯 Python 库,免费版可满足多数日常合并需求。本文针对两种常见场景给出具体实现:
- 独立工作表模式:将每个源文件的所有工作表作为一个独立的工作表添加到合并后的工作簿中,适合需要区分来源文件的场景。
- 追加模式:将所有源文件的数据依次追加到合并工作簿的同一工作表中,适合汇总同类数据的场景。
环境准备
确保 Python 3.7 及以上版本已安装,并执行以下命令安装依赖库:
pip install Spire.Xls.Free
注意:免费版在读写 .xls 格式的 Excel 文档时,有每个文档 5 个工作表,每个工作表 200 行的限制。
模式一:每个文件独立成表
此模式适用于需要保留各文件原始结构、工作表互不干扰的场景。例如,合并不同部门或区域的报表,便于按来源查阅。
代码实现
import os
from spire.xls import *
# 待合并文件所在的文件夹路径
input_folder = './sample_files'
# 合并后的输出文件名
output_file = 'merged_workbook.xlsx'
# 初始化合并工作簿变量
merged_workbook = None
# 遍历文件夹中的所有文件
for filename in os.listdir(input_folder):
# 仅处理 Excel 文件(.xlsx 或 .xls)
if filename.endswith('.xlsx') or filename.endswith('.xls'):
file_path = os.path.join(input_folder, filename)
# 加载当前文件
source_workbook = Workbook()
source_workbook.LoadFromFile(file_path)
if merged_workbook is None:
# 第一个文件作为合并工作簿的基座
merged_workbook = source_workbook
else:
# 将后续文件的每个工作表复制到合并工作簿
for i in range(source_workbook.Worksheets.Count):
sheet = source_workbook.Worksheets.get_Item(i)
merged_workbook.Worksheets.AddCopy(sheet, WorksheetCopyType.CopyAll)
# 保存合并后的工作簿
merged_workbook.SaveToFile(output_file, ExcelVersion.Version2016)
几点说明:
- 第一个文件直接拿来当“母板”,这样能保留第一个文件原来的工作表顺序。
- 用
AddCopy(sheet, WorksheetCopyType.CopyAll)复制工作表,可以连格式、合并单元格、图表一起搬过来,省心。 - 工作表名字自动生成为“原文件名_原工作表名”,避免重名。如果你觉得名字太长,可以自己改一下拼接规则。
模式二:所有数据合并到同一工作表
此模式适用于将多个结构相同的数据表汇总为一张总表,例如按月合并销售明细。假设每个文件的第一行为表头,后续文件只追加数据行。
代码实现
import os
from spire.xls import *
# 待合并文件所在的文件夹路径
input_folder = './excel_worksheets'
# 合并后的输出文件名
output_file = 'merged_into_one_sheet.xlsx'
# 创建新的工作簿作为合并目标
merged_workbook = Workbook()
# 使用第一个工作表作为数据汇总表
merged_sheet = merged_workbook.Worksheets[0]
# 当前写入行号(从1开始)
current_row = 1
# 遍历文件夹中的所有文件
for filename in os.listdir(input_folder):
if filename.endswith('.xlsx') or filename.endswith('.xls'):
file_path = os.path.join(input_folder, filename)
# 加载当前文件
workbook = Workbook()
workbook.LoadFromFile(file_path)
# 获取第一个工作表
sheet = workbook.Worksheets[0]
# 获取已使用区域
source_range = sheet.Range
# 在合并表中定位目标起始单元格
dest_range = merged_sheet.Range[current_row, 1]
# 复制数据
source_range.Copy(dest_range)
# 更新当前行号,指向下一段数据的起始位置
current_row += sheet.LastRow
# 保存合并后的工作簿
merged_workbook.SaveToFile(output_file, ExcelVersion.Version2016)
注意点:
- 仅复制数据:使用
Range.Copy方法主要复制值和公式。 - 行号管理:通过累加
sheet.LastRow确定下一段数据的起始行,保证数据连续追加。 - 表头处理:上述代码中,第一个文件的表头会被保留,后续文件的表头因从第 1 行开始复制(源表第一行),会一并复制,导致重复表头。若希望只保留一个表头,可将后续文件复制时的起始行改为第 2 行(即
source_range = sheet.Range[2, 1])。
本文提供了两种常见 Excel 合并场景的完整 Python 实现,无需安装 Excel 应用程序即可运行。通过将重复性工作自动化,可有效提升数据处理效率,减少人为错误。使用时可根据实际需求选择或调整代码,将其集成到日常工作中。