You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何解析xlsx文件获取文本格式样式及起止位置

Python解析xlsx富文本特殊格式实现方案

依赖安装

使用openpyxl库处理xlsx富文本,该库对新版xlsx的块级格式支持完整,不要使用已停止维护的xlrd/xlwt处理此类需求,安装命令:

pip install openpyxl

实现逻辑

xlsx单元格内的差异化格式文本是以**富文本块(TextRun)**为单位存储的,每个连续同格式的字符段对应一个独立文本块,自带完整字体属性(加粗、字号、颜色等)。实现步骤:

  • 先读取无任何特殊格式的第四句内容,提取默认字体属性作为对比基准
  • 逐行遍历目标单元格的富文本块,累加字符长度计算每个块的起止字符位置
  • 对比每个文本块的字体属性和基准属性,存在差异的块就记录位置、差异属性值

可直接运行的代码

from openpyxl import load_workbook
from openpyxl.cell.rich_text import CellRichText, TextBlock
from openpyxl.cell.text import InlineFont

def parse_special_format_xlsx(file_path: str, target_sheet: str, target_cell_range: list[str]):
    """
    解析xlsx中带特殊格式的文本
    :param file_path: xlsx文件路径
    :param target_sheet: 要读取的工作表名
    :param target_cell_range: 四个语句所在的单元格坐标列表,顺序按[第一句,第二句,第三句,第四句]传入,比如["A1","A2","A3","A4"]
    :return: 每个单元格的特殊格式结果列表
    """
    wb = load_workbook(file_path, rich_text=True, data_only=True)
    ws = wb[target_sheet]
    # 取第四句的格式作为基准
    base_cell = ws[target_cell_range[3]]
    base_font = None
    if isinstance(base_cell.value, CellRichText):
        for block in base_cell.value:
            if isinstance(block, TextBlock):
                base_font = block.font
                break
    else:
        # 普通无富文本单元格直接取单元格字体属性
        base_font = InlineFont(
            bold=base_cell.font.bold,
            sz=base_cell.font.sz,
            color=base_cell.font.color
        )
    res = []
    # 遍历四个目标单元格
    for cell_addr in target_cell_range:
        cell = ws[cell_addr]
        cell_val = cell.value
        cell_result = {
            "cell": cell_addr,
            "full_text": "",
            "special_formats": []
        }
        current_pos = 0
        # 处理富文本单元格
        if isinstance(cell_val, CellRichText):
            full_text = ""
            for block in cell_val:
                # 普通无格式字符串段
                if isinstance(block, str):
                    block_len = len(block)
                    full_text += block
                    current_pos += block_len
                    continue
                # 带独立格式的文本块
                block_text = block.text
                block_len = len(block_text)
                start_pos = current_pos
                end_pos = current_pos + block_len
                full_text += block_text
                # 对比和基准格式的差异
                font_diff = {}
                if block.font.bold != base_font.bold:
                    font_diff["bold"] = block.font.bold
                if block.font.sz != base_font.sz:
                    font_diff["font_size_pt"] = block.font.sz
                # 对比字体颜色
                block_color = block.font.color.rgb if block.font.color else None
                base_color = base_font.color.rgb if base_font.color else None
                if block_color != base_color:
                    font_diff["font_color_rgb"] = block_color
                # 存在格式差异则记录
                if font_diff:
                    cell_result["special_formats"].append({
                        "start_char_index": start_pos,
                        "end_char_index": end_pos,
                        "text": block_text,
                        "format_attrs": font_diff
                    })
                current_pos = end_pos
            cell_result["full_text"] = full_text
        else:
            # 无富文本的普通单元格直接存储全量文本
            cell_result["full_text"] = str(cell_val)
        res.append(cell_result)
    wb.close()
    return res

# 调用示例
if __name__ == "__main__":
    result = parse_special_format_xlsx(
        file_path="你的文件路径.xlsx",
        target_sheet="Sheet1",
        target_cell_range=["A1","A2","A3","A4"] # 按实际四个句子所在单元格坐标修改
    )
    for item in result:
        print(f"单元格{item['cell']} 全量文本:{item['full_text']}")
        for fmt in item["special_formats"]:
            print(f"  特殊文本:{fmt['text']},起止位置:{fmt['start_char_index']}-{fmt['end_char_index']},格式属性:{fmt['format_attrs']}")

返回结果说明

  • 字符索引默认从0开始计数,和Python字符串切片规则一致
  • 格式属性仅返回和常规格式有差异的字段:
    • 加粗文本会返回"bold": True
    • 红色文本会返回对应ARGB值,比如纯红色对应"font_color_rgb": "FFFF0000"
    • 大字号文本会返回对应字号值,比如16磅字号对应"font_size_pt": 16
  • 无特殊格式的第四句返回结果里special_formats为空列表

注意事项

  • 加载工作簿必须加rich_text=True参数,否则openpyxl会自动把富文本转成普通字符串,丢失所有块级格式信息
  • openpyxl读取的字号单位为磅(pt),如果需要换算为px可按1pt ≈ 1.333px计算
  • 如果需要识别单元格背景高亮、删除线、斜体等其他格式,可在代码的格式对比逻辑中扩展对应属性的判断即可

内容的提问来源于stack exchange,提问作者user238664

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:31:12