Automate Document Creation: Replace Bookmarks in Word Templates with Python
Working with Word documents is still a daily task for many businesses. Reports, contracts, and summaries often follow the same structure, which makes them perfect candidates for automation. Instead of manually editing Word files, you can design a template with bookmarks — placeholders that mark where text, images, or tables should go.
With Free Spire.Doc for Python, filling these bookmarks is straightforward. In this tutorial, you’ll learn how to replace bookmarks with dynamic content step by step, turning a plain Word template into a ready-to-use report.
- Prerequisite
- Replace Bookmark Content with Text
- Replace Bookmark Content with an Image
- Replace Bookmark Content with a Table
- Final Thoughts
Prerequisite
Before we dive into code, let’s cover what you need to get started.
1. Install Required Library
Free Spire.Doc for Python is a free but feature-rich library for working with Word documents. Unlike some open-source alternatives, it fully supports advanced Word features like bookmarks, headers/footers, watermarks, and complex tables.
You can install it via pip:
pip install spire.doc.freeOnce installed, you’ll have access to the spire.doc and spire.doc.common modules, which we’ll use in our examples.
2. Design Your Template in MS Word
The template is the backbone of this workflow. Open Microsoft Word and design your document with placeholders where content will go. For example, a quarterly financial report template might include:
- An executive summary section with a bookmark named text_bookmark
- A financial highlights section with a bookmark named image_bookmark
- A detailed financial data section with a bookmark named table_bookmark
To insert a bookmark in Word:
- Place your cursor at the spot where you want the dynamic content.
- Go to Insert > Bookmark.
- Enter a bookmark name (e.g., text_bookmark).
- Click Add.
Repeat for the other placeholders. Save this file as bookmark_template.docx
Replace Bookmark Content with Text
Replacing a bookmark with text is one of the most straightforward tasks. Imagine you want to insert an executive summary paragraph into your financial report.
Get Alexander Stock’s stories in your inbox
Join Medium for free to get updates from this writer.
Here’s how to do it:
from spire.doc import *
from spire.doc.common import *
# Initialize a new Document object
document = Document()
# Load the template Word file
document.LoadFromFile("C:\\Users\\Administrator\\Desktop\\bookmark_template.docx")
# Create a BookmarksNavigator to manage bookmarks in the document
bookmark_navigator = BookmarksNavigator(document)
# Navigate to a specific bookmark
bookmark_navigator.MoveToBookmark("text_bookmark")
# Text for replacement
text = "In Q1 2025, the company recorded a 12% revenue increase and an 8% net profit growth "+\
"compared to Q4 2024. Strong software sales and expanding APAC markets drove results, while "+\
"higher marketing and logistics costs lifted expenses by 6%. The company also reduced debt by "+\
"5% and maintained solid cash reserves, positioning for steady growth in Q2."
# Replace the bookmart content with text
bookmark_navigator.ReplaceBookmarkContent(text, True)
# Save the modified document
document.SaveToFile("ReplaceWithText.docx", FileFormat.Docx2013)
# Release resources
document.Dispose()📌 In this snippet, we use BookmarksNavigator to jump directly to text_bookmark and replace its contents. The second parameter in ReplaceBookmarkContent (True) specifies that the formatting should be preserved after replacement.
Replace Bookmark Content with an Image
Next, let’s say you want to include a chart image representing financial highlights. With Spire.Doc, inserting an image at a bookmark is simple.
from spire.doc import *
from spire.doc.common import *
# Initialize a new Document object
document = Document()
# Load the template Word file
document.LoadFromFile("C:\\Users\\Administrator\\Desktop\\bookmark_template.docx")
# Create a BookmarksNavigator to manage bookmarks in the document
bookmark_navigator = BookmarksNavigator(document)
# Navigate to a specific bookmark
bookmark_navigator.MoveToBookmark("image_bookmark")
# Delete the current bookmark content
bookmark_navigator.DeleteBookmarkContent(True)
# Create a paragraph and append a picture
paragraph = Paragraph(document)
paragraph.AppendPicture("C:\\Users\\Administrator\\Desktop\\chart_img.png");
# Create a TextBodyPart object from the paragraph
textBodyPart = bookmark_navigator.GetBookmarkContent()
textBodyPart.BodyItems.Add(paragraph)
# Replace the bookmark content with TextBodyPart
bookmark_navigator.ReplaceBookmarkContent(textBodyPart)
# Save the modified document
document.SaveToFile("ReplaceWithImage.docx", FileFormat.Docx2013)
# Release resources
document.Dispose()📌 Here’s what’s happening:
- We first navigate to image_bookmark.
- We clear any existing content using DeleteBookmarkContent(True).
- We create a new paragraph, append the image, and wrap it in a TextBodyPart.
- Finally, we replace the bookmark content with this image-containing body part.
This workflow is perfect for charts (generated from Python libraries like Matplotlib), company logos, or infographics.
Replace Bookmark Content with a Table
Now comes the most powerful part: inserting structured tabular data. Tables are essential for financial reporting, KPIs, or product listings.
from spire.doc import *
from spire.doc.common import *
# Initialize a new Document object
document = Document()
# Load the template Word file
document.LoadFromFile("C:\\Users\\Administrator\\Desktop\\bookmark_template.docx")
# Create a BookmarksNavigator to manage bookmarks in the document
bookmark_navigator = BookmarksNavigator(document)
# Navigate to a specific bookmark
bookmark_navigator.MoveToBookmark("table_bookmark")
# Delete the current bookmark content
bookmark_navigator.DeleteBookmarkContent(True)
# Create a table
table = Table(document, True, 1.0)
# Specify table data including header
table_data = [
["Division", "Revenue (USD)", "Expenses (USD)", "Net Profit (USD)"],
["Software", "15,200,000", "7,800,000", "7,400,000"],
["Hardware", "8,600,000", "5,900,000", "2,700,000"],
["Services", "5,400,000", "3,200,000", "2,200,000"],
["Total", "29,200,000", "16,900,000", "12,300,000"]
]
# Set the row and column count
table.ResetCells(len(table_data), len(table_data[0]))
# Fill the table
for r in range(len(table_data)):
data_row = table.Rows[r]
data_row.Height = 20
data_row.HeightType = TableRowHeightType.Exactly
for c in range(len(table_data[r])):
data_row.Cells[c].CellFormat.VerticalAlignment = VerticalAlignment.Middle
paragraph = data_row.Cells[c].AddParagraph()
paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
txt_range = paragraph.AppendText(table_data[r][c])
if r == 0: # Header row
txt_range.CharacterFormat.Bold = True
txt_range.CharacterFormat.FontSize = 13
txt_range.CharacterFormat.FontName = "Georgia"
else: # Data rows
txt_range.CharacterFormat.FontSize = 12
txt_range.CharacterFormat.FontName = "Georgia"
# Create a TextBodyPart object from the table
textBodyPart = bookmark_navigator.GetBookmarkContent()
textBodyPart.BodyItems.Add(table)
# Replace the bookmark content with TextBodyPart
bookmark_navigator.ReplaceBookmarkContent(textBodyPart)
# Save the modified document
document.SaveToFile("ReplaceWithTable.docx", FileFormat.Docx2013)
# Release resources
document.Dispose()📌 In this code, we:
- Define table_data as a list of lists (with headers + rows).
- Use ResetCells to initialize the table dimensions.
- Loop through rows and columns to insert text, format headers, and align data.
- Insert the table into the bookmark location.
The result is a neatly formatted table embedded right in your Word document, fully replacing the bookmark.
Final Thoughts
Template-based Word generation is a powerful technique for automating repetitive documentation tasks. By designing a template once and using bookmarks as placeholders, you can dynamically inject summaries, charts, or tables into the exact spots you’ve planned in your template.
This approach saves time, keeps formatting consistent, and works for all kinds of documents — financial reports, contracts, or internal dashboards. Start by creating a template once, then let Python handle the rest.
Before You Go
If this added value to your day, consider leaving a clap — it keeps writers motivated! 💙










