Python脚本之大数据量读写Excel【一】

最近有些需求是要用到 Excel;根据我的喜好,肯定是数据往大了整!
就是要头发更少。。。

xls和xlsx格式

xls是微软私有的文件格式标准,以二进制方式直接保存文件,最大支持行数65536行、列数256列,而xlsx是基于Office Open XML标准的格式,实质是以zip压缩包保存文件,只是扩展名使用了xlsx,可以用解压软件查看压缩包内容,最大支持1048576行、16384列。

需求

因为我手上的需求 只用到xlsx格式,所以 这期分享都是xlsx格式相关
此外,后面所有代码 只是 读取或写入数据,完全不关心单元格的style;

需求A:
Excel内容 有2种: 1.单个sheet 20w内数据(少) 2.多个sheet 每个sheet 5w内的数据 (多)
过程:Excel上传后,系统进行对账操作,给出对账结果;
故我看 是3个步骤:准备数据生成Excel (上传到系统);我解析此Excel,拿此数据 和表的记录做对账;将我的结果 和 系统的结果做对比;

需求B:
Excel内容:单个sheet 不超过最大限制(100w)
过程:Excel上传后,系统检查内容,无误存表;
故我看 是2个步骤:准备数据生成Excel (上传到系统);我解析此Excel,连库读取表里数据,对比,保证每条记录的准确性、完整性

一般我造的数据量大概100w,Excel大概60M,若只读取一次,我就不care实际花的时间了。若多次读取这样的Excel,就要考虑 读取Excel的时间了。
我找了些资料,最后确定的思路:转Excel为CSV文件。通过脚本,把Excel读取的数据 存入CSV文件【每个Excel的内容 我改动地可能性近乎为0,因为再生成一份 也不是很难的事儿 = = 】。
实际跑脚本时,会先找寻是否有对应的CSV文件,有 -> 会读取对应的CSV文件,拿到数据;没有 ->先读取Excel数据,新生成CSV文件,再读取对应的CSV文件,拿到数据。再去下一步操作。

xlsx格式的 读

需求B: 单一个sheet

    def get_excel_data(self, file):
        import xlrd
        all_data = list()

        Log.info('开始获取Excel的数据。。。')

        book = xlrd.open_workbook(file)
        one_sheet = book.sheet_by_index(0)
        Log.info('sheet :{}'.format(book.sheet_names()))
        hang = range(0, one_sheet.nrows)
        for h in hang:
            ele = one_sheet.row_values(h)
            all_data.append((ele[0], ele[1], ele[2], ele[9], ele[10]))
            # all_data.append(ele)
            # all_data.append(tuple(ele))

        Log.info(all_data)                # 包含 表头

all_data.append() 写了3行,其实是 看实际要用的字段 和 需要的格式;

需求A:多个sheet

    def get_excel_data_sssss(self, file):
        import xlrd
        Log.info('开始获取Excel的数据。。。')

        book = xlrd.open_workbook(file)
        all_sheets = book.sheets()

        all_data = list()

        for s in all_sheets:
            s_index = all_sheets.index(s)

            sheet = book.sheet_by_name(s.name)
            Log.info('sheet:{}, {}'.format(sheet, s.name))

            if s_index == 0:
                hang = range(0, sheet.nrows)
                Log.info('取值:{}'.format(hang))
            else:
                # 表头内容 是一样的
                hang = range(1, sheet.nrows)
                Log.info('取值:{}'.format(hang))

            for c in hang:
                if file.find('zyooooxie_csdn') != -1:
                    ele = sheet.row_values(c)
                    all_data.append((ele[1], ele[3], ele[8], ele[9], ele[10], ele[-1]))

                else:
                    ele = sheet.row_values(c)
                    all_data.append((ele[8], ele[3], ele[11], ele[0]))

            Log.info('当前sheet 读取完成')

        Log.info('Excel文档 读取完毕')
        Log.info(all_data)

xlsx格式的 写

    def insert_excel_new(self, all_data, header):
        """
        Excel 写数据
        :param all_data: 是个list,里面的元素也是list (此list是每张sheet内容的)
        :param header: 表头
        :return:
        """
        import xlsxwriter
        cur_time = time.strftime("_%Y%m%d_%H%M%S")
        w = r'D:\work\gys\test_' + cur_time + '.xlsx'

        workbook = xlsxwriter.Workbook(w, {'constant_memory': True})
        for abc in range(len(all_data)):

            sheet = workbook.add_worksheet(str(abc))
            all_data[abc].insert(0, header)
            
            Log.info('sheet {} 准备新建'.format(abc))
            
            for i in range(1, len(all_data[abc]) + 1):
                rc = ''.join(['A', str(i)])
                sheet.write_row(rc, data=all_data[abc][i - 1])
            
            Log.info('当前sheet 已生成')

        workbook.close()

对已有数据的某Excel 再增加内容

(利用 xlutils 复制后 再保存的方式,我很不信任)

Excel_name = ‘test_20200516_150921.xlsx’

    def addExcelData(self, file, all_data):
        """
        在某个文件现有sheet('test_zyooooxie')再继续添加内容
        :param file: 文件
        :param all_data: [ele1, ele2, ele3]
        :return:
        """
        import openpyxl
        import os
        Log.info('此Excel add')
        wb = openpyxl.load_workbook(file)

        # sheet_names = wb.get_sheet_names()
        # wb_sheet = wb.get_sheet_by_name(sheet_names[0])

        wb_sheet = wb.get_sheet_by_name('csdn_zyooooxie')

        for ABC in range(len(all_data)):
            wb_sheet.append(all_data[ABC])

        new_time = time.strftime("_%Y%m%d_%H%M%S")
        search_result = re.search(r'_2020\d{4}_([01]\d|2[0-4])([0-5]\d)([0-5]\d).xlsx$', os.path.basename(file))
        new_file = os.path.basename(file)[0:search_result.start()] + new_time + '.xlsx'

        w = ''.join([os.path.dirname(file), '\\', new_file])
        wb.save(w)

其实这一篇分享只是讲我现在是咋做的,其他我爬的坑 就放在第二篇了。

交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie

你可能感兴趣的:(Python脚本)