首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用 Python 精准操控 Word 字体:获取与替换方案

使用 Python 精准操控 Word 字体:获取与替换方案

原创
作者头像
用户12495000
发布2026-07-14 09:35:37
发布2026-07-14 09:35:37
20
举报

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

一、为什么选择 Spire.Doc for Python

Spire.Doc for Python 是一款专业的 Word 文档操作组件,无需依赖 Microsoft Office,即可在 Python 环境中完成文档的创建、修改、转换和内容提取。其对象模型与 Word 的文档结构高度吻合:Document 包含多个 Section,每个 Section 包含 BodyBody 内包含 Paragraph,而段落又由 ChildObject(如 TextRange、图片、表格等)组成。字体信息正是存储在 TextRangeCharacterFormat 属性中,包括字体名称(FontName)、字号(FontSize)、颜色(TextColor)等。这种层次分明的设计,为遍历和修改提供了清晰的路径。

二、场景一:批量获取文档中所有字体信息

第一个代码示例的目标是扫描整个 Word 文档,提取每个文本片段使用的字体名称、字号和颜色,并去重后输出到文本文件。这在文档一致性检查、字体合规审计等场景中非常实用。

代码语言:javascript
复制
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()

核心实现步骤

  1. 初始化 Document 并加载文件document.LoadFromFile("/示例文档.docx")
  2. 三层遍历 :依次遍历 Sections → 每个 SectionParagraphs → 每个段落的 ChildObjects
  3. 类型筛选 :通过 isinstance(obj, TextRange) 判断当前子对象是否为文本范围,只有 TextRange 才携带字体格式。
  4. 提取属性 :从 txtRange.CharacterFormat 中获取 FontName(字符串)、FontSize(浮点数,单位为磅)、TextColor.Name(颜色名称)。
  5. 自定义去重 :代码中定义了一个 FontInfo 类,重写了 __eq__ 方法,以“字体名称 + 字号”作为唯一键。每提取一组信息,先判断是否已存在于 font_infos 列表中,若不存在则添加,并拼接到输出字符串中。
  6. 写入文件 :调用 WriteAllText 将结果保存为 TXT 文件。

值得注意的设计细节

  • 去重策略 :为什么只以名称和字号去重?因为颜色不是字体本身的固有属性,同一字体可能在不同位置使用不同颜色,若加入颜色字段会导致重复记录过多。这种设计更聚焦于字体本身特征。
  • 异常处理 :虽然代码未展示,但实际使用时建议对 FontSize 可能为 None 的情况做判断,因为某些特殊样式(如艺术字)可能返回空值。
  • 性能考量 :对于大文档,双层循环已足够高效,但若文档包含大量表格或文本框,还需额外遍历这些容器内的文本(本例未涉及,可扩展)。

运行该脚本后,我们会得到一个清晰的字体清单,例如:

代码语言:javascript
复制
字体名称:宋体、字号:12.000000、字体颜色:Black
字体名称:Arial、字号:10.500000、字体颜色:Red
...

三、场景二:定向替换指定字体

第二个代码示例更为精简,专注于将文档中所有使用“FangSong”(仿宋)的文本替换为“LiSu”(隶书)。这在品牌 VI 统一或排版本地化需求中极为常见。

代码语言:javascript
复制
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()

实现逻辑

  1. 同样加载文档 ,遍历所有 SectionParagraphChildObjects
  2. 定位 TextRange ,获取当前字体名称。
  3. 条件判断 :若 fontName == "FangSong",则修改 txtRange.CharacterFormat.FontName = "LiSu"
  4. 保存新文档document.SaveToFile("/替换字体.docx", FileFormat.Docx)

扩展性与风险提示

  • 部分替换 :该脚本会修改所有符合条件的文本。如果只想替换特定段落或样式,可在遍历中加入额外的筛选条件(如段落样式、所在章节等)。
  • 字体可用性 :替换后的字体“LiSu”必须存在于系统或文档嵌入字体中,否则 Word 会显示为默认字体。生产环境中建议使用通用字体(如“宋体”、“Times New Roman”),或提前嵌入字体。
  • 格式保留Spire.Doc 在替换字体时不会影响其他格式(如加粗、斜体、颜色),因为 CharacterFormat 的各个属性是独立的。

四、对比与整合思考

维度

获取字体

替换字体

核心目的

审计、分析

规范、转换

数据流向

文档 → 文本文件

文档 → 新文档

复杂度

需自定义去重类

简单条件判断

性能瓶颈

列表查找(可改用 set)

无额外开销

两者可以结合使用:先运行获取脚本,了解当前字体分布,再决定哪些字体需要替换,最后执行替换脚本。若需要更精细的控制(如仅替换某字号下的字体),可将两个脚本的逻辑融合,在替换时同时判断 FontSize

五、代码优化与最佳实践

  1. 使用集合(set)简化去重 :若不需要颜色信息,可直接将 (fontName, fontSize) 存入集合,避免自定义类。
  2. 异常捕获 :在 LoadFromFileSaveToFile 外增加 try...except,防止文件权限或格式错误导致程序崩溃。
  3. 批量处理 :若需处理多个文档,可将核心逻辑封装成函数,传入文件路径列表循环执行。
  4. 释放资源 :务必调用 document.Dispose(),尤其是在循环处理大量文档时,避免内存泄漏。

六、总结

通过 Spire.Doc for Python,我们仅用几十行代码就实现了 Word 字体的获取与替换两大核心功能。其对象模型清晰,API 直观,非常适合集成到自动化工作流中。无论是财务报告的字体合规检查,还是企业模板的批量更新,这套方案都能显著减少人工介入,提升准确率。读者可以根据自身需求,在现有代码基础上增加对段落样式、表格内文本或页眉页脚的处理,从而构建更强大的文档治理工具。技术的价值在于解决实际问题,而 Python 与 Spire.Doc 的结合,正是这一理念的生动实践。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、为什么选择 Spire.Doc for Python
  • 二、场景一:批量获取文档中所有字体信息
    • 核心实现步骤
    • 值得注意的设计细节
  • 三、场景二:定向替换指定字体
    • 实现逻辑
    • 扩展性与风险提示
  • 四、对比与整合思考
  • 五、代码优化与最佳实践
  • 六、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档