Ruby XLSX Ecosystem & Peer Libraries

The Ruby ecosystem is fortunate to have a rich set of mature, well-engineered XLSX libraries. Each library represents deliberate architectural choices tailored for specific problem spaces.

This document provides a respectful overview of the peer libraries in the Ruby ecosystem, explains the underlying engineering tradeoffs (such as Streaming vs. In-Memory and Shared String Tables vs. Inline Strings), and shares comprehensive benchmark measurements.


The Peer Libraries

Library I/O Official Self-Description / Focus Best Fit (In Our View)
roo R β€œRoo can access the contents of various spreadsheet files (Excelx, LibreOffice, OpenOffice, CSV).” Unified interface for reading across diverse spreadsheet formats.
creek R β€œA Ruby gem that streams and parses large Excel (xlsx and xlsm) files fast and efficiently.” Streaming large spreadsheet uploads row-by-row with lightweight SAX parsing.
xsv R β€œA fast and lightweight xlsx parser that provides nothing a CSV parser wouldn’t.” High-speed, CSV-like tabular data ingestion without styling overhead.
simple_xlsx_reader R β€œRead xlsx data the Ruby way” β€” parses sheets into Ruby primitives with low memory. Memory-conscious tabular data extraction directly into Ruby types.
caxlsx / axlsx W β€œExcel OOXML (xlsx) with charts, styles, images and autowidth columns” with full schema validation. Generating rich, styled business reports with charts, images, and visual design.
write_xlsx W Pure Ruby port of Perl’s Excel::Writer::XLSX to create files in modern Excel 2007+ format. Creating complex spreadsheets requiring exact Excel feature parity.
xlsxtream W β€œA streaming XLSX spreadsheet writer” allowing very efficient writing of CSV-style data. Ultra-fast, low-memory streaming exports of massive tabular datasets.
fast_excel W β€œUltra Fast Excel Writer” β€” C-extension wrapper for libxlsxwriter with constant memory mode. Maximum-throughput spreadsheet generation when C-extensions are available.
rubyXL RW β€œAllows the parsing, creation, and manipulation of Microsoft Excel (.xlsx/.xlsm) Documents.” Full document DOM inspection, in-memory cell modification, and template editing.
xlsxrb RW Pure Ruby library unifying streaming read/write ($O(1)$ memory) and in-memory manipulation with native encryption. Unified reading, writing, template modification, and password encryption in pure Ruby.

Architectural Tradeoffs

Spreadsheet libraries must balance multiple competing dimensions: memory consumption, execution speed, formatting capabilities, and strict specification compliance.

1. Memory & Execution Model: Streaming vs. In-Memory

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Execution Models                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚       Streaming Model        β”‚       In-Memory Model        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ Processes rows on-the-fly  β”‚ β€’ Builds complete DOM tree   β”‚
β”‚ β€’ O(1) constant RAM footprintβ”‚ β€’ Enables random cell access β”‚
β”‚ β€’ Cannot seek backward       β”‚ β€’ High RAM on large datasets β”‚
β”‚ β€’ Ideal for batch exports/ETLβ”‚ β€’ Ideal for templates/edits  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. String Storage Architecture: Shared String Table (SST) vs. Inline Strings

The OpenXML (ECMA-376) specification defines two ways to store text in cells:

<!-- 1. Shared String Table (SST): Deduplicated dictionary reference -->
<c r="A1" t="s"><v>0</v></c>

<!-- 2. Inline String: Raw text payload inside the cell -->
<c r="A1" t="inlineStr"><is><t>Hello World</t></is></c>

Shared String Table (SST)

Inline Strings


Detailed Benchmark Results

The following benchmarks evaluate processing 1,000,000 cells (100,000 rows Γ— 10 columns) containing standard business data (integers, strings, floats, booleans, and dates) across 3 isolated subprocess runs.

Write Performance (1,000,000 cells)

Library Version Model String Storage Time (Median) Time (Mean) Peak Memory GC Count
xlsxrb (Streaming) - Streaming SST (Shared) 0.95 s 0.95 s 67.6 MB 34.0
xlsxtream 3.1.0 Streaming Inline String 1.16 s 1.17 s 17.0 MB 323.0
fast_excel 0.5.0 Streaming SST (Shared) 2.02 s 2.14 s 148.3 MB 210.0
xlsxrb (In-Memory) - In-Memory SST (Shared) 2.42 s 2.57 s 209.0 MB 16.0
write_xlsx 1.15.0 In-Memory SST (Shared) 4.39 s 4.42 s 217.4 MB 25.0
caxlsx 4.5.0 In-Memory Inline String 5.28 s 5.28 s 177.4 MB 24.0
rubyXL 3.4.38 In-Memory Inline String 43.13 s 43.65 s 2167.2 MB 101.0

Read Performance (1,000,000 cells)

Library Version Model Time (Median) Time (Mean) Peak Memory GC Count
xlsxrb (Streaming) - Streaming 1.73 s 1.72 s 136.2 MB 45.0
xlsxrb (In-Memory) - In-Memory 4.33 s 4.46 s 304.3 MB 77.0
simple_xlsx_reader 5.1.0 Streaming 4.38 s 4.41 s 32.8 MB 918.0
creek 2.6.3 Streaming 7.12 s 7.05 s 840.1 MB 419.0
roo 3.0.0 Streaming 10.95 s 10.33 s 123.4 MB 196.0
xsv 1.4.1 Streaming 14.56 s 14.59 s 73.6 MB 2028.0
rubyXL 3.4.38 In-Memory 30.74 s 30.78 s 2289.6 MB 146.0

Reproducing Benchmarks Locally

The benchmark suite leverages bundler/inline to run each library in an isolated subprocess (Bundler.with_unbundled_env), eliminating cross-gem pollution and ensuring accurate memory measurements.

To run the suite on your machine:

ruby benchmark.rb 100000 10