How to Use the OfficeCLI Merge Command for Batch Report Generation from Templates

The OfficeCLI merge command replaces {{key}} placeholders in DOCX, XLSX, or PPTX templates with JSON data values to generate customized documents individually or at scale through batch processing.

The iOfficeAI/OfficeCLI repository provides a cross-platform .NET CLI tool for automating Microsoft Office document operations. The merge command serves as the core engine for template-based report generation, enabling developers to transform static templates into dynamic documents using structured JSON data sources.

Understanding the Merge Command Architecture

The merge functionality is implemented across several core files in the src/officecli/ directory, with clear separation between command parsing, data processing, and document manipulation.

Command Definition and Argument Parsing

In src/officecli/CommandBuilder.Import.cs (lines 77-84), the command is constructed with required positional arguments for template and output paths, plus essential options:

var mergeTemplateArg = new Argument<string>("template") { Description = "Template file path (.docx, .xlsx, .pptx) with {{key}} placeholders" };
var mergeOutputArg   = new Argument<string>("output")   { Description = "Output file path" };
var mergeDataOpt    = new Option<string>("--data")      { Description = "JSON data or path to .json file", Required = true };
var mergeForceOpt   = new Option<bool>("--force")       { Description = "Overwrite an existing output file." };
var mergeCommand = new Command("merge", "Merge template with JSON data, replacing {{key}} placeholders");

The command requires exactly two positional arguments: the template file path and the output file path. The --data option is mandatory and accepts either inline JSON or a path to a .json file.

Resident Synchronization Mechanism

Before processing begins, the system ensures data consistency through the resident server architecture. In CommandBuilder.Import.cs (lines 98-102), the code invokes ResidentClient.SendSave() to flush any in-memory edits to disk:

ResidentClient.SendSave(Path.GetFullPath(template));

This guarantees the merge operation works against the latest version of the template, preventing race conditions when templates are actively being edited.

JSON Data Processing and Flattening

The TemplateMerger.ParseMergeData method in src/officecli/Core/TemplateMerger.cs (lines 39-50 and 66-88) handles data interpretation with intelligent file detection:

  • If the --data argument ends with .json and the file exists, it reads from disk
  • Otherwise, it parses the string as inline JSON text

The method flattens nested objects and arrays into dot and bracket notation keys. For example, {"user": {"name": "Alice"}, "items": ["a", "b"]} becomes user.name, items[0], and items[1]. Literal top-level keys maintain precedence over flattened equivalents.

Document Format Support and Placeholder Replacement

The TemplateMerger.Merge method (lines 57-84) guards against accidental overwrites—rejecting existing output files unless --force is specified—then dispatches to format-specific implementations based on file extension:

if (File.Exists(outputPath) && !force) … // guard against accidental overwrite
File.Copy(templatePath, outputPath, overwrite: true);
var ext = Path.GetExtension(outputPath).ToLowerInvariant();
return ext switch {
    ".docx" => MergeDocx(outputPath, data),
    ".xlsx" => MergeXlsx(outputPath, data),
    ".pptx" => MergePptx(outputPath, data),
    _ => throw new CliException(...),
};

DOCX Processing Details

For Word documents, MergeDocx processes every <w:t> text node in the document XML. The implementation uses a single-pass regular expression defined by PlaceholderPattern (lines 28-34) that matches {{ … }} syntax while allowing hyphens, dots, array indexes, and inner spaces. Each match resolves against the flattened data dictionary; unresolved placeholders are tracked for reporting.

Batch Report Generation Workflows

While single merges work for individual documents, the batch command enables automated report generation at scale.

Single Document Generation

Execute a one-off merge using the import merge subcommand:

officecli import merge \
    templates/EmployeeSummary.docx \
    output/EmployeeSummary_2024.docx \
    --data '{"name":"Alice","department":"Engineering","salary":"120k"}'

For external data files with force overwrite:

officecli import merge \
    templates/Invoice.docx \
    output/Invoice_2024.docx \
    --data data/invoice-2024.json \
    --force

Processing Multiple Reports via Batch Command

The batch command in src/officecli/CommandBuilder.Batch.cs (lines 26-31) accepts a JSON array of operations. Each object requires a "command" field set to "merge" plus the standard merge parameters:

[
  {
    "command": "merge",
    "template": "templates/QuarterlyReport.docx",
    "output":   "reports/Q1.docx",
    "data":     "{\"quarter\":\"Q1\",\"sales\":125000}"
  },
  {
    "command": "merge",
    "template": "templates/QuarterlyReport.docx",
    "output":   "reports/Q2.docx",
    "data":     "{\"quarter\":\"Q2\",\"sales\":147500}"
  }
]

Execute the batch using file input:

officecli batch myReport.docx --commands @batch.json

Or pipe JSON directly via stdin:

cat <<'EOF' | officecli batch myWorkbook.xlsx --commands -
[
  {
    "command":"merge",
    "template":"templates/FinancialSummary.xlsx",
    "output":"reports/Financial_Q1.xlsx",
    "data":"{\"quarter\":\"Q1\",\"revenue\":850000}"
  },
  {
    "command":"merge",
    "template":"templates/FinancialSummary.xlsx",
    "output":"reports/Financial_Q2.xlsx",
    "data":"{\"quarter\":\"Q2\",\"revenue\":910000}"
  }
]
EOF

Output and Error Reporting

When invoked with --json, the command emits a structured JSON object (lines 106-133 in CommandBuilder.Import.cs) containing:

  • output: The generated file path
  • replacedKeys: Array of successfully substituted placeholders
  • unresolvedPlaceholders: Array of keys not found in the data source

Standard mode provides human-readable summaries to stdout/stderr, including warnings for any placeholders that could not be resolved.

Summary

  • The OfficeCLI merge command processes DOCX, XLSX, and PPTX templates containing {{key}} placeholders, substituting values from JSON data sources
  • Command architecture spans CommandBuilder.Import.cs for CLI parsing, ResidentClient.cs for file synchronization, and TemplateMerger.cs for data processing and document generation
  • Data flattening supports nested objects and arrays via dot notation (e.g., user.name) and bracket notation (e.g., items[0])
  • Batch processing enables automated multi-document generation through the batch command using JSON command arrays
  • Safety features include resident synchronization to prevent stale data and overwrite protection via the --force flag

Frequently Asked Questions

What placeholder syntax does OfficeCLI merge support?

OfficeCLI uses double curly brace syntax: {{key}}. The regex pattern defined in TemplateMerger.cs (lines 28-34) allows hyphens, dots, array indexes, and spaces within the braces, supporting keys like {{user.name}} or {{items[0].title}}.

Can I merge data from external JSON files?

Yes. Pass a file path ending in .json to the --data option instead of inline JSON. The ParseMergeData method automatically detects file paths versus raw JSON strings and reads the file contents when appropriate.

How does the batch command differ from running multiple merge commands?

The batch command accepts a JSON array of operations via stdin or file input, executing them sequentially against the same resident server session. This reduces overhead compared to spawning separate CLI processes and ensures consistent state across multiple merge operations, as implemented in CommandBuilder.Batch.cs (lines 26-31).

What happens if a placeholder in my template has no matching data key?

Unresolved placeholders are collected during processing and reported in the output. When using --json, they appear in the unresolvedPlaceholders array; in standard mode, they are listed in the console summary. The original placeholder text remains in the generated document.

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 →