最近的工作遇到一個需求,整理多個相同格式但是不標準的Excel表格,最終匯總成一個Excel表格,并進行數據透視分析。 表格內涉及到合并的單元格,不同表格表頭位置有偏差等問題。目標是將所有表格內容相同表頭內容統(tǒng)計到一個表內。由于Excel表格內容數據量巨大,如果使用人力的手段,工作量巨大,并且容易出錯(預估工作量3天)。所以決定使用Python對Excel進行自動處理,實現一鍵導出目標Excel的目的。 大致步驟:Python學習交流群:1004391443 1.安裝Python3,pip工具環(huán)境 2.安裝xlrd和xlwt 3.讀取所有源Excel文件 4.將讀取到的Excel信息組織到新的Excel對象中 5.數據緩存和分析 6.向新Excel對象中追加分析結果 7.將新Excel對象保存為目標輸出文件(最終想要的文件) 1.對于Python環(huán)境的安裝本文不做說明。 2.安裝Python擴展包有不同的方式,這里使用pip命令安裝xlrd和xlwt。 在Windows下,打開命令提示符(控制臺),cd python的安裝路徑下Scripts文件夾下(在這里有pip命令執(zhí)行工具)。或者將該路徑添加到系統(tǒng)環(huán)境變量。 xlrd:讀取Excel的擴展包 執(zhí)行:pip install xlrd xlwt:寫入Excel的擴展包 執(zhí)行:pip install xlwt 隨便寫一個py文件寫入import xlrd, xlwt 執(zhí)行該文件不出錯說明安裝成功。 或者打開python自帶的編輯器進行輸入測試。 3.具體代碼如下 # -*- coding: utf-8 -*-import xlrdimport xlwtimport sys def read(file_list): # 創(chuàng)建新的workbook out_work_book = xlwt.Workbook(encoding = 'utf-8') # 為了將多個文件的相同表頭的sheet和并到一個sheet內,定義新sheet寫入的行號位置 out_work_book_rows = [0,0] # 取得傳入的文件列表 (第一個參數為腳本名字) for file_name in file_list[1:]: # 打開文件 workbook = xlrd.open_workbook(file_name) # 取得當前文檔的sheet列表 sheet_names = workbook.sheet_names() for sheet_idx in range(len(sheet_names)): sheet_name = sheet_names[sheet_idx] # sheet = workbook.sheet_by_index(sheet_idx) sheet = workbook.sheet_by_name(sheet_name) # sheet.row_values(n) 獲取整行數據 # sheet.col_values(n) 獲取整列數據 # 獲取行數 rows_count = sheet.nrows # 獲取列數 cols_count = sheet.ncols # 存儲寫入的列數 write_col_count # 創(chuàng)建新的sheet if len(out_work_book_sheet) <= sheet_idx: out_work_book_sheet[sheet_idx] = out_work_book.add_sheet('sheet' sheet_idx) # 寫入sheet for curr_col_num in range(cols_count) # 當前列的內容 col = sheet.col_values(curr_col_num) # 遍歷當前列的所有選項 for index in range(len(col)) # 當前列第index的內容 value = col[index] # 在寫入的sheet的行號上,加入上一個表寫到的位置行號,繼續(xù)向后追加內容 out_work_book_sheet[sheet_idx].write(out_work_book_rows[sheet_idx] index, write_col_count, value) write_col_count out_work_book_rows[sheet_idx] = cols_count # 輸出目標文件 out_work_book.save('out.xls')if __name__ == "__main__": read(sys.argv) 4.針對合并的單元格,上述代碼會出現合并單元格只有一個格子有內容其余為空的情況。這種情形,現將當前sheet表格內所有合并單元格數據保存下來,當遇到屬于合并單元格的部分,則默認選取該合并單元格的第一個格子的數值即可。代碼如下: def get_merged_cells_value(sheet, row_index, col_index): # 獲得當前sheet的所有合并單元格數據 merged = sheet.merged_cells # 判斷給定的單元格,是否屬于合并單元格,如果是合并單元格,就返回合并單元格的內容 for (rlow, rhigh, clow, chigh) in merged: if (row_index >= rlow and row_index < rhigh): if (col_index >= clow and col_index < chigh): cell_value = sheet.cell_value(rlow, clow) return cell_value return None 5.數據緩存可以利用python中的容器,和對象結構,將Excel中的數據對象化,在讀取時候進行實例化然后進行保存。在需要進行數據分析的時候利用。 6.在遇到特殊的表格格式的時候,讀取的內容可能在轉存的時候出現類型錯誤,導致無法識別。例如時間類型,正確顯示需要按特定格式進行讀取并且轉換。 表格類型說明: table.ctype 0 empty 1 string 2 number 3 date 4 boolean 5 error 代碼如下: from datetime import datetime,date def get_merged_cells_value(workbook, sheet, row_index, col_index): # 獲得當前sheet的所有合并單元格數據 merged = sheet.merged_cells # 判斷給定的單元格,是否屬于合并單元格,如果是合并單元格,就返回合并單元格的內容 for (rlow, rhigh, clow, chigh) in merged: if (row_index >= rlow and row_index < rhigh): if (col_index >= clow and col_index < chigh): if sheet.cell(rlow, clow).ctype == 3: date_value = xlrd.xldate_as_tuple(sheet.cell(rlow, clow), workbook.datemode) # 轉換顯示格式為2019/05/05 cell_value = date(*date_value[:3]).strftime('%Y/%m/%d') else: cell_value = sheet.cell_value(rlow, clow) return cell_value return None 7.最終,我們寫一個windows下的bat批處理文件或者在linux下寫一個shell,將文檔名字作為參數傳入執(zhí)行即可。 到此我利用程序完成了幾天的工作,還可以在以后相同的使用環(huán)境下更快速的完成工作。 |
|