# OfficeCLI Template Merge for Placeholder Replacement: A Complete Guide

> Effortlessly replace placeholders in Office templates using the OfficeCLI merge command. Generate polished DOCX, XLSX, or PPTX documents with JSON data, no Office installation needed.

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

---

**Use the `officecli merge` command to replace `{{placeholder}}` tokens in DOCX, XLSX, or PPTX templates with JSON data, producing polished Office documents without any local Office installation.**

The **OfficeCLI template merge** functionality transforms static Office templates into dynamic document generators. This headless tool parses OOXML packages, substitutes Mustache-style placeholders with structured data, and validates output—making it ideal for AI agents, CI pipelines, and batch operations across macOS, Linux, and Windows.

## How Template Merge Works

OfficeCLI implements a four-stage pipeline for placeholder replacement. Understanding this architecture helps you debug failures and optimize large-scale generation.

### 1. Parse the OOXML Package

OfficeCLI opens the ZIP-based container and streams document parts rather than loading entire files into memory. This streaming approach keeps memory usage constant even for multi-megabyte templates with embedded images.

The I/O layer is demonstrated in [[`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js)](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js), which uses the same streaming primitives for live previews and merge operations.

### 2. Locate Placeholders in the DOM

The merge engine walks every textual part—[`document.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/document.xml) for Word, [`slide.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/slide.xml) for PowerPoint, [`sheet.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sheet.xml) for Excel—and builds a lightweight DOM. It scans for the pattern `{{key}}` in:

- Paragraph runs and table cells
- Shape text bodies (`<a:txBody>`)
- Chart titles and axis labels
- Headers, footers, and comments

Placeholders are detected via regex scan on text node values, then mapped to replacement coordinates.

### 3. Substitute JSON Data with Type Safety

The `--data` payload undergoes automatic conversion:

| Source Type | XML Output | Example |
|-------------|-----------|---------|
| String | Escaped text | `"Acme & Co"` → `Acme &amp; Co` |
| Number | Formatted string | `5200.5` → `"5200.5"` |
| Date (ISO) | Localized date | `"2024-08-04"` → `"August 4, 2024"` |
| Boolean | `"true"`/`"false"` | `true` → `"true"` |

XML entities are properly escaped to prevent malformed documents. The DOM model exposed in [[`sdk/node/index.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/node/index.js)](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/node/index.js) shares this parsing logic between CLI and SDK interfaces.

### 4. Validate and Serialize

Post-substitution, OfficeCLI validates the modified OOXML against schema definitions. Structured error codes—`not_found`, `invalid_value`, `schema_violation`—enable programmatic recovery. Error handling contracts are documented in [README.md lines 56-66](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md#L56-L66).

## Command-Line Usage

### Basic Merge with Inline JSON

Replace placeholders in a single template:

```bash
officecli merge invoice-template.docx invoice-001.docx \
  --data '{"client":"Acme Corp","total":"$5,200","date":"2024-08-04"}'

```

### External JSON File for Complex Data

For payloads with nested objects or special characters:

```bash
officecli merge q4-template.pptx q4-acme.pptx --data data.json

```

### Batch Generation Loop

Generate hundreds of documents from one template:

```bash
for i in $(seq -w 1 100); do
  officecli merge invoice-template.docx "invoice-$i.docx" \
    --data "{\"client\":\"Client $i\",\"total\":\"\$$(printf '%.2f' $(awk "BEGIN{print $i*123.45}"))\"}"
done

```

## Node.js SDK Integration

The official SDK exposes identical merge capabilities for JavaScript applications:

```javascript
const oc = require("@officecli/sdk");

async function generateInvoice(templatePath, outputPath, data) {
  const doc = await oc.open(templatePath);
  
  await doc.send({
    command: "merge",
    data: data  // Object with keys matching {{placeholders}}
  });
  
  await doc.save(outputPath);
  await doc.close();
  
  return outputPath;
}

// Usage
generateInvoice(
  "invoice-template.docx",
  "invoice-001.docx",
  { client: "Acme Corp", total: "$5,200", date: "2024-08-04" }
);

```

The SDK shares the underlying DOM model and validation layer with the CLI, ensuring consistent output across interfaces.

## Key Source Files and References

| File | Purpose | Direct Link |
|------|---------|-------------|
| [`README.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) | Usage syntax, error codes, and CLI examples | [View source](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) |
| Command merge wiki | Complete flag reference and advanced patterns | [Wiki page](https://github.com/iOfficeAI/OfficeCLI/wiki/command-merge) |
| [`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js) | Streaming I/O implementation for document parts | [View source](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js) |
| [`sdk/node/index.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/node/index.js) | Node.js SDK entry point with shared DOM logic | [View source](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/node/index.js) |

The [README usage section lines 86-94](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md#L86-L94) contains the definitive command syntax for quick reference.

## Performance and Scaling Considerations

- **Memory efficiency**: Streaming parser handles 100MB+ templates with <50MB RSS
- **CPU-bound operation**: DOM walk and regex substitution dominate; no external process calls
- **Deterministic output**: Same input produces byte-identical output (enables caching)
- **Parallel safety**: Each merge is stateless; safe to run N concurrent processes

For CI pipelines, merge return codes follow Unix conventions: `0` for success, `1` for validation errors, `2` for I/O failures.

## Summary

- **OfficeCLI template merge** replaces `{{key}}` placeholders in DOCX/XLSX/PPTX with JSON data via a streaming OOXML parser
- **Zero dependencies**: No Microsoft Office, LibreOffice, or Wine required
- **Dual interfaces**: CLI for scripts and SDK for Node.js applications share core logic in [`sdk/node/index.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/node/index.js)
- **Validated output**: Schema checking with structured error codes for robust automation
- **Authoritative documentation**: Wiki page [command-merge](https://github.com/iOfficeAI/OfficeCLI/wiki/command-merge) and [README.md](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) provide complete reference

## Frequently Asked Questions

### What placeholder syntax does OfficeCLI template merge support?

OfficeCLI uses **Mustache-style double braces**: `{{variableName}}`. Placeholders are case-sensitive and must match JSON keys exactly. Nested objects use dot notation: `{{invoice.client}}`. See the [command-merge wiki](https://github.com/iOfficeAI/OfficeCLI/wiki/command-merge) for escaping rules when your template needs literal `{{` characters.

### Can I merge data into Excel formulas or PowerPoint charts?

Yes. Placeholders in any text node are substituted before formula evaluation or chart rendering. For charts, replace the `{{title}}` or axis label placeholders—OfficeCLI updates the underlying data XML that feeds the chart engine. Complex scenarios requiring data series replacement need manual XML manipulation outside standard merge.

### How do I handle missing placeholder keys in my JSON data?

By default, OfficeCLI leaves unmatched `{{key}}` placeholders intact and returns warning code `not_found`. Add the `--strict` flag to treat missing keys as fatal errors (exit code 1). Alternatively, preprocess your JSON to include empty string defaults for optional fields.

### Does template merge preserve formatting, images, and macros?

All binary content (images, embedded objects, VBA macros) passes through unchanged. Only text nodes containing `{{placeholders}}` are modified. Formatting applied to placeholder text—font, color, size—is preserved on the substituted value. Macros remain functional in output documents.