使用Python合並Excel工具
前言
很久沒有發博了,乘今天休假,整理一個閑暇時間開發的Excel合並小工具。
GitHub地址:這里
也許你的工作中也會經常需要處理Excel合並的問題,我大體上把這些問題分成兩大類。
- 保留Excel頭部,純數據合並
- 保留Excel頭部,但頭部較復雜,例如含有合並單元格;每個excel需要合並的內容是由第一列的單元格跨越的行數決定的
以下針對上面的情況,分別給出解決方案
保留頭部,純數據的合並
舉例說明:
輸入是這樣的:
輸出希望是這樣的:
引入超級pandas庫,幾行代碼就能搞定,代碼可以在這里
核心代碼如下:
for file in filter_list:
if not file.endswith(self.output_file):
# 重構文件路徑
file_path = os.path.join(sub_dir, file)
# 將excel轉換成DataFrame
print(f'merging {file_path} ...')
dataframe = pd.read_excel(file_path)
# 保存到新列表中
new_list.append(dataframe)
# 多個DataFrame合並為一個
df = pd.concat(new_list)
# 寫入到一個新excel表中
df.to_excel(merged_file, index=False)
保留復雜頭部,文本和數據的混合合並
輸入是這樣的:
希望得到這樣的輸出:
這種情況,要借助強大的openpyxl庫,唯一的缺陷是只支持xlsx格式的文件,要使用這個工具,用戶需要先要把xls格式文件通過excel轉換為xlsx格式了。
openpyxl有非常完善的文檔說明:here
為了保障合並的靈活性,我用文件名來指定合並規則:
- <目標SHEET><處理順序號>-<源SHEET><源文件區塊>.xlsx
- 目標SHEET和源SHEET,用英文字母表示,第一個SHEET是A,依此類推,最大支持26個SHEET,從(A到Z)
- 處理順序號,用數字表示,指定文件被處理的順序,例如A0,代表拷貝到第一個SHEET的第一個需要處理的文件
- 源文件區塊,用數字表示。區塊的划分,是通過文件第一列所占用的行數來決定的。例如有的excel頭部,是一個跨越多行的合並單元格,如下圖,則該文件的第一個區塊就是1-3行,第二個區塊從第四行算起,然后看第一列跨越了多少行來決定第二個區塊的行數
- 當文件名的“-”兩邊一致的情況下,可以省略,例如:A0-A0.xlsx,可以縮寫為A0.xlsx
- 最大支持10000個區塊
舉例說明:
- 拷貝源文件第一個SHEET的頭部到目標文件的第一個SHEET中
A0-A0.xlsx - 拷貝源文件第二個SHEET的第二個區塊的內容到第一個SHEET中
A1-B1.xlsx
代碼入口文件在這里
執行
安裝Python和依賴包
- 安裝最新版本的Python
- 安裝依賴包:
@REM 請cd到當前目錄,例如: cd merge-excel-master
pip install -r requirements.txt
准備excel文件
- 在當前目錄新文件夾("to_combine"), 如果存在不需要重復創建
- 把需要合並的excel文件拷貝到“to_combine”文件夾下
- 請參考前面章節的excel文件命名規則
配置文件
配置文件是config.json,
header_color: 配置頭部背景色
block_colors: 配置區塊的背景色,會自動根據配置的背景色個數,循環使用
column_types: 配置特殊列格式,Excel文件有時候會丟失單元格格式信息,例如時間類型,Excel源文件中會是一個數字,但其實是一個時間,下面的例子,就是以第9列是時間類型格式的特殊處理
{
"header_color": "C0C0C0",
"block_colors": ["99CCFF", "FFFFFF"],
"column_types": [
{
"column_number": 9,
"source_data_type": "n",
"source_value_type": "int",
"target_data_type": "d",
"target_number_format": "%Y.%m"
}
]
}
顏色代碼:可參考這里
運行
excel文件准備好后,在windows上雙擊: "run.cmd"
在mac上,打開terminal, 執行:
python index.py
如果執行成功,會在最后一行顯示“done”,同時在當前目錄生成"combined.xlsx"文件
如果執行失敗,在窗口中會有錯誤提示!