CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-docxtpl

Use a docx as a jinja2 template

Pending
Overview
Eval results
Files

media-composition.mddocs/

Media and Document Composition

Functionality for inserting images, composing sub-documents, and handling text with special characters within templates. These capabilities enable complex document assembly and rich media integration.

Capabilities

InlineImage Class

Class for generating inline images in templates with precise control over dimensions and positioning.

class InlineImage:
    def __init__(self, tpl, image_descriptor, width=None, height=None, anchor=None):
        """
        Initialize InlineImage for insertion into template.
        
        Parameters:
        - tpl: DocxTemplate instance reference
        - image_descriptor: Path to image file or file-like object
        - width: Image width (in EMUs, inches, or Inches() object)
        - height: Image height (in EMUs, inches, or Inches() object)
        - anchor: Optional URL anchor for image hyperlink
        """

InlineImage Properties

Access to image configuration and template reference.

@property
def tpl:
    """Reference to DocxTemplate instance."""

@property  
def image_descriptor:
    """Path or file-like object for image source."""

@property
def width:
    """Image width dimension."""

@property
def height:
    """Image height dimension."""

@property
def anchor:
    """URL anchor for hyperlink (optional)."""

InlineImage String Methods

Methods for converting image to XML representation for template insertion.

def __str__(self) -> str:
    """Return XML representation of inline image."""

def __unicode__(self) -> str:
    """Return Unicode XML representation of inline image."""

def __html__(self) -> str:
    """Return HTML-like representation of inline image."""

Subdoc Class

Class for sub-documents that can be inserted into master documents, enabling complex document composition and modular content assembly.

class Subdoc:
    def __init__(self, tpl, docpath=None):
        """
        Initialize Subdoc for document composition.
        
        Parameters:
        - tpl: DocxTemplate instance reference
        - docpath: Optional path to existing document to use as base
        """

Subdoc Properties

Access to document instances and template reference.

@property
def tpl:
    """Reference to DocxTemplate instance."""

@property
def docx:
    """Main document reference."""

@property
def subdocx:
    """Sub-document instance."""

Subdoc Document Methods

The Subdoc class delegates to python-docx Document methods via __getattr__, providing access to all document creation capabilities:

# Document content creation methods (delegated to python-docx)
def add_paragraph(self, text='', style=None): ...
def add_table(self, rows, cols, style=None): ...
def add_picture(self, image_path_or_stream, width=None, height=None): ...
def add_heading(self, text='', level=1): ...
def add_page_break(self): ...
# ... and all other python-docx Document methods

Subdoc String Methods

Methods for converting subdocument to XML representation for template insertion.

def __str__(self) -> str:
    """Return XML representation of subdocument."""

def __unicode__(self) -> str:
    """Return Unicode XML representation of subdocument."""

def __html__(self) -> str:
    """Return HTML-like representation of subdocument."""

Listing Class

Class for managing text with newlines and special characters while preserving template styling. Useful for code listings, addresses, and multi-line formatted text.

class Listing:
    def __init__(self, text):
        """
        Initialize Listing with text content.
        
        Parameters:
        - text: Text content with newlines and special characters
        """

Listing String Methods

Methods for converting listing to escaped XML representation.

def __str__(self) -> str:
    """Return escaped XML representation of listing text."""

def __unicode__(self) -> str:
    """Return Unicode escaped XML representation of listing text."""

def __html__(self) -> str:
    """Return HTML-like representation of listing text."""

Usage Examples

Image Insertion

from docxtpl import DocxTemplate, InlineImage
from docx.shared import Inches

doc = DocxTemplate("template.docx")

# Create inline image with specific dimensions
logo = InlineImage(doc, "company_logo.png", width=Inches(2), height=Inches(1))

# Image with hyperlink
chart_url = doc.build_url_id("https://example.com/chart-details")
chart = InlineImage(doc, "sales_chart.png", width=Inches(4), height=Inches(3), anchor=chart_url)

context = {
    'company_logo': logo,
    'sales_chart': chart
}

doc.render(context)
doc.save("report_with_images.docx")

Dynamic Image Sizing

from docxtpl import DocxTemplate, InlineImage
from docx.shared import Inches, Cm

doc = DocxTemplate("gallery_template.docx")

