每每咱們在自動化測試彙總,會將數據放在 Excel 文件、CSV文件、數據庫數據庫
Python中處理 excel 數據的模塊很是多,好比: xlxd(只讀)、xlwd(只寫)、openpyxl(可讀寫)app
咱們會採用數據驅動思想,使用 openpyxl 當中的 load_workbook 來處理已存在的 Excel 文件數據,只能讀寫已 .xlsx 爲拓展名的文件;函數
以 .xlsx 爲拓展名的文件,爲一個 Excel 文件對象,一個excel對象中, 每每會有多個表單,一個表單中,有多個單元格對象;測試
問:對excel相關操做使用類來封裝? 封裝有什麼好處呢?spa
1、基本的使用excel
Excel 文件和下面的py文件代碼必定要在同一個文件夾內,否則須要指定具體的 Excel 文件路徑-------你們都是大佬我就很少說了code
讀取數據不須要關閉文件,寫入必須關閉文件;orm
from openpyxl import load_workbook # 第一步. 打開excel文件:使用load_workbook(譯:樓的個人不可)傳入文件名 wb = load_workbook("cases.xlsx") # 返回建立一個Workbook的對象, 至關是一個excel文件 # 第二步. 定位表單兩種方式 # active(譯:艾克體舞)是默認第一個表單 # ws = wb.active # 默認獲取第一個激活的表單, 會建立一個Worksheet對象, 至關於一個表單 # 也能夠指定表單 ws = wb['multiply'] # 第三步. 定位單元格 cell(譯:賽歐),row:(譯:肉)行、column:(譯:犒勞木)列 one_cell = ws.cell(row=2, column=2) # 會建立一個Cell對象, 至關於一個單元格 # 使用 Cell(譯:賽歐)對象中的value屬性, 能獲取單元格中的值 # print(one_cell.value) # 方法一: 定位單元格後,使用value屬性,將數據寫入到指定的單元格 one_cell.value = "休想" # 修改單元格的值 # 方法二: 定位表單,使用cell方法,將數據寫入到指定的單元格 ws.cell(row=2, column=3, value="休想") # 保存excel文件 save(譯:賽烏) # 寫入若是報錯:PermissionError: [Errno 13] Permission denied: 'cases.xlsx' ,必定是excel文件未關閉 wb.save("cases.xlsx")
Excel 文件及打印結果:對象
2、獲取下面表單中數據blog
方法一:cell 方法:
---不推薦使用,由於只能獲取固定的行到行、列到列之間的數據
from openpyxl import load_workbook # 對已經存在的excel進行讀寫操做 # 1. 打開excel文件 wb = load_workbook("cases.xlsx") # 會建立一個Workbook的對象, 是一個excel文件 # 2. 定位表單 ws = wb['aaa'] # 3. 定位單元格 # 方法一:獲取表單中數據:使用ws(譯:我可誰特)當中的cell(譯:賽歐)方法 # range(譯:軟解) # min_row(譯:敏.繞)表明最小行號:max_row(譯:馬克思.肉):最大行號 # min_column(譯:敏.犒勞木)最小列號、max_column(譯:敏.犒勞木):最大列號 for row in range(ws.min_row+1, ws.max_row+1): # 獲取行號 for col in range(ws.min_column, ws.max_column+1): # 獲取列號 data = ws.cell(row, col).value # 獲取值,使用value屬性 print("值爲: {}\n類型爲: {}".format(data, type(data))) # 打印結果
代碼執行結果文檔第一行:
方法二:使用 load_workbook 中 iter_rows(譯:艾特.肉死)方法 + zip 函數 獲取表單中數據
-----推薦使用這用,在自動化測試過程當中每執行一條測試用例,均可以使用表頭來獲取具體的值
from openpyxl import load_workbook # 對已經存在的excel進行讀寫操做 # 1. 打開excel文件 wb = load_workbook("cases.xlsx") # 會建立一個Workbook的對象, 是一個excel文件 # 2. 定位表單 ws = wb['aaa'] # min_row(譯:敏.繞)表明最小行號:max_row(譯:馬克思.肉):最大行號 # min_column(譯:敏.犒勞木)最小列號、max_column(譯:敏.犒勞木):最大列號 # 3. 定位單元格 # 方法二:使用 load_workbook 中 iter_rows(譯:艾特.肉死)方法獲取表單中數據 # openpyxl 版本爲2.6以上,要不沒有參數:values_only # 獲取的是單元格位置 使用 values_only = False 屬性默認獲取單元格對象 # 獲取的是單元格位置 使用 values_only = True 後獲取的是單元格的值 # 獲取表頭元祖,表頭位置爲0,表頭爲第一行,最小行號能夠不寫1,由於最大行號是1 # 結果爲生成器對象,須要使用 tuple 轉換爲元祖,轉換後爲嵌套元祖的元祖 head_data_tuple = tuple(ws.iter_rows(min_row=1, max_row=1, values_only=True))[0] print(head_data_tuple) # 獲取除表頭外測試用例數據,和獲取表頭同樣,最大行,最小列能夠不寫 for one_tuple in tuple(ws.iter_rows(min_row=2, max_row=5, min_col=1, max_col=7, values_only=True)): print(one_tuple) # 表頭和測試數據結果 # ('case_id', 'title', 'l_data', 'r_data', 'expected', 'actual', 'result') # (1, '負數與負數相乘', -2, -4, 8, None, None) # (2, '負數與正數相乘', -3, 4, 12, None, None) # (3, '零與零相乘', 0, 0, 0, None, None) # (4, '正數與正數相乘', 5, 3, -15, None, None) head_data_tuple1 = tuple(ws.iter_rows(min_row=1, max_row=1, values_only=True))[0] one_list1 = [] for one_tuple1 in tuple(ws.iter_rows(min_row=2, max_row=5, min_col=1, max_col=7, values_only=True)): # 表頭的元祖和數據元祖,使用 zip 方法進行轉換(返回zip的生成器對象) # 在使用dict(譯:迪克特)轉換成字典 # 使用append(譯:額噴的)添加到列表當中,獲取到一個嵌套字典的列表 one_list1.append(dict(zip(head_data_tuple1, one_tuple1))) print(one_list1) # 打印結果 # 結果: # [{'case_id': 1, 'title': '負數與負數相乘', 'l_data': -2, 'r_data': -4, 'expected': 8, 'actual': None, 'result': None}, # {'case_id': 2, 'title': '負數與正數相乘', 'l_data': -3, 'r_data': 4, 'expected': 12, 'actual': None, 'result': None}, # {'case_id': 3, 'title': '零與零相乘', 'l_data': 0, 'r_data': 0, 'expected': 0, 'actual': None, 'result': None}, # {'case_id': 4, 'title': '正數與正數相乘', 'l_data': 5, 'r_data': 3, 'expected': -15, 'actual': None, 'result': None}]
3、openpyxl 模塊的封裝:
from openpyxl import load_workbook class HandleExcel: """ 封裝excel文件處理類 """ def __init__(self, filename, sheetname=None): """ :param filename: 文件名 :param sheetname: 表單名,若是表單名只有一個能夠設置爲默認值 """ self.filename = filename self.sheetname = sheetname def get_cases(self): """ 獲取全部的測試用例,實例方法 :return: """ # 打開文件:使用load_workbook(樓的個人不可)傳入文件名 wb = load_workbook(self.filename) # 返回建立一個Workbook的對象, 至關是一個excel文件 if self.sheetname is None: # 定位表單,判斷是否制定表單默認空,爲第一個表單 ws = wb.active # active 獲取第一個表單 else: ws = wb[self.sheetname] # 不然獲取指定的表單 # min_row=最小行號,max_row=最大行號(能夠不寫) # min_col=最小列號,max_col=最大列號 # values_only=獲取單元格的值 # 獲取表頭的信息,使用iter_rows(艾特木肉絲)方法,嵌套元祖的元祖,省略最小行號 head_data_tuple = tuple(ws.iter_rows(max_row=1, values_only=True))[0] one_list = [] for one_tuple in tuple(ws.iter_rows(min_row=2, values_only=True)): # 不須要表頭最小行號爲2,不須要最大行號,最大最小列號 # zip函數將表頭的元祖與每一行用例所在的元祖進行拼接,dict轉換爲字典後,添加到列表當中one_list = [] one_list.append(dict(zip(head_data_tuple, one_tuple))) return one_list def get_one_case(self, row): """ 獲取某一條測試用例 :param row: 行號 :return: """ return self.get_cases()[row - 1] def write_result(self, row, actual, result): """ 寫入數據到測試用例指定的行列中 :param row: 行號 :param actual: 實際結果 :param result: 用例執行的結果(Pass或者Fail) :return: """ # 同一個Workbook對象, 若是將數據寫入到多個表單中, 那麼只有最後一個表單能寫入成功,須要建立不一樣的對象 other_wb = load_workbook(self.filename) # 建立對象 = 打開一個文件 if self.sheetname is None: other_ws = other_wb.active else: other_ws = other_wb[self.sheetname] # 寫入 if isinstance(row, int) and (2 <= row <= other_ws.max_row): # 不能修改表頭,下一行開始 other_ws.cell(row=row, column=6, value=actual) # 在第六行寫入實際結果 other_ws.cell(row=row, column=7, value=result) # 在第七行寫入用例執行的結果 other_wb.save(self.filename) # save保存文件 other_wb.close() # close關閉-----讀數據的時候不須要關閉,寫數據的時候可關閉或不關閉 else: # 若是不是整數,行號小於2,而且大於最大的行號 print("傳入的行號有誤, 行號應爲大於1的整數") if __name__ == '__main__': # 本身寫的模塊本身用使用 main 函數 filename = "cases.xlsx" sheetname = "Sheet1" # 指定第二個表單名 # 建立一個對象,filename=文件名和sheetname=表單名能夠不傳 # do_excel = HandleExcel(filename) # 不傳默認第一個表單 do_excel = HandleExcel(filename, sheetname) # 獲取全部的測試用例cases cases = do_excel.get_cases() print(cases) # 寫入在第二行寫入"初心", "青檸" a = do_excel.write_result(2, "初心7", "青檸") print(a)
*******請你們尊重原創,如要轉載,請註明出處:轉載自:https://www.cnblogs.com/shouhu/ 謝謝!!*******