python寫數(shù)據(jù)到表格

一、openpyxl介紹安裝

1.為什么要學(xué)Excel

存測(cè)試數(shù)據(jù)

有時(shí)候有大批量的數(shù)據(jù),存到TXT文件里面顯然不是最佳的方式,我們可以存到Excel里面去,第一方便我們存數(shù)據(jù)和做數(shù)據(jù),另一方面方便我們讀取數(shù)據(jù),比較明朗。測(cè)試的時(shí)候就從數(shù)據(jù)庫中讀取出來,這點(diǎn)是非常重要的。

存測(cè)試結(jié)果

可以批量把結(jié)果存入到Excel中,也是比較好整理數(shù)據(jù)點(diǎn),比我們的TXT要好。

2.安裝openpyxl

python中與excel操作相關(guān)的模塊:

  • xlrd庫:從excel中讀取數(shù)據(jù),支持xls、xlsx
  • xlwt庫:對(duì)excel進(jìn)行修改操作,不支持對(duì)xlsx格式的修改
  • xlutils庫:在xlw和xlrd中,對(duì)一個(gè)已存在的文件進(jìn)行修改。
  • openpyxl:主要針對(duì)xlsx格式的excel進(jìn)行讀取和編輯。

安裝方式:pip install openpyxl

3.Excel中的三大對(duì)象

  • WorkBook:工作簿對(duì)象
  • Sheet:表單對(duì)象
  • Cell:表格對(duì)象

