應用場景:某個文件夾中有多個Excel文件,現在需要將其合成一個Excel文件,一個工作簿中包含多個表單頁
openpyxl是經典的處理Excel文件的工具,面臨上述需求時,首先想到的就是openpyxl庫進行處理,但是,好像openpyxl只支持單個單元格級別的處理,不支持正頁表單級別的拷貝,而且不支持較老的.xls文件格式,所以對於.xls類型的文件,需要利用pandas進行處理,當數據量較大時合並速度較慢,比單純用pandas的方法慢一倍CSDN,在我的筆記本(CPU雙核2.70GHz)上,對12個25列1000行的Excel文本文件進行合並時,本篇方法耗時約為12s,而pandas實現的方法CSDN耗時約為6s,話不多說,直接上代碼:
#coding: utf-8
import os
import pandas as pd
from openpyxl import Workbook, load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows
#將Excel中的sheet中的內容逐單元格拷貝到另一個sheet
#@wso:output sheet, @wst:target sheet
def copy_sheet(wso,wst):
for i in range(1, wst.max_row+1):
for j in range(1, wst.max_column+1):
v=wst.cell(i,j).value#逐單元格賦值
if v:
wso.cell(i,j,v)
#將Excel中的sheet中的內容添加到另一個Excel的workbook
#@wb:output workbook, @wst:target sheet
def add_sheet(wb,wst):
wso=wb.create_sheet(wst.title)#新建sheet頁
copy_sheet(wso,wst)
#將Excel中各個sheet中的內容添加到另一個Excel的workbook
#wbo:output workbook, wbt:target workbook
def merge_workbook(wbo,wbt):
for sh in wbt.sheetnames:#逐sheet頁添加
add_sheet(wbo,wbt[sh])
#清除工作表中的空白sheet頁
def clear_workbook(wb):
for sh in wb.sheetnames:#逐sheet頁比對:只有1格單元格且單元格內容為空
if wb[sh].dimensions==r'A1:A1' and wb[sh]['A1'].value==None:
del wb[sh]
#使用openpyxl庫和pandas庫將指定路徑文件夾中的所有Excel(*.xlsx和*.xls)文件合並為一個文件
#由於在openpyxl庫中是逐單元格進行的數據賦值,所以速度較慢,數據量較大時尤為明顯
def merge_ExcelFiles(dirPath, outputFileName='合並結果.xlsx'):
dirPath+='\\'
wbo=Workbook()
clear_workbook(wbo)#新建立的Excel文件一般都包含若干空的sheet,首先清除默認生成的空sheet
os.chdir(dirPath)
file_list=os.listdir(dirPath)
for file in file_list:
#如果是*.xlsx文件,則比較簡單,直接利用openpyxl來處理
if file.endswith('.xlsx'):
wbt=load_workbook(dirPath+file)
merge_workbook(wbo, wbt)
print(file)
#如果是*.xls文件,由於openpyxl不支持,則需要用pandas來對*.xls文件進行讀取
if file.endswith('.xls'):#參數sheet_name默認為0,此時函數返回的直接就是DataFrame類型,但是那樣的話只能讀取第一個sheet,設置為None可以讀取所有的sheet,返回數據則是字典類型
df=pd.read_excel(dirPath+file, sheet_name=None, dtype='object')#參數dtype默認是None,但為了保護數據(例如身份證號被科學計數法丟失後面幾位數字),需要使用object類型
for key, value in df.items():#但是依然使用openpyxl來保存,因為openpyxl對Excel的支持較好,例如如果sheet的名字相同,則會自動進行“sheet+1”避免重名
ws=wbo.create_sheet(key)
for r in dataframe_to_rows(pd.DataFrame(value), index=False, header=True):
ws.append(r)
print(file)
clear_workbook(wbo)
print('OK!')
wbo.save(dirPath+outputFileName)
if __name__=="__main__":
dirPath=r'D:\課程\學生基礎信息'
import time
time0=time.time()
merge_ExcelFiles(dirPath,'合並結果.xlsx')
time1=time.time()
print("Spending Time:{:.3f}s".format(time1-time0))