docx-templates
Template-based Word document generation using Jinja2 syntax. Create reports, contracts, and documents with loops, conditionals, tables, and mail merge capabilities.
What this skill does
# Docx-Templates Skill
> Generate Word documents from templates using Jinja2 syntax. Create professional reports, contracts, and documents with dynamic content, loops, conditionals, and tables.
## Quick Start
```bash
# Install docxtpl
pip install docxtpl
# Install with image support
pip install docxtpl Pillow
# For Excel data sources
pip install docxtpl openpyxl pandas
# Verify installation
python -c "from docxtpl import DocxTemplate; print('docxtpl ready!')"
```
## When to Use This Skill
**USE when:**
- Generating documents from templates with dynamic data
- Creating mail merge documents from data sources
- Building reports with loops and conditional sections
- Need to maintain consistent formatting across generated documents
- Generating contracts, invoices, letters from templates
- Processing batch document generation from databases or spreadsheets
- Templates need professional formatting preserved
- Non-technical users maintain template design
**DON'T USE when:**
- Building documents programmatically from scratch (use python-docx)
- Need complex document manipulation beyond template filling
- PDF output is the final format (generate docx then convert)
- Templates require complex macros or VBA
- Real-time collaborative editing needed
## Prerequisites
```bash
# Core installation
pip install docxtpl>=0.16.0
# For image handling
pip install docxtpl Pillow>=9.0.0
# For data processing
pip install docxtpl pandas>=2.0.0 openpyxl>=3.1.0
# For database connections
pip install docxtpl sqlalchemy psycopg2-binary
# All dependencies
pip install docxtpl Pillow pandas openpyxl sqlalchemy
```
### Verify Installation
```python
from docxtpl import DocxTemplate, InlineImage
from docx.shared import Mm, Inches
print("docxtpl installed successfully!")
# Quick test
# template = DocxTemplate("template.docx")
# context = {"name": "World"}
# template.render(context)
# template.save("output.docx")
```
## Core Capabilities
### 1. Basic Template Rendering
**Simple Variable Substitution:**
```python
"""
Basic template rendering with variable substitution.
"""
from docxtpl import DocxTemplate
from typing import Dict, Any
from pathlib import Path
def render_simple_template(
template_path: str,
output_path: str,
context: Dict[str, Any]
) -> None:
"""
Render a template with simple variable substitution.
Args:
template_path: Path to .docx template
output_path: Path for output document
context: Dictionary of values to substitute
Template syntax:
{{ variable_name }} - Simple variable
{{ object.property }} - Nested property
"""
# Load template
template = DocxTemplate(template_path)
# Render with context
template.render(context)
# Save output
template.save(output_path)
print(f"Document saved to {output_path}")
def create_sample_letter(output_path: str) -> None:
"""Create a sample letter using template rendering."""
# First, create a simple template (normally you'd have this prepared)
# Template content would have: {{ recipient_name }}, {{ date }}, etc.
context = {
"recipient_name": "John Smith",
"recipient_title": "Director of Operations",
"company_name": "Acme Corporation",
"street_address": "123 Business Ave",
"city_state_zip": "New York, NY 10001",
"date": "January 17, 2026",
"subject": "Project Proposal",
"salutation": "Dear Mr. Smith",
"body_paragraph_1": """
We are pleased to submit our proposal for the infrastructure
upgrade project. Our team has extensive experience in similar
projects and we are confident we can deliver exceptional results.
""".strip(),
"body_paragraph_2": """
The attached documents outline our approach, timeline, and
budget estimates. We would welcome the opportunity to discuss
this proposal at your convenience.
""".strip(),
"closing": "Sincerely",
"sender_name": "Jane Doe",
"sender_title": "Project Manager"
}
# Render template
render_simple_template("letter_template.docx", output_path, context)
# Example context for a business report
report_context = {
"report_title": "Q4 2025 Performance Report",
"prepared_by": "Analytics Team",
"date": "January 15, 2026",
"executive_summary": "Strong performance across all metrics...",
"total_revenue": "$2,450,000",
"growth_rate": "15.3%",
"customer_count": "1,250",
"key_achievements": [
"Launched new product line",
"Expanded to 3 new markets",
"Achieved ISO certification"
]
}
```
**Nested Object Access:**
```python
"""
Access nested objects and complex data structures in templates.
"""
from docxtpl import DocxTemplate
from dataclasses import dataclass, asdict
from typing import List, Dict, Optional
from datetime import date
@dataclass
class Address:
"""Address data structure."""
street: str
city: str
state: str
zip_code: str
country: str = "USA"
@property
def full_address(self) -> str:
return f"{self.street}\n{self.city}, {self.state} {self.zip_code}"
@dataclass
class Contact:
"""Contact information."""
name: str
email: str
phone: str
title: Optional[str] = None
@dataclass
class Company:
"""Company data structure."""
name: str
address: Address
contacts: List[Contact]
industry: str
website: str
def to_dict(self) -> Dict:
"""Convert to dictionary for template rendering."""
return {
"name": self.name,
"address": asdict(self.address),
"contacts": [asdict(c) for c in self.contacts],
"industry": self.industry,
"website": self.website
}
def render_with_nested_data(
template_path: str,
output_path: str,
company: Company
) -> None:
"""
Render template with nested data structures.
Template syntax for nested access:
{{ company.name }}
{{ company.address.street }}
{{ company.contacts[0].email }}
"""
template = DocxTemplate(template_path)
context = {
"company": company.to_dict(),
"generated_date": date.today().strftime("%B %d, %Y")
}
template.render(context)
template.save(output_path)
# Example usage
company = Company(
name="TechCorp Industries",
address=Address(
street="456 Innovation Blvd",
city="San Francisco",
state="CA",
zip_code="94105"
),
contacts=[
Contact(
name="Alice Johnson",
email="[email protected]",
phone="555-0101",
title="CEO"
),
Contact(
name="Bob Williams",
email="[email protected]",
phone="555-0102",
title="CTO"
)
],
industry="Technology",
website="https://techcorp.com"
)
# render_with_nested_data("company_profile.docx", "techcorp_profile.docx", company)
```
### 2. Loops and Iterations
**Rendering Lists and Tables:**
```python
"""
Use loops to render lists, tables, and repeated content.
"""
from docxtpl import DocxTemplate
from typing import List, Dict, Any
from dataclasses import dataclass
from decimal import Decimal
@dataclass
class LineItem:
"""Invoice line item."""
description: str
quantity: int
unit_price: Decimal
discount: Decimal = Decimal("0")
@property
def subtotal(self) -> Decimal:
return self.quantity * self.unit_price * (1 - self.discount / 100)
@dataclass
class Invoice:
"""Invoice data structure."""
invoice_number: str
date: str
due_date: str
client_name: str
client_address: str
items: List[LineItem]
tax_rate: Decimal = Decimal("8.5")
notes: str = ""
@property
def subtotal(self) -> Decimal:
return sum(item.subtotal for item in self.items)
@Related in office-docs
openpyxl
IncludedCreate and manipulate Microsoft Excel workbooks programmatically. Build spreadsheets with formulas, charts, conditional formatting, and pivot tables. Handle large datasets efficiently with streaming mode.
python-docx
IncludedCreate and manipulate Microsoft Word documents programmatically. Build reports, contracts, and documentation with full control over paragraphs, tables, headers, styles, and images.
python-pptx
IncludedCreate and manipulate PowerPoint presentations programmatically. Build slide decks with layouts, shapes, charts, tables, and images. Generate data-driven presentations from templates.
pypdf
IncludedManipulate PDF documents programmatically. Merge, split, rotate, and watermark PDFs. Extract text and metadata. Handle form filling and encryption/decryption.