Python 一大重要的功能,就是可處理大量數據,那分不開的即是使用Excel表格了,這里我做下學習之后的總結,望對我,及廣大同仁們是一個幫助
Python處理Excel數據需要用到2個庫:xlwt
和xlrd
。xlwt
庫負責將數據導入生成Excel表格文件,而xlrd
庫則負責將Excel表格中的數據取出來。xlrd
庫讀取Excel的數據也是輕輕松松,先來看下實現代碼
原表格簡要說明:
# coding = utf-8 # 將excel中某列數據中,含有指定字符串的記錄取出,並生成用這個字符串命名的excel文件 import xlrd, xlwt import os, sys # 按項目 導出到新的excel文件 def export_all_excel(): root_dir = '/Users/zhaojs/Downloads' for root, dirs, files in os.walk(root_dir): for file in files: file_xls = os.path.join(root_dir, file) if file_xls.endswith('.xls'): wb = xlrd.open_workbook(file_xls) # 獲取列表 sheet = wb.sheet_by_index(0) # 創建寫入文件 workbook = xlwt.Workbook(encoding="utf-8") # 總行數 total_rows = sheet.nrows # 總列數 total_cols = sheet.ncols print("行數 : %d 列數 : %d" % (total_rows, total_cols)) # 按項目簡稱小寫 創建sheet 對象 worksheet = workbook.add_sheet('全部') new_data = [ ['作業號', 'CPU/GPU', '項目', '場景文件', '渲染軟件', '幀', '提交時間', '完成時間', '層名', '提交賬戶', '平台', '內存(GB)', '余額消費(RMB)', '完成幀數', '總幀數', '消耗時間(機時)', '實際消費(RMB)', '差值'] ] loop_res = [] for i in range(10, total_rows - 1): # 去除最后一行總計 # 取出第i行 第 13 列的數據 平台名稱 # platform_name = sheet.cell_value(i, 13) excel_filename = 'all_projects.xls' outputs = sheet.row_values(i) # 將列表內的值轉成字符串 data = [str(z) for z in outputs] if data == '\n': pass else: tmp = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''] # 作業號 tmp[0] = data[1] # CPU/GPU || 實際消費 if data[13] == 'gpu': tmp[1] = 'GPU' sum_real_consumption = round(float(data[20]) * 4, 3) tmp[16] = str(sum_real_consumption) else: tmp[1] = 'CPU' sum_real_consumption = round(float(data[20]) * 1.3, 3) tmp[16] = str(sum_real_consumption) # 項目 tmp[2] = data[4][0:3] # 場景文件 tmp[3] = data[4] # 渲染軟件 tmp[4] = data[5] # 幀 tmp[5] = data[6] # 提交時間 tmp[6] = data[7] # 完成時間 tmp[7] = data[8] # 層名 tmp[8] = data[10] # 提交賬戶 tmp[9] = data[12] # 平台 tmp[10] = data[13] # 內存(GB) tmp[11] = data[14] # 余額消費(RMB) tmp[12] = data[15] # 完成幀數 tmp[13] = data[18] # 總幀數 tmp[14] = data[19] # 消耗時間(機時) tmp[15] = data[20] # 差值 計算差值 實際消費 - 余額消費 difference_value = 0 if (sum_real_consumption - float(data[15])) < 0 else int( sum_real_consumption - float(data[15])) tmp[17] = difference_value loop_res.append(tmp) # 形成帶表頭的列表集 new_data.append(tmp) # 計算匯總數據 sum_prices = 0 # 總消費 sum_finish_frames = 0 # 總完成幀數 sum_frames = 0 # 總幀數之和 sum_times = 0 # 機時之和 sum_real_consumption = 0 # 實際消費 difference_value = 0 # 差值 z = 0 for res in loop_res: # sys.exit() sum_prices += float(res[12]) sum_finish_frames += int(float(res[13])) sum_frames += int(float(res[14])) sum_times += float(res[15]) sum_real_consumption += float(res[16]) difference_value += float(res[17]) z = z + 1 tmp_data = ['', '', '', '', '', '', '', '', '', '', '', '', round(sum_prices, 3), sum_finish_frames, sum_frames, round(sum_times, 3), sum_real_consumption, difference_value] # 合成最終列表 new_data.append(tmp_data) i = 0 for data in new_data: for j in range(len(data)): worksheet.write(i, j, data[j]) i = i + 1 workbook.save('./' + excel_filename) if __name__ == "__main__": # Common_Excel().abc(123) export_all_excel()
總結一下,分為一下幾步:
- 首先通過
xlrd
庫的open_workbook
方法打開Excel文件(我這里的test.xls,是已存在數據的excel表格) - 然后通過
sheet_by_index
方法獲取表 - 然后分別獲取表的行數和列數,便於后面循環遍歷
- 根據列數和行數,循環遍歷,根據某列單元格內的數據,即通過
cell_value
方法獲取每個單元格中的數據,匹配到我手寫的字符串,如符合,則取出該行所有數據,再次循環該行數據,將其寫入到新的sheet中
工作表的相關操作
獲取一個工作表,有多種方式
# 通過索引
sheet1 = wb.sheets()[0] sheet1 = wb.sheet_by_index(0) # 通過名字
sheet1 = wb.sheet_by_name('test') # 獲取所有表名sheet_names = wb.sheet_names()
獲取某一行或某一列的所有數據
# 獲取行中所有數據,返回結果是一個列表
tabs = sheet1.row_values(rowx=0, start_colx=0, end_colx=None) # 返回一行一共有多少數據 len_value = sheet1.row_len(rowx=0)
row_values
的三個參數分別是:行號、開始的列和結束的列,其中結束的列為None
表示獲取從開始列到最后的所有數據
類似的還有獲取某一列的數據
cols = sheet1.col_values(colx=0, start_rowx=0, end_rowx=None)
處理時間數據
時間數據比較特殊,沒發直接通過上面的cell_value
方法獲取。需要先轉換為時間戳,然后再格式化成我們想要的格式。
比如要獲取Excel表格中,格式為2019/8/13 20:46:35
的時間數據
# 獲取時間 time_value = sheet1.cell_value(3, 0) # 獲取時間戳 time_stamp = int(xlrd.xldate.xldate_as_datetime(time_value, 0).timestamp()) print(time_stamp) # 格式化日期 time_rel = time.strftime("%Y/%m/%d", time.localtime(time_stamp)) print(time_rel)
基本也是三步走:
- 通過
cell_value
方法獲取時間值 - 然后通過
xldate_as_datetime
方法獲取時間戳 - 然后格式化一下