Skip to content

Latest commit

Β 

History

223 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ExcelBench

Objective, reproducible spreadsheet-library benchmarks with a Python-first decision surface.

Most Excel library comparisons focus on speed. ExcelBench focuses on the question developers actually have:

Can this library handle my real spreadsheet without breaking the parts I care about?

ExcelBench models 22 XLSX features across 14 Python adapters plus a cross-language context lane (Apache POI, Excelize, zavora-xlsx). Tier 4 (sheet protection, page setup, chart anchoring) was added in the 2026-09-08 competitor snapshot.

Results at a Glance

Competitor snapshot: 2026-10-02 | WolfXL 2.0.5 (latest PyPI) | 17 fidelity adapters incl. SheetJS CE 0.20.3, ExcelJS 4.4.0, LibreOffice 26.8.0.3 | Snapshot README | Fidelity | Mutation | Calc | Cross-language

Green features in that snapshot (read / write, out of 21ΒΉ): openpyxl 21/21 / 21/21, WolfXL 19/21 / 18/21, ExcelJS 12/21 / 15/21, aspose-cells-foss 11/21 / 14/21, LibreOffice 12/21 / 12/21, SheetJS CE 9/21 / 8/21; write-only xlsxwriter 15/21.

Mutation suite (two-cell edit on a corporate template, content-model preservation; features kept / features in the template): WolfXL Preserved 17/17; openpyxl 16/17 (drops custom XML); LibreOffice 15/17 (cell styles, page setup); aspose-cells-foss 15/17 (drops 87 string cells, custom XML); SheetJS 8/17 and zavora-xlsx 8/17 (charts, tables, styles and more); ExcelJS fails to load the template. Every engine that ran applied both edits. Wall times in that run are not comparable (host under heavy unrelated load).

Calc tier (133-formula financial DAG, cache-free fixture, LibreOffice oracle): LibreOffice 133/133, aspose-cells-foss 25/133, WolfXL 0/133, zavora 0/133. SheetJS CE, ExcelJS, and the other non-calculating adapters are not applicable.

Cross-language context (write lane): Apache POI 5.5.1 18/21, Excelize 2.10.1 18/21, zavora-xlsx 0.1.2 8/21. The POI and Excelize misses are the three Tier 4 features, which the ExcelBench adapters do not implement yet (NotImplementedError). They are not library gaps.

ΒΉ pivot_tables is excluded from every denominator because no adapter produced a score for it in either competitor snapshot.

Python release snapshot: 2026-04-29 UTC | wheel-backed WolfXL 2.0 rerun | Fidelity | Perf | Dashboard

In that snapshot, WolfXL reaches 18/18 green features with 100% pass rate.

Performance snapshot: 2026-10-02 UTC | WolfXL 2.0.5 through its public API (wolfxl.load_workbook, wolfxl.Workbook) | Perf. It supersedes the 2026-04-29 perf numbers for WolfXL, which measured private backend objects.

Cross-language context snapshot: Apache POI 18/18 | Excelize 18/18

Pivot capability lane: separate artifact because the shipped macOS pivot fixture is not scoreable, while excelize can still emit pivot-bearing workbooks.

Historical public baseline: 2026-02-17 | Excel 16.105.3 | macOS (Apple Silicon) | Full results

Newer performance snapshot: 2026-04-20 | Perf results

Read Public Reporting Status before quoting numbers across snapshots.

ExcelBench Heatmap

The current story: ExcelBench now has three useful lanes. The Python release lane answers the migration question. The cross-language lane answers the ecosystem-positioning question. The pivot capability lane captures pivot evidence separately when the scored fixture is not valid on this platform. Keep every claim tied to the exact dated artifact you are citing.

Comparison Scope

ExcelBench intentionally keeps the main public comparison Python-first. That is the decision surface most users care about: openpyxl, xlsxwriter, python-calamine, pandas, and adjacent Python options.

