xlrd读取excel工具类(适配大量模版)

xlrd读取excel工具类

代码特色: 不用下标去匹配列,采用正则匹配,这样就不用关心excel模板中列的位置而获取想要的信息
用于读取大量模板类似但是列顺序不一样的excel

一. 工具类代码

# 工具类
import xlrd
import re
from datetime import datetime
from xlrd import xldate_as_tuple

class ExcelExport:
    """
    本类是读取excel的工具类,封装了读取excel常用的方法,主要借助xlrd的方法
    """
    def __init__(self, file):
        """
        类的初始化方法
        :param file: excel文件路径
        """
        self.wookbook = xlrd.open_workbook(file)
        self.__start_row = 0
        self.__excel_titles = []

    def set_sheet(self, index):
        """
        设置操作sheet,保存到属性sheet中
        :param index: sheet的下表,为不小于0的整数
        :return:
        """
        self.sheet = self.wookbook.sheet_by_index(index)

    def get_start_row(self, reg):
        """
        获取开始的行,即表头开始的行
        :param reg: 表头所在行中某一个特有的列的正则,例如表头为['标称生产企业','生产日期'],reg即为'^标称生产'
        :return:返回开始行
        """
        for curr_row in range(self.sheet.nrows):
            for curr_col in range(self.sheet.ncols):
                if re.search(reg, str(self.sheet.cell_value(curr_row,curr_col))):
                    self.__start_row = curr_row
                    break
        return self.__start_row

    def get_excel_titles(self, reg):
        """
        获取excel表头list
        :param reg: 表头所在行中某一个特有的列的正则,例如表头为['标称生产企业','生产日期'],reg即为'^标称生产'
        :return: 表头list
        """
        if self.__start_row == 0:
            self.get_start_row(reg)
        self.__excel_titles = self.sheet.row_values(self.__start_row)
        return self.__excel_titles

    def __format_date(self, cell):
        """
        格式化日期
        :param cell: excel某一cell类型的格子
        :return: 返回格式化好的日期
        """
        type = cell.ctype
        rq = ''
        # 如果是日期类型
        if type == 3:
            date = datetime(*xldate_as_tuple(cell.value, 0))
            rq = date.strftime('%Y-%m-%d')
        # 如果是字符串
        elif type == 1:
            rq = cell.value.replace('.', '-')
        # 如果是数字
        elif type == 2:
            rq = self.parse(cell.value, '-')
        return rq

    def parse(self, num, split):
        """
        将数字转换为日期格式字符串,例如 20181019用-转换为: 2018-10-19
        :param num: num需要转换的数字
        :param split: 分隔符
        :return: 转换后的字符串
        """
        str1 = str(int(num))
        if len(str1) == 8:
            new_str = str1[0:4] + split + str1[4:6] + split + str1[6:]
        else:
            new_str = str1
        return new_str

    def get_one_data(self, excel_titles, data, curr_row, date_data = None):
        """
        根据正则获取一行数据
        :param exce_titles: excel表头list
        :param data:正则格式字典,key为需要保存的变量字符串,value为正则表达式,例如{'cybh':'样编'},得到的数据为cybh = excel对应的数据
        :param curr_row:需要获取数据的行
        :param date_data: 日期格式的数据list,默认为None,如果excel中有日期格式的数据,将变量名称保存为list,例如['scrq','ggrq']
        :return: 返回行数据字典
        """
        detail = {}
        if date_data == None:
            for i in excel_titles:
                for e in data.items():
                    if re.search(e[1], str(i)):
                        str1 = 'detail["%s"]="%s"' % (e[0],self.sheet.cell_value(curr_row, excel_titles.index(i)))
                        exec(str1)
            for d in data:
                if not detail.get(d):
                    detail[d] = ''
        else:
            for i in excel_titles:
                for e in data.items():
                    if re.search(e[1], str(i)):
                        if not e[0] in date_data:
                            str1 = 'detail["%s"]="%s"' % (e[0],self.sheet.cell_value(curr_row, excel_titles.index(i)))
                            exec(str1)
                        else:
                            rq = self.__format_date(self.sheet.cell(curr_row, excel_titles.index(i)))
                            str1 = 'detail["%s"]="%s"' % (e[0], rq)
                            exec(str1)
            for d in data:
                if not detail.get(d):
                    detail[d] = ''
        return detail

二. 测试代码

from inspection.utils import ExcelExport

excel = ExcelExport('F:/gov_1542056901814.xls')
excel.set_sheet(0)
excel_titles = excel.get_excel_titles('^标称生产')
data = {'cybh':'样编','num':'序号','bcscqymc':'生产企业名称','bcscqydz':'生产企业地址','bcydwmc':'被抽样单位名称'
        ,'bcydwdz':'被抽样单位地址','spmc':'品名','ggxh':'格型','sb':'商标','bzz':'标准值','jcjg':'检验结果'
        ,'bhdxm':'不合格项目','jyjg':'检验机构','fl':'分类','ggh':'公告号','rwly':'任务来源','bz':'备注'
        ,'bcydwszsf':'被抽样单位所在省份','spxl':'食品细类','scrq':'生产日期'}
start_row = excel.get_start_row('^标称生产')
for curr_row in range(start_row + 1, excel.sheet.nrows):
    detail = excel.get_one_data(excel_titles,data,curr_row,date_data=['scrq'])
    print(detail)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值