Python_openpyxl、xlrd&xlwt_对excel表格进行读写

openpyxl 和 xlrd&xlwt 都能对excel进行读写,但是它们读写的格式不同,openpyxl 只能读写 xlsx格式的excel,xlrd&xlwt 只能读写 xls格式的excel。

openpyxl

创建excel文件

import openpyxl
# ====== 创建格式为xlsx的excel文件 ======
# 创建一个工作簿,若表格已存在,则覆盖
wb = openpyxl.Workbook()

# 创建一个名为test的sheet
wb.create_sheet('test')

# 保存文件。注:创建表格会有两个sheet,按顺序名称分别为Sheet和test
wb.save('test.xlsx')

# 关闭工作薄
wb.close()

读写已有excel文件

import openpyxl

#
====== 打开已有的excel表格 ====== # 打开一个工作簿 wb = openpyxl.load_workbook('test.xlsx') # 选择一个sheet # sheet = wb["Sheet1"] # 通过表名选择 sheet = wb.worksheets[0] # 通过索引选择 # 关闭工作薄 wb.close()

对sheet进行读写

# coding:utf-8
import openpyxl

# ====== 向sheet写入数据 ======
# 打开一个工作簿
wb = openpyxl.load_workbook('test.xlsx')
# 选择一个sheet
# sheet = wb["Sheet1"]     # 通过表名选择
sheet = wb.worksheets[0]      # 通过索引选择

# 获取行数
row = sheet.max_row
# 获取列数
column = sheet.max_column
print(row, column)

# 写入数据
sheet.append(["aaa", "bbb", "ccc"])     # 在最后一行写入一行数据,列表中每一个数据表示每列写入的数据
sheet.append([1, 2, 3, 4])

# 读取数据
ce = sheet.cell(row=1, column=1)    # 读取第1行,第1列的数据
print(ce.value)

# 更新数据
ce.value = "ddd"    # 更新第1行,第1列的数据为 ddd
sheet.cell(3, 1, '')    # 更新第3行第1列的数据为 空串

# 删除数据
# 从第2行开始删除,删除1行
sheet.delete_rows(2, amount=1)
# 删除第3列
sheet.delete_cols(3)

# 保存文件
wb.save('test.xlsx')
# 关闭工作薄
wb.close()

简单封装

# coding:utf-8
import openpyxl
import os


class Workbook:
    workbook = None
    filename = None

    @classmethod
    def get_workbook(cls, filename, is_create=False):
        """ 获取工作簿,若文件存在则打开,若文件不存在则新建 """
        cls.filename = filename
        is_file = os.path.exists(filename)
        if is_create:
            is_file = False
        if is_file:
            cls.workbook = openpyxl.load_workbook(filename)
        else:
            cls.workbook = openpyxl.Workbook()
        return cls()

    def sheet_by_name(self, sheet_name):
        """ 通过表的名称获取sheet对象 """
        ws = WorkSheet(self.workbook)
        return ws.sheet_by_name(sheet_name)

    def sheet_by_index(self, index):
        """ 通过表的索引获取sheet对象 """
        ws = WorkSheet(self.workbook)
        return ws.sheet_by_index(index)

    def save(self, filename=None):
        if filename is None:
            filename = self.filename
        self.workbook.save(filename)

    def close(self):
        self.workbook.close()


