Skip to content

command batch

goworm edited this page Jul 3, 2026 · 60 revisions

batch

Execute multiple commands in a single pass.

Synopsis

officecli batch <file> [--input <file>] [--commands '<json>'] [--stop-on-error] [--force] [--json]

Description

Executes a sequence of commands from a JSON array, opening the document once and saving once at the end. This is more efficient than running individual commands.

By default, execution continues on error — per-item errors surface in BatchResult.Error and any failure still returns exit 1, but the rest of the batch runs and succeeded changes are saved to disk. This is the safer default for dump → batch round-trips, where aborting on the first failing item could lose 80% of the document.

Use --stop-on-error to opt back into the strict abort-on-first-error mode. --force is decoupled from continue-on-error and remains the docx-protection bypass.

Commands are read from a JSON file (--input), inline JSON (--commands), or from stdin.

Arguments

Name Type Required Default Description
file FileInfo Yes - Office document path

Options

Name Type Required Default Description
--input FileInfo No stdin JSON file containing batch commands
--commands string No - Inline JSON array of batch commands (alternative to --input or stdin)
--stop-on-error bool No false Abort the batch on the first failing command. Default: continue, then return exit 1 if any item failed.
--force bool No false docx-protection bypass (decoupled from error handling)
--json bool No false Output results as structured JSON envelope {success, data} (parity with resident mode)

Input Format

The input is a JSON array of command objects. Each object has the following fields:

Field Type Required Description
command string Yes Command name: get, query, set, add, remove, move, swap, view, raw, raw-set, validate. Alias: op
path string No DOM path (for get, set, remove, move)
parent string No Parent path (for add)
type string No Element type (for add)
from string No Source path for copy (for add)
index int No Insert position (for add, move)
after string No Insert/move after anchor path or find:text (for add, move)
before string No Insert/move before anchor path or find:text (for add, move)
to string No Target parent (for move). Auto-inferred from after/before if omitted.
path2 string No Second element path (for swap)
props object OR string[] No Properties for set / add. Accepts an object ({"font":"Arial","size":"12pt"}) or an array of "k=v" strings (["font=Arial","size=12pt"]) — the latter is friendlier to hand-authored JSONL and mirrors the CLI --prop k=v form.
selector string No CSS-like selector (for query)
mode string No View mode (for view)
depth int No Child depth (for get)
part string No Part path (for raw, raw-set)
xpath string No XPath expression (for raw-set)
action string No XML action (for raw-set)
xml string No XML fragment (for raw-set)

Output Format

Text Mode (default)

Each result is prefixed with its 1-based index:

[1] OK
[2] output text here
[3] ERROR: error message
---
3 commands: 2 succeeded, 1 failed

JSON Mode

{
  "results": [
    { "index": 0, "success": true, "output": "..." },
    { "index": 1, "success": true, "output": "..." },
    { "index": 2, "success": false, "error": "error message", "item": { "command": "set", "path": "/slide[999]", "props": { "title": "bad" } } }
  ],
  "summary": {
    "total": 3,
    "executed": 3,
    "succeeded": 2,
    "failed": 1,
    "skipped": 0
  }
}

When get or query commands return structured data, the output field contains the parsed JSON object directly (not a double-encoded string).

Failed results include the original batch item in the item field, so the caller can inspect the failing command and its parameters without having to correlate by index.

Large Output (spill-to-file)

When the JSON output exceeds 8 KB, the full results are written to a temp file and a slim envelope is returned inline:

{
  "outputFile": "/tmp/officecli_batch_abc123.json",
  "outputSize": 156234,
  "results": [
    { "index": 0, "success": true },
    { "index": 1, "success": true },
    { "index": 2, "success": false, "error": "Slide 999 not found", "item": { "command": "set", "path": "/slide[999]", "props": { "title": "bad" } } }
  ],
  "summary": { "total": 3, "executed": 3, "succeeded": 2, "failed": 1, "skipped": 0 }
}

The temp file contains the full original JSON with all output fields. Error messages and the original item are always inline so the caller can act without reading the file.

Examples

From stdin

echo '[
  {"command": "set", "path": "/body/p[1]", "props": {"style": "Heading1", "text": "Title"}},
  {"command": "add", "parent": "/body", "type": "paragraph", "props": {"text": "New paragraph"}},
  {"command": "set", "path": "/body/p[2]", "props": {"bold": "true"}}
]' | officecli batch report.docx

From file

officecli batch report.docx --input commands.json

JSON output

officecli batch report.docx --input commands.json --json

Continue on error

officecli batch report.docx --input commands.json --force

Complex batch example

commands.json:

