在文档排版处理中,Word 文档的字体管理是一项高频需求。无论是批量检查文档中使用了哪些字体,还是统一将某种字体替换为另一种,手动操作既耗时又易遗漏。借助 Python 生态中的 Spire.Doc for Python 库,我们可以通过简洁的代码实现对 Word 文档内部字体信息的深度读取和定向替换,极大提升处理效率。本文将结合两个具体代码实例,详细剖析实现原理与技巧。

Spire.Doc for Python 是一款专业的 Word 文档操作组件,无需依赖 Microsoft Office,即可在 Python 环境中完成文档的创建、修改、转换和内容提取。其对象模型与 Word 的文档结构高度吻合:Document 包含多个 Section,每个 Section 包含 Body,Body 内包含 Paragraph,而段落又由 ChildObject(如 TextRange、图片、表格等)组成。字体信息正是存储在 TextRange 的 CharacterFormat 属性中,包括字体名称(FontName)、字号(FontSize)、颜色(TextColor)等。这种层次分明的设计,为遍历和修改提供了清晰的路径。
第一个代码示例的目标是扫描整个 Word 文档,提取每个文本片段使用的字体名称、字号和颜色,并去重后输出到文本文件。这在文档一致性检查、字体合规审计等场景中非常实用。
from spire.doc import *
from spire.doc.common import *
# 将字符串写为 txt 文件的函数
def WriteAllText(fname:str,text:List[str]):
fp = open(fname,"w", encoding="utf-8")
for s in text:
fp.write(s)
# 自定义 FontInfo 类
class FontInfo:
def __init__(self):
self._m_name = ''
self._m_size = None
def __eq__(self,other):
if isinstance(other,FontInfo):
return self._m_name == other.get_name() and self._m_size == other.get_size()
return False
def get_name(self):
return self._m_name
def set_name(self, value):
self._m_name = value
def get_size(self):
return self._m_size
def set_size(self, value):
self._m_size = value
# 声明变量
fontInformations = ""
font_infos = []
# 创建一个 Document 类的对象
document = Document()
# 加载 Word 文档
document.LoadFromFile("/示例文档.docx")
# 遍历文档的所有节
for i in range(document.Sections.Count):
# 获取当前节
section = document.Sections.get_Item(i)
# 遍历该节中的所有段落
for j in range(section.Body.Paragraphs.Count):
# 获取当前段落
paragraph = section.Body.Paragraphs.get_Item(j)
# 遍历段落中的所有子对象
for k in range(paragraph.ChildObjects.Count):
# 获取指定子对象
obj = paragraph.ChildObjects.get_Item(k)
# 判断子对象是否为文本范围
if isinstance(obj, TextRange):
# 获取指定文本范围
txtRange = obj if isinstance(obj, TextRange) else None
# 获取字体的名称和大小
fontName = txtRange.CharacterFormat.FontName
fontSize = txtRange.CharacterFormat.FontSize
# 获取文本的颜色
textColor = txtRange.CharacterFormat.TextColor.Name
# 将字体信息保存在 fontInformations 变量中
fontInfo = FontInfo()
fontInfo.set_name(fontName)
fontInfo.set_size(fontSize)
if fontInfo not in font_infos:
font_infos.append(fontInfo)
str = "字体名称:{0:s}、字号:{1:f}、字体颜色:{2:s}".format(fontInfo.get_name(), fontInfo.get_size(), textColor)
fontInformations += str
fontInformations += '\r'
# 将字体信息写入 txt 文件
WriteAllText("/获取字体.txt", fontInformations)
document.Dispose()document.LoadFromFile("/示例文档.docx")。Sections → 每个 Section 的 Paragraphs → 每个段落的 ChildObjects。isinstance(obj, TextRange) 判断当前子对象是否为文本范围,只有 TextRange 才携带字体格式。txtRange.CharacterFormat 中获取 FontName(字符串)、FontSize(浮点数,单位为磅)、TextColor.Name(颜色名称)。FontInfo 类,重写了 __eq__ 方法,以“字体名称 + 字号”作为唯一键。每提取一组信息,先判断是否已存在于 font_infos 列表中,若不存在则添加,并拼接到输出字符串中。WriteAllText 将结果保存为 TXT 文件。FontSize 可能为 None 的情况做判断,因为某些特殊样式(如艺术字)可能返回空值。运行该脚本后,我们会得到一个清晰的字体清单,例如:
字体名称:宋体、字号:12.000000、字体颜色:Black
字体名称:Arial、字号:10.500000、字体颜色:Red
...第二个代码示例更为精简,专注于将文档中所有使用“FangSong”(仿宋)的文本替换为“LiSu”(隶书)。这在品牌 VI 统一或排版本地化需求中极为常见。
from spire.doc import *
from spire.doc.common import *
# 创建一个 Document 类的对象
document = Document()
# 加载 Word 文档
document.LoadFromFile("/示例文档.docx")
# 遍历所有节
for i in range(document.Sections.Count):
# 获取当前节
section = document.Sections.get_Item(i)
# 遍历每一个段落
for j in range(section.Body.Paragraphs.Count):
# 获取指定段落
paragraph = section.Body.Paragraphs.get_Item(j)
# 遍历段落下的所有子对象
for k in range(paragraph.ChildObjects.Count):
# 获取子对象
obj = paragraph.ChildObjects.get_Item(k)
# 检查子对象是否是文本范围
if isinstance(obj, TextRange):
# 获取文本范围
txtRange = obj if isinstance(obj, TextRange) else None
# 获取字体名称
fontName = txtRange.CharacterFormat.FontName
# 检查字体名称是否为 FangSong
if (fontName == "FangSong"):
# 替换为另一个字体
txtRange.CharacterFormat.FontName = "LiSu"
# 保存修改后文档
document.SaveToFile("/替换字体.docx", FileFormat.Docx)
# 释放资源
document.Dispose()Section、Paragraph 和 ChildObjects。fontName == "FangSong",则修改 txtRange.CharacterFormat.FontName = "LiSu"。document.SaveToFile("/替换字体.docx", FileFormat.Docx)。Spire.Doc 在替换字体时不会影响其他格式(如加粗、斜体、颜色),因为 CharacterFormat 的各个属性是独立的。维度 | 获取字体 | 替换字体 |
|---|---|---|
核心目的 | 审计、分析 | 规范、转换 |
数据流向 | 文档 → 文本文件 | 文档 → 新文档 |
复杂度 | 需自定义去重类 | 简单条件判断 |
性能瓶颈 | 列表查找(可改用 set) | 无额外开销 |
两者可以结合使用:先运行获取脚本,了解当前字体分布,再决定哪些字体需要替换,最后执行替换脚本。若需要更精细的控制(如仅替换某字号下的字体),可将两个脚本的逻辑融合,在替换时同时判断 FontSize。
(fontName, fontSize) 存入集合,避免自定义类。LoadFromFile 和 SaveToFile 外增加 try...except,防止文件权限或格式错误导致程序崩溃。document.Dispose(),尤其是在循环处理大量文档时,避免内存泄漏。通过 Spire.Doc for Python,我们仅用几十行代码就实现了 Word 字体的获取与替换两大核心功能。其对象模型清晰,API 直观,非常适合集成到自动化工作流中。无论是财务报告的字体合规检查,还是企业模板的批量更新,这套方案都能显著减少人工介入,提升准确率。读者可以根据自身需求,在现有代码基础上增加对段落样式、表格内文本或页眉页脚的处理,从而构建更强大的文档治理工具。技术的价值在于解决实际问题,而 Python 与 Spire.Doc 的结合,正是这一理念的生动实践。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。