DEV Community

Allen Yang
Allen Yang

Posted on

Insert and Manage Fields in Word Documents with Python

Insert and Manage Fields in Word Documents with Python

A field is a special element in Word whose displayed content is composed of a field code and a field result, and it can update dynamically based on the environment or the document state. Common examples are the "Page X" text in footers, table of contents page numbers, cross-references to a chapter, and conditional content such as "show one phrase if a quantity is above 100". Inserting fields manually requires knowing the field code syntax, and when dozens of fields are scattered across one document, updating them one by one is tedious.

Python can automate all of this: insert different types of fields in bulk, update all field results, read the text inside fields, remove fields that are no longer needed, and even convert fields into plain text. This article demonstrates these operations using Spire.Doc for Python.

Setting Up the Environment

Install the Spire.Doc library:

pip install Spire.Doc
Enter fullscreen mode Exit fullscreen mode

Then import the required modules in your script:

from spire.doc import *
from spire.doc.common import *
Enter fullscreen mode Exit fullscreen mode

Inserting a Simple Field into a Paragraph

Paragraph.AppendField() appends a field of a specified type to the end of a paragraph. The example below inserts a PageRef field, whose code points to a bookmark name and a display format:

document = Document()
document.LoadFromFile("document.docx")

# Get the last section and add a new paragraph
section = document.LastSection
par = section.AddParagraph()

# Insert a PageRef field and set its code
field = par.AppendField("pageRef", FieldType.FieldPageRef)
field.Code = "PAGEREF  bookmark1 \\# \"0\" \\* Arabic  \\* MERGEFORMAT"

# Update fields to get correct results
document.IsUpdateFields = True

document.SaveToFile("InsertField.docx", FileFormat.Docx)
document.Close()
Enter fullscreen mode Exit fullscreen mode

The first argument of AppendField() is the display text of the field, and the second is a FieldType enum value that declares the category. FieldType.FieldNone creates an empty field, while values such as FieldType.FieldPageRef and FieldType.FieldMergeField correspond to concrete field types. After insertion, assigning the Code property is equivalent to typing the field code manually.

Creating a Conditional IF Field

The IF field performs conditional logic and is one of the most useful fields for dynamic document generation. It is more complex than a plain field: you add an IfField object to the paragraph, build up the condition, the true text, and the false text, and then close the field with an end mark:

def create_if_field(document, paragraph):
    if_field = IfField(document)
    if_field.Type = FieldType.FieldIf
    if_field.Code = "IF "
    paragraph.Items.Add(if_field)

    # Condition: the merge field Count is greater than 100
    paragraph.AppendField("Count", FieldType.FieldMergeField)
    paragraph.AppendText(" > ")
    paragraph.AppendText("\"100\" ")
    # True and false values
    paragraph.AppendText("\"Thanks\" ")
    paragraph.AppendText("\"The minimum order is 100 units\"")

    # Add the field end mark
    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)

# Fill the Count field with merge data
document.MailMerge.Execute(["Count"], ["2"])

# Update all fields
document.IsUpdateFields = True

document.SaveToFile("IFField.docx", FileFormat.Docx2013)
document.Close()
Enter fullscreen mode Exit fullscreen mode

IfField inherits from Field. It is added to the paragraph through Items.Add(), after which you assemble the content pieces. The whole field runs from its start mark to a FieldMarkType.FieldEnd end mark, and the End property links the end mark back to the field object. Combined with MailMerge.Execute() to supply the merge data, the IF field renders different text depending on the actual value.

Result Preview

Below is a preview of the Word document generated using the above code:

Create Fields in Word Using Python

Updating All Fields in a Document

A field displays its "last calculated result". If the document was generated dynamically or the underlying data changed, the fields must be recalculated before saving:

document = Document()
document.LoadFromFile("document.docx")

# Update all fields before saving
document.IsUpdateFields = True

document.SaveToFile("UpdateFields.docx", FileFormat.Docx)
Enter fullscreen mode Exit fullscreen mode

Set IsUpdateFields before calling SaveToFile(), and the document recalculates every field result when it is saved. This is often the final step when generating Word documents programmatically.

Reading Text from Fields

The Document.Fields property returns a collection of all fields in the document, and each field exposes its currently calculated result through the FieldText property:

document = Document()
document.LoadFromFile("document.docx")

fields = document.Fields
for i in range(fields.Count):
    field = fields.get_Item(i)
    print(field.FieldText)

document.Close()
Enter fullscreen mode Exit fullscreen mode

Iterating the collection lets you quickly check whether a field took effect and whether its result is as expected, without knowing the document structure. fields[0] accesses the first field by index.

Converting Fields to Plain Text

Sometimes a document is finalized and no longer needs dynamic updates, such as an order or a contract being exported to a customer. Converting fields to plain text prevents the results from shifting when the recipient opens the file in a different environment:

document = Document()
document.LoadFromFile("document.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

    # Replace the field with text, then remove the field
    field.OwnerParagraph.ChildObjects.Insert(index, text_range)
    field.OwnerParagraph.ChildObjects.Remove(field)

document.SaveToFile("FieldToText.docx", FileFormat.Docx)
document.Close()
Enter fullscreen mode Exit fullscreen mode

The idea is to read the current field text, insert a TextRange at the field's position inside its paragraph, and then remove the field object. Because fields.Count changes as fields are removed, processing fields[0] in a loop cleans up the remaining fields one by one.

Removing Unwanted Fields

Removing a field is simpler than converting it: locate the paragraph that owns the field and delete it by index:

document = Document()
document.LoadFromFile("document.docx")

# Get the first field and its owning paragraph
field = document.Fields[0]
par = field.OwnerParagraph

# Locate the field and remove it by index
index = par.ChildObjects.IndexOf(field)
par.ChildObjects.RemoveAt(index)

document.SaveToFile("RemoveField.docx", FileFormat.Docx)
document.Close()
Enter fullscreen mode Exit fullscreen mode

OwnerParagraph returns the paragraph that contains the field. ChildObjects is the collection of objects inside that paragraph; after IndexOf() finds the field's subscript, RemoveAt() deletes it. To remove fields in bulk, put this logic in a loop.

Practical Tips

  • In Word, press Alt+F9 to toggle the display of field codes, and use it to verify that a critical field code was written correctly.
  • IsUpdateFields must be set before SaveToFile(), otherwise fields are not recalculated in the saved output.
  • For IF fields, assemble the condition strictly as "expression + comparison operator + value", and wrap text values in English double quotes.
  • Converting fields to text loses their dynamic behavior, so do it only when the document is finalized or about to be distributed; keep fields while the document is still being worked on.
  • Call document.Close() when finished to release resources.

Conclusion

This article covered the common ways to work with fields in Word documents using Python: inserting simple fields with AppendField(), building conditional fields with IfField, updating every field with IsUpdateFields, reading field text through Document.Fields, converting fields to plain text, and locating and removing fields via OwnerParagraph. With these techniques, page numbers, conditions, and merge data in dynamic documents can all be handled by a script.

Top comments (0)