Cross-language libraries matter too, but for a different reason: they show how strong WolfXL looks next to mature spreadsheet tooling outside Python. The current checked-in cross-language lane includes:

  • Apache POI
  • Excelize
  • zavora-xlsx (Rust writer, added 2026-09-08)

Pivot tables sit in a separate capability lane. On macOS, the shipped pivot fixture does not currently contain scoreable pivot OOXML, so the pivot story is tracked as a dedicated artifact instead of being mixed into the scored lane.

See cross-language comparison strategy.

Lanes

  1. Python replacement lane Use this when the question is: what should a Python team use instead of openpyxl?

  2. Cross-language context lane Use this when the question is: how does WolfXL compare to serious spreadsheet tooling in Java, Go, and Rust?

  3. Pivot capability lane Use this when the question is: can the cross-language helpers detect or emit pivot-bearing workbooks even when the main scored fixture is not valid on macOS?

  4. Template-mutation lane Use this when the question is: which engine can surgically edit a corporate template fastest while preserving everything else in the workbook?

  5. Formula-recalculation lane Use this when the question is: which engine actually computes a 133-formula financial DAG from scratch (cache-free fixture, LibreOffice oracle)?

Library Comparison

Library Caps Fidelity Read Speed Write Speed Modify
wolfxl R+W R 20/21, W 19/21 in 2026-09-08 competitor snapshot (18/18 in 2026-04-29 snapshot) 1.69x (13.46 ms) 1.20x (22.28 ms) Patch (Preserved, 17/17 features in 2026-10-02 mutation suite)
openpyxl R+W R 21/21, W 21/21 in 2026-09-08 competitor snapshot 1.00x (22.79 ms, baseline) 1.00x (26.70 ms, baseline) Rewrite (16/17 features in 2026-10-02 mutation suite)
aspose-cells-foss R+W R 11/21, W 14/21 in 2026-09-08 competitor snapshot not measured not measured Rewrite (15/17 features)
xlsxwriter W 15/18 in 2026-04-29 release snapshot -- 0.86x (31.12 ms) No
xlsxwriter-constmem W 12/18 in 2026-04-29 release snapshot -- 0.86x (31.17 ms) No
python-calamine R 1/18 in 2026-04-29 release snapshot 14.02x (1.63 ms) -- No
pandas R+W 3/18 in 2026-04-29 release snapshot 0.80x (28.43 ms) 1.00x (26.66 ms) Rebuild
polars R 0/18 in 2026-04-29 release snapshot 3.72x (6.13 ms) -- No

Speed columns come from the 2026-10-02 perf snapshot: sum of per-feature p50 wall times over the same 19 xlsx features for every library (warmup 3, 25 iterations, Apple M4 Pro, Python 3.12.3), shown as openpyxl's total divided by the library's total. WolfXL 2.0.5 is measured through its public API (wolfxl.load_workbook, wolfxl.Workbook), like every other library. aspose-cells-foss was not part of the perf run. Always cite the artifact date, workload, and profile. See METHODOLOGY.md and Public Reporting Status.

Key Findings

  • High-fidelity libraries are rare: in the 2026-04-29 release snapshot, only openpyxl and WolfXL reached 18/18 green features; in the 2026-09-08 competitor snapshot (21 scored features; pivot_tables unscored), openpyxl holds 21/21 read and write while WolfXL 2.1.0 reaches 20/21 read and 19/21 write
  • WolfXL 2.1.0 regression signal: conditional-formatting read scores 0 and named-range / print-title writes score 2 in the 2026-09-08 snapshot; tracked for the WolfXL repo
  • Patch modify is structurally different: WolfXL's load_workbook(path, modify=True) uses surgical ZIP patching; it is the only engine whose output keeps every template feature in the 2026-10-02 mutation suite
  • The abstraction tax is real: pandas wraps openpyxl but drops from 16 to 3 green features due to DataFrame coercion (errors become NaN)
  • Speed vs fidelity tradeoff is measurable: use the perf snapshot together with the fidelity matrix rather than quoting one without the other
  • Optimization modes have clear costs: openpyxl-readonly loses 13 green features for streaming speed
  • Cross-language context is now strong too: Apache POI and Excelize land at 18/18 in the scored write lane; zavora-xlsx 0.1.2 writes fast but corrupts hyperlink relationships on mutate and cannot recalculate
  • Calculation is a differentiator: in the 2026-10-02 calc rerun, LibreOffice, WolfXL Community 2.0.7, and WolfXL Commercial 2.3.0 compute all 133 formulas; aspose-cells-foss covers 25/133 and zavora-xlsx 0/133. Community's save() writes no calculated values (0/133 saved), while Commercial saves all 133

