
calamine
Pure Rust Library for Spreadsheets
Read XLS, XLSX, XLSM, XLSB, ODS & More with Zero-Copy Deserialization in Rust.
What is calamine?
calamine is a high-performance, pure Rust library for reading and deserializing Excel and OpenDocument spreadsheet files. It supports formats like XLS, XLSX, XLSM, XLSB, ODS, and more, focusing on fast, safe, and zero-copy data extraction. Designed for reliability and minimal dependencies, calamine avoids external system libraries and relies solely on pure Rust implementations. Its API enables developers to efficiently extract cell values, handle VBA projects, and parse formulas without complex setup or runtime overhead.
The library excels in performance-critical applications, offering significantly faster processing than Python, C#, and Go alternatives. With built-in Serde integration, calamine allows seamless mapping of spreadsheet data to Rust structs. It supports lazy loading for large files, header row configuration, and optional features like chrono date/time support and picture data extraction. Whether you're building CLI tools, web backends, or embedded systems, calamine delivers robust, predictable performance across platforms.
Getting Started with calamine
To start using calamine, add it to your Rust project via Cargo. You can install it directly using cargo add calamine or manually add the dependency to your Cargo.toml. The library is available on crates.io and its source code is hosted on calamine GitHub. For advanced usage, enable optional features like chrono for date/time support or picture for image data extraction. The library compiles cleanly on stable Rust and requires no external binaries or system libraries.
Install calamine via Cargo
cargo add calamineSerde-Based Spreadsheet Deserialization
calamine provides powerful Serde integration for mapping spreadsheet data directly to Rust structs. Using RangeDeserializerBuilder, developers can define strongly-typed data models and automatically deserialize rows into structured records. The library includes helper functions like deserialize_as_f64_or_none and deserialize_as_f64_or_string to handle mixed-type columns gracefully. This approach ensures type safety, reduces boilerplate, and enables compile-time validation of data structures. It's especially useful for data pipelines, reporting tools, and ETL applications where reliability and performance are critical.
Deserialize Spreadsheet Rows into Rust Structs
use calamine::{deserialize_as_f64_or_none, open_workbook, RangeDeserializerBuilder, Reader, Xlsx};
use serde::Deserialize;
#[derive(Deserialize)]
struct Record {
metric: String,
#[serde(deserialize_with = "deserialize_as_f64_or_none")]
value: Option,
}
let mut excel: Xlsx<_> = open_workbook("file.xlsx")?;
let range = excel.worksheet_range("Sheet1")?;
let iter = RangeDeserializerBuilder::with_headers(&["metric", "value"]).from_range(&range)?;
for result in iter {
let record: Record = result?;
println!("{:?}", record);
} VBA Project and Formula Extraction
calamine enables extraction of VBA project modules and formula definitions from Excel files. Developers can retrieve VBA code from modules, detect broken references, and inspect defined names and their formulas. This capability is essential for migration tools, audit utilities, and legacy system analysis. The API provides structured access to VBA metadata and supports both simple and complex workbook introspection scenarios. Whether you're analyzing macros for security or converting legacy Excel logic, calamine delivers precise, low-level access to hidden workbook content.
Extract VBA Code and Defined Names
use calamine::{open_workbook_auto, Reader};
let mut workbook = open_workbook_auto("file.xlsx")?;
if let Ok(Some(vba)) = workbook.vba_project() {
let module = vba.get_module("Module1").unwrap();
println!("{}", module);
for ref in vba.get_references() {
if ref.is_missing() { println!("Broken: {}", ref.name); }
}
}
for (name, formula) in workbook.defined_names() {
println!("{}: {}", name, formula);
}Lazy Loading and Large File Handling
calamine supports lazy loading for XLSX and XLSB files, enabling efficient processing of large spreadsheets without loading all sheets into memory at once. By configuring header rows and using range-based iteration, developers can minimize memory footprint and maximize throughput. This feature is particularly valuable for serverless functions, CLI tools, and embedded deployments where resources are constrained. Benchmarks show calamine reading 1M+ rows with minimal memory overhead compared to alternatives like openpyxl and ClosedXML, making it ideal for high-scale data ingestion pipelines.
Process Large Spreadsheets Efficiently
use calamine::{open_workbook, Reader, Xlsx};
let mut excel: Xlsx<_> = open_workbook("large.xlsx")?;
let range = excel
.worksheet_range("Sheet1")?
.expect("Sheet not found");
for row in range.rows() {
// Process row without loading entire file
process_row(row);
}Performance Optimization and Benchmarks
calamine delivers exceptional performance, processing 41 million cells in under 25 seconds—outperforming Python, C#, and Go libraries by up to 9.4x. Its zero-copy design and minimal heap allocations reduce CPU and memory usage significantly. Benchmarks on a 186MB XLSX file show calamine using only 186MB disk reads versus 1.5GB for excelize. The library's deterministic memory behavior and low GC pressure make it suitable for real-time and latency-sensitive applications. Developers benefit from predictable resource usage and consistent throughput across diverse workloads.
