本文主要是介绍Python实现获取带合并单元格的表格数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Python实现获取带合并单元格的表格数据》由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,所以本文我们就来聊聊如何使用Python实现获取带合并单元格的表格数据吧...
由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,现将将封装成类,并通过调用list_excel_data()获取列表形式的数据, dict_excel_data():获取字典格式的数据。
当以字典形式获取数据时要注意,默认以第一行作为字典的key。
代码如下:
from openpyxl import load_workbook class Get_table_data(): """ 对带有合并单元格的表格数据进行处理 """ def __init__(self,sh): """ 定义初始传入的表 :param sh: 表 """ self.sh = sh def get_row_col(self): """ # 获取表格的行、列信息 :param sh: 表 :return: """ # title = sh.title # 获取sheet名称 max_row_num = self.sh.max_row # 获取最大js行数 max_col_num = self.sh.max_column # 获取最大列数 # min_row_num=sh.min_row # 获取最小行数 # min_col_num = sh.min_column # 获取最小列数 return max_row_num,max_col_num # 获取合并的单元格的坐标信息及合并的单元格行、列数 def get_merge_data(self): """ 通过获取的合并单元格的转换成特定的格式 :return: 合并的单元格的索引信息 """ # 查询该sheet表单所有合并单元格 merge_lists = self.sh.merged_cells # print('merge_lists',merge_lists) merge_all_list = [] # 接收最终内容并返回 # 遍历合并单元格 for merge_list in merge_lists: # 获取单个合并单元格的起始行(row_min)终止行(row_max)和起始列(col_min)终止列(col_max) row_min, row_max, col_min, col_max = merge_list.min_row, merge_list.max_row, merge_list.min_col, merge_list.max_col # 这里判断如果合并单元格起始、终止的行和列都不相等,说明合并单元格既合并了行又合并了列,两个for循环依次取出行列位置分别存在x,y中 if row_min != row_max and col_min != col_max: row_col = [(x, y) for x in range(row_min, row_max + 1) for y in range(col_min, col_max + 1)] merge_all_list.append(row_col) # 取出的值存在列表中 # 这里判断如果合并单元格起始、终止行相等,起始、终止列不相等,说明合并单元格只合并了列,所以行不动,只循环取出列的值,存在y中,行可以随意取row_min/row_max elif row_min == row_max and col_min != col_max: row_col = [(row_min, y) for y in range(col_min, col_max + 1)] merge_all_list.append(row_col) # 取出的值存在列表中 # 这里判断如果合并单元格起始、终止行不相等,起始、终止列相等,说明合并单元格只合并了行,所以列不动,只循环取出行的值,存在x中,列可以随意取col_min/col_max elif row_min != row_max and col_min == col_max: row_col = [(x, col_min) for x in range(row_min, row_max + 1)] merge_all_list.append(row_col) # 取出的值存在列表中 return merge_all_list # 最终返回列表 # 得到的是个这样的列表值:[[(2, 1), (3, 1)], [(10, 1), (10, 2), (10, 3), (11, 1), (11, 2), (11, 3)]] def merge_values(self,merge_cell): # 传入一个元组入参 """ 处理合并单元格,返回合并的单元格数值 :param merge_cell: 合并的单元格信息,以内嵌二元组的列表形式 :return: 返回单元格数值 """ # 循环取出合并单元格方法得到的值(这个值还是列表),检查传入的参数是不是在这些值里面 for i in range(0, len(merge_cell)): # 获取合并单元格的值:合并单元格左上角的第一个行列坐标的值 cell_value = self.sh.cell(row=merge_cell[i][0][0], column=merge_cell[i][0][1]).value return cell_value def list_excel_data(self): """ 按列表格式获取表中所有行数据 :return: 按行以列表嵌套的格式 """ merge_list = self.get_merge_data() # 获取表格合并的单元格的信息 merge_list_all = sum(merge_list,[]) # 将合并的单元格转换成一个大列表 table_value = [] for row in range(1,self.sh.max_row + 1): row_value = [] # 定义一个空列表存放有数据的行数据 for col in range(1,self.sh.max_column + 1): cell_data = (row, col) if cell_data in merge_list_all: row_value.append(self.merge_values(merge_list)) # 是合并单元格,则调用合并单元格数值获取函数 else: # 不在,说明不是合并单元格,使用普通单元格方法获取即可 row_value.append(self.sh.cell(*cell_data).value) table_value.append(row_value) return table_value def dict_excel_data(self): """ 按字典格式显示表中数据 :return: 按行以字典嵌套列表的格式 """ merge_list = self.get_merge_data() # 获取表格合并的单元格的信息 merge_list_all = sum(merge_list, []) # 将合并的单元China编程格转换成一个大列表 list_val = [] for row in range(1, self.sh.max_row + 1): if row > 1: # 第二行开始 dict_val = {} # 定义一个空字典存放数据 for col in range(1, self.sh.max_column + 1): title_row = (1, col) # 表格的第一行:标题栏 cell_data = (row, col) if cell_data in merge_list_all: # 是合并单元格,则调用合并单元格数值获取函数 dict_val[self.merge_values(merge_list)] = self.merge_values(merge_list) else: # 不在,说明不是合并单元格,使用普通单元格方法获取即可 dict_val[self.sh.cell(*title_row).value] = self.sh.cell(*cell_data).value list_val.append(dict_val) return list_val # 读取excel表 wb = load_workbook('shebei.xlsx') # 获取指定的sheet sheet_sb = wb['sheet'] c = Get_table_data(sheet_sb) # 创建获取表格数据对象 print(c.dict_excel_data()) # 字典格式 # print(c.list_excel_data()) # 列表格式
知识延展
python使用xlrd实现读取合并单元格
操作方法:
1.使用xlrd自带属性:merged_cells
# 获取表格中所有合并单元格位置,以列表形式返回 (起始行,结束行,起始列,结束列) merged = sheet.merged_cells #结果:[(1,5,0,1),(5,9,0,1)]
2.使用循环判断是合并单元格还是普通单元格,并将合并单元格中的首行值赋值给合并单元格
def get_cell_type(row_index, col_index): """既能得到合并单元格也能得到普通单元格""" cell_value = None for (rlow, rhigh, clow, chigh) in merged: # 遍历表格中所有合并单元格位置信息 # print(rlow,rhigh,clow,chigh) if (row_index >= rlow and row_index < rhigh): # 行坐标判断 if (col_index >= clow and col_index < chigh): # 列坐标判断 # 如果满足条件,就把合并单元格第一个位置的值赋给其它合并单元格 cell_value = sheet.cell_value(rlow, clow) print('合并单元格') break # 不符合条件跳出循环,防止覆盖 else: print('普通单元格') cell_value = sheet.cell_value(row_index, col_index) # else: 添加改行后只那一个单元格的内容5,0 会返回2个值普通单元格/合并单元格 # print('普通单元格') # cell_value = sheet.cell_value(row_index, col_index) return cell_value # 直接输入单元格的坐标。来获取单元格内容 # print(get_cell_type(5, 0)) # 利用循环输出某列的单元格内容 for i in range(1, 9): print(get_cell_type(i, 2))
PS:最简单的读取Excel文件中合并单元格操作
问题:
1.当输出内容时,使用坐标来获取print,若最外层有else会返回2个值(还在确认若无最外层else是否会有其他问题存在)
2.第一次使用时可以正常,再次使用时sheet.merged_cells返回列表为空??
解决方法:在打开文件中加入formatting_info=True,就能正常显示
python 读取excel 并处理被合并单元格的数据
以下代码仅是示例,视情况优化调整
from openpyxl import load_workbook from openpyxl.cell import MergedCell import time import pandas as pd def excel_to_md(file_path, output_file_path): # 替换原数据中的\r\n def replace_value(str): return str.replace('\n', '').replace('\r', '')编程 if str else '' start = time.time() # 使用 openpyxl的load_workbook 读取excel单元格属性 合并单元格数据组 merged_xls = pd.ExcelFile(load_workbook(file_path), engine="openpyxl") # 使用 pandas的read_excel 读取数据 with pd.ExcelFile(file_path, engine="openpyxl") as xls: with open(output_file_path, 'w') as f: for sheet_name in xls.sheet_names: df = pd.read_excel(xls, sheet_name=sheet_name,engine="openpyxl") df.dropna(axis=1, how='all', inplace=Truhttp://www.chinasem.cne) df.dropna(axis=0, how='all', inplace=True) # print(f'sheet_name: {sheet_name},开始获取 合并单元格集合 ') # cells_time = time.time() sheet = merged_xls.book[sheet_name] merged_cells = sheet.merged_cells # print(f'sheet_name: {sheet_name},存在 合并的单元格 {len(merged_cells.ranges)if merged_cells else 0}个') for item in merged_cells: top_col, top_row, bottom_col, bottom_row = item.bounds base_value = replace_value(item.start_cell.value) # 1-based index转为0-based index top_row -= 1 top_col -= 1 df.iloc[top_row:bottom_row, top_col:bottom_col] = base_value python # print(f'sheet_name: {sheet_name},给合并的单元格赋值 完成 %.5f sec' %(time.time()-cells_time)) # 将空单元格赋值为空字符 df = df.fillna('') # 开始是写入 f.write(f'# {sheet_name}\n') for index, row in df.iterrows(): # 处理空表头读取为 Unnamed: 0 替换成 Unnamed-0 row_str = ';'.join([f'{str(col).replace(": ","-") if "Unnamed:" in str(col) else col}:{row[col]}' for col in df.columns]) replace_value(row_str) f.write(f'{row_str}\n') merged_xls.close() print(file_path+' 执行时间 : %.5f sec' %(time.time()-start)) excel_to_md('test.xlsx','test.xlsx.md')
到此这篇关于Python实现获取带合并单元格的表格数据的文章就介绍到这了,更多相关Python获取表格数据内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于Python实现获取带合并单元格的表格数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!