# How to Use OfficeCLI Python and Node.js SDKs for Programmatic Document Manipulation

> Automate Excel, Word, and PowerPoint with OfficeCLI Python and Node.js SDKs. Manipulate documents programmatically using lightweight, language-agnostic tools. Get started today.

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

---

**OfficeCLI provides lightweight language-agnostic SDKs for Python and Node.js that forward JSON commands to a resident process via named pipes, enabling Excel, Word, and PowerPoint automation without learning a new API.**

The [iOfficeAI/OfficeCLI](https://github.com/iOfficeAI/OfficeCLI) repository ships native SDKs that wrap the command-line interface, allowing developers to programmatically create, edit, and save Office documents from their preferred runtime. Both implementations share an identical **wire protocol** that serializes commands as newline-terminated JSON over platform-specific pipes, ensuring feature parity across languages.

## Architecture of the OfficeCLI SDKs

The Python and Node.js SDKs serve as thin transport layers that delegate all document processing to the resident OfficeCLI binary.

### Python SDK Structure

In [`sdk/python/officecli.py`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/python/officecli.py), the `create()` and `open()` factory functions spawn the `officecli` binary via `subprocess.Popen` and return a `Document` handle. The `Document` class exposes three core methods:

- **`send(command)`** – Dispatches a single JSON command and waits for the response envelope
- **`batch(commands)`** – Sends multiple commands in one round-trip
- **`close()`** – Terminates the resident process gracefully

The transport layer uses `_send_unix()` or `_send_win()` depending on the platform, implementing a bounded-connect-then-blocking-read pattern that matches the resident's `TrySend` logic with exponential back-off for busy-resident scenarios.

### Node.js SDK Structure

In [`sdk/node/index.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/node/index.js), the equivalent `create()` and `open()` functions use `child_process.spawn` to launch the binary. The `Document` class mirrors the Python implementation with `send()`, `batch()`, and `close()` methods, and supports the `await using` syntax on Node.js ≥ 24 for automatic resource disposal.

### Shared Wire Protocol

Both SDKs calculate pipe addresses using `pipe_paths()` (Python) or `pipePaths()` (Node.js), generating deterministic names based on the absolute file path hash. The request format is strictly `JSON.stringify(req) + '\n'`, and responses contain `ExitCode`, `Stdout`, `Stderr`, and a `success` boolean flag parsed from `json.loads()` (Python) or `JSON.parse()` (Node.js).

## Installing the OfficeCLI SDKs

Both SDKs include an `install()` helper that fetches the official installer from Cloudflare-fronted mirrors (with GitHub fallback) if the binary is not detected in the system path.

**Python installation:**

```python
import officecli
officecli.install()  # Idempotent; skips if already present

```

**Node.js installation:**

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

```

For package manager installation, reference [`pyproject.toml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/pyproject.toml) in `sdk/python/` or [`package.json`](https://github.com/iOfficeAI/OfficeCLI/blob/main/package.json) in `sdk/node/`.

## Creating and Opening Documents

Use `create()` to spawn a new workbook and `open()` to attach to existing files. Both methods return a `Document` instance that holds the pipe connection.

**Creating a new Excel file (Python):**

```python
import officecli

with officecli.create("report.xlsx", "--force") as doc:
    # Document manipulation happens here

    ...

# Resident automatically terminated on context exit

```

**Creating a new Excel file (Node.js):**

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

const doc = await oc.create("report.xlsx", ["--force"]);
try {
  // Document manipulation happens here
} finally {
  await doc.close();
}

```

The `open()` method connects to an existing resident if one is already handling the file, avoiding duplicate process overhead.

## Reading and Writing Cell Data

Send JSON commands matching the CLI's native syntax using `doc.send()`. The `set` command writes cell data; the `get` command retrieves it.

**Python example:**

```python
with officecli.create("demo.xlsx") as doc:
    # Write to Sheet1!A1

    doc.send({
        "command": "set",
        "path": "/Sheet1/A1",
        "props": {"text": "Hello, Office CLI!"}
    })
    
    # Read back the value

    resp = doc.send({"command": "get", "path": "/Sheet1/A1"})
    print(resp["stdout"]["text"])  # "Hello, Office CLI!"

```

**Node.js example:**

```javascript
const doc = await oc.create("demo.xlsx");

await doc.send({
  command: "set",
  path: "/Sheet1/A1",
  props: { text: "Hello, Office CLI!" }
});

const { stdout } = await doc.send({ 
  command: "get", 
  path: "/Sheet1/A1" 
});
console.log(stdout.text);

```

## Batch Operations for Performance

For bulk updates, use `batch()` to send multiple commands in a single pipe transaction, reducing connection overhead.

```python
import officecli

with officecli.create("batch_demo.xlsx") as doc:
    resp = doc.batch([
        {"command": "set", "path": "/Sheet1/A1", "props": {"text": "One"}},
        {"command": "set", "path": "/Sheet1/A2", "props": {"text": "Two"}},
        {"command": "set", "path": "/Sheet1/A3", "props": {"text": "Three"}},
        {"command": "save"}
    ])
    print("Batch exit code:", resp["exitCode"])

```

The batch response contains the aggregated results for all commands in the sequence.

## Working with Existing Files

To manipulate existing documents without spawning a new resident process when one is already active:

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

const doc = await oc.open("existing.xlsx");
const { stdout } = await doc.send({ 
  command: "get", 
  path: "/Sheet1/B2" 
});
console.log("B2 value:", stdout.text);
await doc.close();

```

## Summary

- **OfficeCLI Python and Node.js SDKs** forward JSON commands to a resident process over named pipes, exposing the full CLI functionality without wrapper abstraction.
- **Core files**: [`sdk/python/officecli.py`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/python/officecli.py) and [`sdk/node/index.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/sdk/node/index.js) implement identical transport logic for their respective runtimes.
- **Key methods**: `create()`, `open()`, `send()`, `batch()`, and `close()` provide the complete document lifecycle.
- **Batch operations** reduce latency by bundling multiple commands into a single pipe write.
- **Both SDKs** support automatic installation helpers and deterministic pipe naming based on file path hashing.

## Frequently Asked Questions

### How do the OfficeCLI SDKs handle concurrent access to the same file?

Both SDKs calculate deterministic pipe names using `pipe_paths()` (Python) or `pipePaths()` (Node.js) based on the absolute file path hash. When `open()` is called on a file already managed by a resident process, the SDK connects to the existing pipe rather than spawning a new instance, preventing file lock conflicts and process duplication.

### What is the difference between send() and batch() in the OfficeCLI SDKs?

The `send()` method transmits a single JSON command and waits for the immediate response, suitable for individual read/write operations. The `batch()` method accepts an array of command objects, sends them as a concatenated sequence in one pipe transaction, and returns a single response envelope containing results for all operations—significantly improving throughput for bulk updates.

### Do I need to manually install the OfficeCLI binary before using the Python or Node.js SDK?

No. Both SDKs expose an `install()` function (`officecli.install()` in Python, `oc.install()` in Node.js) that automatically downloads the appropriate binary from the official repository via Cloudflare mirrors if the `officecli` command is not found in the system path. This check is idempotent and skips re-installation if the binary is already present.

### Can I use the OfficeCLI SDKs with Word and PowerPoint documents, or only Excel?

Yes. Because the SDKs proxy raw JSON commands to the resident CLI process, they support any command available in the OfficeCLI binary, including those targeting Word (`*.docx`) and PowerPoint (`*.pptx`) files. Simply change the file extension in `create()` or `open()` and use the appropriate path syntax (e.g., `/Slide1/Title` for PowerPoint or `/Paragraph1` for Word) in your `set` and `get` commands.