python读取excel文件可读取xlsx格式和xls格式可直接读取超链接,读出为字典格式(列表套字典),处理合并单元格的问题 -凯发k8官方网
凯发k8官方网
收集整理的这篇文章主要介绍了
python读取excel文件可读取xlsx格式和xls格式可直接读取超链接,读出为字典格式(列表套字典),处理合并单元格的问题
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
直接上代码:(代码有注释,代码下方有解释)
1.可读取excel中的xlsx格式文件
2.可读取excel中的xls格式文件
3.可直接读取网页上的excel的超链接
4.解决有列合并的情况以及行合并的问题,由合并的情况,分别对应的填充
5.返回数据为 {"sheet1":[{},{},{}....], "sheet2":[{},{},{}....]} 注意,有的工作表中的名字是自己工作表的名字,这里只举例
import os from datetime import datetime from pprint import pprint import requests import win32com.client as win32 import xlrd from collections import counter from fake_useragent import useragent from xlrd import xldate_as_tupleclass readexcel:"""1.可读取excel中的xlsx格式文件2.可读取excel中的xls格式文件3.可直接读取网页上的excel的超链接读出的格式为[{},{},{}]。。。每一个字典为,一行对应列名的一个字典"""def __init__(self, file_path=none, index=none, header=none, auto_header=false, url=none, headers=none):"""传入的参数的解释:param file_path: (str)如果要读取的是文件,传入路径参数,绝对路径和相对路径都可以,兼容性强:param index: (int)选择第几行为列名,索引从0开始:param header: (list)传入列名,要与数据列对应,不建议用,除非表中没有头:param auto_header: (bool)自动识别列名:param url: (str)如果要直接读取url, 直接传入网页中excel中的超链接:param headers: (dict)如果读取的超链接,有的网站的文件有反爬,所以为了防止需要注意的是,file_path和url只能二选一,意为读取文件或者超链接index、header、auto_header 只需要三选一即可headers 可传可不传,不传时,请求头只有user-agent,一般的文件都可以如果你的文件也有反爬的话,建议传入headers"""self.file_path = file_pathself.url = urlself.headers = headersself.index = indexself.header = headerself.auto_header = auto_header# 判断文件类型if file_path is not none: # 传入的是文件if 'xlsx' in file_path: # 如果传入的文件是 xlsx 文件类型,将xlsx文件类型转化为xlsx# 将原来的文件名,替换成同名不同类型的文件,即xls结尾的文件(注意这块直接得到的是文件名,虽然传入的完整路径)filename = os.path.basename(file_path).replace("xlsx", 'xls')# 文件导出的目录路径和文件名称,文件名称如上export_name = os.path.join(os.path.dirname(os.path.abspath(file_path)), filename)self.xlsx_to_xls(file_path, export_name) # 开始进行转换self.file_path = export_name # 设置文件路径为转换后的文件路径else:# 如果是xls直接将目录进行拼接,绝对路径,并且设置文件路径self.file_path = os.path.join(os.path.dirname(os.path.abspath(file_path)), os.path.basename(file_path))else: # 超链接if self.headers is none: # 如果没有传入请求头,默认的只有随机的user-agentself.headers = {"user-agent": useragent().random}else:# 如果传入了请求头,就用该请求头,用随机的user-agent,有就更新,无则加入进去self.headers.update({"user-agent": useragent().random})# 设置文件路径为读取excel超链接的文件之后的文件路径,当前路径,读取后会删除文件self.file_path = self.read_url_excel()# formatting_info=true, 防止merged_cells获取合并的行或者列时为空列表self.workbook = xlrd.open_workbook(self.file_path, formatting_info=true) # 读取文件self.sheet_names = self.workbook.sheet_names() # 获取该文件所有的工作表名# 如果index和header都没有传入,则设置index为0,即就是从第一行开始读取if self.index is none or self.header is not none:self.index = 0def merge_cell(self, sheet_info):""":param sheet_info: 传入表格的对象:return:返回,有合并的行和列的键值对"""merge = {}merge_cells = sheet_info.merged_cellsfor (rlow, rhigh, clow, chigh) in merge_cells:value_mg_cell = sheet_info.cell_value(rlow, clow)if sheet_info.cell(rlow, clow).ctype == 3: # 对读出来的时间格式进行转换date = datetime(*xldate_as_tuple(value_mg_cell, 0))value_mg_cell = date.strftime('%y-%m-%d')if rhigh - rlow == 1:# merge transverse cellsfor n in range(chigh - clow - 1):merge[(rlow, clow n 1)] = value_mg_cellelif chigh - clow == 1:for n in range(rhigh - rlow - 1):merge[(rlow n 1, clow)] = value_mg_cellreturn mergedef xlsx_to_xls(self, fname, export_name, delete_flag=false):"""将xlsx文件转化为xls文件:param fname: 传入待转换的文件路径(可传绝对路径,也可传入相对路径,都可以):param export_name: 传入转换后到哪个目录下的路径(可传绝对路径,也可传入相对路径,都可以):param delete_flag: 转换成功后,是否删除原来的xlsx的文件,默认删除 布尔类型:return: 无返回值"""excel = win32.gencache.ensuredispatch('excel.application')excel.visible = falseexcel.displayalerts = falseabsolute_path = os.path.join(os.path.dirname(os.path.abspath(fname)), os.path.basename(fname))save_path = os.path.join(os.path.dirname(os.path.abspath(fname)), os.path.basename(export_name))wb = excel.workbooks.open(absolute_path)wb.saveas(save_path, fileformat=56) # fileformat = 51 is for .xlsx extensionwb.close() # fileformat = 56 is for .xls extensionexcel.application.quit()# 是否删除原来的数据文件if delete_flag:os.remove(absolute_path)def list_dic(self, key_list, value_list):"""两个列表组成字典:param key_list: 键名列表:param value_list: 值列表:return: 返回组成好的字典"""dic = dict(map(lambda x, y: [x, y], key_list, value_list))return dicdef read_url_excel(self):# 请求r = requests.get(url=self.url, headers=self.headers)file_b = r.content# 判断文件类型, 确定文件类型和名称if 'xlsx' in self.url:name = 'temp.xlsx'else:name = 'temp.xls'# 保存文件with open(name, 'wb') as f:f.write(file_b)# 判断是否需要转换,并且确定文件路径if name == 'temp.xlsx':export_name = 'temp.xls'self.xlsx_to_xls(name, export_name, delete_flag=true)else:export_name = namereturn export_namedef read_excel(self):# 取出所有的工作表的名称sheet_name_list = self.sheet_namesdic_data = {} # 所有的工作表字典,对应该工作表中的数据,键值对形式for sheet_name in sheet_name_list:sheet_simple = [] # 每张工作表# 某个工作表的名称sheet = self.workbook.sheet_by_name(sheet_name)if sheet.nrows != 0:auto_index = 0 # 自动识别头在第几行# 根据这些数据确定,行索引, 可以自己去设置,更改,按自己的需求flag_list = ['项目名称', '工程名称', '许可证号', '证号', '许可证编号', '建设规模','施工单位', '勘察单位', '投资额', '勘察单位', '设计单位', '工程地址', '工程地址', '层数']# 不要包含这些数据的行, 可以自己去设置,更改,按自己的需求del_list = ['表', '明细', '合计', '总计']if self.auto_header: # 自动识别头for row_i in range(0, sheet.nrows): # 循环每一行# 每行所有数据连起来的字符串row_data = ''.join([str(r_v) for r_v in sheet.row_values(row_i)]).strip()for del_str in del_list: # 跳过表名if del_str not in row_data:for flag in flag_list:if flag in row_data: # 判断表头auto_index = row_iheader = [str(row_value).replace("\n", "").replace(" ", "") for row_value insheet.row_values(auto_index) ifrow_value != '']row_index = auto_index 1else: # 手动头或者自定义头if self.header is none: # 如果没有传入表头,则用index取表头header = [row_value.replace("\n", "").replace(" ", "") for row_value insheet.row_values(self.index) if row_value != '']row_index = self.indexelse: # 传入了头,就用header = self.headerrow_index = 0values_merge_cell = self.merge_cell(sheet) # 这里是调用处理合并单元格的函数# row_index 从第几行开始读取for i in range(row_index, sheet.nrows): # 开始为组成字典准备数据other_line = []# 处理类型# 可参考 https://www.cnblogs.com/xxiong1031/p/7069006.htmlfor j in range(sheet.ncols):ctype = sheet.cell(i, j).ctype # 表格的数据类型cell = sheet.cell_value(i, j)if ctype == 3:# 转成datetime对象date = datetime(*xldate_as_tuple(cell, 0))cell = date.strftime('%y-%m-%d')other_line.append(cell)# other_line = sheet.row_values(i)# print(other_line)# print(other_line)for key in values_merge_cell.keys():if key[0] == i:if key[1] != '':other_line[key[1]] = str(values_merge_cell[key]).replace("\xa0", "")dic = self.list_dic(header, other_line) # 调用组合字典的函数,传入key和value,字典生成# print(self.url)# # pprint(dic)# print(other_line)value_list = [str(v).strip() for v in dic.values()]value_str = ''.join(value_list).strip()pass_list = del_list flag_listpass_flag = truefor pass_str in pass_list:if pass_str in value_str:pass_flag = falsebreakif pass_flag and len(counter(value_list)) > 1 and value_str != '':try:del dic['序号']except:pass# pprint(dic)sheet_simple.append(dic)dic_data[str(sheet_name)] = sheet_simpleos.remove(self.file_path)return dic_dataif __name__ == '__main__':# 读取文件,自动识别头readexcel = readexcel(file_path='./abcd/w020200220406735094729 (1).xls', auto_header=true)pprint(readexcel.read_excel())# 读取超链接,自动识别头,里面有表格合并readexcel_1 = readexcel(url='http://zjj.laibin.gov.cn/xxcx/bjgb/p020211122537271486773.xls', auto_header=true)pprint(readexcel_1.read_excel())注意的几点问题:
1. 创建类,传入参数是,如果是文件格式,就用file_path=‘文件路径’ 的方式,如果是超链接的方式 就用 url='超链接'
2. 里面的flag_list 和del_list 根据需要可以去修改,如果没有该需求,可以把这个两个列表设置我空列表
3.如果你读出来的excel数据有问题,可以随时联系我,私聊或者评论,我会第一时间进行修改,进行更正
谢谢大家
总结
以上是凯发k8官方网为你收集整理的python读取excel文件可读取xlsx格式和xls格式可直接读取超链接,读出为字典格式(列表套字典),处理合并单元格的问题的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: