python之openpyxl,详解,实战

一:excel基本概念

1: 一个excel表格文件包含一个工作簿(workbook),一个wb可以包含多个工作表(worksheets)

用户正在查看的表定义为激活的工作表(active sheet)。每个工作表都有行和列。行以数字1开始,列以字母A开始,

一个工作表由单元格(cell)组成,cell只存储两种数据类型,数字和字符串(除了纯数字,其它均为字符串类型)

2: 在excel中设计测试用例的时候,当代码里的值为None的时候,对应cell中不需要输入任何值,空读取出来就是None

 

二: openpyxl

对于openpyxl来说:

一个excel文件为一个workbook对象,一个sheet为一个worksheet对象,一个单元格为一个cell对象

1:三大属性

1:WorkBook 属性

sheetnames:返回所有WorkSheets的名字列表,以list形式存储

worksheets:返回所有WorkSheet的列表,以list形式存储

avtive:返回当前默人选中的WorkSheet

2:WorkSheet属性

3:cell属性

2:常规方法,操作

1:准备测试数据,用load_workbook模块,打开测试数据文件(需要传入数据文件路径),生成workbook对象(wb)

import os

from openpyxl import load_workbook
file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "login_case.xlsx")
wb = load_workbook(file_path)  # 看源码,需要传入要加载数据的文件的绝对路径
sh = wb["login"]  # 根据表单名称,选择sheet(表单)

2:在表单中,获取单元格的数据

单元格对象:

cel = sh.cell(2, 2)  # excel中的 下标是从1开始的
print(cel.value)  # 获取单元格的值
sh.cell(row, colum).value = 新的值  # 修改单元格的数据

3,获取当前表单(sheet)中总行数和总列数,在excel中可能会不小心写了空格,如果想要检查是否有空格,可以直接打印最大行数和列数,来进行检查!!

sh.max_row  # 总行数

sh.max_colum   # 总列数

4,按行读取数据

wb = load_workbook(file_path)  # 看源码,需要传入要加载数据的文件的绝对路径
sh = wb["login"]  # 根据表单名称,选择sheet(表单)
print(sh.rows)  # 直接打印出来的是该表单的所有行的数据的可迭代对象,
print(list(sh.rows))  # 使用list 转换成列表后,返回一个列表,列表成员是每一行的数据(元祖形式)
for i in list(sh.rows):  # 使用list 转换成列表后,返回一个列表,列表成员是每一行的数据(元祖形式),用for循环打印出来好看些
    print(i)

打印返回结果如下图:

 

5,保存数据,是保存整改工作簿

wb.save(文件路径),保存源文件时需要注意,文件有没有被占用,如果被占用,则会报没有权限的错误!

6,关闭文件,释放资源

wb.close

 

三:实战

1:首先明确,我们从excel中读取出来的数据,需要的格式如下:

datas = [
    {"user":"python27","passwd":"lemonban","check":{"code": 0, "msg": "登录成功"}},
    {"user":"python27","passwd":"lemonban11","check":{"code": 1, "msg": "账号或密码不正确"}},
    {"user":"python25","passwd":"lemonban","check":{"code": 1, "msg": "账号或密码不正确"}}
]
excel内部数据如下图:

python之openpyxl,详解,实战_第1张图片

分析可知:需要、将excel中的第一列(表头),读取出来,作为字典的key

import os

from openpyxl import load_workbook
file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "login_cases.xlsx") 
# 前提准备工作,找出需要操作的excel文件路径
wb = load_workbook(file_path)  # 看源码,需要传入要加载数据的文件的绝对路径,生成workbook对象
sh = wb["login"]  # 根据表单名称,选择sheet(表单)
print(list(sh.rows))  # 将excel中数据,按行读取出来,并转换成列表

titles = []
for item in list(sh.rows)[0]:  
# 将excel中数据,按行读取出来,并转换成列表,然后遍历列表中的第一行的每一列,添加到空列表中,当字典中的key
    titles.append(item.value)
print(titles)

2:将除第一行的数据,读取出来,作为字典的value值
这里的第二个for循环,是因为要去每一行的每一列的值,需要按照下标遍历每一行的每一列,所以,range的范围是,len(item)  ,item 行数

