excelstream
🦀 High-performance Rust library for Excel import/export with streaming support
✨ What's New in v0.4.0:
- 📏 Column Width & Row Height - Customize column widths and row heights for perfect formatting!
- 🎨 Cell Formatting - 14 predefined styles: bold, italic, highlights, borders, number formats!
- 🎨 Easy Styling API -
write_header_bold(),write_row_styled(),write_row_with_style()- 💰 Number Formats - Currency, percentage, decimal, integer formats
- 📅 Date Formats - MM/DD/YYYY and timestamp formats
✨ Features
- 🚀 Streaming Read - Process large Excel files without loading entire file into memory
- 💾 Streaming Write - Write millions of rows with constant ~80MB memory usage
- ⚡ High Performance - 30K-45K rows/sec throughput with true streaming
- 🎨 Cell Formatting - 14 predefined styles (bold, currency, %, highlights, borders)
- 📏 Column Width & Row Height - Customize column widths and row heights
- 📐 Formula Support - Write Excel formulas (=SUM, =AVERAGE, =IF, etc.)
- 🎯 Typed Values - Strong typing with Int, Float, Bool, DateTime, Formula
- 🔧 Memory Efficient - Configurable flush intervals for memory-limited environments
- ❌ Better Errors - Context-rich error messages with available sheets list
- 📊 Multi-format Support - Read XLSX, XLS, ODS formats
- 🔒 Type-safe - Leverage Rust's type system for safety
- 📝 Multi-sheet - Support multiple sheets in one workbook
- 🗄️ Database Export - PostgreSQL integration examples
- ✅ Production Ready - 50+ tests, CI/CD, zero unsafe code
📦 Installation
Add to your Cargo.toml:
[]
= "0.2"
🚀 Quick Start
Reading Excel Files (Streaming)
use ExcelReader;
Writing Excel Files (Streaming - v0.2.0)
use ExcelWriter;
Key Benefits:
- ✅ Constant ~80MB memory usage regardless of dataset size
- ✅ High throughput: 30K-45K rows/sec with true streaming
- ✅ Direct ZIP streaming - data written to disk immediately
- ✅ Full formatting support: bold, styles, column widths, row heights
Writing with Typed Values (Recommended)
For better Excel compatibility and performance, use typed values:
use ExcelWriter;
use CellValue;
Benefits of write_row_typed():
- ✅ Numbers are stored as numbers (not text)
- ✅ Booleans display as TRUE/FALSE
- ✅ Excel formulas work correctly
- ✅ Better type safety
- ✅ Excellent performance: 42K+ rows/sec
Writing Excel Formulas
use ExcelWriter;
use CellValue;
Supported Formulas:
- ✅ Basic arithmetic:
=A1+B1,=A1*B1,=A1/B1 - ✅ SUM, AVERAGE, COUNT, MIN, MAX
- ✅ Cell ranges:
=SUM(A1:A10) - ✅ Complex formulas:
=IF(A1>100, "High", "Low") - ✅ All standard Excel functions
Cell Formatting and Styling
New in v0.3.0: Apply 14 predefined cell styles including bold headers, number formats, highlights, and borders!
Bold Headers
use ExcelWriter;
let mut writer = new?;
// Write bold header
writer.write_header_bold?;
// Regular data rows
writer.write_row?;
writer.write_row?;
writer.save?;
Styled Cells
Apply different styles to individual cells:
use ;
use ExcelWriter;
let mut writer = new?;
writer.write_header_bold?;
// Mix different styles in one row
writer.write_row_styled?;
writer.write_row_styled?;
writer.save?;
Uniform Row Styling
Apply the same style to all cells in a row:
// All cells bold
writer.write_row_with_style?;
// All cells highlighted yellow
writer.write_row_with_style?;
Available Cell Styles
| Style | Format Code | Example | Use Case |
|---|---|---|---|
CellStyle::Default |
None | Plain text | Regular data |
CellStyle::HeaderBold |
Bold | Header | Column headers |
CellStyle::NumberInteger |
#,##0 | 1,234 | Whole numbers |
CellStyle::NumberDecimal |
#,##0.00 | 1,234.56 | Decimals |
CellStyle::NumberCurrency |
$#,##0.00 | $1,234.56 | Money amounts |
CellStyle::NumberPercentage |
0.00% | 95.00% | Percentages |
CellStyle::DateDefault |
MM/DD/YYYY | 01/15/2024 | Dates |
CellStyle::DateTimestamp |
MM/DD/YYYY HH:MM:SS | 01/15/2024 14:30:00 | Timestamps |
CellStyle::TextBold |
Bold | Bold text | Emphasis |
CellStyle::TextItalic |
Italic | Italic text | Notes |
CellStyle::HighlightYellow |
Yellow bg | 🟨 Text | Warnings |
CellStyle::HighlightGreen |
Green bg | 🟩 Text | Success |
CellStyle::HighlightRed |
Red bg | 🟥 Text | Errors |
CellStyle::BorderThin |
Thin borders | ▭ Text | Boundaries |
Complete Example
use ExcelWriter;
use ;
See also: Run cargo run --example cell_formatting to see all 14 styles in action!
Column Width and Row Height
New in v0.4.0: Customize column widths and row heights for better formatting!
Column Width
Set column widths before writing any rows:
use ExcelWriter;
let mut writer = new?;
// Set column widths BEFORE writing rows
writer.set_column_width?; // Column A = 25 units wide
writer.set_column_width?; // Column B = 12 units wide
writer.set_column_width?; // Column C = 15 units wide
// Now write rows
writer.write_header_bold?;
writer.write_row?;
writer.save?;
Important:
- ⚠️ Column widths must be set before writing any rows
- Default column width is 8.43 units
- One unit ≈ width of one character in default font
- Typical range: 8-50 units
Row Height
Set row height for the next row to be written:
use ExcelWriter;
let mut writer = new?;
// Set height for header row (taller)
writer.set_next_row_height?;
writer.write_header_bold?;
// Regular row (default height)
writer.write_row?;
// Set height for next row
writer.set_next_row_height?;
writer.write_row?;
writer.save?;
Important:
- Height is in points (1 point = 1/72 inch)
- Default row height is 15 points
- Typical range: 10-50 points
- Setting is consumed by next
write_row()call
Complete Example with Sizing
use ExcelWriter;
use ;
See also: Run cargo run --example column_width_row_height for a complete demonstration!
Direct FastWorkbook Usage (Maximum Performance)
For maximum performance, use FastWorkbook directly:
use FastWorkbook;
Performance Metrics:
- ExcelWriter.write_row(): 36,870 rows/sec
- ExcelWriter.write_row_typed(): 42,877 rows/sec
- FastWorkbook direct: 44,753 rows/sec
- Memory usage: Constant ~80MB for any dataset size
Memory-Constrained Writing (For Kubernetes Pods)
In v0.2.0, all writers use streaming with constant memory:
use ExcelWriter;
Memory usage in v0.2.0:
- Constant ~80MB regardless of dataset size
- Configurable flush interval and buffer size
- Suitable for Kubernetes pods with limited resources
Multi-sheet workbook
use ExcelWriterBuilder;
📚 Examples
The examples/ directory contains detailed examples:
Basic Usage:
basic_read.rs- Basic Excel file readingbasic_write.rs- Basic Excel file writingstreaming_read.rs- Reading large files with streamingstreaming_write.rs- Writing large files with streaming
Performance Comparisons:
three_writers_comparison.rs- Compare all 3 writer types (recommended!)write_row_comparison.rs- String vs typed value writingwriter_comparison.rs- Standard vs fast writer comparisonfast_writer_test.rs- Fast writer performance benchmarks
Advanced Features:
memory_constrained_write.rs- Memory-limited writing for podsauto_memory_config.rs- Auto memory configuration democsv_to_excel.rs- CSV to Excel conversionmulti_sheet.rs- Creating multi-sheet workbooks
PostgreSQL Integration:
postgres_to_excel.rs- Basic PostgreSQL exportpostgres_streaming.rs- Streaming PostgreSQL exportpostgres_to_excel_advanced.rs- Advanced async with connection pooling
Running examples:
# Create sample data first
# Read Excel file
# Streaming with large files
# Performance comparisons (RECOMMENDED)
# Memory-constrained writing
MEMORY_LIMIT_MB=512
# Multi-sheet workbooks
# PostgreSQL examples (requires database setup)
🔧 API Documentation
ExcelReader
open(path)- Open Excel file for readingsheet_names()- Get list of sheet namesrows(sheet_name)- Iterator for streaming row readingread_cell(sheet, row, col)- Read specific celldimensions(sheet_name)- Get sheet dimensions (rows, cols)
ExcelWriter (Streaming)
new(path)- Create new writerwrite_row(data)- Write row with stringswrite_row_typed(cells)- Write row with typed values (recommended)write_header(headers)- Write header rowadd_sheet(name)- Add new sheetset_flush_interval(rows)- Configure flush frequency (default: 1000)set_max_buffer_size(bytes)- Configure buffer size (default: 1MB)set_column_width(col, width)- Not yet implemented in streaming modesave()- Save and finalize workbook
FastWorkbook (Direct Access)
new(path)- Create fast writeradd_worksheet(name)- Add worksheetwrite_row(data)- Write row (optimized)set_flush_interval(rows)- Set flush frequencyset_max_buffer_size(bytes)- Set buffer limitclose()- Finish and save file
Types
CellValue- Enum: Empty, String, Int, Float, Bool, DateTime, Error, FormulaRow- Row with index and cells vectorCell- Cell with position (row, col) and value
🎯 Use Cases
Processing Large Excel Files (100MB+)
// Streaming ensures only small portions are loaded into memory
let mut reader = open?;
let mut total = 0.0;
for row_result in reader.rows?
Exporting Database to Excel
let mut writer = new?;
writer.write_header?;
// Fetch from database and write directly
for record in database.query?
writer.save?;
Converting CSV to Excel
use File;
use ;
let csv = new;
let mut writer = new?;
for in csv.lines.enumerate
writer.save?;
⚡ Performance
Benchmarked with 1 million rows × 30 columns (mixed data types):
| Writer Method | Throughput | Memory Usage | Features |
|---|---|---|---|
| ExcelWriter.write_row() | 36,870 rows/sec | ~80MB constant ✅ | Simple API, string-based |
| ExcelWriter.write_row_typed() | 42,877 rows/sec | ~80MB constant ✅ | Type-safe, best balance |
| ExcelWriter.write_row_styled() | ~42,000 rows/sec | ~80MB constant ✅ | Cell formatting + styles |
| FastWorkbook (direct) | 44,753 rows/sec | ~80MB constant ✅ | Maximum speed, low-level |
Key Characteristics:
- ✅ High throughput - 30K-45K rows/sec depending on method
- ✅ Constant memory - stays at ~80MB regardless of dataset size
- ✅ True streaming - data written directly to disk via ZIP
- ✅ Predictable performance - no memory spikes or slowdowns
Recommendations
| Use Case | Recommended Method | Why |
|---|---|---|
| General use | write_row_typed() |
Best balance of speed, type safety, and features |
| Simple exports | write_row() |
Easy API, good performance |
| Formatted reports | write_row_styled() |
Cell formatting with minimal overhead |
| Maximum speed | FastWorkbook |
Direct access, highest throughput |
📖 Documentation
- README.md (this file) - Complete guide with examples
- CONTRIBUTING.md - How to contribute
- CHANGELOG.md - Version history
- Examples in
/examplesdirectory - Doc tests in source code
🛠️ Development
Build
Test
Run examples
Benchmark
📋 Requirements
- Rust 1.70 or higher
- Dependencies:
calamine- Reading Excel fileszip- ZIP compression for writingthiserror- Error handling
🚀 Production Ready
- ✅ Battle-tested - Handles 1M+ row datasets with ease
- ✅ High performance - 30K-45K rows/sec with true streaming
- ✅ Memory efficient - Constant ~80MB usage, perfect for K8s pods
- ✅ Reliable - 50+ comprehensive tests covering edge cases
- ✅ Safe - Zero unsafe code, full Rust memory safety
- ✅ Compatible - Excel, LibreOffice, Google Sheets
- ✅ Unicode support - Special characters, emojis, CJK
- ✅ CI/CD - Automated testing on every commit
🤝 Contributing
Contributions welcome! Please see CONTRIBUTING.md for guidelines.
Areas for Contribution:
- Cell formatting and styling (Phase 3)
- Conditional formatting
- Charts and images support
- More examples and documentation
- Performance optimizations
All contributions must:
- Pass
cargo fmt --check - Pass
cargo clippy -- -D warnings - Pass all tests
cargo test --all-features - Include tests for new features
📄 License
MIT License - see LICENSE file for details.
🙏 Credits
This library uses:
- calamine - Excel reader
- Custom FastWorkbook - High-performance streaming writer
📧 Contact
For questions or suggestions, please create an issue on GitHub.
Made with ❤️ and 🦀 by the Rust community