Python实现获取带合并单元格的表格数据

2025-05-18 14:50

本文主要是介绍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实现获取带合并单元格的表格数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154647

相关文章

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

IDEA中新建/切换Git分支的实现步骤

《IDEA中新建/切换Git分支的实现步骤》本文主要介绍了IDEA中新建/切换Git分支的实现步骤,通过菜单创建新分支并选择是否切换,创建后在Git详情或右键Checkout中切换分支,感兴趣的可以了... 前提:项目已被Git托管1、点击上方栏Git->NewBrancjsh...2、输入新的分支的

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互