IronCalc Ruby
Ruby bindings for IronCalc, a modern spreadsheet engine written in Rust. Create, read and manipulate xlsx files — manage sheets, set and read cell values, and evaluate formulas.
Built with magnus / rb-sys, and modeled on the IronCalc Python bindings.
Installation
Add this line to your application's Gemfile:
gem "ironcalc"
A Rust toolchain is required to build from source.
Usage
require "ironcalc"
# Raw API — call evaluate yourself.
model = IronCalc.create("model", "en", "UTC", "en")
model.set_user_input(0, 1, 1, "=21*2")
model.evaluate
model.get_formatted_cell_value(0, 1, 1) # => "42"
model.save_to_xlsx("out.xlsx")
# User API — auto-evaluates and tracks diffs for collaboration.
um = IronCalc.create_user_model("model", "en", "UTC", "en")
um.set_user_input(0, 1, 1, "=1+2")
um.get_formatted_cell_value(0, 1, 1) # => "3"
diffs = um.flush_send_queue # binary diff to send to peers
Coordinates: sheet is a 0-based index; row and column are 1-based. Styles
are exchanged as plain Ruby hashes via get_cell_style / set_cell_style.
Top-level methods
create, load_from_xlsx, load_from_icalc, load_from_bytes,
create_user_model, create_user_model_from_xlsx,
create_user_model_from_icalc, create_user_model_from_bytes.
Errors raised by the engine surface as IronCalc::Error.
Relationship to the Python bindings
ironcalc-ruby is a thin binding over the same Rust engine as the
IronCalc Python bindings,
and deliberately mirrors their API. Both are compiled native extensions (Python
via pyo3, Ruby via magnus / rb-sys) exposing a module named
ironcalc backed by the IronCalc engine.
What's identical
- Two APIs: a raw
Model(you callevaluateyourself) and a higher-levelUserModel(auto-evaluates and tracks diffs). - Top-level constructors, same names and argument order
(name_or_path, locale, tz, language_id):create,load_from_xlsx,load_from_icalc,load_from_bytes,create_user_model,create_user_model_from_xlsx,create_user_model_from_icalc,create_user_model_from_bytes. - Method names and signatures on
Model/UserModel—set_user_input,get_formatted_cell_value,evaluate,insert_rows,set_column_width,add_sheet,save_to_xlsx,to_bytes, … (Python'ssnake_caseis also Ruby's convention, so they match exactly). - Coordinates:
sheetis a 0-based index;rowandcolumnare 1-based. - Semantics: the same engine, so the same inputs produce the same results.
# Python
import ironcalc as ic
model = ic.create("model", "en", "UTC", "en")
model.set_user_input(0, 1, 1, "=21*2")
model.evaluate()
model.get_formatted_cell_value(0, 1, 1) # "42"
# Ruby
require "ironcalc"
model = IronCalc.create("model", "en", "UTC", "en")
model.set_user_input(0, 1, 1, "=21*2")
model.evaluate
model.get_formatted_cell_value(0, 1, 1) # "42"
Idiomatic Ruby adaptations
A few return and argument types follow Ruby conventions instead of being literal ports:
| Concern | Python | Ruby |
|---|---|---|
| Module access | ic.create(...) |
IronCalc.create(...) |
| Error type | WorkbookError |
IronCalc::Error |
| Cell style | typed Style / Font / … objects |
plain Hash (get_cell_style / set_cell_style) |
| Cell type | CellType enum |
Symbol (:number, :text, …) |
| Worksheet properties | list of SheetProperty objects |
array of Hashes (:name, :state, :sheet_id, :color) |
| Sheet dimensions | tuple (min_row, max_row, min_col, max_col) |
4-element Array |
| Binary blobs | bytes |
binary String |
| Version | ironcalc.__version__ |
IronCalc::VERSION |
Rather than reconstruct Python's per-field style classes, Ruby exchanges styles as plain hashes (serialized as JSON across the boundary). Everything else is kept as close to the Python bindings as the two languages allow.
Development
bundle install
bundle exec rake compile
bundle exec rake test
License
Dual-licensed under MIT or Apache-2.0, matching IronCalc.