二、openpyxl對(duì)Excel的操作

  • 創(chuàng)建一個(gè)工作?。簑b = openpyxl.Workbook()
  • 新增一個(gè)sheet表單:wb.create_sheet('test_case')
  • 保存case.xlsx文件:wb.save('cases.xlsx')
  • 打開工作簿:wb = openpyxl.load_workbook('cases.xlsx')
  • 選取表單:sh = wb['Sheet1'
  • 讀取第一行、第一列的數(shù)據(jù):ce = sh.cell(row = 1,column = 1)
  • 按行讀取數(shù)據(jù):row_data = list(sh.rows)
  • 關(guān)閉工作薄:wb.close()
  • 按列讀取數(shù)據(jù):columns_data = list(sh.columns)
  • 寫入數(shù)據(jù)之前,該文件一定要處于關(guān)閉狀態(tài)
  • 寫入第一行、第四列的數(shù)據(jù) value = 'result':sh.cell(row = 1,column = 4,value = 'result')
  • 獲取最大行總數(shù)、最大列總數(shù):sh.max_row、sh.max_column
  • del 刪除表單的用法:del wb['sheet_name']
  • remove 刪除表單的用法:sh = wb['sheet_name'] wb.remove(sh)

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 1 import openpyxl 2 # 創(chuàng)建一個(gè)工作簿
3 wb = openpyxl.Workbook() 4 # 創(chuàng)建一個(gè)test_case的sheet表單
5 wb.create_sheet('test_case')
6 # 保存為一個(gè)xlsx格式的文件
7 wb.save('cases.xlsx')
8 # 讀取excel中的數(shù)據(jù)
9 # 第一步:打開工作簿
10 wb = openpyxl.load_workbook('cases.xlsx') 11 # 第二步:選取表單
12 sh = wb['Sheet1'] 13 # 第三步:讀取數(shù)據(jù)
14 # 參數(shù) row:行 column:列
15 ce = sh.cell(row = 1,column = 1) # 讀取第一行,第一列的數(shù)據(jù)
16 print(ce.value) 17 # 按行讀取數(shù)據(jù) list(sh.rows)
18 print(list(sh.rows)[1:]) # 按行讀取數(shù)據(jù),去掉第一行的表頭信息數(shù)據(jù)
19 for cases in list(sh.rows)[1:]: 20 case_id = cases[0].value 21 case_excepted = cases[1].value 22 case_data = cases[2].value 23 print(case_excepted,case_data) 24 # 關(guān)閉工作薄
25 wb.close()</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

三.封裝一個(gè)讀取用例的excel類:用來實(shí)現(xiàn)讀取數(shù)據(jù)和寫入數(shù)據(jù)的功能

cases.xlsx的測(cè)試數(shù)據(jù):

image

1.按行讀取數(shù)據(jù),存儲(chǔ)在列表中

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 1 import openpyxl 2 class Case: #這個(gè)類用來存儲(chǔ)用例的
3 slots = [] #特殊的類屬性,可以用來限制這個(gè)類創(chuàng)建的實(shí)例屬性添加 可寫可不寫
4 pass
5
6 class ReadExcel(object): #讀取excel數(shù)據(jù)的類
7 def init(self,file_name,sheet_name):
8 """
9 這個(gè)是用來初始化讀取對(duì)象的 10 :param file_name: 文件名 ---> str類型 11 :param sheet_name: 表單名 ———> str類型 12 """
13 # 打開文件
14 self.wb = openpyxl.load_workbook(file_name) 15 # 選擇表單
16 self.sh = self.wb[sheet_name] 17 def read_data_line(self): 18 #按行讀取數(shù)據(jù)轉(zhuǎn)化為列表
19 rows_data = list(self.sh.rows) 20 # print(rows_data)
21 # 獲取表單的表頭信息
22 titles = [] 23 for title in rows_data[0]: 24 titles.append(title.value) 25 # print(titles)
26 #定義一個(gè)空列表用來存儲(chǔ)測(cè)試用例
27 cases = [] 28 for case in rows_data[1:]: 29 # print(case)
30 data = [] 31 for cell in case: #獲取一條測(cè)試用例數(shù)據(jù)
32 # print(cell.value)
33 data.append(cell.value) 34 # print(data)
35 #判斷該單元格是否為字符串,如果是字符串類型則需要使用eval();如果不是字符串類型則不需要使用eval()
36 if isinstance(cell.value,str): 37 data.append(eval(cell.value)) 38 else: 39 data.append(cell.value) 40 #將該條數(shù)據(jù)存放至cases中
41 # print(dict(list(zip(titles,data))))
42 case_data = dict(list(zip(titles,data))) 43 cases.append(case_data) 44 return cases 45 if name == 'main': 46 r = ReadExcel('cases.xlsx','Sheet1') 47 data1 = r.read_data_line() 48 print(data1)</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

2.按行讀取數(shù)據(jù),存儲(chǔ)在對(duì)象中

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 1 import openpyxl 2 class Case: 3 pass
4 class ReadExcel(object): 5 def init(self,filename,sheetname):
6 self.wb = openpyxl.load_workbook(filename) 7 self.sh = self.wb[sheetname] 8 def read_data_obj(self): 9 """
10 按行讀取數(shù)據(jù) 每條用例存儲(chǔ)在一個(gè)對(duì)象中 11 :return: 12 """
13 rows_data = list(self.sh.rows) 14 # print(rows_data)
15 # 獲取表單的表頭信息
16 titles = [] 17 for title in rows_data[0]: 18 titles.append(title.value) 19 # print(titles)
20 # 定義一個(gè)空列表用來存儲(chǔ)測(cè)試用例
21 cases = [] 22 for case in rows_data[1:]: 23 # print(case)
24 #創(chuàng)建一個(gè)Case類的對(duì)象,用來保存用例數(shù)據(jù)
25 case_obj = Case() 26 data = [] 27 for cell in case: # 獲取一條測(cè)試用例數(shù)據(jù)
28 # print(cell.value)
29 # data.append(cell.value)
30 # print(data)
31 if isinstance(cell.value,str): # 判斷該單元格是否為字符串,如果是字符串類型則需要使用eval();如果不是字符串類型則不需要使用eval()
32 data.append(eval(cell.value)) 33 else: 34 data.append(cell.value) 35 # 將該條數(shù)據(jù)存放至cases中
36 # print(dict(list(zip(titles,data))))
37 case_data = list(zip(titles, data)) 38 # print(case_data)
39 for i in case_data: 40 setattr(case_obj,i[0],i[1]) 41 # print(case_obj)
42 # print(case_obj.case_id,case_obj.data,case_obj.excepted)
43 cases.append(case_obj) 44 return cases 45 if name == 'main': 46 r = ReadExcel('cases.xlsx','Sheet1') 47 res = r.read_data_obj() 48 for i in res: 49 print(i.caseid, i.excepted, i.data)</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

3.將測(cè)試用例封裝到列表中,讀取指定列的數(shù)據(jù)

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 1 import openpyxl 2 class Case: 3 pass
4 class ReadExcelZy(object): 5 def init(self,filename,sheetname):
6 self.wb = openpyxl.load_workbook(filename) 7 self.sheet = self.wb[sheetname] 8 # list1 參數(shù)為一個(gè)列表,傳入的是指定讀取數(shù)據(jù)的列,比如[1,2,3]
9 # 每一行[1,3,5]列的數(shù)據(jù),讀取出來就作為一條測(cè)試用例,放在字典中
10 # 所有的用例放在列表中并且進(jìn)行返回
11 def read_data(self,list1): 12 """
13 :param list1: list--->要讀取列 list類型 14 :return: 返回一個(gè)列表,每一個(gè)元素為一個(gè)用例(用例為dict類型) 15 """
16 # 獲取最大的行數(shù)
17 max_r = self.sheet.max_row 18 cases = [] #定義一個(gè)空列表,用來存放所有的用例數(shù)據(jù)
19 titles = [] #定義一個(gè)空列表,用來存放表頭
20 # 遍歷所有的行數(shù)據(jù)
21 for row in range(1,max_r+1): 22 if row != 1: #判斷是否是第一行
23 case_data = [] #定義一個(gè)空列表,用來存放該行的用例數(shù)據(jù)
24 for column in list1: 25 info = self.sheet.cell(row,column).value 26 # print(info)
27 case_data.append(info) 28 # print(list(zip(titles,case_data)))
29 case = dict(zip(titles,case_data)) #將該條數(shù)據(jù)和表頭進(jìn)行打包組合,作用相當(dāng)于dict(list(zip(titles,case_data)))
30 # print(case)
31 cases.append(case) 32 # print(cases)
33 else: #獲取表頭數(shù)據(jù)
34 for column in list1: 35 title = self.sheet.cell(row,column).value 36 titles.append(title) 37 # print(titles)
38 return cases 39 if name == 'main': 40 r = ReadExcelZy("cases.xlsx","Sheet1") 41 res = r.read_data([1,2,3]) 42 for o in res: 43 print(o['caseid'],o['data'],o['excepted'])</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

4.將測(cè)試用例封裝到對(duì)象中,讀取指定列的數(shù)據(jù)

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 1 import openpyxl 2 class Case: 3 pass
4 class ReadExcelZy(object): 5 def init(self,filename,sheetname):
6 self.wb = openpyxl.load_workbook(filename) 7 self.sheet = self.wb[sheetname] 8
9 # list1 參數(shù)為一個(gè)列表,傳入的是指定讀取數(shù)據(jù)的列,比如[1,2,3]
10 # 每一行[1,3,5]列的數(shù)據(jù),讀取出來就作為一條測(cè)試用例,放在字典中
11 # 所有的用例放在對(duì)象中并且進(jìn)行返回
12 def read_data_obj(self,list2): 13 max_r1 = self.sheet.max_row #獲取最大行數(shù)
14 cases = [] 15 titles = [] #用來存放表頭數(shù)據(jù)
16 for row in range(1,max_r1+1): 17 if row != 1: 18 case_data = [] 19 for column in list2: 20 info = self.sheet.cell(row,column).value 21 # print(info)
22 case_data.append(info) 23 cases_data = list(zip(titles,case_data)) 24 #將一條用例存到一個(gè)對(duì)象中(每一列對(duì)應(yīng)對(duì)象的一個(gè)屬性)
25 case_obj = Case() 26 for i in cases_data: 27 # print(i)
28 setattr(case_obj,i[0],i[1]) 29 # print(case_obj.caseid,case_obj.excepted,case_obj.data)
30 cases.append(case_obj) 31 else: 32 for column in list2: 33 title = self.sheet.cell(row,column).value 34 titles.append(title) 35 return cases 36 if name == 'main': 37 r = ReadExcelZy("cases.xlsx","Sheet1") 38 res = r.read_data_obj([1,2,3]) 39 for i in res: 40 print(i.caseid,i.data,i.excepted)</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

5.優(yōu)化第4部分代碼,將設(shè)置對(duì)象屬性寫在初始化方法中(封裝Excel類讀取數(shù)據(jù)最常用的方法)

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 1 import openpyxl 2 class Case: # 這個(gè)類用來存儲(chǔ)用例的
3 def init(self, attrs):
4 """
5 初始化用例
6 :param attrs:zip類型——>[{key,value},(key1,value1)......]
7 """
8 for i in attrs: 9 setattr(self, i[0], i[1]) 10 class ReadExcel(object): 11 def init(self, filename, sheetname): 12 """
13 定義需要打開的文件及表名 14 :param filename: 文件名 15 :param sheetname: 表名 16 """
17 self.wb = openpyxl.load_workbook(filename) 18 self.sheet = self.wb[sheetname] 19 def read_data_obj_new(self, list2): 20 # 獲取最大行數(shù)
21 max_r1 = self.sheet.max_row 22 cases = [] 23 # 用來存放表頭數(shù)據(jù)
24 titles = [] 25 for row in range(1, max_r1 + 1): 26 if row != 1: 27 case_data = [] 28 for column in list2: 29 info = self.sheet.cell(row, column).value 30 # print(info)
31 case_data.append(info) 32 case = list(zip(titles, case_data)) 33 # 新建對(duì)象時(shí),將對(duì)象傳給Case類 34 case_obj = Case(case) 35 # print(case_obj.caseid,case_obj.excepted,case_obj.data)
36 cases.append(case_obj) 37 else: 38 # 獲取表頭
39 for column in list2: 40 title = self.sheet.cell(row, column).value 41 titles.append(title) 42 if None in titles: 43 raise ValueError("傳入的表頭的數(shù)據(jù)有顯示為空") 44 return cases 45 if name == 'main': 46 r = ReadExcel('cases.xlsx', 'Sheet1') 47 res1 = r.read_data_obj_new([1, 2, 3]) 48 for i in res1: 49 print(i.caseid, i.data, i.excepted)</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

三.完整流程的代碼

一、將測(cè)試數(shù)據(jù)參數(shù)化

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 1 import unittest 2 from python.register_new.register import register 3 from python.register_new.register_testcase_new import RegisterTestCase 4 from HTMLTestRunnerNew import HTMLTestRunner 5 class RegisterTestCase(unittest.TestCase): 6 # 初始化測(cè)試用例
7 def init(self,modethod_name,excepted,data):
8 # modethod_name 測(cè)試用例方法名
9 super().init(modethod_name) 10 # excepted 測(cè)試用例的預(yù)期結(jié)果
11 self.excepted = excepted 12 # data 測(cè)試用例參數(shù)值
13 self.data = data 14
15 def setUp(self): 16 print("準(zhǔn)備測(cè)試環(huán)境,執(zhí)行測(cè)試用例之前會(huì)執(zhí)行此操作") 17
18 def tearDown(self): 19 print("還原測(cè)試環(huán)境,執(zhí)行完測(cè)試用例之后會(huì)執(zhí)行此操作") 20
21 def test_register(self): 22 res = register(*self.data) 23 try: 24 self.assertEquals(self.excepted,res) 25 except AssertionError as e: 26 print("該條測(cè)試用例執(zhí)行未通通過") 27 raise e 28 else: 29 print("該條測(cè)試用例執(zhí)行通過") 30
31 # 創(chuàng)建測(cè)試套件
32 suite = unittest.TestSuite() 33
34 # 將測(cè)試用例添加至測(cè)試套件中
35 case = [{'excepted':'{"code": 1, "msg": "注冊(cè)成功"}','data':'('python1', '123456','123456')'}, 36 {'excepted':'{"code": 0, "msg": "兩次密碼不一致"}','data':'('python1', '1234567','123456')'}] 37 for case in cases: 38 suite.addTest(RegisterTestCase('test_register',case['excepted'],case['data'])) 39
40 # 執(zhí)行測(cè)試套件,生成測(cè)試報(bào)告
41 with open("report.html",'wb') as f: 42 runner = HTMLTestRunner( 43 stream = f, 44 verbosity = 2, 45 title = 'python_test_report', 46 description = '這是一份測(cè)試報(bào)告', 47 tester = 'WL'
48 ) 49 runner.run(suite) </pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

二.將調(diào)用封裝好的Excel類的完整代碼流程

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; overflow: auto; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">import unittest from python.register_new.register import register from python.register_new.register_testcase_new import RegisterTestCase from HTMLTestRunnerNew import HTMLTestRunner from python.readexcel import ReadExcel class RegisterTestCase(unittest.TestCase): # 初始化測(cè)試用例
def init(self, modethod_name, excepted, data): # modethod_name 測(cè)試用例方法名
super().init(modethod_name) # excepted 測(cè)試用例的預(yù)期結(jié)果
self.excepted = excepted # data 測(cè)試用例參數(shù)值
self.data = data def setUp(self): print("準(zhǔn)備測(cè)試環(huán)境,執(zhí)行測(cè)試用例之前會(huì)執(zhí)行此操作") def tearDown(self): print("還原測(cè)試環(huán)境,執(zhí)行完測(cè)試用例之后會(huì)執(zhí)行此操作") def test_register(self):
res = register(*self.data) try:
self.assertEquals(self.excepted, res) except AssertionError as e: print("該條測(cè)試用例執(zhí)行未通通過") raise e else: print("該條測(cè)試用例執(zhí)行通過") # 創(chuàng)建測(cè)試套件
suite = unittest.TestSuite() # 調(diào)用封裝好的讀取數(shù)據(jù)的Excel類,獲取測(cè)試數(shù)據(jù)
r1 = ReadExcel('cases.xlsx', 'Sheet1')
cases = r1.read_data_obj_new([2, 3]) # 將測(cè)試用例添加至測(cè)試套件中
for case in cases: # 需要使用eval()函數(shù)對(duì)except和data進(jìn)行自動(dòng)識(shí)別
suite.addTest(RegisterTestCase('test_register', eval(case.excepted), eval(case.data))) # 執(zhí)行測(cè)試套件,生成測(cè)試報(bào)告
with open("report.html", 'wb') as f:
runner = HTMLTestRunner(
stream=f,
verbosity=2,
title='python_test_report',
description='這是一份測(cè)試報(bào)告',
tester='WL')
runner.run(suite)</pre>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容