See the release snapshot dashboard for the fresh wheel-backed combined view, or the historical dashboard for the older public baseline.

Score Legend

Score Meaning
🟒 3 Complete -- full fidelity, indistinguishable from Excel
🟑 2 Functional -- works for common cases, some edge-case failures
🟠 1 Minimal -- basic recognition but significant limitations
πŸ”΄ 0 Unsupported -- errors, corruption, or complete data loss

Libraries Tested

XLSX Profile (14 adapters)

Library Version Lang Caps Green Features
WolfXL 2.1.0 Python (Rust core) R+W R 20/21, W 19/21 (2026-09-08 snapshot)
openpyxl 3.1.5 Python R+W R 21/21, W 21/21 (2026-09-08 snapshot)
aspose-cells-foss 26.7 Python (JVM-core FOSS) R+W R 11/21, W 14/21 (2026-09-08 snapshot)
XlsxWriter 3.2.9 Python W 15/18
xlsxwriter-constmem 3.2.9 Python W 12/18
openpyxl-readonly 3.1.5 Python R 3/18
pandas 3.0.0 Python R+W 3/18
pyexcel 0.7.4 Python R+W 3/18
tablib 3.9.0 Python R+W 3/18
pylightxl 1.61 Python R+W 2/18
python-calamine 0.6.1 Rust R 1/18
polars 1.38.1 Rust R 0/18
xlwt 1.3.0 Python W 4/18
xlrd 2.0.2 Python R .xls only

Green-feature counts are per dated snapshot; x/18 numbers come from the 2026-04-29 release snapshot and x/21 from the 2026-09-08 competitor snapshot (Tier 4 added; pivot_tables is unscored and excluded from the denominator). Never mix counts across snapshots.

Cross-Language Context (oracle helpers)

Library Version Lang Caps Notes
Apache POI 5.x Java W 18/18 scored write lane (2026-04-29)
Excelize 2.x Go W 18/18 scored write lane (2026-04-29)
zavora-xlsx 0.1.2 Rust W Fast writer; 0.1.2 corrupts hyperlink relationships on mutate; no recalc

XLS Profile (2 adapters)

Library Green Features Notes
xlrd 4/4 Full .xls read fidelity
python-calamine 2/4 Cross-format reader

Optional: Rust Backends (PyO3)

Five additional adapters via Rust/PyO3 extension modules:

Library Caps Source Notes
WolfXL (calamine-styled) R PyPI Full-fidelity Rust reader with style extraction
WolfXL (rust_xlsxwriter) W PyPI Full-fidelity Rust writer
calamine (basic) R Local Direct calamine bindings (data only, no styles)
rust_xlsxwriter (direct) W Local Direct rust_xlsxwriter bindings
umya-spreadsheet R+W Local Rust read + write
# WolfXL adapters (from PyPI β€” no Rust toolchain needed)
uv sync --extra rust

# Local-only adapters (requires Rust toolchain + maturin)
uv run maturin develop --manifest-path rust/excelbench_rust/Cargo.toml \
  --features calamine,rust_xlsxwriter,umya

uv sync may uninstall locally-built extensions; rerun maturin develop after.

Cross-Language Context

