Python 批量导入多个 CSV 至单个 Excel 文件

日常数据处理中,经常遇到需要把一批 CSV 文件汇总到一个 Excel 工作簿的场景------每个 CSV 对应一个工作表,方便统一查看和分发。Python 原生 csv 模块可以读取数据,但要逐个写入 Excel 的不同工作表,还需要额外的写入逻辑。使用 Free Spire.XLS for Python 免费库可以直接将 CSV 加载为工作簿对象,再将其工作表复制到目标工作簿中,代码量很少。

环境准备

通过 pip 安装免费版本即可,支持 Python 3.6+ 以及 Windows、macOS、Linux:

bash 复制代码
pip install Spire.Xls.Free

Free Spire.XLS for Python 无需安装 Microsoft Excel,在服务器或无桌面环境中也能运行。需要注意,免费版对 .xls 格式的读写有工作表数量限制(每个工作簿最多 5 个,每个工作表最多 200 行);如果输出为 .xlsx 格式,则不触发这一限制。对于工作表数量较多或行数较大的场景,建议输出 .xlsx。

核心思路

单个 CSV 文件用 Workbook.LoadFromFile() 加载后,数据会出现在工作簿的第一个工作表(索引 0)中。要合并多个 CSV,可以:

  1. 创建一个目标 Workbook;
  2. 遍历 CSV 文件列表,每个文件单独加载;
  3. 用 Worksheets.AddCopy() 将其工作表复制到目标工作簿;
  4. 重命名复制过来的工作表,便于区分;
  5. 保存目标工作簿为 .xlsx。

AddCopy 方法会连同数据、格式一并复制,第二个参数 WorksheetCopyType.CopyAll 可确保完整性。

完整代码

以下脚本将指定目录下所有 CSV 文件合并到一个 Excel 文件中,每个 CSV 对应一个工作表:

python 复制代码
import os
import glob
from spire.xls import *
from spire.xls.common import *

def merge_csv_to_excel(csv_dir, output_path, delimiter=","):

"""

将目录下的所有 CSV 文件合并到一个 Excel 文件中。

每个 CSV 对应一个工作表,工作表名取自文件名(不含扩展名)。


参数:

csv_dir: CSV 文件所在目录

output_path: 输出 Excel 文件路径(建议 .xlsx)

delimiter: CSV 分隔符,默认逗号

"""

csv_files = glob.glob(os.path.join(csv_dir, "*.csv"))

if not csv_files:

print("未找到 CSV 文件")

return


# 创建目标工作簿

target_book = Workbook()


# 删除默认生成的空白工作表(保留一个作为占位,后续按需删除)

# 这里先不删,处理完第一个文件后再统一处理


for idx, file_path in enumerate(csv_files):

file_name = os.path.splitext(os.path.basename(file_path))[0]


# 加载单个 CSV 文件

source_book = Workbook()

source_book.LoadFromFile(file_path, delimiter, 1, 1)


# 获取 CSV 解析后的工作表

source_sheet = source_book.Worksheets[0]


# 复制到目标工作簿

target_book.Worksheets.AddCopy(source_sheet, WorksheetCopyType.CopyAll)


# 重命名新复制的工作表

new_sheet = target_book.Worksheets[target_book.Worksheets.Count - 1]

new_sheet.Name = file_name[:31]  # Excel 工作表名最长 31 个字符


source_book.Dispose()


print(f"已导入: {file_name}")


# 删除目标工作簿中最初的空白工作表

# 默认 Workbook() 会创建 3 个工作表,删除未使用的

for i in range(target_book.Worksheets.Count - 1, -1, -1):

sheet = target_book.Worksheets[i]

# 如果工作表名仍是默认的 Sheet1/Sheet2/Sheet3,且不在已导入的列表中

if sheet.Name in ["Sheet1", "Sheet2", "Sheet3"]:

target_book.Worksheets.RemoveAt(i)


# 保存为 xlsx

target_book.SaveToFile(output_path, FileFormat.Version2016)

target_book.Dispose()

print(f"\n合并完成: {output_path}")

if` `name` == `"main"`:`
`
merge_csv_to_excel(`
`
csv_dir=`"./csv_files"`,`
`
output_path=`"./merged_output.xlsx"`,`
`
delimiter=`","
`
)`
`
`

几个关键点

  1. LoadFromFile 的参数 。 LoadFromFile(fileName, separator, startRow, startColumn) 中,separator 指定分隔符,不限于逗号。如果处理的是制表符分隔的 TSV,传入 "\t" 即可;分号分隔的欧洲数据文件传入 ";"。

  2. 工作表命名 。 Excel 工作表名最长 31 个字符,且不能包含 \ / ? * [ ] : 等字符。上面的代码用 file_name[:31] 做了截断,如果实际文件名中包含特殊字符,建议再做一次替换处理。

  3. 删除默认工作表 。 Workbook() 初始化时会自动创建 3 个空白工作表。上面的代码在导入完成后遍历删除名称为 Sheet1/Sheet2/Sheet3 的工作表,但要注意如果 CSV 文件名恰好也叫 Sheet1.csv,会产生误删。更稳妥的做法是在创建目标工作簿后立即清空默认工作表:

python 复制代码
target_book = Workbook()
while target_book.Worksheets.Count > 0:
    target_book.Worksheets.RemoveAt(0)

这样 AddCopy 添加的工作表从第一个开始,逻辑更干净。但需要注意,如果删除所有工作表后直接 AddCopy,部分版本可能报错,此时可以先保留一个再替换。根据实际库版本调整即可。

  1. 非 UTF-8 编码的 CSV 。 如果 CSV 文件使用 GBK 等编码,LoadFromFile 可能无法正确解析中文。这种情况下可以先用 Python 的 csv 模块读取并转码为临时文件,再交给 Spire.XLS 加载,或者确认该库当前版本是否支持通过参数指定编码。

这个脚本适合轻量自动化场景,把零散 CSV 归集到一个 Excel 工作簿,每个文件单独一个 sheet。Free Spire.XLS for Python 的优势在于脱离 Office 环境运行,CSV 导入 API 封装简洁,不需要手动逐行读写单元格。