# How the OfficeCLI Merge Command Replaces {{key}} Placeholders in Word, Excel, and PowerPoint

> Learn how OfficeCLI merge command replaces {{key}} placeholders seamlessly in Word, Excel, and PowerPoint documents. Maintain formatting with JSON data.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-07-27

---

**OfficeCLI's `merge` command scans OOXML document structures using the regex pattern `{{\s*([^}]+)\s*}}` to locate Mustache-style placeholders, then substitutes them with values from a JSON payload while preserving all original formatting.**

The **OfficeCLI merge command** provides a deterministic, token-free way to programmatically populate Microsoft Office templates. According to the `iOfficeAI/OfficeCLI` source code, the engine operates directly on the raw OOXML package (ZipArchive) without requiring COM automation or the Office desktop suite, enabling server-side document generation for Word, Excel, and PowerPoint files.

## The Universal Placeholder Engine

The merge functionality treats **`.docx`**, **`.xlsx`**, and **`.pptx`** files as standard ZIP archives containing XML parts. The engine loads the relevant document components—such as [`word/document.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/word/document.xml), `xl/worksheets/sheet*.xml`, or `ppt/slides/slide*.xml`—and traverses their DOM structures to identify text nodes containing placeholder syntax.

At its core, the system uses a compiled regular expression to detect keys:

```csharp
{{\s*([^}]+)\s*}}

```

The captured group (`key`) is looked up in a deserialized JSON dictionary. When matched, the text node content is replaced with the corresponding value, while surrounding formatting elements—such as `<w:rPr>` in Word or `<a:pPr>` in PowerPoint—remain untouched to ensure visual consistency.

## Word Document Processing (.docx)

For Word templates, the logic resides in **[`WordHandler.Helpers.FindReplace.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Helpers.FindReplace.cs)**. This handler walks the document’s XML DOM to locate and substitute placeholders.

### Scanning Text Runs and Content Controls

The Word processor targets several OOXML elements:

- **`<w:t>` text runs** inside paragraphs, tables, headers, and footers
- **`<w:sdt>` content controls** (structured document tags)
- **Page-number and date fields** treated as standard runs

When the helper detects a placeholder within a run, it replaces the run text with the JSON value and updates the associated run properties to inherit the original style. If a placeholder is the only content of a run, the engine injects a non-breaking space (`&nbsp;` or Unicode `0xA0`) to prevent layout collapse.

## Excel Spreadsheet Processing (.xlsx)

Excel handling is implemented in **[`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs)** under `src/officecli/Handlers/Excel/`. The engine iterates over the worksheet’s `SheetData` rows to process cell values.

### Cell Values and Rich Text Handling

The handler extracts each cell’s string value and performs placeholder substitution. For **rich-text cells**, the engine rebuilds the `<is>` inline string fragments to preserve styling while updating the text content. This ensures that merged spreadsheets maintain their original fonts, colors, and formatting even after data injection.

## PowerPoint Presentation Processing (.pptx)

PowerPoint merging is managed by **[`PptxBatchEmitter.Resources.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PptxBatchEmitter.Resources.cs)**, which handles placeholders inside shapes, tables, and charts.

### Shapes, Tables, and Chart Titles

The PowerPoint processor scans:

- **Shape text boxes** via `<a:t>` elements (including placeholders in auto-shapes)
- **Table cells** and **chart titles**
- **Slide-master placeholders**

When a placeholder is detected in a shape’s text element, the emitter replaces it with the JSON data. For empty content, it creates a "sized placeholder" using `<a:solidFill>` to ensure the layout does not collapse after replacement.

## Step-by-Step Execution Flow

The **[`MergeCommand.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/MergeCommand.cs)** file orchestrates the following workflow:

1. **Load the template** – Opens the OOXML package using `ZipArchive` and parses the relevant XML parts.
2. **Parse the JSON payload** – Deserializes the supplied JSON string or file into a `key → value` dictionary.
3. **Traverse the XML DOM** – Dispatches to format-specific handlers:
   - Word → [`WordHandler.Helpers.FindReplace.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Helpers.FindReplace.cs)
   - Excel → [`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs)
   - PowerPoint → [`PptxBatchEmitter.Resources.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PptxBatchEmitter.Resources.cs)
4. **Detect placeholders** – Applies the regex `{{\s*([^}]+)\s*}}` to match text nodes.
5. **Replace the text** – Substitutes the node content with the JSON value while leaving formatting nodes intact.
6. **Handle empty placeholders** – Inserts non-breaking spaces or minimal sized blocks to preserve layout.
7. **Persist the package** – Writes the modified XML files back into the ZIP archive to produce the final document.

## Implementation Examples

### Command-Line Usage

```bash

# Merge a Word template with inline JSON

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

# Merge an Excel template using a JSON file

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

```python
from officecli import Doc

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

```javascript
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);

```

## Key Source Files

| File | Role |
|------|------|
| [`src/officecli/Handlers/Word/WordHandler.Helpers.FindReplace.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Word/WordHandler.Helpers.FindReplace.cs) | Scans Word runs, detects `{{key}}` patterns, and substitutes values while preserving run properties. |
| [`src/officecli/Handlers/Excel/ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Excel/ExcelHandler.cs) | Walks worksheet XML, replaces placeholders in cell text and rich-text fragments. |
| [`src/officecli/Handlers/Pptx/PptxBatchEmitter.Resources.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PptxBatchEmitter.Resources.cs) | Handles placeholder detection and replacement inside PowerPoint shapes, tables, and chart titles. |
| [`src/officecli/Commands/MergeCommand.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Commands/MergeCommand.cs) | Parses CLI arguments, loads the JSON payload, and dispatches to format-specific handlers. |

## Summary

- **OfficeCLI** uses a single regex pattern (`{{\s*([^}]+)\s*}}`) to detect placeholders across all Office formats.
- The engine operates on raw OOXML via `ZipArchive`, eliminating dependencies on Microsoft Office applications.
- **Word** processing preserves `<w:rPr>` run properties and handles content controls.
- **Excel** processing rebuilds `<is>` inline strings to maintain rich-text styling.
- **PowerPoint** processing includes safeguards like sized placeholders to prevent layout collapse.
- Empty placeholders trigger automatic insertion of non-breaking spaces or solid fills to preserve document structure.

## Frequently Asked Questions

### What regex pattern does OfficeCLI use to detect placeholders?

OfficeCLI uses the compiled regex pattern `{{\s*([^}]+)\s*}}` to match Mustache-style placeholders. The pattern accounts for optional whitespace inside the braces and captures the key name in the first group for lookup in the JSON payload.

### How does OfficeCLI handle formatting when replacing text in Word documents?

According to [`WordHandler.Helpers.FindReplace.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Helpers.FindReplace.cs), the engine replaces only the text content of `<w:t>` elements while leaving the parent `<w:rPr>` (run properties) nodes untouched. This ensures the substituted text inherits the original font, size, color, and styling defined in the template.

### Can OfficeCLI merge templates with placeholders inside Excel charts?

Yes. The [`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs) implementation processes placeholders within chart titles and axis labels stored in the worksheet XML. However, the engine primarily targets the underlying cell data and chart text elements that contain the placeholder strings.

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

If a `{{key}}` is detected but not found in the deserialized JSON dictionary, the placeholder text remains unchanged in the output document. The engine only performs substitution when a matching key exists, leaving unmatched placeholders intact as visual indicators of missing data.