使用Python精準(zhǔn)獲取與替換Word字體的方案詳解
在文檔排版處理中,Word 文檔的字體管理是一項(xiàng)高頻需求。無論是批量檢查文檔中使用了哪些字體,還是統(tǒng)一將某種字體替換為另一種,手動(dòng)操作既耗時(shí)又易遺漏。借助 Python 生態(tài)中的 Spire.Doc for Python 庫,我們可以通過簡潔的代碼實(shí)現(xiàn)對(duì) Word 文檔內(nèi)部字體信息的深度讀取和定向替換,極大提升處理效率。本文將結(jié)合兩個(gè)具體代碼實(shí)例,詳細(xì)剖析實(shí)現(xiàn)原理與技巧。

一、為什么選擇 Spire.Doc for Python
Spire.Doc for Python 是一款專業(yè)的 Word 文檔操作組件,無需依賴 Microsoft Office,即可在 Python 環(huán)境中完成文檔的創(chuàng)建、修改、轉(zhuǎn)換和內(nèi)容提取。其對(duì)象模型與 Word 的文檔結(jié)構(gòu)高度吻合:Document 包含多個(gè) Section,每個(gè) Section 包含 Body,Body 內(nèi)包含 Paragraph,而段落又由 ChildObject(如 TextRange、圖片、表格等)組成。字體信息正是存儲(chǔ)在 TextRange 的 CharacterFormat 屬性中,包括字體名稱(FontName)、字號(hào)(FontSize)、顏色(TextColor)等。這種層次分明的設(shè)計(jì),為遍歷和修改提供了清晰的路徑。
二、場景一:批量獲取文檔中所有字體信息
第一個(gè)代碼示例的目標(biāo)是掃描整個(gè) Word 文檔,提取每個(gè)文本片段使用的字體名稱、字號(hào)和顏色,并去重后輸出到文本文件。這在文檔一致性檢查、字體合規(guī)審計(jì)等場景中非常實(shí)用。
from spire.doc import *
from spire.doc.common import *
# 將字符串寫為 txt 文件的函數(shù)
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 = []
# 創(chuàng)建一個(gè) Document 類的對(duì)象
document = Document()
# 加載 Word 文檔
document.LoadFromFile("/示例文檔.docx")
# 遍歷文檔的所有節(jié)
for i in range(document.Sections.Count):
# 獲取當(dāng)前節(jié)
section = document.Sections.get_Item(i)
# 遍歷該節(jié)中的所有段落
for j in range(section.Body.Paragraphs.Count):
# 獲取當(dāng)前段落
paragraph = section.Body.Paragraphs.get_Item(j)
# 遍歷段落中的所有子對(duì)象
for k in range(paragraph.ChildObjects.Count):
# 獲取指定子對(duì)象
obj = paragraph.ChildObjects.get_Item(k)
# 判斷子對(duì)象是否為文本范圍
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}、字號(hào):{1:f}、字體顏色:{2:s}".format(fontInfo.get_name(), fontInfo.get_size(), textColor)
fontInformations += str
fontInformations += '\r'
# 將字體信息寫入 txt 文件
WriteAllText("/獲取字體.txt", fontInformations)
document.Dispose()核心實(shí)現(xiàn)步驟
- 初始化 Document 并加載文件 :
document.LoadFromFile("/示例文檔.docx")。 - 三層遍歷 :依次遍歷
Sections→ 每個(gè)Section的Paragraphs→ 每個(gè)段落的ChildObjects。 - 類型篩選 :通過
isinstance(obj, TextRange)判斷當(dāng)前子對(duì)象是否為文本范圍,只有TextRange才攜帶字體格式。 - 提取屬性 :從
txtRange.CharacterFormat中獲取FontName(字符串)、FontSize(浮點(diǎn)數(shù),單位為磅)、TextColor.Name(顏色名稱)。 - 自定義去重 :代碼中定義了一個(gè)
FontInfo類,重寫了__eq__方法,以“字體名稱 + 字號(hào)”作為唯一鍵。每提取一組信息,先判斷是否已存在于font_infos列表中,若不存在則添加,并拼接到輸出字符串中。 - 寫入文件 :調(diào)用
WriteAllText將結(jié)果保存為 TXT 文件。
值得注意的設(shè)計(jì)細(xì)節(jié)
- 去重策略 :為什么只以名稱和字號(hào)去重?因?yàn)轭伾皇亲煮w本身的固有屬性,同一字體可能在不同位置使用不同顏色,若加入顏色字段會(huì)導(dǎo)致重復(fù)記錄過多。這種設(shè)計(jì)更聚焦于字體本身特征。
- 異常處理 :雖然代碼未展示,但實(shí)際使用時(shí)建議對(duì)
FontSize可能為None的情況做判斷,因?yàn)槟承┨厥鈽邮剑ㄈ缢囆g(shù)字)可能返回空值。 - 性能考量 :對(duì)于大文檔,雙層循環(huán)已足夠高效,但若文檔包含大量表格或文本框,還需額外遍歷這些容器內(nèi)的文本(本例未涉及,可擴(kuò)展)。
運(yùn)行該腳本后,我們會(huì)得到一個(gè)清晰的字體清單,例如:
字體名稱:宋體、字號(hào):12.000000、字體顏色:Black
字體名稱:Arial、字號(hào):10.500000、字體顏色:Red
三、場景二:定向替換指定字體
第二個(gè)代碼示例更為精簡,專注于將文檔中所有使用“FangSong”(仿宋)的文本替換為“LiSu”(隸書)。這在品牌 VI 統(tǒng)一或排版本地化需求中極為常見。
from spire.doc import *
from spire.doc.common import *
# 創(chuàng)建一個(gè) Document 類的對(duì)象
document = Document()
# 加載 Word 文檔
document.LoadFromFile("/示例文檔.docx")
# 遍歷所有節(jié)
for i in range(document.Sections.Count):
# 獲取當(dāng)前節(jié)
section = document.Sections.get_Item(i)
# 遍歷每一個(gè)段落
for j in range(section.Body.Paragraphs.Count):
# 獲取指定段落
paragraph = section.Body.Paragraphs.get_Item(j)
# 遍歷段落下的所有子對(duì)象
for k in range(paragraph.ChildObjects.Count):
# 獲取子對(duì)象
obj = paragraph.ChildObjects.get_Item(k)
# 檢查子對(duì)象是否是文本范圍
if isinstance(obj, TextRange):
# 獲取文本范圍
txtRange = obj if isinstance(obj, TextRange) else None
# 獲取字體名稱
fontName = txtRange.CharacterFormat.FontName
# 檢查字體名稱是否為 FangSong
if (fontName == "FangSong"):
# 替換為另一個(gè)字體
txtRange.CharacterFormat.FontName = "LiSu"
# 保存修改后文檔
document.SaveToFile("/替換字體.docx", FileFormat.Docx)
# 釋放資源
document.Dispose()實(shí)現(xiàn)邏輯
- 同樣加載文檔 ,遍歷所有
Section、Paragraph和ChildObjects。 - 定位 TextRange ,獲取當(dāng)前字體名稱。
- 條件判斷 :若
fontName == "FangSong",則修改txtRange.CharacterFormat.FontName = "LiSu"。 - 保存新文檔 :
document.SaveToFile("/替換字體.docx", FileFormat.Docx)。
擴(kuò)展性與風(fēng)險(xiǎn)提示
- 部分替換 :該腳本會(huì)修改所有符合條件的文本。如果只想替換特定段落或樣式,可在遍歷中加入額外的篩選條件(如段落樣式、所在章節(jié)等)。
- 字體可用性 :替換后的字體“LiSu”必須存在于系統(tǒng)或文檔嵌入字體中,否則 Word 會(huì)顯示為默認(rèn)字體。生產(chǎn)環(huán)境中建議使用通用字體(如“宋體”、“Times New Roman”),或提前嵌入字體。
- 格式保留 :
Spire.Doc在替換字體時(shí)不會(huì)影響其他格式(如加粗、斜體、顏色),因?yàn)?nbsp;CharacterFormat的各個(gè)屬性是獨(dú)立的。
四、對(duì)比與整合思考
| 維度 | 獲取字體 | 替換字體 |
|---|---|---|
| 核心目的 | 審計(jì)、分析 | 規(guī)范、轉(zhuǎn)換 |
| 數(shù)據(jù)流向 | 文檔 → 文本文件 | 文檔 → 新文檔 |
| 復(fù)雜度 | 需自定義去重類 | 簡單條件判斷 |
| 性能瓶頸 | 列表查找(可改用 set) | 無額外開銷 |
兩者可以結(jié)合使用:先運(yùn)行獲取腳本,了解當(dāng)前字體分布,再?zèng)Q定哪些字體需要替換,最后執(zhí)行替換腳本。若需要更精細(xì)的控制(如僅替換某字號(hào)下的字體),可將兩個(gè)腳本的邏輯融合,在替換時(shí)同時(shí)判斷 FontSize。
五、代碼優(yōu)化與最佳實(shí)踐
- 使用集合(set)簡化去重 :若不需要顏色信息,可直接將
(fontName, fontSize)存入集合,避免自定義類。 - 異常捕獲 :在
LoadFromFile和SaveToFile外增加try...except,防止文件權(quán)限或格式錯(cuò)誤導(dǎo)致程序崩潰。 - 批量處理 :若需處理多個(gè)文檔,可將核心邏輯封裝成函數(shù),傳入文件路徑列表循環(huán)執(zhí)行。
- 釋放資源 :務(wù)必調(diào)用
document.Dispose(),尤其是在循環(huán)處理大量文檔時(shí),避免內(nèi)存泄漏。
六、總結(jié)
通過 Spire.Doc for Python,我們僅用幾十行代碼就實(shí)現(xiàn)了 Word 字體的獲取與替換兩大核心功能。其對(duì)象模型清晰,API 直觀,非常適合集成到自動(dòng)化工作流中。無論是財(cái)務(wù)報(bào)告的字體合規(guī)檢查,還是企業(yè)模板的批量更新,這套方案都能顯著減少人工介入,提升準(zhǔn)確率。讀者可以根據(jù)自身需求,在現(xiàn)有代碼基礎(chǔ)上增加對(duì)段落樣式、表格內(nèi)文本或頁眉頁腳的處理,從而構(gòu)建更強(qiáng)大的文檔治理工具。技術(shù)的價(jià)值在于解決實(shí)際問題,而 Python 與 Spire.Doc 的結(jié)合,正是這一理念的生動(dòng)實(shí)踐。
到此這篇關(guān)于使用Python精準(zhǔn)獲取與替換Word字體的方案詳解的文章就介紹到這了,更多相關(guān)Python獲取與替換Word字體內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中l(wèi)ist列表添加元素的3種方法總結(jié)
這篇文章主要介紹了Python中l(wèi)ist列表添加元素的3種方法總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
python實(shí)現(xiàn)動(dòng)態(tài)GIF英數(shù)驗(yàn)證碼識(shí)別示例
這篇文章主要為大家介紹了python實(shí)現(xiàn)動(dòng)態(tài)GIF英數(shù)驗(yàn)證碼識(shí)別示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
python 用for循環(huán)實(shí)現(xiàn)1~n求和的實(shí)例
今天小編就為大家分享一篇python 用for循環(huán)實(shí)現(xiàn)1~n求和的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02
Python網(wǎng)絡(luò)請(qǐng)求使用Requests庫抓取解析數(shù)據(jù)
在網(wǎng)絡(luò)編程中,請(qǐng)求和接收數(shù)據(jù)是最常見的任務(wù)之一,Python的Requests庫提供了豐富的功能,使得HTTP請(qǐng)求變得非常簡單,在本文中,我們將了解如何使用Requests庫發(fā)起HTTP請(qǐng)求,并解析返回的數(shù)據(jù)2023-08-08
mac安裝python3后使用pip和pip3的區(qū)別說明
這篇文章主要介紹了mac安裝python3后使用pip和pip3的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09
python實(shí)現(xiàn)簡單http服務(wù)器功能
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡單http服務(wù)器功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
使用Pyinstaller的最新踩坑實(shí)戰(zhàn)記錄
這篇文章主要給大家介紹了最近在使用Pyinstaller的踩坑實(shí)戰(zhàn)記錄,主要介紹了PYTHON2X.DLL缺失和WINDOWS2003 32BIT提示程序無效這兩個(gè)問題的解決方法,文中給出了詳細(xì)的解決方法,需要的朋友們下面來一起看看吧。2017-11-11