ExcelBench now ships a separate cross-language context snapshot for mature non-Python spreadsheet libraries:

  • Apache POI (Java)
  • Excelize (Go)
  • zavora-xlsx (Rust writer, added 2026-09-08; helper in tools/external-oracles/zavora)

These are not framed as Python drop-in replacements. They answer a different question: how strong is WolfXL relative to serious spreadsheet tooling outside Python?

Current checked-in cross-language snapshot:

Current takeaways from that snapshot:

  • apache-poi: 18/18 green features in the scored write surfaces of this lane
  • excelize: 18/18 green features in the scored write surfaces of this lane
  • pivot_tables: tracked in a separate capability artifact because the shipped macOS fixture does not contain scoreable pivot OOXML, while excelize can still emit pivot-bearing workbooks

The concrete rollout plan for the first two candidates is here:

Run the dedicated cross-language context snapshot with:

uv run excelbench cross-language-context --tests fixtures/excel --output results-cross-language

Run the dedicated pivot capability artifact with:

uv run excelbench cross-language-pivot-context --fixture fixtures/excel/tier2/15_pivot_tables.xlsx --output results-cross-language-pivots

How It Works

  1. Generate reference files -- xlwings drives real Excel to produce canonical .xlsx/.xls test files with known features.
  2. Read tests -- each library reads the Excel-generated file; extracted values are compared to the expected manifest.
  3. Write tests -- each library writes a new file from the same spec; the output is verified by a trusted oracle (Excel via xlwings, or openpyxl in CI).
  4. Score -- pass rates map to the 0-3 fidelity scale per feature.

Full methodology: METHODOLOGY.md

Public Reporting Rules

  • Treat each results/ directory as a dated snapshot.
  • Do not merge February fidelity claims and April perf claims into one undated headline.
  • Cite the artifact date and workload whenever quoting a speedup number.
  • Keep WolfXL-specific release claims aligned with the WolfXL repo's evidence page.

See docs/public-reporting.md.

WolfXL Docs

WolfXL documentation lives in the wolfxl repository.

Quick Start

# Install
uv sync

# Run the benchmark against pre-built fixtures (no Excel required)
uv run excelbench benchmark --tests fixtures/excel --output results

# Template-mutation suite (wall time, RSS, preservation)
uv run excelbench mutation

# Formula-recalculation tier (cache-free fixture, LibreOffice oracle)
uv run excelbench calc

# Generate the heatmap
uv run excelbench heatmap

# Generate the combined fidelity + performance dashboard
uv run excelbench dashboard

# View results
open results/xlsx/README.md  # macOS; use xdg-open on Linux

To regenerate canonical fixtures from scratch (requires Excel installed):

uv run excelbench generate --output fixtures/excel

Feature Coverage

Tested (22 features)

Tier Features Count
Tier 0 -- Core Cell values, formulas, multiple sheets 3
Tier 1 -- Formatting Text formatting, background colors, number formats, alignment, borders, dimensions 6
Tier 2 -- Advanced Merged cells, conditional formatting, data validation, hyperlinks, images, comments, freeze panes, pivot tables 8
Tier 3 -- Workbook metadata Named ranges, tables 2
Tier 4 -- Production surfaces (2026-09-08) Sheet protection, page setup, chart anchoring 3

Pivot tables are tested but score N/A across all adapters in the current macOS run. Green-feature denominators: /18 in the 2026-04-29 release snapshot, /21 in the 2026-09-08 and 2026-10-02 competitor snapshots (22 features modeled; pivot_tables is unscored and excluded).

Planned

None currently queued. Tier 4 (charts anchoring, print settings, protection) shipped 2026-09-08.

Detailed Results

Project Status

v0.1.0 -- actively maintained benchmarking harness with dated fidelity and performance snapshots, reproducible methodology, and multi-adapter coverage across Python and Rust-backed spreadsheet libraries.

Contributing

See CONTRIBUTING.md for setup instructions, how to add features, and how to add library adapters.

License

MIT

About

Comprehensive benchmark suite for Excel library feature parity (Python & Rust)

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages