【压测参数准备:python结合xlwt和xlrd实现excel文件拆分】

【需求】

在压测的过程中遇到了一一些问题:
从数据库拉出来大几十w条数据作为压测的接口参数,如何实现如下的需求?
	1.如何实现单个个并发的参数化?
	2.如何实现多个并发的参数化?
	3.是将所有的并发需要的参数都放在一个文件中?
	4.还是将每个并发的参数进行数据隔离,一个并发对应一个参数化文件?

【思考思路】

经过思考后,决定采用一个并发对应一个参数文件的形式进行数据隔离,那么问题又来了?
假设有100个并发,我难道需要手动搞100个数据文件吗?
的确,我一开始确实是这么做的,在10个并发每个并发需要5000条数据的场景下,的确是通过人肉去实现的
人肉实现步骤:
	第一步:导出数据库原始数据5w条,存到data5w.xls文件中
	第二步:新建10数据文件,data1.xls..........data10.xls
	第三步:从data5w.xls文件中每一次剪切5000条数据,分别粘贴到这10个文件中

操作下来就特别人肉,如过每个并发需要5w条,有100个并发,人肉去实现,这个过程太痛苦了
能用脚本实现的功能为什么还要人肉去做呢?
于是研究了一下python如何去操作Excel.
总结了一下自己的思路:
python操作Excel思路:
	第一步:获取所有的sheet页名称,放到一个列表中,然后循环去操作每个sheet页中的内容
	第二步:针对单个sheet页的内容进行操作,需要考虑有多少行数据,每一行有多少列
	第三步::设定一个参数,存储拆分后的每个data.xls文件寸的总记录数
	第四步:利用分页思想,将当前sheet页的数据进行分页拆解,分页大小就上一步设定的参数值
	第五步:将每一页的数据保存到一个data.xls文件中,如果出现整除除不尽的情况,就将这些零散的数据单独存储
	到最后一个data.xls文件中
	第六步:考虑到需要存储的data.xls文件不能被覆盖的问题,可以用总共的页数,作为动态拼接存储文件的名称
	第七步:执行运行程序,得到想要的结果
分页思想:
	场景1:假设有1000条数据,需要每个文件存储100条数据,正好可以存储到10个文件
			total=1000
			page_size=100
			total_page=10
	场景2:假设有1002条数据,需要每个文件存储100条数据,前10个文件,每个文件100条,第11个文件,只需要存储2条
			total=1002
			page_size=100
			total_page=11

[脚本实现]

实现思路:
第一步:定义一个工具类:def extractExcelUtils(object)
第二步:__init__(self, file_path, row_size, save_path)需要传入三个入参,
	file_path:文件路径data/data5w.xls
	row_size:希望拆分后每个data.xls文件存储的数据条数
	save_path:存储的文件夹路径:target_data/
第三步:封装四个方法
	方法1:get_all_sheet_names(),返回sheet名称列表
	方法2:work_sheet(sheet_name)返回得到的sheet
	方法3:get_current_sheet_total_rows(sheet_name),返回当前sheet页的所有可用行
	方法4:get_current_sheet_total_cols(sheet_name),返回当前sheet页每一条记录可用列
第四步:定义读取xls文件的方法read_data(sheet_name),返回当前sheet页所有数据列表,每一行数据一个存储一次
第五步:定义一个数据拼接的方法join_data(sheet_name),将原始数据拼接成自己需要的参数
第六步:定义一个写入方法write_data(sheet,workbook,data_list,file_path),将清洗后的数据写入到xls文件中
"""
    :param sheet:  当前sheet页名称
    :param workbook:  当前workbook
    :param data_list:  需要存储的数据列表
    :param file_path:  存储的文件路径
    :return:
"""
第七步:定义一个extract_file(sheet_name_list)方法,将上面的所有方法进行组装
第八步:组装完成以后,开始运行程序

[脚本源码]

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: 胡浩浩
# datetime: 2021/11/29 15:19 
# ide: PyCharm
import xlrd
import time
import random
import xlwt


