- name
- officecli
- description
- Create, analyze, proofread, and modify Office documents (.docx, .xlsx, .pptx) using the officecli CLI tool. Use when the user wants to create, inspect, check formatting, find issues, add charts, or modify Office documents.
# officecli
AI-friendly CLI for .docx, .xlsx, .pptx. Single binary, no dependencies, no Office installation needed.
## Install & Update
Same command for both install and upgrade:
```bash
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/iOfficeAI/OfficeCLI/main/install.sh | bash
# Windows (PowerShell)
irm https://raw.githubusercontent.com/iOfficeAI/OfficeCLI/main/install.ps1 | iex
```
After installation, run `source ~/.zshrc` (macOS) or `source ~/.bashrc` (Linux) to make the `officecli` command available.
Verify: `officecli --version`
officecli auto-updates daily in the background.
---
## Strategy
**L1 (read) → L2 (DOM edit) → L3 (raw XML)**. Always prefer higher layers. Add `--json` for structured output.
---
## Help System (IMPORTANT)
**When unsure about property names, value formats, or command syntax, ALWAYS run help instead of guessing.** One help query is faster than guess-fail-retry loops.
**Three-layer navigation** — start from the deepest level you know:
```bash
officecli pptx set # All settable elements and their properties
officecli pptx set shape # Shape properties in detail
officecli pptx set shape.fill # Specific property format and examples
```
Replace `pptx` with `docx` or `xlsx`. Commands: `view`, `get`, `query`, `set`, `add`, `raw`.
---
## Performance: Resident Mode
For multi-step workflows (3+ commands on the same file), use `open`/`close`:
```bash
officecli open report.docx # keep in memory — fast subsequent commands
officecli set report.docx ... # no file I/O overhead
officecli close report.docx # save and release
```
---
## Quick Start
**PPT:**
```bash
officecli create slides.pptx
officecli add slides.pptx / --type slide --prop title="Q4 Report" --prop background=1A1A2E
officecli add slides.pptx '/slide[1]' --type shape --prop text="Revenue grew 25%" --prop x=2cm --prop y=5cm --prop font=Arial --prop size=24 --prop color=FFFFFF
officecli set slides.pptx '/slide[1]' --prop transition=fade --prop advanceTime=3000
```
**Word:**
```bash
officecli create report.docx
officecli add report.docx /body --type paragraph --prop text="Executive Summary" --prop style=Heading1
officecli add report.docx /body --type paragraph --prop text="Revenue increased by 25% year-over-year."
```
**Excel:**
```bash
officecli create data.xlsx
officecli set data.xlsx /Sheet1/A1 --prop value="Name" --prop bold=true
officecli set data.xlsx /Sheet1/B1 --prop value="Score" --prop bold=true
officecli set data.xlsx /Sheet1/A2 --prop value="Alice"
officecli set data.xlsx /Sheet1/B2 --prop value=95
```
---
## L1: Create, Read & Inspect
```bash
officecli create <file> # Create blank .docx/.xlsx/.pptx (type from extension)
officecli view <file> <mode> # outline | stats | issues | text | annotated
officecli get <file> <path> --depth N # Get a node and its children [--json]
officecli query <file> <selector> # CSS-like query
officecli validate <file> # Validate against OpenXML schema
```
### view modes
| Mode | Description | Useful flags |
| ----------- | ------------------------------------- | ------------------------------------------------ |
| `outline` | Document structure | |
| `stats` | Statistics (pages, words, shapes) | |
| `issues` | Formatting/content/structure problems | `--type format\|content\|structure`, `--limit N` |
| `text` | Plain text extraction | `--start N --end N`, `--max-lines N` |
| `annotated` | Text with formatting annotations | |
### get
Any XML path via element localName. Use `--depth N` to expand children. Add `--json` for structured output.
```bash
officecli get report.docx '/body/p[3]' --depth 2 --json
officecli get slides.pptx '/slide[1]' --depth 1 # list all shapes on slide 1
officecli get data.xlsx '/Sheet1/B2' --json
```
Run `officecli docx get` / `officecli xlsx get` / `officecli pptx get` for all available paths.
### Stable ID Addressing
Elements with stable IDs return `@attr=value` paths instead of positional indices. These paths survive insert/delete operations — use them for multi-step workflows.
**Returned path format (output):**
```
/slide[1]/shape[@id=550950021] # PPT shape (cNvPr.Id)
/slide[1]/shape[@id=550950021]/paragraph[1] # child inherits parent's @id=
/slide[1]/table[@id=1388430425]/tr[1]/tc[2] # PPT table
/body/p[@paraId=1A2B3C4D] # Word paragraph
/comments/comment[@commentId=1] # Word comment
/footnote[@footnoteId=2] # Word footnote
/endnote[@endnoteId=1] # Word endnote
/body/sdt[@sdtId=123456] # Word content control
```
**All formats accepted as input** — use returned paths directly for subsequent `set`/`remove`:
```bash
officecli set slides.pptx '/slide[1]/shape[@id=550950021]' --prop bold=true
officecli set slides.pptx '/slide[1]/shape[@name=Title 1]' --prop text="New" # @name= also works (PPT)
officecli set slides.pptx '/slide[1]/shape[2]' --prop color=red # positional still works
```
Elements without stable IDs (slide, paragraph, run, tr/tc, row) use positional indices as fallback.
**When to use stable IDs:** Prefer `@id=` / `@paraId=` paths in multi-step workflows where you add or remove elements between commands — positional indices shift, but stable IDs do not.
### query
CSS-like selectors: `[attr=value]`, `[attr!=value]`, `[attr~=text]`, `[attr>=value]`, `[attr<=value]`, `:contains("text")`, `:empty`, `:has(formula)`, `:no-alt`.
```bash
officecli query report.docx 'paragraph[style=Normal] > run[font!=Arial]'
officecli query slides.pptx 'shape[fill=FF0000]'
```
### validate
```bash
officecli validate report.docx # Check for schema errors
officecli validate slides.pptx # Must pass before delivery
```
**For large documents**, ALWAYS use `--max-lines` or `--start`/`--end` to limit output.
---
## L2: DOM Operations
### set — modify properties
```bash
officecli set <file> <path> --prop key=value [--prop ...]
```
**Any XML attribute is settable** via element path (found via `get --depth N`) — even attributes not currently present.
Without `find=`, `set` applies format to the entire element. To target specific text within a paragraph, use `find=` (see **find** section below).
Run `officecli <format> set` for all settable elements. Run `officecli <format> set <element>` for detail.
**Value formats:**
| Type | Format | Examples |
| ---------- | ---------------------- | ----------------------------------------------------- |
| Colors | Hex, named, RGB, theme | `FF0000`, `red`, `rgb(255,0,0)`, `accent1`..`accent6` |
| Spacing | Unit-qualified | `12pt`, `0.5cm`, `1.5x`, `150%` |
| Dimensions | EMU or suffixed | `914400`, `2.54cm`, `1in`, `72pt`, `96px` |
### find — format or replace matched text
Use `find=` with `set` to target specific text within a paragraph (or broader scope) for formatting or replacement. The matched text is automatically split into its own run(s). Add `regex=true` for regex matching. Format props are separate `--prop` flags — do NOT nest them (e.g. `--prop bold=true`, not `--prop format=bold:true`).
```bash
# Format matched text (auto-splits runs)
officecli set doc.docx '/body/p[1]' --prop find=weather --prop highlight=yellow
officecli set doc.docx '/body/p[1]' --prop find=weather --prop bold=true --prop color=red
# Regex matching
officecli set doc.docx '/body/p[1]' --prop 'find=\d+%' --prop regex=true --prop color=red
# Replace text
officecli set doc.docx / --prop find=draft --prop replace=final
# Replace + format
officecli set doc.docx '/body/p[1]' --prop find=TODO --prop replace=DONE --prop bold=true
# Bulk: color all dates red across all paragraphs
officecli set doc.docx / --prop 'find=\d{4}-\d{2}-\d{2}' --prop regex=true --prop color=red
# Replace in header
officecli set doc.docx '/header[1]' --prop find=Draft --prop replace=Final
```
**PPT find works the same way:**
```bash
# Format matched text
officecli set slides.pptx '/slide[1]/shape[1]' --prop find=weather --prop bold=true --prop color=red
# Regex
officecli set slides.pptx '/slide[1]/shape[1]' --prop 'find=\d+%' --prop regex=true --prop color=red
# Replace across all slides
officecli set slides.pptx / --prop find=draft --prop replace=final
# Replace + format
officecli set slides.pptx '/slide[1]/shape[1]' --prop find=TODO --prop replace=DONE --prop bold=true
# Replace in table
officecli set slides.pptx '/slide[1]/table[1]' --prop find=old --prop replace=new
```
Path controls search scope: `/` = all slides, `/slide[N]` = single slide, `/slide[N]/shape[M]` = single shape, `/slide[N]/table[M]` = table, `/slide[N]/notes` = notes pane.
> **Known limitation:** Notes pane find+format writes correctly, but `get` returns plain text only — run-level formatting cannot be verified via CLI.
**Behavior matrix:**
| Props | Effect |
| --------------------------------- | ----------------------------------------- |
| `find` + format props | Split runs, apply format to matched text |
| `find` + `replace` | Replace matched text |
| `find` + `replace` + format props | Replace text and apply format to new text |
- Add `regex=true` to enable regex matching: `--prop 'find=\d+%' --prop regex=true`
- Batch JSON: `{"props":{"find":"\\d+%","regex":"true","color":"FF0000"}}`
- Path controls search scope: `/` = body only (excludes headers/footers), `/header[1]` = first header, `/footer[1]` = first footer, `/body/p[1]` = specific paragraph, etc.
- If `find=` matches nothing, the command succeeds with no changes (no error)
- `--json` output includes a `"matched": N` field indicating the number of matches found
- Matching is **case-sensitive** by default. For case-insensitive, use regex: `--prop 'find=(?i)error' --prop regex=true`
- `find:` / `find=` matches work across run boundaries — text split across multiple runs is still found
**Excel limitations:** Excel only supports `find` + `replace` (text replacement). `find` + format props (formatting matched text without replacing) is not supported in Excel — use Word or PowerPoint for that. In Excel, `find` without `replace` is treated as an unsupported property.
Auf GitHub ansehen