class WorkSheet:

    def __init__(self, workbook):
        self.workbook = workbook
        self.sheet = None

    def sheet_by_name(self, name):
        """ 通过表的名称获取sheet对象 """
        self.sheet = self.workbook[name]
        return self

    def sheet_by_index(self, index):
        """ 通过表的索引获取sheet对象 """
        self.sheet = self.workbook.worksheets[index]
        return self

    def get_cell_value(self,  row, column):
        """ 获取单元格的值 """
        return self.sheet.cell(row, column).value

    def get_col_values(self, column):
        """ 获取指定列的所有值 """
        col_values = []
        rows = self.rows
        for row in range(rows):
            row += 1
            v = self.get_cell_value(row, column)
            col_values.append(v)
        return col_values

    def get_row_values(self, row):
        """ 获取指定行的所有值 """
        row_values = []
        columns = self.columns
        for column in range(columns):
            column += 1
            v = self.get_cell_value(row, column)
            row_values.append(v)
        return row_values

    def write_cell_value(self, row, column, value):
        """ 写入或更新单元格的值 """
        return self.sheet.cell(row, column, value)

    def insert_row_values(self, values, row=None):
        """
        插入一行数据,默认插入最后一行
        :param values: 插入的数据
        :type values: list
        :param row: 行号
        :type row: int
        """
        if row is None:
            self.sheet.append(values)
        else:
            self.sheet.insert_rows(row)
            col = 1
            for v in values:
                self.write_cell_value(row, col, v)
                col += 1

    def insert_column_values(self, values, column=None):
        """ 插入一列数据,默认插入最后一列 """
        if column is None:
            col = self.columns
            row = self.rows
            v = self.get_cell_value(1, 1)
            if col == 1 and row == 1 and v is None:
                column = 1
            else:
                column = self.columns + 1
        else:
            self.sheet.insert_cols(column)
        row = 1
        for v in values:
            self.write_cell_value(row, column, v)
            row += 1

    def delete_rows(self, row, amount=1):
        """ 删除行数, row表示删除起始行,amount表示删除的行数 """
        self.sheet.delete_rows(row, amount)

    @property
    def rows(self):
        """ 表格的行数 """
        return self.sheet.max_row

    @property
    def columns(self):
        """ 表格的列数 """
        return self.sheet.max_column


def handle_values(values):
    """ 处理表格数据 """
    if isinstance(values, str):
        values = [values]
    new_values = []
    for i, value in enumerate(values):
        # 替换换行符;将英文分号替换为中文分号;
        try:
            # 替换换行符解决jira无法导入问题,替换分号解决jira分割问题,替换逗号解决csv文件分割问题
            v = value.replace("\n", "").replace(";", "").replace(",", "")
            new_values.append(v)
        except Exception as e:
            raise RuntimeError("第【%s】的数据替换失败,失败原因:%s" % (i + 1, e))
    return new_values


def save_to_csv(filename, col_values):
    # 将数据另存到新的文件
    filename_path = filename.split('\\')
    new_filenames = filename_path[-1].split('.')
    new_filenames.pop()
    new_filename = "jira_" + ".".join(new_filenames) + ".csv"
    filename_path.pop()
    filename_path.append(new_filename)
    new_filename_path = "\\".join(filename_path)
    with open(new_filename_path, "w") as f:
        for col_value in col_values:
            try:
                f.write(col_value + "\n")
            except Exception as e:
                raise RuntimeError("数据写入文件失败【%s】,报错:%s" % (col_value, e))
    print("生成jira导入文件:%s" % new_filename)


