rust-excel-core 0.1.0

Read, write, and modify Excel (.xlsx) files — combines calamine, rust_xlsxwriter, and umya-spreadsheet for best-in-class performance
Documentation

rust-excel

A high-performance Rust toolkit for reading, writing, and modifying Excel (.xlsx) files. Combines three engines for best-in-class speed:

  • calamine - fast bulk reads (~2.5x faster than alternatives)
  • rust_xlsxwriter - fast file creation (~1.4x faster writes)
  • umya-spreadsheet - full in-memory mutation (read + write + modify)

Crates

Crate Description
rust-excel-core Library crate for Excel operations. Publish to crates.io.
rust-excel-api REST API server (Axum) with 40+ endpoints. React 19 compatible.

Quick Start

As a library

[dependencies]
rust-excel-core = "0.1"
use rust_excel_core::{Workbook, CellValue, sheet};

// Create a new workbook
let mut wb = Workbook::new();
let ws = wb.get_sheet_mut("Sheet1").unwrap();

// Write cells
sheet::set_cell_value(ws, 1, 1, &CellValue::String("Hello".into()));
sheet::set_cell_value(ws, 1, 2, &CellValue::Number(42.0));
sheet::set_cell_value(ws, 2, 1, &CellValue::Boolean(true));
sheet::set_cell_value(ws, 3, 1, &CellValue::Formula("=SUM(B1:B10)".into()));

// Save to bytes
let bytes = wb.save_to_bytes().unwrap();

// Open an existing file
let wb = Workbook::open("spreadsheet.xlsx").unwrap();
let ws = wb.get_sheet("Sheet1").unwrap();
let val = sheet::get_cell_value(ws, 1, 1);

Fast paths

use rust_excel_core::{Workbook, CellValue, RangeData};

// Fast bulk read from raw bytes (calamine, 2.5x faster)
let bytes = std::fs::read("large_file.xlsx").unwrap();
let data = Workbook::read_data_from_bytes(&bytes, "Sheet1").unwrap();
for row in &data.rows {
    for cell in row {
        // process cells...
    }
}

// Fast file creation (rust_xlsxwriter, 1.4x faster)
let data = RangeData {
    start_row: 1, start_col: 1, end_row: 2, end_col: 2,
    rows: vec![
        vec![CellValue::String("Name".into()), CellValue::String("Age".into())],
        vec![CellValue::String("Alice".into()), CellValue::Number(30.0)],
    ],
};
let xlsx_bytes = Workbook::create_from_data(vec![("People".into(), data)]).unwrap();

As a REST API

cargo run -p rust-excel-api
# Server starts on http://localhost:3001
# Create a workbook
curl -X POST http://localhost:3001/workbooks

# Upload an Excel file
curl -X POST http://localhost:3001/workbooks/upload \
  -F "file=@spreadsheet.xlsx"

# Read a cell
curl http://localhost:3001/workbooks/{id}/sheets/Sheet1/cells/1/1

# Write a cell
curl -X PUT http://localhost:3001/workbooks/{id}/sheets/Sheet1/cells/1/1 \
  -H "Content-Type: application/json" \
  -d '{"value": {"type": "String", "value": "Hello"}}'

# Bulk read (calamine fast path)
curl http://localhost:3001/workbooks/{id}/sheets/Sheet1/data

# Download
curl http://localhost:3001/workbooks/{id}/download -o output.xlsx

API Endpoints

Workbooks

  • POST /workbooks - Create empty workbook
  • POST /workbooks/upload - Upload .xlsx file (multipart)
  • GET /workbooks/{id} - Get workbook info
  • GET /workbooks/{id}/download - Download as .xlsx
  • DELETE /workbooks/{id} - Delete workbook

Sheets

  • GET /workbooks/{id}/sheets - List sheets
  • POST /workbooks/{id}/sheets - Add sheet
  • GET /workbooks/{id}/sheets/{name} - Get sheet info
  • PATCH /workbooks/{id}/sheets/{name} - Rename sheet
  • DELETE /workbooks/{id}/sheets/{name} - Remove sheet

Cells

  • GET /workbooks/{id}/sheets/{name}/cells/{row}/{col} - Read cell
  • PUT /workbooks/{id}/sheets/{name}/cells/{row}/{col} - Write cell
  • GET /workbooks/{id}/sheets/{name}/data - Bulk read (fast)
  • GET /workbooks/{id}/sheets/{name}/range?r1=&c1=&r2=&c2= - Read range
  • PUT /workbooks/{id}/sheets/{name}/range - Write range

Rows & Columns

  • POST /workbooks/{id}/sheets/{name}/rows/{at} - Insert rows
  • DELETE /workbooks/{id}/sheets/{name}/rows/{at} - Delete rows
  • PATCH /workbooks/{id}/sheets/{name}/rows/{at}/height - Set row height
  • POST /workbooks/{id}/sheets/{name}/columns/{at} - Insert columns
  • DELETE /workbooks/{id}/sheets/{name}/columns/{at} - Delete columns
  • PATCH /workbooks/{id}/sheets/{name}/columns/{at}/width - Set column width

Styles

  • GET /workbooks/{id}/sheets/{name}/cells/{row}/{col}/style - Get style
  • PATCH /workbooks/{id}/sheets/{name}/cells/{row}/{col}/style - Apply style
  • PATCH /workbooks/{id}/sheets/{name}/range/style?r1=&c1=&r2=&c2= - Apply range style

Merges

  • GET /workbooks/{id}/sheets/{name}/merges - List merges
  • POST /workbooks/{id}/sheets/{name}/merges - Merge cells
  • DELETE /workbooks/{id}/sheets/{name}/merges - Unmerge cells

Benchmarks

Measured on 50,000 cells (5000 rows x 10 cols):

Operation Time vs umya-spreadsheet alone
Read (calamine cached) 27 ms 2.5x faster
Read (calamine direct) 27 ms 2.5x faster
Write (rust_xlsxwriter) 48 ms 1.4x faster
Write (fast, from model) 54 ms 1.2x faster
Read (umya cell-by-cell) 66 ms baseline
Write (umya native) 67 ms baseline

Run benchmarks yourself:

cargo bench -p rust-excel-core

Features

  • Full cell type support: strings, numbers, booleans, formulas, empty
  • Sheet management: add, remove, rename, list
  • Range operations: bulk read/write rectangular regions
  • Row/column operations: insert, delete, resize
  • Cell styling: fonts, colors, borders, alignment, number formats
  • Cell merging and unmerging
  • Byte-level I/O: open from bytes, save to bytes (no filesystem needed)
  • Cached upload bytes for fast subsequent reads
  • Automatic dirty tracking with cache invalidation
  • Serde serialization for all types
  • CORS-enabled REST API for React/frontend integration

License

MIT