excelstream
🦀 High-performance Rust library for Excel import/export with streaming support
✨ Features
- 🚀 Streaming Read - Read large Excel files without loading entire content into memory
- 💾 Streaming Write - Write Excel files row by row with optimized memory usage
- ⚡ Fast Writer - Custom optimized writer 25-44% faster than standard writer for large datasets
- 🎯 Typed Values - Write with proper data types, Excel formulas work correctly (1-5% faster)
- 🎯 Memory Constrained - Configurable memory limits for Kubernetes pods with limited resources
- 📊 Multi-format Support - XLSX, XLS, ODS
- 🔒 Type-safe - Leverage Rust's type system
- ⚡ Zero-copy - Minimize memory allocations
- 📝 Multi-sheet - Support multiple sheets in one workbook
- 🎨 Formatting - Basic cell formatting support
- 🗄️ PostgreSQL - Database export examples included
📦 Installation
Add to your Cargo.toml:
[]
= "0.1.0"
🚀 Quick Start
Reading Excel Files (Streaming)
use ExcelReader;
Writing Excel Files (Streaming)
use ExcelWriter;
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)
- ✅ Excel formulas work correctly (SUM, AVERAGE, etc.)
- ✅ Better type safety
- ✅ 1-5% faster than string-based writing
High-Performance Writing (Fast Writer)
For maximum performance with large datasets (100K+ rows), use FastWorkbook:
use FastWorkbook;
Performance: Fast Writer achieves 40K rows/sec (1M rows in 24.8 seconds), 25% faster than standard writer for large datasets.
See Fast Writer Documentation for details.
Memory-Constrained Writing (For Kubernetes Pods)
For pods with limited memory (< 512MB), use auto memory configuration:
use create_workbook_auto;
Manual configuration for specific memory limits:
use FastWorkbook;
let mut workbook = new?;
// For pods < 512MB RAM - optimal configuration
workbook.set_flush_interval; // Flush every 1000 rows (best balance)
workbook.set_max_buffer_size; // 256KB buffer
workbook.add_worksheet?;
// ... write data ...
workbook.close?;
Kubernetes deployment:
env:
- name: MEMORY_LIMIT_MB
value: "512"
See Memory-Constrained Guide for details.
Writing with Typed Values
use ExcelWriter;
use CellValue;
Why use typed values?
- Numbers stored as numbers (not text)
- Excel formulas work correctly
- Better Excel compatibility
- 1-5% faster than string conversion
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
new(path)- Create new writerwrite_row(data)- Write row with stringswrite_row_typed(cells)- Write row with typed valueswrite_header(headers)- Write header with formattingadd_sheet(name)- Add new sheetset_column_width(col, width)- Set column widthsave()- Save workbook to file
FastWorkbook (High Performance)
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
Memory Helpers
create_workbook_auto(path)- Auto-detect memory config from envcreate_workbook_with_profile(path, profile)- Use specific memory profileMemoryProfile::Low- For pods < 512MBMemoryProfile::Medium- For pods 512MB-1GBMemoryProfile::High- For pods > 1GB
Types
CellValue- Enum for cell values: Empty, String, Int, Float, Bool, DateTime, ErrorRow- Struct representing a row with index and cellsCell- Struct for a 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
The library is designed for high performance with three writer options:
Writer Performance Comparison
Tested with 1 million rows × 30 columns (mixed data types):
| Writer Type | Time | Throughput | Use Case |
|---|---|---|---|
| ExcelWriter.write_row() | 31.08s | 32,177 rows/s | Simple string data |
| ExcelWriter.write_row_typed() | 30.63s | 32,649 rows/s | Recommended for most cases |
| FastWorkbook | 24.80s | 40,329 rows/s | Large datasets (100K+ rows) |
Performance at 100K rows:
write_row_typed(): +5% faster thanwrite_row()FastWorkbook: +44% faster than ExcelWriter methods
Key Insights:
- 🏆 FastWorkbook is 25-44% faster for large datasets
- ✅ write_row_typed() is recommended for most use cases (better Excel compatibility + 1-5% faster)
- 📊 write_row() is simplest for basic string data
Memory Usage
Standard vs Fast Writer (100K rows, 5 columns):
| Writer | Time | Speed | Memory |
|---|---|---|---|
| Standard | 491ms | 203K rows/s | ~300MB |
| Fast | 434ms | 230K rows/s | ~250MB |
| Improvement | -11.6% | +13.1% | -16.7% |
Fast Writer with different flush intervals (1M rows):
| Configuration | Time | Speed | Memory Peak |
|---|---|---|---|
| Default (1000 flush) | 9.9s | 101K rows/s | ~250MB |
| Balanced (500 flush) | 10.9s | 91K rows/s | ~150MB |
| Low memory (100 flush) | 10.5s | 95K rows/s | ~80MB |
Recommendation: Use 1000-row flush interval for best balance of speed and memory.
Features by Writer Type
| Feature | write_row() | write_row_typed() | FastWorkbook |
|---|---|---|---|
| Simple API | ✅ | ✅ | ✅ |
| Excel formulas work | ❌ | ✅ | ⚠️ Limited |
| Type safety | ❌ | ✅ | ❌ |
| Speed | Baseline | +1-5% | +25-44% |
| Memory efficient | ✅ | ✅ | ✅✅ |
| Good for large datasets | ✅ | ✅ | ✅✅✅ |
See Performance Documentation for more details.
📖 Documentation
- Quick Start Guide - Get started in 5 minutes
- Fast Writer Guide - High-performance writing
- Memory-Constrained Guide - For Kubernetes pods
- Optimization Summary - Performance details
- Contributing Guide - How to contribute
🛠️ Development
Build
Test
Run examples
Benchmark
📋 Requirements
- Rust 1.70 or higher
- Dependencies:
calamine- Reading Excel filesrust_xlsxwriter- Standard Excel writerzip- Custom fast writer ZIP handlingthiserror- Error handling
🚀 Production Ready
- ✅ Tested with 1M+ row datasets
- ✅ Memory-safe with Rust's ownership
- ✅ Works in Kubernetes pods with limited resources
- ✅ Comprehensive error handling
- ✅ Zero unsafe code
- ✅ Validated Excel output (readable by Excel/LibreOffice)
🤝 Contributing
Contributions welcome! Please feel free to submit a Pull Request.
📄 License
MIT License - see LICENSE file for details.
🙏 Credits
This library uses:
- calamine - Excel reader
- rust_xlsxwriter - Excel writer
📧 Contact
For questions or suggestions, please create an issue on GitHub.
Made with ❤️ and 🦀 by the Rust community