Skip to main content

Django integration for docxtpl - generate documents from Word templates with multi-format export

Project description

django-docxtpl

PyPI version Python Versions Django Versions License: MIT

Django integration for docxtpl - generate documents from Word templates with Jinja2 syntax and export to multiple formats.

Features

  • 📝 Generate Word documents (.docx) from templates using Jinja2 syntax
  • 📄 Export to multiple formats: DOCX, PDF, ODT, HTML, TXT
  • 🔄 Automatic format conversion via LibreOffice headless
  • 📑 Update Table of Contents (TOC), charts, and dynamic fields automatically
  • 🎯 Simple API with DocxTemplateResponse
  • 🏗️ Class-based views with DocxTemplateView and DocxTemplateDetailView
  • ⚡ Automatic file extension based on output format

Installation

pip install django-docxtpl

For PDF and other format conversions, you'll need LibreOffice installed:

# Ubuntu/Debian
sudo apt install libreoffice-core libreoffice-writer

# Ubuntu/Debian (headless server - minimal installation)
sudo apt install libreoffice-core libreoffice-writer-nogui

# macOS
brew install --cask libreoffice

# Alpine Linux (Docker)
apk add libreoffice-writer

# RHEL/CentOS/Fedora
sudo dnf install libreoffice-writer

Quick Start

1. Add to INSTALLED_APPS (optional)

INSTALLED_APPS = [
    ...
    "django_docxtpl",
]

2. Create a Word template

Create a .docx file with Jinja2 placeholders:

Hello {{ name }}!

Your order #{{ order_number }} has been confirmed.

3. Use in your views

Function-based view:

from django_docxtpl import DocxTemplateResponse

def generate_document(request):
    context = {
        "name": "John Doe",
        "order_number": "12345",
    }
    return DocxTemplateResponse(
        request,
        template="documents/order.docx",
        context=context,
        filename="order_confirmation",  # Extension added automatically
        output_format="pdf",  # or "docx", "odt", "html", "txt"
    )

Class-based view:

from django_docxtpl import DocxTemplateView

class OrderDocumentView(DocxTemplateView):
    template_name = "documents/order.docx"
    filename = "order_confirmation"
    output_format = "pdf"

    def get_context_data(self, **kwargs):
        return {
            "name": self.request.user.get_full_name(),
            "order_number": kwargs.get("order_id"),
        }

Detail view for model instances:

from django_docxtpl import DocxTemplateDetailView

class InvoiceDocumentView(DocxTemplateDetailView):
    model = Invoice
    template_name = "documents/invoice.docx"
    output_format = "pdf"
    context_object_name = "invoice"

    def get_filename(self):
        return f"invoice_{self.object.number}"

Configuration

Add these optional settings to your settings.py:

# Directory where your .docx templates are stored
DOCXTPL_TEMPLATE_DIR = BASE_DIR / "docx_templates"

# Path to LibreOffice executable (auto-detected if not set)
DOCXTPL_LIBREOFFICE_PATH = "/usr/bin/soffice"

Supported Output Formats

Format Extension Requires LibreOffice
DOCX .docx No (Yes if update_fields=True)
PDF .pdf Yes
ODT .odt Yes
HTML .html Yes
TXT .txt Yes

Template Syntax

django-docxtpl uses docxtpl which supports full Jinja2 syntax:

{% for item in items %}
- {{ item.name }}: {{ item.price }}€
{% endfor %}

Total: {{ total }}€

{% if discount %}
Discount applied: {{ discount }}%
{% endif %}

See the docxtpl documentation for advanced features like images, tables, and rich text.

Updating TOC and Charts

If your template contains a Table of Contents (TOC), charts, or other dynamic fields that need to be updated after rendering, use the update_fields parameter:

# Function-based view
return DocxTemplateResponse(
    request,
    template="reports/annual_report.docx",
    context=context,
    output_format="pdf",
    update_fields=True,  # Updates TOC, charts, page numbers, etc.
)

# Class-based view
class AnnualReportView(DocxTemplateView):
    template_name = "reports/annual_report.docx"
    output_format = "pdf"
    update_fields = True

Note: This feature requires LibreOffice, even when output format is DOCX.

Performance Considerations

Document generation, especially PDF conversion with LibreOffice, can be slow (1-5 seconds per document). For production environments, consider:

  1. Use a task queue - Offload document generation to background workers using Celery, Django-RQ, or Huey:

Example 1:

