Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

officework

xlsx and docx engines that do not destroy your forms, plus a bridge that drives a running office app from Python — the way xlwings drives Excel, but on your own machine and without Excel.

Written in Rust (15,000+ lines, 240+ tests), exposed to Python through PyO3.

日本語の説明は GitHub にあります (Japanese documentation on GitHub): Python の手引き

Install

$ pip install officework

0.5.0 is in beta. It is published as 0.5.0b1, so the line above still gives you 0.4.0. To try the beta:

$ pip install --pre officework

Wheels are abi3 (CPython 3.10+), so one wheel per platform covers every version; Linux, macOS and Windows are published. The wheel is just the engines and the bridge — a few MB, no GUI. pandas is imported only if you ask for it (pip install officework[pandas]).

Three ways in

from officework import sheet             # the engine — no app needed
b = sheet.Book.open("form7.xlsx")
s = b["quote"]
s["A30"] = "Nihon Funen Co., Ltd."       # borders, merges, widths stay intact
s["C30"] = "=B30*100"                    # a formula; recalculated on the spot
s.insert_row(30)                         # remaining formulas follow the move
b.save("out.xlsx")                       # shapes and print setup carried over
from officework import doc               # the engine — docx, no app needed
d = doc.Doc.open("report.docx")
print(d.unsupported)                     # anything it could not read, never dropped in silence
d.replace("Old Name Ltd.", "New Name Ltd.")   # per-run formatting is left alone
d[3].text = "replaced"                   # the paragraph stays a heading, stays aligned
print(d.tables[0][1][2].text)            # table, row, cell
d.save("out.docx")                       # styles, headers, shapes, tracked changes carried over
from officework import calc as xw        # the bridge — drives the running app
import pandas as pd

wb = xw.Book()                           # a blank workbook comes up
wb.sheets.active["A1"].value = df        # the DataFrame lands in the sheet
df2 = wb.sheets.active["A1"].options(pd.DataFrame, expand="table").value

The bridge talks over a unix socket on this machine only — no TCP is opened. It needs officework running.

Let an AI drive the app (MCP)

$ pip install "officework[mcp]"

That installs officework-mcp, an MCP server speaking over stdin/stdout. Register it with an MCP client (Claude Code, Claude Desktop, …) and the assistant can read and write the workbook you have open — the same bridge the Python API uses, so the same rules apply: your machine only, no TCP.

// claude_desktop_config.json
{ "mcpServers": { "officework": { "command": "officework-mcp" } } }

The tools it exposes are deliberately few: book_info, used_range, read_range, read_formulas, write_range, set_format, autofit, save. Reading a range gives values; read_formulas gives the formulas behind them.

The app is a separate download

These engines are what aiseed office — a spreadsheet and a word processor with a window — uses whenever it meets the Microsoft formats. The app is downloaded on its own (.deb, .tar.gz, .dmg, setup.exe, Flatpak); this wheel does not carry it. Nothing here needs it: the engines are complete without a screen.

If the app is installed, officework starts it, and the bridge above drives it:

$ officework report.xlsx        # opens it in aiseed office

Spreadsheets and documents open as tabs of one window. Passing a second file adds a tab rather than opening another window. To point at a build of your own:

$ OFFICEWORK_OFFICEWORK=/path/to/officework officework report.xlsx

Your old vocabulary still works

Code written for openpyxl, xlwings or python-docx largely runs as-is:

ws = wb.active                          # openpyxl: cell(), append, iter_rows,
ws.cell(2, 3).value                     #   dimensions, create_sheet,
ws.append(["Aug", "pens", 5000])        #   copy_worksheet, freeze_panes …
xw.Range("B2").offset(1, 2).address     # xlwings: '$D$3' — resize,
xw.Range("A1").current_region           #   last_cell, current_region …
d.tables[0].cell(0, 1).text             # python-docx: row_cells, columns,
d[3].runs[0].font.name                  #   runs, clear …

The inventory — all 324 core members of the three libraries, judged one by one — is in the repo: docs/pysheet-gokan.ja.adoc. Interop is proven with the originals' own eyes: openpyxl reads what this engine writes, including the computed values it cannot produce itself. See the Python manual for the details and the deliberate differences.

Since 0.3.0 the wheel also typesets equations: officework.tex takes LaTeX and returns SVG or PNG. With TeX installed it typesets there (matrix columns align); without it, matplotlib's mathtext does the job; with neither, it refuses with the reason — never a silent empty picture.

