如何用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