# tasks.py (Huey example)
from huey.contrib.djhuey import task
from django.core.files.base import ContentFile
from django_docxtpl.converters import convert_docx
from docxtpl import DocxTemplate
from io import BytesIO

@task()
def generate_report_pdf(report_id):
    report = Report.objects.get(pk=report_id)
    
    doc = DocxTemplate("templates/report.docx")
    doc.render({"report": report})
    
    buffer = BytesIO()
    doc.save(buffer)
    buffer.seek(0)
    
    pdf_content = convert_docx(buffer, "pdf", update_fields=True)
    
    # Save to storage, send email, etc.
    report.pdf_file.save(f"report_{report_id}.pdf", ContentFile(pdf_content))

Example 2:

# tasks.py (Huey example) - Using render_to_file utility
from huey.contrib.djhuey import task
from django_docxtpl import render_to_file

@task()
def generate_report_to_disk(output_dir, filename, context):
    """Generate a document and save it to disk."""
    output_path = render_to_file(
        template="reports/monthly.docx",
        context=context,
        output_dir=output_dir,
        filename=filename,
        output_format="pdf",
        update_fields=True,
    )
    return str(output_path)
  1. Serve DOCX when possible - Skip LibreOffice conversion for faster response times
  2. Cache generated documents - Store frequently requested documents

API Reference

DocxTemplateResponse

DocxTemplateResponse(
    request,
    template,           # Path to .docx template
    context=None,       # Template context dict
    filename="document",# Output filename (without extension)
    output_format="docx",# Output format
    as_attachment=True, # Download as attachment or inline
    update_fields=False,# Update TOC, charts, and dynamic fields
)

DocxTemplateView

Class attributes:

  • template_name - Path to .docx template
  • filename - Output filename (default: "document")
  • output_format - Output format (default: "docx")
  • as_attachment - Serve as attachment (default: True)
  • update_fields - Update TOC, charts, and dynamic fields (default: False)

Override methods:

  • get_template_name() - Dynamic template selection
  • get_filename() - Dynamic filename
  • get_output_format() - Dynamic format selection
  • get_update_fields() - Dynamic field update control
  • get_context_data(**kwargs) - Provide template context

DocxTemplateDetailView

Same as DocxTemplateView plus:

  • model - Django model class
  • pk_url_kwarg - URL kwarg for primary key (default: "pk")
  • slug_url_kwarg - URL kwarg for slug (default: "slug")
  • slug_field - Model field for slug lookup (default: "slug")
  • context_object_name - Context variable name for object

Error Handling

from django_docxtpl import ConversionError, LibreOfficeNotFoundError

try:
    response = DocxTemplateResponse(request, template="doc.docx", output_format="pdf")
except LibreOfficeNotFoundError:
    # LibreOffice not installed
    pass
except ConversionError as e:
    # Conversion failed
    pass

Development

# Clone the repository
git clone https://github.com/ctrl-alt-d/django-docxtpl.git
cd django-docxtpl

# Create virtual environment
python -m venv venv
source venv/bin/activate

# Install with development dependencies
pip install flit
flit install -s --deps develop

# Run tests
pytest

# Run linter
ruff check .

# Format code
ruff format .

License

MIT License - see LICENSE for details.

Credits

  • docxtpl - Python library for generating docx documents
  • python-docx - Python library for Word documents

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_docxtpl-0.2.0.tar.gz (39.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_docxtpl-0.2.0-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file django_docxtpl-0.2.0.tar.gz.

File metadata

  • Download URL: django_docxtpl-0.2.0.tar.gz
  • Upload date:
  • Size: 39.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_docxtpl-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8c87582ea09acfd60192bd70c7f4912635152dd6d7f5800c877f142c1374a694
MD5 9bb1746e010be41fc32a90a64114716e
BLAKE2b-256 ae85f0a2a8580b00b2b55dcaf092bba67f403628e1945bb54ff2b217462f7640

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_docxtpl-0.2.0.tar.gz:

Publisher: publish.yml on ctrl-alt-d/django-docxtpl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_docxtpl-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: django_docxtpl-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_docxtpl-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f02da8c14e761b7cd0b43af70e18d184060c61658d44b30328ccd652575fb1a7
MD5 b4827c2c6d8fcf6fdc4818cecdb006c1
BLAKE2b-256 942247759b64fc7a193b90aa43656e274f6f7a2249d7b25d09c7cff2d9807aa8

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_docxtpl-0.2.0-py3-none-any.whl:

Publisher: publish.yml on ctrl-alt-d/django-docxtpl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page