def export_jira_file(file_name, sheet_index=0, test_summary=None, action=None, result=None):
    """
    file_name:excel的xlsx文件
    sheet_index:sheet页索引
    test_summary:jira的“test_summary”在excel中对应的名称。如果以列表传入多个excel字段,会拼接成一个字段
    action:jira的“action”在excel中对应的名称。如果以列表传入多个excel字段,会拼接成一个字段
    result:jira的“result”在excel中对应的名称。如果以列表传入多个excel字段,会拼接成一个字段
    """
    test_summary = test_summary or ["用例名称"]
    action = action or "用例步骤"
    result = result or "预期结果"

    # 打开一个工作簿
    wb = Workbook.get_workbook(file_name)
    # 选择一个sheet
    _sheet = wb.sheet_by_index(sheet_index)  # 通过索引选择

    # 获取表格所有字段
    sheet_fields = _sheet.get_row_values(1)

    field_values = []
    for filed_names in [test_summary, action, result]:
        if isinstance(filed_names, str):
            filed_names = [filed_names]

        join_values = []    # 待连接值
        for fn in filed_names:
            if fn not in sheet_fields:
                raise RuntimeError("表格不存在字段:%s" % fn)
            # 获取字段列号
            col_num = sheet_fields.index(fn) + 1
            # 获取字段列值
            col_values = _sheet.get_col_values(col_num)[1:]
            # 处理空白值
            col_values_new = []
            t_value = None
            for value in col_values:
                if value:
                    col_values_new.append(value)
                    t_value = value
                else:
                    col_values_new.append(t_value)
            col_values = col_values_new
            try:
                col_values = handle_values(col_values)
            except RuntimeError as e:
                raise RuntimeError("【%s】%s" % (fn, e))
            join_values.append(col_values)
        if len(join_values) == 1:
            field_values.append(join_values[0])
        else:
            new_values = []
            for i in zip(*join_values):
                i = "-".join(i)
                new_values.append(i)
            field_values.append(new_values)
    # 拼接用例名称、操作步骤、预期结果
    join_insert_values = []

    for i in zip(*field_values):
        v = ";".join(i)
        join_insert_values.append(v)

    # 去重(清空使用的行会产生空白行,空白行会产生与上一行一样的数据)
    d = {}
    for iv in join_insert_values:
        d[iv] = 1
    join_insert_values = d.keys()

    # 增加tcid字段
    insert_values = []
    insert_values.append("TCID;TestSummary;Action;Result")
    for i, iv in enumerate(join_insert_values):
        iv = str(i + 1) + ";" + iv
        insert_values.append(iv)
    # 保存为csv
    save_to_csv(file_name, insert_values)

    # 关闭工作薄
    wb.close()


if __name__ == '__main__':
    file_name = "用例.xlsx"
    sheet_index = 0
    # test_summary = ["需求编号", "模块", "用例名称"]
    test_summary = "用例名称"
    action = "用例步骤"
    result = "预期结果"
    export_jira_file(file_name=file_name, sheet_index=sheet_index, test_summary=test_summary, action=action, result=result)
View Code

xlrd&xlwt

xlrd

xlrd只能对excel文件进行读

# coding:utf-8
import xlrd


# 使用xlrd创建一个工作薄对象
workbook = xlrd.open_workbook('C:/Users/41850/Desktop/test.xls')

# 根据工作表的名称创建表格对象
# sheet = workbook.sheet_by_name('Sheet1')
# 根据工作表的索引创建表格对象,索引从0开始
sheet = workbook.sheet_by_index(0)

# 获取sheet名称
sheet_name = sheet.name
print(u"表格名称: %s" % sheet_name)

# 获取工作表的行数
row_count = sheet.nrows
# 获取工作表的列数
col_count = sheet.ncols
print("行数: %s  列数: %s" % (row_count, col_count))

# 获取数据
row_value = sheet.row_values(0)     # 获取第1行数据
col_value = sheet.col_values(0)     # 获取第1列数据
cell_value = sheet.cell_value(0, 1)     # 获取第1行第2列数据
print("获取的数据值为:%s, %s, %s" %(row_value, col_value, cell_value))

xlwt

xlwt只能对xls文件进行写

# coding:utf-8
import xlwt

# 打开一个工作薄
filename = 'C:/Users/41850/Desktop/test1.xls'
write_book = xlwt.Workbook(encoding="utf-8")


# 新增个表格,若文件已存在,则覆盖
sheet = write_book.add_sheet('test')

# 写入数据(行号, 列号, 写入值)
sheet.write(0, 0, 123.456)
sheet.write(1, 0, 789)
sheet.write(2, 0, 'hello')

# 保存
write_book.save(filename)

注意,xlwt没有直接修改已有 xls 文件的方法。通常的做法是,读取出文件,复制一份数据,对其进行修改,再保存。

# coding:utf-8
import xlrd
from xlutils.copy import copy

# 打开文件
filename = 'C:/Users/41850/Desktop/test1.xls'
rb = xlrd.open_workbook(filename)

# 复制
wb = copy(rb)
# 选取表单
s = wb.get_sheet(0)
# 写入数据
s.write(0, 1, 'new data')
# 保存
wb.save(filename)

 

posted @ 2021-10-08 15:15  码上测  阅读(494)  评论(0编辑  收藏  举报