class excelUtils(object):
    """
    如何将一个Excel文件拆分成多个Excel文件
        需要处理多个sheet页签的情况
    """

    def __init__(self, file_path, row_size, save_path):
        """

        :param file_path: 源文件个路径
        :param row_size:  拆分以后每个文件的数据量
        :param save_path: 存储文件的地址
        """
        self.workbook = xlrd.open_workbook(file_path)
        self.row_size = row_size
        self.save_path = save_path

    def work_sheet(self, sheet_name):
        """

        :param sheet_name: sheet页名称
        :return: 返回sheet_name对应的sheet对象
        """
        sheet = self.workbook.sheet_by_name(sheet_name)
        return sheet

    def get_all_sheet_names(self):
        """

        :return: 返回当前Excel中所有sheet_name
        """
        name_list = self.workbook.sheet_names()
        return name_list

    def get_current_sheet_total_rows(self, sheet_name):
        """

        :param sheet_name: sheet页名称
        :return: 返回当前sheet页可用的最大行数
        """
        ws = self.work_sheet(sheet_name=sheet_name)
        total_rows = ws.nrows
        return total_rows

    def get_current_sheet_total_cols(self, sheet_name):
        """

        :param sheet_name: sheet页名称
        :return: 返回当前sheet页可用最大列
        """
        ws = self.work_sheet(sheet_name=sheet_name)
        total_cols = ws.ncols
        return total_cols

    def join_data(self, sheet_name):

        """
            清洗数据,将清洗后的数据数据返回

        :param sheet_name: 当前sheet页名称
        :param file_path: 文件路径
        :return:    返回当前sheet页清洗后的数据
        """
        data = self.read_data(sheet_name)
        for item in data:
            index = "".join(random.sample(
                'zFyVxwTvutRsrqpPonFmlkjLihSgfedcHbaABCvDEFGHIJKLMNOPQRSJHSADSWQWDewteyeydhgASsadavvfsvdDHSAJHQasdsadxzsdWEW2d323dfwefew4msadacodvuwivbyw8133289TUVWXYZ',
                7))
            item[2] = "YT" + time.strftime('%H%M%S') + index
            item[3] = time.strftime('%Y-%m-%d %H:%M:%S')
        # print(data)
        return data

    def read_data(self, sheet_name):
        """
            读取数据文件
        :param sheet_name:  sheet页名称
        :param file_path:  文件路径
        :return:
        """
        sheet = self.work_sheet(sheet_name=sheet_name)
        data_list = []
        total_rows = self.get_current_sheet_total_rows(sheet_name)
        total_cols = self.get_current_sheet_total_cols(sheet_name)
        for row in range(total_rows):
            data_detail = []
            for col in range(total_cols):
                data_detail.append(sheet.cell_value(row, col))
            data_list.append(data_detail)

        return data_list

    def write_data(self, sheet, workbook, data_list, file_path):
        """

        :param sheet:  当前sheet页名称
        :param workbook:  当前workbook
        :param data_list:  需要存储的数据列表
        :param file_path:  存储的文件路径
        :return:
        """
        for i in range(len(data_list)):
            for j in range(len(data_list[0])):
                sheet.write(i, j, data_list[i][j])
        workbook.save(file_path)

    def extract_file(self, sheet_name_list):
        """

        :param sheet_name_list: sheet页名称列表
        :return: 无返回值
        """
        num = 1
        for sheet_name in sheet_name_list:
            data = self.join_data(sheet_name=sheet_name)
            # print(data)
            total_rows = self.get_current_sheet_total_rows(sheet_name)
            print(total_rows)
            if total_rows // self.row_size == total_rows / self.row_size:
                file_size = total_rows // self.row_size
                print(file_size)
            else:
                file_size = total_rows // self.row_size + 1
                print(file_size)
            for i in range(file_size):
                file_path = "../data_YT_100/data%s.xlsx" % (str(num))
                print(file_path)
                current_workbook = xlwt.Workbook(encoding="utf-8")
                current_sheet = current_workbook.add_sheet("Sheet1")
                data_list = data[self.row_size * (i):self.row_size * (i + 1)]
                self.write_data(current_sheet, current_workbook, data_list, file_path)
                num += 1
        return "拆解成功"


if __name__ == '__main__':
    eu = excelUtils("../data/71w.xls", 10000, "../data_YT_100")
    sheet_name_list = eu.get_all_sheet_names()
    print(sheet_name_list)
    data = eu.extract_file(sheet_name_list)

    print(data)

脚本执行结果

在这里插入图片描述

总结

	经过自己的努力,终觉解决的这个参数化文件的拆解的工作,一劳永逸。
等下次再遇到类似的需求,完全可以复用,只需要改动少量脚本逻辑,即可实现新的业务需求。

猜你喜欢

转载自blog.csdn.net/hzxyzyq/article/details/121852743