How OfficeCLI Template Merge Works with {{key}} Placeholders Across DOCX, XLSX, and PPTX Files

The OfficeCLI merge command replaces {{key}} placeholders in Word, Excel, and PowerPoint documents using a single-pass regex substitution that preserves formatting and reports unresolved placeholders.

OfficeCLI's template merge functionality lets you populate Office documents with JSON data by replacing {{key}} markers. This deep dive examines the implementation in the iOfficeAI/OfficeCLI repository, showing exactly how the tool handles DOCX, XLSX, and PPTX files differently while maintaining consistent placeholder syntax.

Command Entry Point and Data Parsing

The merge operation begins in CommandBuilder.Import.cs, which defines the CLI interface and delegates to Core/TemplateMerger.cs.

Argument Handling

Lines 284-313 of CommandBuilder.Import.cs parse the template path, output path, JSON data (--data), and optional --force flag:

var data = Core.TemplateMerger.ParseMergeData(dataArg);
var mergeResult = Core.TemplateMerger.Merge(template, output, data, force);

JSON Flattening Strategy

TemplateMerger.ParseMergeData (lines 39-89) accepts either inline JSON or a file path, then builds a flat Dictionary<string,string> through two passes:

  • Pass 1: Stores literal top-level keys directly—"a.b" takes precedence over nested { "a": { "b": … } }
  • Pass 2: Flattens nested objects into dot-notation (a.b) and arrays into bracket-notation (items[0])

This flattening enables natural template syntax like {{user.name}} and {{items[0].price}} regardless of JSON structure.

Placeholder Detection Regex

The core pattern matching uses a compiled regex defined at line 28 of TemplateMerger.cs:

private static readonly Regex PlaceholderPattern =
    new(@"\{\{\s*(\w[\w.\-\[\] ]*?)\s*\}\}", RegexOptions.Compiled);

This pattern tolerates:

  • Outer whitespace: {{ key }}
  • Hyphens and spaces: {{customer-name}}, {{order date}}
  • Dot-paths: {{invoice.total}}
  • Array indexes: {{line_items[3]}}

Format-Specific Merge Implementation

TemplateMerger.Merge (lines 57-89) copies the template and dispatches to format-specific handlers based on file extension.

DOCX: Word Document Handling

The MergeDocx method processes the full document structure:

  1. Opens WordprocessingDocument and enumerates main document, headers, footers, footnotes, endnotes, and comments
  2. For every <w:t> (text) element containing {{, calls SinglePassReplace
  3. SinglePassReplace runs the regex once, substitutes matches, records used keys, and does not re-scan output—preventing nested placeholder expansion
  4. ScanUnresolvedDocx (second pass) collects any remaining placeholders

Source: lines 91-126, 130-166, 168-210

XLSX: Excel Spreadsheet Handling

The MergeXlsx method focuses on cell-level operations:

  1. Opens SpreadsheetDocument, iterates all worksheets
  2. Extracts cell text handling inline strings, shared strings, and plain strings
  3. Applies SinglePassReplace to each cell's text
  4. Writes results back via SetCellText as inline strings
  5. Post-merge scan collects unresolved placeholders

Source: lines 28-68, 70-108

PPTX: PowerPoint Presentation Handling

The MergePptx method handles rich text runs carefully:

  1. Opens PresentationDocument, iterates slides and notes
  2. For each <p:sp> (shape) with TextBody:
    • Concatenates all run texts
    • Runs SinglePassReplace
    • Re-writes runs: first run receives new text, subsequent runs removed—preserving original formatting of first run
  3. Post-merge scan gathers unresolved placeholders

Source: lines 29-73, 75-87, 89-115

Result Reporting and Metrics

The Merge method returns a MergeResult containing:

Property Description
ReplacedCount Total substitutions across document
UnresolvedPlaceholders Sorted list of placeholders not found in JSON data
UsedKeys Keys that actually appeared in template

The CLI prints a summary and writes warnings to stderr for unresolved placeholders.

Practical Usage Examples

Command-Line Merge


# Basic inline JSON

officecli merge template.docx merged.docx --data '{"name":"Alice","date":"2026-07-29"}'

# JSON file with force overwrite

officecli merge report.xlsx report-out.xlsx --data data.json --force

Template Document Example


Dear {{ name }},

Your appointment is scheduled for {{ date }}.

Best regards,
{{ sender.department }}

JSON Data File

{
  "name": "Alice Chen",
  "date": "2026-07-29",
  "sender": {
    "name": "Dr. Smith",
    "department": "Research Division"
  }
}

Programmatic C# Usage

var data = OfficeCli.Core.TemplateMerger.ParseMergeData(
    "{\"title\":\"Q1 Report\",\"year\":2024}");
    
var result = OfficeCli.Core.TemplateMerger.Merge(
    "presentation.pptx", 
    "presentation-merged.pptx", 
    data, 
    force: true);

Console.WriteLine($"Replacements: {result.ReplacedCount}");

if (result.UnresolvedPlaceholders.Any())
{
    Console.WriteLine("Unresolved: " + 
        string.Join(", ", result.UnresolvedPlaceholders));
}

Key Implementation Files

Summary

  • Single-pass substitution: SinglePassReplace prevents recursive expansion by not re-scanning output text
  • Format-aware handling: DOCX preserves document parts, XLSX manages cell string types, PPTX collapses runs while keeping first-run formatting
  • Flat key dictionary: Nested JSON flattens to dot-notation, enabling intuitive template keys
  • Comprehensive reporting: MergeResult tracks replacements, used keys, and unresolved placeholders
  • CLI and programmatic APIs: Both command-line and C# library usage supported

Frequently Asked Questions

What placeholder syntax does OfficeCLI support?

OfficeCLI accepts {{key}} syntax with flexible spacing. Keys can include letters, numbers, dots for nesting, brackets for arrays, hyphens, and spaces: {{ user.name }}, {{items[0]}}, {{order-date}}, and {{customer name}} are all valid.

How does OfficeCLI handle nested JSON objects in templates?

The ParseMergeData method flattens nested objects into dot-notation keys automatically. A JSON object like {"user": {"name": "Alice"}} becomes accessible as {{user.name}} without manual flattening.

Why does PowerPoint merging preserve only the first run's formatting?

The PPTX handler concatenates all text runs in a shape, performs substitution, then assigns the result to the first run and removes subsequent runs. This maintains the formatting of the first run while ensuring clean text replacement—a necessary trade-off since PowerPoint's run-based structure would create fragmented styling if individual runs were modified.

What happens to unresolved placeholders after merging?

Unresolved placeholders remain as literal text in the output document. The MergeResult includes a sorted list of these placeholders, and the CLI writes a warning to stderr. You can use this list to debug missing JSON keys or intentional optional placeholders.

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 →