# 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
| `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
```toml
[dependencies]
rust-excel-core = "0.1"
```
```rust
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
```rust
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
```bash
cargo run -p rust-excel-api
# Server starts on http://localhost:3001
```
```bash
# 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):
| 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:
```bash
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