template-engine

Auto-fill document templates with data - mail merge for any format

INSTALLATION
npx skills add https://github.com/claude-office-skills/skills --skill template-engine
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Template Engine Skill

Overview

This skill enables template-based document generation - define templates with placeholders, then automatically fill them with data. Works with Word, Excel, PowerPoint, and more.

How to Use

  • Describe what you want to accomplish
  • Provide any required input data or files
  • I'll execute the appropriate operations

Example prompts:

  • "Mail merge for bulk letters/contracts"
  • "Generate personalized reports from data"
  • "Create certificates from templates"
  • "Auto-fill forms with user data"

Domain Knowledge

Template Syntax (Jinja2-based)

{{ variable }}           - Simple substitution

{% for item in list %}   - Loop

{% if condition %}       - Conditional

{{ date | format_date }} - Filter

Word Template Example

from docxtpl import DocxTemplate

# Create template with placeholders:

# Dear {{ name }},

# Thank you for your order #{{ order_id }}...

def fill_template(template_path: str, data: dict, output_path: str):

    doc = DocxTemplate(template_path)

    doc.render(data)

    doc.save(output_path)

    return output_path

# Usage

fill_template(

    "templates/order_confirmation.docx",

    {

        "name": "John Smith",

        "order_id": "ORD-12345",

        "items": [

            {"name": "Product A", "qty": 2, "price": 29.99},

            {"name": "Product B", "qty": 1, "price": 49.99}

        ],

        "total": 109.97

    },

    "output/confirmation_john.docx"

)

Excel Template

from openpyxl import load_workbook

import re

def fill_excel_template(template_path: str, data: dict, output_path: str):

    wb = load_workbook(template_path)

    ws = wb.active

    # Find and replace placeholders like {{name}}

    for row in ws.iter_rows():

        for cell in row:

            if cell.value and isinstance(cell.value, str):

                for key, value in data.items():

                    placeholder = "{{" + key + "}}"

                    if placeholder in cell.value:

                        cell.value = cell.value.replace(placeholder, str(value))

    wb.save(output_path)

    return output_path

Bulk Generation (Mail Merge)

import csv

from pathlib import Path

def mail_merge(template_path: str, data_csv: str, output_dir: str):

    """Generate documents for each row in CSV."""

    Path(output_dir).mkdir(exist_ok=True)

    with open(data_csv) as f:

        reader = csv.DictReader(f)

        for i, row in enumerate(reader):

            output_path = f"{output_dir}/document_{i+1}.docx"

            fill_template(template_path, row, output_path)

            print(f"Generated: {output_path}")

# Usage with contacts.csv:

# name,email,company

# John,john@example.com,Acme

# Jane,jane@example.com,Corp

mail_merge(

    "templates/welcome_letter.docx",

    "data/contacts.csv",

    "output/letters"

)

Advanced: Conditional Content

from docxtpl import DocxTemplate

# Template with conditionals:

# {% if vip %}

# Thank you for being a VIP member!

# {% else %}

# Thank you for your purchase.

# {% endif %}

doc = DocxTemplate("template.docx")

doc.render({

    "name": "John",

    "vip": True,

    "discount": 20

})

doc.save("output.docx")

Best Practices

  • Use clear placeholder naming ({{client_name}})
  • Validate data before rendering
  • Handle missing data gracefully
  • Keep templates version-controlled

Installation

# Install required dependencies

pip install python-docx openpyxl python-pptx reportlab jinja2

Resources

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card