data_lists = []  # 定义一个总列表,存储数据
for item in list(sh.rows)[1:]:  # 将excel中数据,按行读取出来,转换成list后,遍历列表中从第二行开始的每一列
    value_dict = {}  # 定义空字典,接受读取出来的数据
    for index in range(len(item)):
        # 按照下标遍历每一行的每一列,获取单元格的数据,len(item) 的意思是你这个列表中长度有多少(就是有多少列),
        # 然后range(len(item)),就是按照列长度遍历多少次
        value_dict[titles[index]] = item[index].value
        # 将tiltes数据按照每次遍历的index(下标取值)作为key,同一次遍历出来的列表(item),
        # 通过index(下标)取值.value,item[index].value,通过字典[key] = value,赋值方式,添加到字典中

    print(value_dict)
    data_lists.append(value_dict)  # 将字典作为列表的成员,添加到总列表中
print(data_lists)

3:前面整理好思路后,对其进行封装。另外,封装中使用了zip函数,减少了一次循环,使代码更加简洁

具体代码如下:

"""
excel类,你的需求是实现是什么?
1、读取表头
2、读取数据 - 读取表头以外的所有数据。 - 返回值:列表,成员是每一行数据

初始化工作?  加载一个excel,打开一个表单。

"""
from openpyxl import load_workbook
import json

class HandleExcel:
    def __init__(self, file_path, sheet_name):
        self.wb = load_workbook(file_path)
        self.sh = self.wb[sheet_name]

    def __read_titles(self):  # 将读取表头的方法定义为私有属性,在后面读取所有数据的时候直接调用,是拿来给自己类内部使用的,不需要开放给外部
        titles = []
        for item in list(self.sh.rows)[0]:
            titles.append(item.value)
        return titles

    def read_all_datas(self):
        alldatas = []
        titles = self.__read_titles()
        for item in list(self.sh.rows)[1:]:
            values = []
            for val in item:
                values.append(val.value)
            res = dict(zip(titles, values))
            # 将请求数据从json字符串转换成字典对象,项目做的特殊处理
            # res["request_data"] = json.loads(res["request_data"])
            alldatas.append(res)
        return alldatas

    def close_file(self):
        self.wb.close()

if __name__ == '__main__':
    import os
    from Common.handle_path import datas_dir

    he = HandleExcel(datas_dir + r"\api_cases.xlsx", "注册")
    cases = he.read_all_datas()
    he.close_file()
    for case in cases:
        print(cases)

四:其它常用函数补充

1--  zip函数:

用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表,

在 Python 3.x 中为了减少内存,zip() 返回的是一个对象,如果需要展示列表,则需要用list转换,展示字典则用dict转换

代码示例如下:

li1 = ['user', 'passwd', 'check']
li2 = ["python27","lemonban66666",{"code": 0, "msg": "登录成功"}]

res = zip(li1,li2)
print(dict(res))

运行结果如下:

2--  eval 函数

eval() 函数用来执行一个字符串表达式,并返回表达式的值。还能将字符串转成python中的对象,eval转成了str(types.StringType)。但是遇到特殊字符的时候,(特殊字符包括:null, false,true)eval不能用,就要用json.loads

eg:

a = eval("2+2")  # 执行一个字符串表达式,返回表达式的值
print(a)  # 返回结果为4
s = '{"one":1,"two":2}' # 将字符串转换成python的对象,去掉单引号,变成字典类型
print(eval(s))

输出结果如下:

{'one': 1, 'two': 2}

3-- json.loads,dumps 函数

使用 JSON 函数需要导入 json 库:import json。而且,必须使用双引号,不支持单引号

函数 描述
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象
1-- json.loads 将str转换为dict格式
import json

jsonData = '{"a":1,"b":2,"c":3,"d":4,"e":5}'
print(type(jsonData))

text = json.loads(jsonData)
print(text)
print(type(text))

输出结果如下图:

 

2-- json.dumps 将dict转化为json字符串格式,这里需要注意一个点,如果涉及到中文的话,记得将ensure_ascii 参数设为False

import json

jsonData = {"a":1,"b":2,"c":3,"d":4,"e":"哈哈"}
print(type(jsonData))

text = json.dumps(jsonData, ensure_ascii=False)
print(text)
print(type(text))

输出入下图:

python之openpyxl,详解,实战_第2张图片

 

总结:如果需要进行数据类型的转换的时候,如果不涉及的数据计算,json和eval都可以用,涉及到计算的用eval,其它用json.loads 和json.dumps

 

 

你可能感兴趣的:(python,excel)