# Different image sizes
images = []
image_files = ["photo1.jpg", "photo2.jpg", "photo3.jpg"]
sizes = [Inches(2), Cm(5), Inches(1.5)]

for img_file, size in zip(image_files, sizes):
    img = InlineImage(doc, img_file, width=size, height=size)
    images.append(img)

context = {
    'gallery_images': images
}

doc.render(context)
doc.save("photo_gallery.docx")

Subdocument Composition

from docxtpl import DocxTemplate, Subdoc

doc = DocxTemplate("main_template.docx")

# Create subdocument with content
subdoc = doc.new_subdoc()

# Add content to subdocument using python-docx methods
subdoc.add_heading("Technical Specifications", level=2)
subdoc.add_paragraph("This section contains detailed specifications.")

# Create table in subdocument
table = subdoc.add_table(rows=3, cols=2)
table.cell(0, 0).text = "Component"
table.cell(0, 1).text = "Value"
table.cell(1, 0).text = "CPU"
table.cell(1, 1).text = "Intel i7"
table.cell(2, 0).text = "RAM"
table.cell(2, 1).text = "16GB"

context = {
    'technical_details': subdoc
}

doc.render(context)
doc.save("complete_document.docx")

Complex Document Assembly

from docxtpl import DocxTemplate, Subdoc, InlineImage
from docx.shared import Inches

doc = DocxTemplate("complex_template.docx")

# Create multiple subdocuments
intro_section = doc.new_subdoc()
intro_section.add_heading("Introduction", level=1)
intro_section.add_paragraph("This document presents our quarterly analysis.")

results_section = doc.new_subdoc()
results_section.add_heading("Results", level=1)
results_section.add_paragraph("Key findings from our analysis:")

# Add image to results section
chart_img = InlineImage(doc, "quarterly_chart.png", width=Inches(5))
results_section.add_paragraph().add_run().add_picture(chart_img.image_descriptor)

context = {
    'introduction': intro_section,
    'results': results_section,
    'executive_signature': InlineImage(doc, "signature.png", width=Inches(2))
}

doc.render(context)
doc.save("quarterly_report.docx")

Text Listings and Special Characters

from docxtpl import DocxTemplate, Listing

doc = DocxTemplate("code_template.docx")

# Code listing with proper formatting
python_code = Listing("""def calculate_total(items):
    total = 0
    for item in items:
        total += item['price'] * item['quantity']
    return total

# Example usage
items = [
    {'name': 'Widget', 'price': 10.00, 'quantity': 5},
    {'name': 'Gadget', 'price': 25.00, 'quantity': 2}
]
result = calculate_total(items)""")

# Address with line breaks
address = Listing("""John Doe
123 Main Street
Apartment 4B
New York, NY 10001
United States""")

# Text with special characters
special_text = Listing("Special chars: < > & \" ' \n\nNew line after special chars")

context = {
    'code_example': python_code,
    'customer_address': address,
    'notes': special_text
}

doc.render(context)
doc.save("formatted_document.docx")

Mixed Media Document

from docxtpl import DocxTemplate, InlineImage, Subdoc, Listing, RichText
from docx.shared import Inches

doc = DocxTemplate("mixed_media_template.docx")

# Header image
header_img = InlineImage(doc, "header_banner.png", width=Inches(6))

# Rich text introduction
intro = RichText()
intro.add("Welcome to our ", bold=False)
intro.add("Annual Report 2024", bold=True, color="0066CC", size=14)

# Code listing
sample_code = Listing("""# Configuration
SERVER_URL = "https://api.example.com"
API_KEY = "your-api-key-here"
TIMEOUT = 30""")

# Subdocument with mixed content
details = doc.new_subdoc()
details.add_heading("Technical Details", level=2)
details.add_paragraph("Architecture overview:")
arch_img = InlineImage(doc, "architecture_diagram.png", width=Inches(4))
details.add_paragraph("System Architecture").add_run()._element.append(arch_img._element)

context = {
    'header_banner': header_img,
    'introduction': intro,
    'configuration': sample_code,
    'technical_section': details
}

doc.render(context)
doc.save("mixed_media_report.docx")

Install with Tessl CLI

npx tessl i tessl/pypi-docxtpl

docs

index.md

media-composition.md

rich-text.md

template-processing.md

tile.json