betteroffice-xlsx
Read, recalculate, render, and write XLSX workbooks from Python. The engine is the Rust BetterOffice XLSX core, compiled into the wheel — no Excel, no LibreOffice subprocess, no COM.
pip install betteroffice-xlsx
Formulas actually calculate
from betteroffice_xlsx import Workbook
wb = Workbook.open_path("budget.xlsx")
sheet = wb["Sheet1"]
sheet["B1"] = 10
sheet["B2"] = 32
sheet["B3"] = "=SUM(B1:B2)"
print(sheet["B3"]) # 42.0 <- computed here, not read from a cache
print(sheet.formula("B3")) # 'SUM(B1:B2)'
wb.save_path("budget-out.xlsx")
Value and formula are separate accessors on purpose: sheet["B3"] is the value,
sheet.formula("B3") is the source text. Writing a cell recalculates its
dependents, so the value above is computed here rather than read back from the
file.
Workbook.open starts from the values the authoring application cached, and a
cell you have not touched keeps that cached value — including if it was stale
when the file was written. Use open_recalculated, or call recalculate(),
when you need every formula evaluated by this engine rather than trusted from
the file.
Render a sheet to PNG
png = wb.render_png("Sheet1", scale=2.0, range="A1:H40")
png.write("preview.png")
print(png.width, png.height)
Rendering is the same grid layout and display list the browser editor uses, so server-side output matches what the web canvas paints.
Opening, recalculating, rendering, and saving release the GIL, so they run in parallel across threads instead of serializing your workers.
Reading without recalculating
Workbook.open keeps whatever values the file already carried. Use
open_recalculated to evaluate everything up front, or call recalculate()
later:
wb = Workbook.open_recalculated(open("report.xlsx", "rb").read())
summary = wb.recalculate()
print(summary.changed, summary.cycles)
Compared with openpyxl
openpyxl |
betteroffice-xlsx |
|
|---|---|---|
| Read cell values | yes | yes |
| Evaluate formulas | no — returns the formula string, or a stale cached value | yes |
| Render to an image | no | yes, PNG |
| Engine | pure Python | Rust, compiled |
openpyxl is a far broader library and covers plenty this does not. If you need
formulas evaluated or a sheet rasterized, that is the gap this fills.
API
Workbook.open(data) |
open from bytes |
Workbook.open_path(path) |
open from a path |
Workbook.open_recalculated(data) |
open and evaluate every formula |
wb.recalculate() |
re-evaluate; returns a Calculation summary |
wb.sheet_names / wb.sheet_count |
sheet metadata |
wb[key] / wb.sheet(key) |
a Sheet by name or index |
sheet[addr] |
cell value — see the note below on when it is recalculated |
sheet[addr] = value |
set from what a user would type |
sheet.formula(addr) |
source formula, or None |
wb.render_png(sheet, ...) |
render to PNG |
wb.save() / wb.save_path(path) |
serialize to XLSX |
Cell values come back as None, float, str, bool, or CellError.
Numbers are f64 in the engine, so they arrive as float and are not narrowed
to int. Errors are a CellError instance rather than a string, so #DIV/0!
as a value is distinguishable from a cell containing that text. CellError
compares equal to its code, and hashes like it, so it works as a dict key:
if sheet["D3"] == "#DIV/0!":
...
Writing accepts None (clears the cell), bool, int, float, Decimal, and
str. date, datetime, time, and timedelta raise TypeError for now:
converting them needs the workbook's date system, which is not exposed yet, and
stringifying them would write text that only looks like a date. Pass the Excel
serial number as a float if you need a date today.
Strings are interpreted the way Excel interprets typed input: a leading = is a
formula, TRUE/FALSE become booleans, and numeric text becomes a number.
Prefix with an apostrophe to force text.
sheet["A1"] = "'=1+1" # the text "=1+1"
sheet["A2"] = "=1+1" # the formula, evaluating to 2.0
Errors raise XlsxError, or one of ParseError, RangeError, RenderError.
Status
0.0.x, and the API may change before 0.1.0. save regenerates the package
from the features the model represents; package parts the model does not cover
are not retained, so this is not a round-trip-preserving editor for arbitrary
workbooks. Collaboration, agent proposals, undo/redo, and the styling APIs exist
in the Rust engine but are not yet exposed here.
Wheels are built for Linux (x86_64, aarch64), macOS (arm64, x86_64), and Windows (x86_64) against the stable ABI for CPython 3.9 and up.
The extension embeds Carlito, a Calibri-metric-compatible face used to measure
and draw cell text, under the SIL Open Font License. Its license travels with
the wheel — see THIRD-PARTY-NOTICES.md and licenses/Carlito-OFL.txt. The
package's own code is Apache-2.0.
Links
- BetterOffice — the project
- Documentation
- Source —
bindings/python - betteroffice-xlsx on crates.io — the engine this wraps
Apache-2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file betteroffice_xlsx-0.0.1.tar.gz.
File metadata
- Download URL: betteroffice_xlsx-0.0.1.tar.gz
- Upload date:
- Size: 515.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62e705fcadf857a7a5f768b0006a49ade68f21a330e495945509b0ee085761f1
|
|
| MD5 |
8e8460a912e1613f6b2f74da77185c74
|
|
| BLAKE2b-256 |
56f44a36e98a0d47562b3c029f8f7e170048a675804b65ead196ffa2bef52f66
|
File details
Details for the file betteroffice_xlsx-0.0.1-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: betteroffice_xlsx-0.0.1-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88e57b094ec01168351024e16ed54368e62ebd2b12bd6c60788b14fa3da8914c
|
|
| MD5 |
99e4694c4f200b46b8ff59b8bd337953
|
|
| BLAKE2b-256 |
bd5289876c7db84acd3bbfbbad87cb04e7d7db8fa635d83d36e08aa2cfd189f8
|
File details
Details for the file betteroffice_xlsx-0.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: betteroffice_xlsx-0.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b521f47c5dae011568bba9e006c8615606c434276a32a363368c2abb443d0570
|
|
| MD5 |
1bc6d5dccc342ceb700ab6dd3e8ba68d
|
|
| BLAKE2b-256 |
b65d3d59688d08abe8beee1c288f248402d984f0f4cb5ba8a9162a381eb8912f
|
File details
Details for the file betteroffice_xlsx-0.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: betteroffice_xlsx-0.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cee1c5b4a981037a90038b4ff76fbe5ce88666c6720df00405117de5fe48157d
|
|
| MD5 |
ea5396bf0510f18b1e305cf48d287eca
|
|
| BLAKE2b-256 |
fb617adf289489fb44be6629cabd731d063f8d173e8ee69cf7b4d0ba82a2a6d2
|
File details
Details for the file betteroffice_xlsx-0.0.1-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: betteroffice_xlsx-0.0.1-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.9 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bea4062bb78f7a598845ee57d8dc99fdd4f84e4fb5567f030a6a302527ef1653
|
|
| MD5 |
d34c8f5572bcb9a640426d2d79b5d923
|
|
| BLAKE2b-256 |
cabc19c054a516a43b6d0e7ede3ecac59fd2710b6388d05137d65651d6897b52
|
File details
Details for the file betteroffice_xlsx-0.0.1-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: betteroffice_xlsx-0.0.1-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7234650c2bc7731b5effbf6d37928da13b3c8624e37241caace3d15764176ac7
|
|
| MD5 |
ba3cfadd65e0074d0070800c1b954498
|
|
| BLAKE2b-256 |
8834824f6ab08ead0212a52cad117a4a5c127dd32749389e6cd27f50c3bb6be2
|