How OfficeCLI Template Merge Replaces {{key}} Placeholders in Word, Excel, and PowerPoint

OfficeCLI's merge command implements a universal template engine that scans OOXML documents for Mustache-style {{key}} placeholders and substitutes them with JSON values, working identically across Word (.docx), Excel (.xlsx), and PowerPoint (.pptx) formats.

The OfficeCLI repository (iOfficeAI/OfficeCLI) provides a deterministic document generation solution that operates directly on Office Open XML (OOXML) structures. By using a single regex-based placeholder syntax, the tool enables developers and AI agents to populate templates without rendering engines or layout shifts.

How OfficeCLI Template Merge Works Across Office Formats

Word Document Processing

In WordHandler.Helpers.FindReplace.cs, the engine targets <w:t> text runs inside paragraphs, tables, headers, and footers. The implementation uses the regex pattern {{([^}]+)}} to locate placeholders within runs. When a match is found, the text content is replaced while preserving surrounding run properties (<w:rPr>), ensuring fonts and styles remain intact. The handler also processes content controls (<w:sdt>) and treats page numbers or date fields as standard runs.

Excel Spreadsheet Processing

The ExcelHandler.cs file (located under src/officecli/Handlers/Excel/) iterates over the worksheet's SheetData rows to extract cell values. For standard cells, it performs direct string substitution. When processing rich-text cells, the engine rebuilds the <is> inline string fragments to maintain styling information while replacing the {{key}} patterns with JSON values.

PowerPoint Presentation Processing

In PptxBatchEmitter.Resources.cs, the logic detects placeholders within shape text boxes by scanning <a:t> elements. The handler replaces placeholders in auto-shapes, table cells, chart titles, and data labels. When encountering empty placeholders, the emitter creates a "sized placeholder" using <a:solidFill> to prevent layout collapse, ensuring the slide structure remains stable after substitution.

The Step-by-Step Merge Process

  1. Load the template – The binary opens the OOXML package using ZipArchive and parses the relevant parts (word/document.xml, xl/worksheets/sheet*.xml, ppt/slides/slide*.xml).

  2. Parse the JSON payload – The supplied JSON string deserializes into a dictionary mapping keys to replacement values.

  3. Traverse the XML DOM – Format-specific handlers walk the XML tree:

  4. Detect placeholders – The compiled regex {{\s*([^}]+)\s*}} matches text nodes containing placeholders, capturing the key for dictionary lookup.

  5. Replace the text – When a key exists, the node’s text content updates to the JSON value while leaving formatting attributes untouched.

  6. Handle empty placeholders – If a placeholder represents the only content, the engine injects a non-breaking space (Unicode 0xA0) or minimal sized block to preserve layout dimensions.

  7. Persist the modified package – Updated XML files write back into the zip archive, producing the final merged document without temporary files.

Code Examples for OfficeCLI Template Merge

CLI usage:


# Merge a Word template

officecli merge template.docx report-001.docx \
    '{"client":"Acme Corp","total":"$5,200","date":"2026-07-15"}'

# Merge an Excel template (cell placeholders)

officecli merge budget-template.xlsx budget-q2.xlsx data.json

# Merge a PowerPoint template

officecli merge deck-template.pptx q4-acme.pptx '{"title":"Q4 Report","author":"AI Agent"}'

Python SDK:

from officecli import Doc

# JSON payload for placeholders

data = {"client": "Acme Corp", "total": "$5,200"}

# Word merge

with Doc("invoice-template.docx") as d:
    d.merge("invoice-001.docx", data)

# Excel merge

with Doc("budget-template.xlsx") as d:
    d.merge("budget-q2.xlsx", data)

# PowerPoint merge

with Doc("deck-template.pptx") as d:
    d.merge("deck-q2.pptx", data)

Node.js SDK:

import { Doc } from "@officecli/sdk";

const data = { title: "Q4 Report", author: "AI Agent" };

// PowerPoint merge
await using d = await Doc.open("deck-template.pptx");
await d.merge("deck-q4.pptx", data);

Summary

  • OfficeCLI uses a universal regex pattern ({{([^}]+)}}) to identify placeholders across all Office formats.
  • Word processing preserves run properties (<w:rPr>) while replacing text in runs and content controls via WordHandler.Helpers.FindReplace.cs.
  • Excel processing handles both standard cells and rich-text fragments (<is>) through ExcelHandler.cs.
  • PowerPoint processing maintains slide layouts by creating sized placeholders when content is empty, implemented in PptxBatchEmitter.Resources.cs.
  • The engine operates on raw OOXML zip archives, enabling deterministic generation without external rendering dependencies.

Frequently Asked Questions

What file formats does OfficeCLI template merge support?

OfficeCLI template merge supports Word documents (.docx), Excel spreadsheets (.xlsx), and PowerPoint presentations (.pptx). The engine parses the OOXML structure directly, meaning it works with any file conforming to the Office Open XML standard, including documents created by Microsoft Office, LibreOffice, or Google Docs exports.

How does OfficeCLI handle formatting when replacing placeholders?

The engine preserves original formatting by only modifying text content while leaving surrounding XML properties intact. In Word, run properties (<w:rPr>) remain unchanged. In Excel, rich-text cells rebuild their <is> inline string fragments to maintain styling. In PowerPoint, text properties (<a:pPr>) stay attached to the replaced text, ensuring visual consistency with the template.

Can I use template merge with nested JSON objects?

The current implementation maps flat key-value pairs from the JSON payload using the regex capture group ([^}]+). While the engine looks up exact keys in the deserialized dictionary, complex nested objects would need to be flattened before submission or referenced using dot-notation string keys depending on the specific SDK implementation.

What happens if a placeholder key is missing from the JSON payload?

When a key specified in {{key}} does not exist in the JSON payload, the engine typically leaves the placeholder text unchanged or replaces it with an empty string depending on the handler configuration. For PowerPoint specifically, the PptxBatchEmitter.Resources.cs implementation creates a sized placeholder block to prevent layout collapse when content is empty.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →