You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用python-docx读取Word文档文本的字体大小与类型等格式?

解决python-docx读取字体格式及分类的问题

我之前也踩过这个坑——直接访问run.font.size或者run.font.name经常返回None,这是因为Word里的文本格式大多是继承自段落样式或文档默认样式,不是每个run都单独设置了这些属性。下面给你具体的解决方法:

一、正确获取字体大小和类型

要拿到文本实际生效的格式,得优先检查run自身的设置,没有的话再读取它所属样式的设置,最后 fallback 到文档默认样式。

示例代码:获取单个run的完整字体信息

from docx import Document
from docx.shared import Pt

def get_run_font_info(run, default_style):
    # 获取字体大小
    font_size = run.font.size
    if not font_size:
        font_size = run.style.font.size
    if not font_size:
        font_size = default_style.font.size
    # 转成Pt数值方便查看
    font_size_pt = font_size.pt if font_size else "未设置"

    # 获取字体名称(兼容样式继承)
    font_name = run.font.name
    if not font_name:
        font_name = run.style.font.name
    if not font_name:
        font_name = default_style.font.name
    font_name = font_name if font_name else "未设置"

    # 判断是否加粗(处理样式继承的情况)
    is_bold = run.font.bold
    if is_bold is None:
        is_bold = run.style.font.bold
    is_bold = is_bold if is_bold is not None else False

    return {
        "size": font_size_pt,
        "name": font_name,
        "is_bold": is_bold,
        "text": run.text.strip()
    }

# 读取目标文档
doc = Document("your_document.docx")
default_style = doc.styles["Normal"]

# 遍历所有段落和run
for para in doc.paragraphs:
    for run in para.runs:
        if run.text.strip():  # 跳过空文本的run
            font_info = get_run_font_info(run, default_style)
            print(f"文本: {font_info['text']} | 字体大小: {font_info['size']}pt | 字体类型: {font_info['name']} | 是否加粗: {font_info['is_bold']}")

二、按字体格式分类文本

如果要按「字体大小+类型+是否加粗」的组合来分类文本,可以用字典存储,键是格式组合元组,值是对应文本的列表:

示例代码:格式分类实现

from docx import Document
from docx.shared import Pt

def get_run_font_key(run, default_style):
    # 生成唯一的格式标识键
    font_size = run.font.size or run.style.font.size or default_style.font.size
    font_size_pt = font_size.pt if font_size else 0

    font_name = run.font.name or run.style.font.name or default_style.font.name or "未知字体"

    is_bold = run.font.bold
    if is_bold is None:
        is_bold = run.style.font.bold
    is_bold = is_bold if is_bold is not None else False

    return (font_size_pt, font_name, is_bold)

doc = Document("your_document.docx")
default_style = doc.styles["Normal"]

# 初始化分类字典
formatted_text_groups = {}

for para in doc.paragraphs:
    for run in para.runs:
        text = run.text.strip()
        if not text:
            continue
        key = get_run_font_key(run, default_style)
        if key not in formatted_text_groups:
            formatted_text_groups[key] = []
        formatted_text_groups[key].append(text)

# 输出分类结果
for (size, name, bold), texts in formatted_text_groups.items():
    print(f"\n--- 格式: {size}pt | {name} | 加粗: {bold} ---")
    print("文本列表:")
    for text in texts:
        print(f"- {text}")

额外提醒

  • Word的样式继承逻辑比较复杂,如果遇到自定义样式,可能需要额外处理run.style的层级关系;
  • 对于中文字体,部分场景下run.font.name会返回西文字体,这时候可以导入from docx.oxml.ns import qn,然后用run._element.rPr.rFonts.get(qn('w:eastAsia'))获取中文字体;
  • 建议跳过空文本的run,避免无效数据干扰结果。

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

火山引擎 最新活动