Packages
Fast, memory-efficient Elixir library for parsing spreadsheet files (.xls, .xlsx, .xlsm, .xlsb, .ods) powered by Rust and Calamine. Features precompiled NIFs, smart type handling, and support for hidden sheets.
Current section
Files
Jump to
Current section
Files
spreadsheet
README.md
README.md
# Spreadsheet
<!-- MDOC !-->
A fast, memory-efficient Elixir library for parsing spreadsheet files powered by Rust and [Calamine](https://docs.rs/calamine/latest/calamine/).
## Features
- π **Fast Performance** - Native Rust implementation via NIFs for high-speed parsing
- π **Multiple Formats** - Supports .xls, .xla, .xlsx, .xlsm, .xlam, .xlsb, and .ods files
- πΎ **Memory Efficient** - Parse from file paths or binary content
- ποΈ **Sheet Management** - List and filter sheet names, including hidden sheets
- π
**Smart Type Handling** - Automatic conversion of dates to NaiveDateTime and numbers to Float
- π§ **Simple API** - Clean, functional interface with {:ok, result} | {:error, reason} patterns
## Usage
### Getting Sheet Names
List all sheet names in a file:
```elixir
iex> Spreadsheet.sheet_names("financial_data.xlsx")
{:ok, ["Q1 Revenue", "Q2 Revenue", "Summary"]}
```
Or from binary content:
```elixir
iex> content = File.read!("financial_data.xlsx")
iex> Spreadsheet.sheet_names_from_binary(content)
{:ok, ["Q1 Revenue", "Q2 Revenue", "Summary"]}
```
### Filtering Hidden Sheets
Exclude hidden sheets from the results:
```elixir
iex> Spreadsheet.sheet_names("workbook.xlsx", hidden: false)
{:ok, ["Visible Sheet"]}
```
### Parsing Sheet Data
Parse a specific sheet by name:
```elixir
iex> Spreadsheet.parse("sales.xlsx", "Q1 Data")
{:ok, [
["Product", "Sales", "Date"],
["Widget A", 1500.0, ~N[2024-01-15 00:00:00]],
["Widget B", 2300.0, ~N[2024-01-20 00:00:00]]
]}
```
Or from binary content:
```elixir
iex> content = File.read!("sales.xlsx")
iex> Spreadsheet.parse_from_binary(content, "Q1 Data")
{:ok, [
["Product", "Sales", "Date"],
["Widget A", 1500.0, ~N[2024-01-15 00:00:00]],
["Widget B", 2300.0, ~N[2024-01-20 00:00:00]]
]}
```
### Data Type Handling
The library automatically converts data types:
- **Dates**: Converted to `NaiveDateTime` structs
- **Numbers**: Converted to `Float` values
- **Empty cells**: Returned as `nil`
- **Text**: Returned as strings
For detailed information on the underlying parsing engine, see the [Calamine documentation](https://docs.rs/calamine/latest/calamine/).
<!-- MDOC !-->
## Installation
Add `spreadsheet` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:spreadsheet, "~> 0.2.0"}
]
end
```
### No Rust Installation Required
By default, the library uses precompiled NIFs, so **you don't need Rust installed**. If you want to force compilation from source, set the application environment:
```elixir
config :rustler_precompiled, :force_build, spreadsheet: true
```
## Performance
ExSpreadsheet is built for performance and handles large files efficiently:
- **Native Speed**: Rust-powered parsing for maximum throughput
- **Memory Efficient**: Streaming approach minimizes memory usage
- **Cross-Platform**: Precompiled NIFs for major platforms (Linux, macOS, Windows)
- **Production Ready**: Battle-tested in high-volume data processing environments
## Why Spreadsheet?
Compared to other Elixir spreadsheet libraries:
- **Faster**: Native Rust implementation outperforms pure Elixir parsers
- **More Formats**: Supports more file formats including .ods and legacy .xls files
- **Better Memory Usage**: Efficient memory handling for large files
- **Zero Setup**: No need to install external dependencies
### Alternatives
- [XlsxReader](https://hex.pm/packages/xlsx_reader) - Pure Elixir, XLSX only
- [Xlsxir](https://hex.pm/packages/xlsxir) - XML-based parsing, XLSX only
## Development
### Publishing a new version
Follow the [rustler_precompiled guide](https://hexdocs.pm/rustler_precompiled/precompilation_guide.html):
1. Release a new tag
2. Push the code with the new tag: `git push origin main --tags`
3. Wait for all NIFs to be built
4. Download precompiled NIFs: `mix rustler_precompiled.download Spreadsheet.Calamine --all`
5. Release the package to Hex.pm
## Copyright and License
Copyright (c) 2025 Wilhelm H Kirschbaum
This work is free. You can redistribute it and/or modify it under the
terms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details.