[
  {
    "command": "set",
    "path": "/",
    "props": { "title": "Quarterly Report", "author": "Finance Team" }
  },
  {
    "command": "add",
    "parent": "/body",
    "type": "paragraph",
    "props": { "text": "Executive Summary", "style": "Heading1" }
  },
  {
    "command": "add",
    "parent": "/body",
    "type": "paragraph",
    "props": { "text": "This report covers Q4 2024 performance." }
  },
  {
    "command": "add",
    "parent": "/body",
    "type": "table",
    "props": { "rows": "4", "cols": "3" }
  },
  {
    "command": "set",
    "path": "/body/tbl[1]/tr[1]/tc[1]",
    "props": { "text": "Category", "bold": "true", "shd": "4472C4", "color": "FFFFFF" }
  },
  {
    "command": "set",
    "path": "/body/tbl[1]/tr[1]/tc[2]",
    "props": { "text": "Q3", "bold": "true", "shd": "4472C4", "color": "FFFFFF" }
  },
  {
    "command": "set",
    "path": "/body/tbl[1]/tr[1]/tc[3]",
    "props": { "text": "Q4", "bold": "true", "shd": "4472C4", "color": "FFFFFF" }
  },
  {
    "command": "get",
    "path": "/body",
    "depth": 1
  },
  {
    "command": "validate"
  }
]

Excel batch example

[
  { "command": "add", "parent": "/", "type": "sheet", "props": { "name": "Summary" } },
  { "command": "set", "path": "/Summary/A1", "props": { "value": "Total Revenue", "bold": "true" } },
  { "command": "set", "path": "/Summary/B1", "props": { "formula": "=SUM(Sheet1!B:B)", "numFmt": "#,##0.00" } },
  { "command": "add", "parent": "/Summary", "type": "chart", "props": {
    "chartType": "bar",
    "title": "Revenue by Quarter",
    "categories": "Q1,Q2,Q3,Q4",
    "series1": "Revenue:1000,2000,1500,3000"
  }}
]

PowerPoint batch example

[
  { "command": "add", "parent": "/", "type": "slide", "props": { "title": "Introduction", "layout": "title" } },
  { "command": "set", "path": "/slide[1]", "props": { "background": "1A1A2E" } },
  { "command": "add", "parent": "/slide[1]", "type": "shape", "props": {
    "text": "Welcome",
    "x": "2cm", "y": "3cm", "width": "20cm", "height": "5cm",
    "font": "Arial", "size": "36", "bold": "true", "color": "FFFFFF",
    "fill": "none"
  }},
  { "command": "add", "parent": "/", "type": "slide", "props": { "layout": "blank" } },
  { "command": "add", "parent": "/slide[2]", "type": "chart", "props": {
    "chartType": "pie",
    "title": "Market Share",
    "categories": "Product A,Product B,Product C",
    "data": "Share:40,35,25",
    "x": "2cm", "y": "2cm", "width": "20cm", "height": "15cm"
  }}
]

Persisting changes for external readers

A standalone batch saves to disk on its own, so this example needs nothing extra:

officecli batch report.docx --input commands.json   # applied AND saved to disk
python my_reader.py report.docx                      # reads the new content

But if a resident is already running for the file — because you called open, or ran any earlier command that auto-started one — the batch is applied in memory and the save is deferred. It will be flushed automatically by the idle auto-save (adaptive 2–10s after the last command), but if a non-OfficeCLI tool must read the file right away, flush explicitly:

officecli open report.docx                           # resident now holds the file
officecli batch report.docx --input commands.json    # applied in memory, NOT yet on disk
officecli save report.docx                            # flush to disk, keep the resident (stays fast)
python my_reader.py report.docx                       # now reads the new content
officecli close report.docx                           # flush + release when finished

Use save for an immediate mid-session flush and close when you are done. The full set of flush triggers (explicit save/close + automatic idle auto-save / idle shutdown) is in open / close → When the file on disk is refreshed.

Notes

  • All commands in a batch run in a single pass (one open/save cycle standalone; a deferred flush under a resident), making batch mode significantly faster than individual commands.
  • By default, execution continues on error and returns a non-zero exit if any item failed; use --stop-on-error to abort on the first failure (--force is a deprecated alias of the continue default).
  • Succeeded commands' changes are kept even when a later command fails (partial application by design — add commands are not idempotent, so rollback would cause duplicates on retry).
  • Returns non-zero exit code when any command fails.
  • Read-only commands (get, query, view, validate) can be mixed with write commands.
  • Add commands accept path as fallback when parent is not set.
  • A standalone batch (no resident running) opens the file, applies every item, and saves to disk before exiting — no separate save/close is needed, and an external tool can read the file immediately afterward.
  • When a resident is active (you ran open, or any prior command auto-started one), the batch is forwarded into the resident and applied in memory with the save deferred — the file on disk is not updated until a flush: the idle auto-save (adaptive 2–10s), officecli save, officecli close, or idle shutdown. (Under OFFICECLI_RESIDENT_FLUSH=each the batch flushes once, before it returns.) This is the same deferred-flush behavior as individual commands; see Persisting changes for external readers below. (A read routed through OfficeCLI still sees the change immediately.)

See Also


Based on OfficeCLI v1.0.73

Clone this wiki locally