python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python Word 文档域

Python 操作 Word 文档域的完整教程

作者:用户835629078051

域(Field)是 Word 中的一种特殊元素,它的显示内容由域代码和域结果组成,可以根据环境或文档状态动态更新,本文介绍了用Python在Word文档中操作域的常用方法,感兴趣的朋友一起看看吧

域(Field)是 Word 中的一种特殊元素,它的显示内容由域代码和域结果组成,可以根据环境或文档状态动态更新。例如页脚里的"第 X 页"、目录页码、章节引用,以及"如果数量大于 100 则显示某段文字"这种条件判断,都是通过域实现的。手动在 Word 中插入域需要熟悉域代码的写法,而且当一个文档里散落着几十个域时,逐个更新很麻烦。

用 Python 可以自动完成这些工作:批量插入不同类型的域、更新所有域的显示结果、读取域中的文本、删除不需要的域,甚至把域直接转换为普通文本。本文以 Spire.Doc for Python 为例演示这些操作。

环境准备

安装 Spire.Doc 库:

pip install Spire.Doc

在脚本中引入模块:

from spire.doc import *
from spire.doc.common import *

在段落中插入一个简单的域

Paragraph.AppendField() 可以从现有文档中取出一个段落,在段落末尾插入指定类型的域。下面以页码引用(PageRef)域为例,域代码指定了要引用的书签名和显示格式:

document = Document()
document.LoadFromFile("文档.docx")
# 获取最后一个节并新建一个段落
section = document.LastSection
par = section.AddParagraph()
# 插入 PageRef 域并设置域代码
field = par.AppendField("pageRef", FieldType.FieldPageRef)
field.Code = "PAGEREF  bookmark1 \\# \"0\" \\* Arabic  \\* MERGEFORMAT"
# 更新域以获得正确的结果
document.IsUpdateFields = True
document.SaveToFile("插入域.docx", FileFormat.Docx)
document.Close()

AppendField() 的第一个参数是域的显示文本,第二个参数是 FieldType 枚举,用来声明域的类别。FieldType.FieldNone 表示空域,FieldType.FieldPageRef、FieldType.FieldMergeField 等则对应具体的域类型。插入后专门设置 Code 属性,相当于手动输入域代码。

创建带条件的 IF 域

IF 域可以用来做条件判断,是动态文档生成中最常用的域之一。它比普通域复杂一些,需要先把 IfField 对象加入段落,再拼装条件、真值和假值三部分文本,最后补一个域结束标记:

def create_if_field(document, paragraph):
    if_field = IfField(document)
    if_field.Type = FieldType.FieldIf
    if_field.Code = "IF "
    paragraph.Items.Add(if_field)
    # 条件:合并字段 Count 的值大于 100
    paragraph.AppendField("Count", FieldType.FieldMergeField)
    paragraph.AppendText(" > ")
    paragraph.AppendText("\"100\" ")
    # 真值和假值
    paragraph.AppendText("\"Thanks\" ")
    paragraph.AppendText("\"The minimum order is 100 units\"")
    # 添加域结束标记
    end = document.CreateParagraphItem(ParagraphItemType.FieldMark)
    end.Type = FieldMarkType.FieldEnd
    paragraph.Items.Add(end)
    if_field.End = end
document = Document()
section = document.AddSection()
paragraph = section.AddParagraph()
create_if_field(document, paragraph)
# 用邮件合并数据填充 Count 字段
document.MailMerge.Execute(["Count"], ["2"])
# 更新所有域
document.IsUpdateFields = True
document.SaveToFile("IF域.docx", FileFormat.Docx2013)
document.Close()

IfField 是 Field 的子类,通过 Items.Add() 加入段落后再拼装内容。整个域以开始标记开始、以 FieldMarkType.FieldEnd 结束,End 属性用来把结束标记和域对象关联起来。配合 MailMerge.Execute() 把合并数据填进文档,IF 域就能根据实际数值显示不同的结果。

结果演示

以下是上述两段代码生成的域:

更新文档中的所有域

域显示的是"最后一次计算的结果"。如果文档是在程序里动态生成的,或者数据发生了变化,需要在保存前重新计算:

document = Document()
document.LoadFromFile("文档.docx")
# 保存前更新所有域
document.IsUpdateFields = True
document.SaveToFile("更新域.docx", FileFormat.Docx)

IsUpdateFields 设置在 SaveToFile() 之前即可,保存时文档会重新计算所有域的结果。这是动态生成 Word 文档时经常要做的最后一步。

读取域中的文本

Document.Fields 属性返回文档中全部域的集合,每个域通过 FieldText 属性暴露当前计算出的文本结果:

document = Document()
document.LoadFromFile("文档.docx")
fields = document.Fields
for i in range(fields.Count):
    field = fields.get_Item(i)
    print(field.FieldText)
document.Close()

遍历集合可以在不了解文档结构的情况下,快速排查某个域是否生效、结果是否符合预期。fields[0] 可以直接按索引访问第一个域。

将域转换为普通文本

有时文档定稿后不再需要动态更新,比如把生成的订单或合同导出给客户查看。这时可以把域转换为普通文本,避免接收方打开文件时域结果因环境差异而发生变化:

document = Document()
document.LoadFromFile("文档.docx")
fields = document.Fields
count = fields.Count
for i in range(0, count):
    field = fields[0]
    s = field.FieldText
    index = field.OwnerParagraph.ChildObjects.IndexOf(field)
    text_range = TextRange(document)
    text_range.Text = s
    text_range.CharacterFormat.FontSize = 24
    # 用文本替换域的位置,再移除域
    field.OwnerParagraph.ChildObjects.Insert(index, text_range)
    field.OwnerParagraph.ChildObjects.Remove(field)
document.SaveToFile("域转文本.docx", FileFormat.Docx)
document.Close()

核心思路是:先读取域的当前文本,在域所在段落的位置插入一个 TextRange,再把原本的域对象移出段落。由于每次处理后 fields.Count 会相应变化,使用 fields[0] 循环处理即可把剩余域逐一清理干净。

删除不需要的域

删除域比转换更简单——找到域所在的段落,按索引直接移除:

document = Document()
document.LoadFromFile("文档.docx")
# 获取第一个域及其所在段落
field = document.Fields[0]
par = field.OwnerParagraph
# 定位域在段落中的位置并删除
index = par.ChildObjects.IndexOf(field)
par.ChildObjects.RemoveAt(index)
document.SaveToFile("删除域.docx", FileFormat.Docx)
document.Close()

OwnerParagraph 返回域所属的段落,ChildObjects 是段落内的对象集合,IndexOf() 找到域的下标后,RemoveAt() 即可把它删除。需要批量删除时,把这段逻辑放进循环即可。

实用提示

总结

本文介绍了用 Python 在 Word 文档中操作域的常用方法:用 AppendField() 插入简单域、用 IfField 构造条件域、用 IsUpdateFields 统一更新所有域、借助 Document.Fields 读取域文本、把域转为普通文本,以及通过 OwnerParagraph 定位并删除域。掌握这些操作后,动态文档中的页码、条件和合并数据都可以交给脚本统一处理。

到此这篇关于Python 操作 Word 文档域的完整教程的文章就介绍到这了,更多相关Python Word 文档域的插入与管理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文