python操作Excel表格


一、openpyxl介紹安裝

1.為什么要學Excel

存測試數據

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

存測試結果

可以批量把結果存入到Excel中,也是比較好整理數據點,比我們的TXT要好。

2.安裝openpyxl

python中與excel操作相關的模塊:

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

官方說法:網址:http://www.python-exceel.org/

安裝方式:pip install openxl

3.Excel中的三大對象

  • WorkBook:工作簿對象
  • Sheet:表單對象
  • Cell:表格對象

二、openpyxl對Excel的操作

  • 創建一個工作薄:wb = openpyxl.Workbook()
  • 新增一個sheet表單:wb.create_sheet('test_case')
  • 保存case.xlsx文件:wb.save('cases.xlsx')
  • 打開工作簿:wb = openpyxl.load_workbook('cases.xlsx')
  • 選取表單:sh = wb['Sheet1'
  • 讀取第一行、第一列的數據:ce = sh.cell(row = 1,column = 1)
  • 按行讀取數據:row_data = list(sh.rows)
  • 關閉工作薄:wb.close()
  • 按列讀取數據:columns_data = list(sh.columns)
  • 寫入數據之前,該文件一定要處於關閉狀態
  • 寫入第一行、第四列的數據 value = 'result':sh.cell(row = 1,column = 4,value = 'result')
  • 獲取最大行總數、最大列總數:sh.max_row、sh.max_column
  • del 刪除表單的用法:del wb['sheet_name'] 
  • remove 刪除表單的用法:sh = wb['sheet_name'] wb.remove(sh) 
  •  
 1 import openpyxl
 2 # 創建一個工作簿
 3 wb = openpyxl.Workbook()
 4 # 創建一個test_case的sheet表單
 5 wb.create_sheet('test_case')
 6 # 保存為一個xlsx格式的文件
 7 wb.save('cases.xlsx')
 8 # 讀取excel中的數據
 9 # 第一步:打開工作簿
10 wb = openpyxl.load_workbook('cases.xlsx')
11 # 第二步:選取表單
12 sh = wb['Sheet1']
13 # 第三步:讀取數據
14 # 參數 row:行  column:列
15 ce = sh.cell(row = 1,column = 1)   # 讀取第一行,第一列的數據
16 print(ce.value)
17 # 按行讀取數據 list(sh.rows)
18 print(list(sh.rows)[1:])     # 按行讀取數據,去掉第一行的表頭信息數據
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 # 關閉工作薄
25 wb.close()

 

三.封裝一個讀取用例的excel類:用來實現讀取數據和寫入數據的功能

 cases.xlsx的測試數據:

1.按行讀取數據,存儲在列表中

 1 import openpyxl
 2 class Case: #這個類用來存儲用例的
 3     __slots__ = [] #特殊的類屬性,可以用來限制這個類創建的實例屬性添加 可寫可不寫
 4     pass
 5 
 6 class ReadExcel(object): #讀取excel數據的類
 7     def __init__(self,file_name,sheet_name):
 8         """
 9         這個是用來初始化讀取對象的
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         #按行讀取數據轉化為列表
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         #定義一個空列表用來存儲測試用例
27         cases = []
28         for case in rows_data[1:]:
29             # print(case)
30             data = []
31             for cell in case: #獲取一條測試用例數據
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                 #將該條數據存放至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)

2.按行讀取數據,存儲在對象中

 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         按行讀取數據  每條用例存儲在一個對象中
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         # 定義一個空列表用來存儲測試用例
21         cases = []
22         for case in rows_data[1:]:
23             # print(case)
24             #創建一個Case類的對象,用來保存用例數據
25             case_obj = Case()
26             data = []
27             for cell in case:  # 獲取一條測試用例數據
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             # 將該條數據存放至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)

 3.將測試用例封裝到列表中,讀取指定列的數據

 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 參數為一個列表,傳入的是指定讀取數據的列,比如[1,2,3]
 9         # 每一行[1,3,5]列的數據,讀取出來就作為一條測試用例,放在字典中
10         # 所有的用例放在列表中並且進行返回
11     def read_data(self,list1):
12         """
13         :param list1:  list--->要讀取列   list類型
14         :return:    返回一個列表,每一個元素為一個用例(用例為dict類型)
15         """
16         # 獲取最大的行數
17         max_r = self.sheet.max_row
18         cases = []   #定義一個空列表,用來存放所有的用例數據
19         titles = []   #定義一個空列表,用來存放表頭
20         # 遍歷所有的行數據
21         for row in range(1,max_r+1):
22             if row != 1:      #判斷是否是第一行
23                 case_data = [] #定義一個空列表,用來存放該行的用例數據
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))  #將該條數據和表頭進行打包組合,作用相當於dict(list(zip(titles,case_data)))
30                 # print(case)
31                 cases.append(case)
32                 # print(cases)
33             else:   #獲取表頭數據
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'])

 4.將測試用例封裝到對象中,讀取指定列的數據

 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 參數為一個列表,傳入的是指定讀取數據的列,比如[1,2,3]
10         # 每一行[1,3,5]列的數據,讀取出來就作為一條測試用例,放在字典中
11         # 所有的用例放在對象中並且進行返回
12     def read_data_obj(self,list2):
13         max_r1 = self.sheet.max_row      #獲取最大行數
14         cases = []
15         titles = []      #用來存放表頭數據
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                 #將一條用例存到一個對象中(每一列對應對象的一個屬性)
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)

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

 1 import openpyxl
 2 class Case:  # 這個類用來存儲用例的
 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         # 獲取最大行數
21         max_r1 = self.sheet.max_row
22         cases = []
23         # 用來存放表頭數據
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                 # 新建對象時,將對象傳給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("傳入的表頭的數據有顯示為空")
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)

三.完整流程的代碼

一、將測試數據參數化

 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     # 初始化測試用例
 7     def __init__(self,modethod_name,excepted,data): 
 8         # modethod_name 測試用例方法名
 9         super().__init__(modethod_name)
10         # excepted 測試用例的預期結果
11         self.excepted = excepted
12         # data 測試用例參數值                
13         self.data = data
14 
15     def setUp(self):
16         print("准備測試環境,執行測試用例之前會執行此操作")
17 
18     def tearDown(self):
19         print("還原測試環境,執行完測試用例之后會執行此操作")
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("該條測試用例執行未通通過")
27             raise e
28         else:
29             print("該條測試用例執行通過")  
30 
31 # 創建測試套件
32 suite = unittest.TestSuite()
33 
34 # 將測試用例添加至測試套件中
35 case = [{'excepted':'{"code": 1, "msg": "注冊成功"}','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 # 執行測試套件,生成測試報告
41 with open("report.html",'wb') as f:
42     runner = HTMLTestRunner(
43         stream = f,
44         verbosity = 2,
45         title = 'python_test_report',
46         description = '這是一份測試報告',
47         tester = 'WL'
48     )
49     runner.run(suite)  

二.將調用封裝好的Excel類的完整代碼流程

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):
    # 初始化測試用例
    def __init__(self, modethod_name, excepted, data):
        # modethod_name 測試用例方法名
        super().__init__(modethod_name)
        # excepted 測試用例的預期結果
        self.excepted = excepted
        # data 測試用例參數值
        self.data = data

    def setUp(self):
        print("准備測試環境,執行測試用例之前會執行此操作")

    def tearDown(self):
        print("還原測試環境,執行完測試用例之后會執行此操作")

    def test_register(self):
        res = register(*self.data)
        try:
            self.assertEquals(self.excepted, res)
        except AssertionError as e:
            print("該條測試用例執行未通通過")
            raise e
        else:
            print("該條測試用例執行通過")


# 創建測試套件
suite = unittest.TestSuite()
# 調用封裝好的讀取數據的Excel類,獲取測試數據
r1 = ReadExcel('cases.xlsx', 'Sheet1')
cases = r1.read_data_obj_new([2, 3])
# 將測試用例添加至測試套件中
for case in cases:
    # 需要使用eva()函數對except和data進行自動識別
    suite.addTest(RegisterTestCase('test_register', eval(case.excepted), eval(case.data)))
# 執行測試套件,生成測試報告
with open("report.html", 'wb') as f:
    runner = HTMLTestRunner(
        stream=f,
        verbosity=2,
        title='python_test_report',
        description='這是一份測試報告',
        tester='WL')
    runner.run(suite)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM