Last modified: Jul 08, 2026

Python-docx Tab Stops & Indentation Control

Precise formatting is key to professional documents. Python-docx offers powerful tools for controlling tab stops and indentation. This guide will help you master these features.

You can create clean, readable Word documents with perfect alignment. Let's explore how to control every aspect of paragraph spacing and positioning.

Understanding Tab Stops in Python-docx

Tab stops define where the cursor jumps when you press the Tab key. Python-docx supports five tab stop types: left, center, right, decimal, and bar.

Each tab stop has a position in inches or centimeters. You can add multiple tab stops to a single paragraph style.

To add a tab stop, use the add_tab_stop() method on a paragraph's paragraph_format object. Here's a basic example:

 
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_TAB_ALIGNMENT

doc = Document()
paragraph = doc.add_paragraph()

# Add a left-aligned tab stop at 2 inches
paragraph.paragraph_format.add_tab_stop(Inches(2), WD_TAB_ALIGNMENT.LEFT)

# Add a right-aligned tab stop at 4 inches
paragraph.paragraph_format.add_tab_stop(Inches(4), WD_TAB_ALIGNMENT.RIGHT)

paragraph.add_run("Item\tPrice\tTotal")
paragraph.add_run("\nApple\t$1.50\t$3.00")
paragraph.add_run("\nBanana\t$0.75\t$1.50")

doc.save("tab_example.docx")

This creates a simple price list. The tab stops align the text neatly at 2 and 4 inches. Notice how WD_TAB_ALIGNMENT controls the alignment type.

You can also set tab leader characters. These fill the space with dots, dashes, or lines. Use the WD_TAB_LEADER enum for this.

 
from docx.enum.text import WD_TAB_LEADER

# Add a tab stop with dot leader
paragraph.paragraph_format.add_tab_stop(
    Inches(5), 
    WD_TAB_ALIGNMENT.RIGHT, 
    WD_TAB_LEADER.DOTS
)

Tab leaders are great for table of contents or lists where you need visual guidance.

Mastering Paragraph Indentation

Indentation controls the space between paragraph text and the page margins. Python-docx provides four indentation properties: left, right, first_line, and hanging.

These are set through the paragraph_format object. Each property accepts values in inches, centimeters, or points.

Here's how to set basic indentation:

 
from docx.shared import Inches

paragraph = doc.add_paragraph("This paragraph has left indentation.")
paragraph.paragraph_format.left_indent = Inches(0.5)

paragraph2 = doc.add_paragraph("This has right indentation.")
paragraph2.paragraph_format.right_indent = Inches(0.3)

paragraph3 = doc.add_paragraph("First line indentation here.")
paragraph3.paragraph_format.first_line_indent = Inches(0.25)

First-line indent is common in books and reports. It indents only the first line of a paragraph. Hanging indent does the opposite.

Hanging indent pushes all lines except the first inward. This is useful for bibliographies or numbered lists.

 
# Hanging indent example
para = doc.add_paragraph("This paragraph uses a hanging indent. All lines except the first are indented by 0.5 inches.")
para.paragraph_format.left_indent = Inches(0.5)
para.paragraph_format.first_line_indent = Inches(-0.5)

Notice the negative first_line_indent. This creates the hanging effect by pulling the first line back to the left margin.

Combining Tabs and Indentation

You can use tabs and indentation together for complex layouts. This is common in forms, invoices, and structured documents.

For example, you might indent a paragraph and then use tab stops to align columns within it.

 
from docx.shared import Pt

# Create a styled paragraph with both features
styled_para = doc.add_paragraph()
styled_para.paragraph_format.left_indent = Inches(1)
styled_para.paragraph_format.add_tab_stop(Inches(3), WD_TAB_ALIGNMENT.CENTER)
styled_para.paragraph_format.add_tab_stop(Inches(5), WD_TAB_ALIGNMENT.RIGHT)

styled_para.add_run("Name\tPosition\tSalary")
styled_para.add_run("\nJohn\tManager\t$75,000")
styled_para.add_run("\nJane\tAnalyst\t$55,000")

This creates a simple table-like structure without using actual tables. It's lightweight and flexible.

For more complex multi-column layouts, check out our Python docx Multi-Column Layouts Guide.

Working with Paragraph Spacing

Spacing before and after paragraphs works alongside indentation. Use space_before and space_after properties.

Line spacing controls the vertical space between lines within a paragraph. Use line_spacing with values like 1.0, 1.5, or 2.0.

 
from docx.shared import Pt

para = doc.add_paragraph("This paragraph has custom spacing.")
para.paragraph_format.space_before = Pt(12)
para.paragraph_format.space_after = Pt(6)
para.paragraph_format.line_spacing = 1.5

Combining spacing with indentation gives you full control over document appearance.

Using Styles for Consistent Formatting

Instead of applying formatting to each paragraph, define styles. This saves time and ensures consistency.

Python-docx allows you to modify built-in styles or create custom ones.

 
from docx.enum.style import WD_STYLE_TYPE

# Create a custom style
style = doc.styles.add_style('IndentStyle', WD_STYLE_TYPE.PARAGRAPH)
style.paragraph_format.left_indent = Inches(0.75)
style.paragraph_format.first_line_indent = Inches(0.25)
style.paragraph_format.space_after = Pt(6)

# Apply the style
para = doc.add_paragraph("This uses our custom style.", style='IndentStyle')

For more on clean document generation, see our Python docx Best Practices for Clean Generation guide.

Practical Examples

Let's build a real-world example: a formatted letter with indented paragraphs and tab stops for the date and signature.

 
doc = Document()

# Add date with right tab
date_para = doc.add_paragraph()
date_para.paragraph_format.add_tab_stop(Inches(5), WD_TAB_ALIGNMENT.RIGHT)
date_para.add_run("January 15, 2025\t")

# Add recipient address with left indent
address = doc.add_paragraph("John Smith\n123 Main Street\nCityville, State 12345")
address.paragraph_format.left_indent = Inches(0.5)

# Add body with first-line indent
body = doc.add_paragraph(
    "Dear Mr. Smith,\n\n"
    "Thank you for your recent inquiry. We are pleased to provide the following information. "
    "Our team has reviewed your request and we will respond within five business days."
)
body.paragraph_format.first_line_indent = Inches(0.3)
body.paragraph_format.space_after = Pt(12)

# Add signature with right tab
sign_para = doc.add_paragraph()
sign_para.paragraph_format.add_tab_stop(Inches(4), WD_TAB_ALIGNMENT.LEFT)
sign_para.add_run("Sincerely,\tJane Doe")

doc.save("formatted_letter.docx")

This letter uses indentation for the address and body. Tab stops align the date and signature properly.

Common Pitfalls and Solutions

One common mistake is forgetting to import the correct modules. Always import Inches, Pt, and WD_TAB_ALIGNMENT when needed.

Another issue is setting indentation on the wrong object. Indentation belongs to paragraph_format, not the paragraph itself.

Remember that tab stops are relative to the paragraph's left margin. If you indent a paragraph, tab stops shift accordingly.

For more advanced formatting, consider using templates. Our Python DOCX Templates with Jinja2 guide shows how to combine Python-docx with Jinja2 for dynamic documents.

Conclusion

Mastering tab stops and indentation control in Python-docx gives you professional document formatting. You can align text precisely, create clean layouts, and automate complex documents.

Start with simple examples and gradually add more features. Use styles for consistency and templates for repeatable documents.

With these tools, you can generate Word documents that look hand-crafted and professional. Experiment with different combinations to find what works for your needs.