Skip to content

Read, write, and edit XLSX files from Rust or Python.

CrabXL uses one Rust engine for a Rust crate and a Python package. The Python package follows openpyxl. CrabXL reads large sheets in bounded memory. When you save an edit, CrabXL keeps the parts that you did not change.

Install

Use Rust 1.88 or newer.

Code examples

In Rust, row and column numbers start at zero. In Python, supported calls follow openpyxl. To use compatible openpyxl code, change one import.

use crabxl::{CellAddress, CellValue, SaveOptions, WorkbookEditor, WorkbookReader};

fn main() -> crabxl::Result<()> {
    // Stream the cells that are present, row by row
    let mut workbook = WorkbookReader::open("input.xlsx")?;
    let mut rows = workbook.rows("Sheet1")?;
    while let Some(row) = rows.next_row()? {
        for cell in row.cells {
            println!("{:?}: {:?}", cell.address, cell.value);
        }
    }

    // Edit one value and keep everything else as it was
    let mut editor = WorkbookEditor::open("input.xlsx")?;
    editor.set_value("Sheet1", CellAddress::new(0, 0)?, CellValue::Integer(42))?;
    editor.save_path("output.xlsx", SaveOptions::default())?;
    Ok(())
}

Features

#CapabilityDetails
Stream rows

CrabXL reads only the cells that the file contains. It reads them in batches of limited size and keeps their positions. To keep a full sheet in memory, use read_sheet.

CrabXL reads only the cells that the file contains. It reads them in batches of limited size and keeps their positions. To keep a full sheet in memory, use read_sheet.
Write sequentially

Write a new workbook one row at a time. In Python, write only mode writes the rows to a temporary file. You can save that workbook one time.

Write a new workbook one row at a time. In Python, write only mode writes the rows to a temporary file. You can save that workbook one time.
Edit existing files

Change the values of supported cells, then save the file. The parts of the file that you did not change keep their original bytes.

Change the values of supported cells, then save the file. The parts of the file that you did not change keep their original bytes.
Read exact values

CrabXL reads exact integers, text, rich text, dates, styles, and formula records.

CrabXL reads exact integers, text, rich text, dates, styles, and formula records.
Control memory

Set a memory limit, or use Auto. Auto selects streaming or full loading. Shared strings can stay in RAM or on disk.

Set a memory limit, or use Auto. Auto selects streaming or full loading. Shared strings can stay in RAM or on disk.
Pick compression

Select a Deflate level from 0 to 9. The default level is 6. The default backend is zlib-rs, which is written in Rust. Native zlib is an optional feature.

Select a Deflate level from 0 to 9. The default level is 6. The default backend is zlib-rs, which is written in Rust. Native zlib is an optional feature.
Migrate from openpyxl

To use compatible code, write import crabxl as openpyxl. CrabXL does not need openpyxl at run time.

To use compatible code, write import crabxl as openpyxl. CrabXL does not need openpyxl at run time.

Benchmarks

These tests call CrabXL 0.1.0a11 from Python. Each CrabXL mode is compared with the matching mode of other Python libraries.

At one million cells, the standard mode is about 19 times faster than openpyxl. The read_only mode is about 12 times faster than openpyxl read_only.

One million cells (100,000 rows by ten columns)

Wall time
  • CrabXLStandard0.57 s
  • CrabXLread_only0.52 s
  • openpyxlStandard10.91 s
  • openpyxlread_only6.06 s
  • python-calamineStandard0.72 s
Peak memory
  • CrabXLStandard55.0 MiB
  • CrabXLread_only23.9 MiB
  • openpyxlStandard427.2 MiB
  • openpyxlread_only34.4 MiB
  • python-calamineStandard95.4 MiB
Median wall time and peak memory for each library and mode
Library and mode10,000 cells100,000 cells1,000,000 cells
Wall timePeak memoryWall timePeak memoryWall timePeak memory
CrabXLStandard0.08 s24.2 MiB0.15 s27.0 MiB0.57 s55.0 MiB
CrabXLread_only0.08 s23.9 MiB0.13 s24.0 MiB0.52 s23.9 MiB
openpyxlStandard0.21 s29.5 MiB0.89 s66.7 MiB10.91 s427.2 MiB
openpyxlread_only0.22 s25.8 MiB0.70 s27.0 MiB6.06 s34.4 MiB
python-calamineStandard0.06 s20.3 MiB0.13 s27.0 MiB0.72 s95.4 MiB

Large files

This test does not include openpyxl, so it can use larger files. The NYC 311 file has the same shape as the sample in the calamine README: 1,000,001 rows, 41 columns, text, and dates.

With 10,000,000 integer cells, the read_only mode is about 1.8 times faster than python-calamine and uses about 24 MiB. On the NYC 311 file, the standard mode is about 1.2 times faster than python-calamine. The read_only mode is slower on this file, but it uses 56 MiB instead of 2,391 MiB.

Median wall time and peak memory for large reads
Library and mode10,000,000 integer cellsNYC 311, 28,478,615 values
Wall timePeak memoryWall timePeak memory
CrabXLStandard4.95 s335.1 MiB26.77 s1,676.2 MiB
CrabXLread_only3.53 s23.9 MiB35.05 s55.6 MiB
python-calamineStandard6.34 s706.3 MiB32.66 s2,391.4 MiB

The test conditions are the same as above, with python-calamine 0.9.0. The values include the 20 MiB of the Python interpreter.

Read the large file report

Test conditions: CPython 3.12, CrabXL 0.1.0a11, openpyxl 3.1.5, python-calamine 0.9.0, and XlsxWriter 3.3.0. The computer used Linux x86_64 on an Intel Xeon at 2.10 GHz. Each process ran on two fixed CPU cores. Each size had one warmup run and three measured runs. The time includes Python start and imports. The memory includes the Python interpreter, which uses about 20 MiB. The data has integers in ten columns. python-calamine only reads, and XlsxWriter only writes.

Read the full report and the raw data

Current status

If CrabXL does not support an operation, it returns an error. Read the roadmap before you use a feature in production.

Read the roadmap

Works today

  • Streaming reads and full sheet snapshots
  • Sequential writes and write only mode
  • Value edits that keep the unchanged parts
  • openpyxl calls for supported operations

Not yet

  • Formula calculation
  • Full openpyxl compatibility
  • Complete style and rich text objects
  • Advanced worksheet features and some structural edits

Platforms

Rust
Rust 1.88 or newer
Python
CPython 3.11 to 3.15 on Linux x86_64 and ARM64, Windows x86_64, and macOS on Intel and Apple Silicon