Last modified: Jul 08, 2026

Python-docx Text Boxes & Shapes Tutorial

Adding visual elements like text boxes and shapes makes Word documents more engaging. Python-docx is a powerful library for creating and modifying Word files. This tutorial shows you how to add text boxes and shapes using python-docx.

You will learn step-by-step methods. Each section includes code examples and outputs. This guide is perfect for beginners who want to enhance their document automation skills.

What are Text Boxes and Shapes?

Text boxes are containers that hold text. You can place them anywhere in a document. Shapes include rectangles, circles, arrows, and lines. Both elements add visual appeal.

Python-docx lets you insert these objects easily. You can control their size, position, and style. This makes your automated documents look professional.

Setting Up Your Environment

First, install python-docx. Use pip in your terminal.


pip install python-docx

Now import the library in your script.


from docx import Document
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

Create a new document object.


doc = Document()

Adding a Text Box

Text boxes are not directly supported in python-docx. But you can use XML manipulation. The OxmlElement function helps create custom elements.

Here is how to add a simple text box.


from docx import Document
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

doc = Document()

# Create a text box element
text_box = OxmlElement('w:txbxContent')
paragraph = OxmlElement('w:p')
run = OxmlElement('w:r')
text = OxmlElement('w:t')
text.text = 'This is a text box!'
run.append(text)
paragraph.append(run)
text_box.append(paragraph)

# Create the shape container
shape = OxmlElement('w:txbx')
shape.append(text_box)

# Add to document body
doc.element.body.append(shape)

doc.save('text_box_example.docx')

Important: This creates a basic text box. For full control, you need to set dimensions and position using XML attributes.

Adding Shapes like Rectangles and Circles

Shapes are created using DrawingML (dml) elements. Python-docx does not have built-in methods. But you can use OxmlElement again.

Here is an example of adding a rectangle shape.


from docx import Document
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

doc = Document()

# Create a shape element (rectangle)
shape = OxmlElement('w:shape')
shape.set(qn('w:type'), '#rect')
shape.set(qn('w:style'), 'position:absolute;left:100px;top:100px;width:200px;height:100px;')

# Add text inside the shape (optional)
textbox = OxmlElement('w:textbox')
paragraph = OxmlElement('w:p')
run = OxmlElement('w:r')
text = OxmlElement('w:t')
text.text = 'Rectangle Shape'
run.append(text)
paragraph.append(run)
textbox.append(paragraph)
shape.append(textbox)

doc.element.body.append(shape)

doc.save('shape_example.docx')

Remember: The w:style attribute uses CSS-like syntax. Adjust left, top, width, and height values as needed.

Positioning and Sizing Text Boxes

Positioning is crucial for layout. Use the w:style attribute to set exact coordinates. You can also use percentage values.

Here is a text box positioned at the top-right corner.


from docx import Document
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

doc = Document()

# Create text box with positioning
shape = OxmlElement('w:shape')
shape.set(qn('w:type'), '#rect')
shape.set(qn('w:style'), 'position:absolute;right:10px;top:10px;width:150px;height:80px;')

textbox = OxmlElement('w:textbox')
paragraph = OxmlElement('w:p')
run = OxmlElement('w:r')
text = OxmlElement('w:t')
text.text = 'Top Right Box'
run.append(text)
paragraph.append(run)
textbox.append(paragraph)
shape.append(textbox)

doc.element.body.append(shape)
doc.save('positioned_textbox.docx')

Tip: Use left and top for absolute positioning. Use right and bottom for relative positioning.

Styling Shapes with Colors and Borders

You can add fill colors and borders to shapes. Use XML attributes like fillcolor and strokecolor.

Here is a blue rectangle with a red border.


from docx import Document
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

doc = Document()

shape = OxmlElement('w:shape')
shape.set(qn('w:type'), '#rect')
shape.set(qn('w:style'), 'position:absolute;left:50px;top:50px;width:200px;height:100px;')
shape.set(qn('w:fillcolor'), '#0000FF')  # Blue fill
shape.set(qn('w:strokecolor'), '#FF0000')  # Red border
shape.set(qn('w:strokeweight'), '2pt')  # Border thickness

textbox = OxmlElement('w:textbox')
paragraph = OxmlElement('w:p')
run = OxmlElement('w:r')
text = OxmlElement('w:t')
text.text = 'Styled Shape'
run.append(text)
paragraph.append(run)
textbox.append(paragraph)
shape.append(textbox)

doc.element.body.append(shape)
doc.save('styled_shape.docx')

Note: Colors are in hex format. The strokeweight sets border thickness.

Adding Multiple Shapes in One Document

You can add many shapes to the same document. Just repeat the process for each shape.

Here is an example with two shapes: a circle and a line.


from docx import Document
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

doc = Document()

# Circle shape
circle = OxmlElement('w:shape')
circle.set(qn('w:type'), '#ellipse')
circle.set(qn('w:style'), 'position:absolute;left:50px;top:50px;width:100px;height:100px;')
circle.set(qn('w:fillcolor'), '#00FF00')

doc.element.body.append(circle)

# Line shape
line = OxmlElement('w:shape')
line.set(qn('w:type'), '#line')
line.set(qn('w:style'), 'position:absolute;left:50px;top:200px;width:300px;height:2px;')
line.set(qn('w:strokecolor'), '#000000')
line.set(qn('w:strokeweight'), '3pt')

doc.element.body.append(line)

doc.save('multiple_shapes.docx')

Output: A green circle and a black line appear in the document.

Using Python-docx Best Practices

When working with shapes, always test your XML. Small errors can break the document. Use doc.save() to check results.

For cleaner code, consider using helper functions. This reduces repetition and improves readability. For more tips, read our Python docx Best Practices for Clean Generation guide.

Also, learn about Python docx Multi-Column Layouts Guide for advanced document structure.

Common Issues and Solutions

Issue: Text box not visible. Solution: Check the position values. Ensure they are within page boundaries.

Issue: Shape appears but no text. Solution: Make sure the w:textbox element is inside the shape.

Issue: Document corrupt. Solution: Validate your XML. Use a simple shape first to test.

Conclusion

Adding text boxes and shapes with python-docx requires XML manipulation. This tutorial provided practical examples. You learned to create, position, and style shapes.

Practice with different shapes and styles. Experiment with sizes and colors. This skill enhances your document automation projects.

For more advanced techniques, explore our Future of Python DOCX Automation Trends article. Keep coding and creating professional documents.