New in 0.5.0, the engines print. save() looks at the extension, so a workbook or a document becomes a PDF without an app, an office suite or a print driver:

b.save("quote.pdf")                      # the sheet, paginated, with headers
d.save("report.pdf")                     # the document, typeset

The fonts are subsetted, so a Japanese page is around 25 KB rather than the 20 MB a whole CJK font would cost. Neither openpyxl nor python-docx can do this at all.

Charts are drawn the same way — as shapes, by this library, not as an instruction for Excel to render later. So they appear in the PDF and on the screen too, not only after you open the file in Excel:

ws.add_chart("bar", data="B3:C8", categories="A4:A8", at="A10",
             title="Target and actual")

For finer control there is a small chart layer whose shape is borrowed from d3 — build a scale, then place marks through it:

from officework import chart
c = chart.Chart(340, 180, title="Attainment")
x = c.band(branches)
y = c.linear([0, 150])
c.axis_left(y, fmt=lambda v: f"{int(v)}%")
c.bars(x, y, rates, color="70AD47", labels=True)
c.place(ws, "A20")

What you give up is a live Excel chart: ours is fixed at the data it was drawn from. Redraw it to update it.

New in 0.4.0, the bridge reaches the rest of a cell's formatting — align, valign, indent, rotation, shrink, locked, underline, strike, superscript, subscript — plus page setup and the table-design commands, so a macro can finish a form rather than only fill it.

Why the engines exist

openpyxl and python-docx rewrite the parts of the file they do not understand. For a document used as a printed form — the way most Japanese offices use one — that means the borders, merged cells, column widths, shapes, styles and headers you spent an afternoon on come back wrong.

These engines keep the original as the source of truth and write back only what changed. b.unsupported / d.unsupported list anything they could not read, so nothing is dropped in silence.

The docx side is checked against an independent reader (genoffice's TypeScript docx engine) over 51 real documents, 43 of which this project did not write: 46 survive an open-and-save untouched, and no document loses a single part of its zip. The rest — footnote marks, second and later section breaks, equations — are listed in d.unsupported rather than dropped quietly.

Measured on one machine, 1096 rows × 20 columns (21,920 cells):

DataFrame → sheet 44 ms
sheet → DataFrame 65 ms

License

AGPL-3.0-or-later.

Using it inside your company — building forms, running ledgers, writing scripts — carries no obligations at all. Obligations appear only if you ship something built on it to third parties, or offer a modified version as a network service.

Release files for officework 0.5.0b1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for officework 0.5.0b1
File Size Uploaded
officework-0.5.0b1.tar.gz 968.2 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for officework 0.5.0b1
File Interpreter ABI Platform
officework-0.5.0b1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
officework-0.5.0b1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
officework-0.5.0b1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.10 abi3 macOS 10.12+ x86-64, macOS 11.0+ ARM64, macOS 10.12+ universal2 (ARM64, x86-64) Details

Total release size: 14.4 MB

Release files / officework-0.5.0b1.tar.gz

Download URL officework-0.5.0b1.tar.gz
Size 968.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c7afb3316f470933f66371f4ae26353ea8d03ad621c86b921eafcdd1e08c4691
BLAKE2b-256 checksum
How to use checksums
23fd5fd8853e7078f366a4a4e114d37217138aa0da52e62ff1bb0bc6ef999f3a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release files / officework-0.5.0b1-cp310-abi3-win_amd64.whl

Download URL officework-0.5.0b1-cp310-abi3-win_amd64.whl
Size 3.2 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
7fe15c4851966336301e08e4fdb5c209dd71829b35e4072598d25b7dcfdcf581
BLAKE2b-256 checksum
How to use checksums
d3a4fac344cc4b39ec90856bcf501d6eb0d9399962e7f9d0916579b0ca851c7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release files / officework-0.5.0b1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL officework-0.5.0b1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.7 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
d608f34fa0b268847764afee7d8f7592030ed878d2c06d71d81902e7f468f8d1
BLAKE2b-256 checksum
How to use checksums
284a8a209d2ee7c611458dc5a625afe74ff705fc5d9c8ba127d771447ef6332d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release files / officework-0.5.0b1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL officework-0.5.0b1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 6.5 MB
Tags CPython 3.10 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
bc0695be6f20dc76b5a4ddf794c8be144bfb958c5df757ba31a67a39c817ebf0
BLAKE2b-256 checksum
How to use checksums
4a81ed323e99c9d29a588a3ac8d0d73b9b7c5b9da70795eff29cd738ddba11d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page