Module: Rbxl

Defined in:
lib/rbxl.rb,
lib/rbxl/row.rb,
lib/rbxl/cell.rb,
lib/rbxl/errors.rb,
lib/rbxl/version.rb,
lib/rbxl/empty_cell.rb,
lib/rbxl/read_only_cell.rb,
lib/rbxl/write_only_cell.rb,
lib/rbxl/read_only_workbook.rb,
lib/rbxl/read_only_worksheet.rb,
lib/rbxl/write_only_workbook.rb,
lib/rbxl/write_only_worksheet.rb,
ext/rbxl_native/native.c

Overview

Minimal, memory-friendly XLSX reader/writer inspired by openpyxl.

Rbxl exposes two explicit, non-overlapping modes:

The API is intentionally narrow so that memory usage stays predictable for large workbooks. Neither mode materializes the full workbook in memory; reads pull rows from the underlying XML one at a time, and writes accumulate only the rows added before WriteOnlyWorkbook#save.

Reading

require "rbxl"

book = Rbxl.open("report.xlsx")
sheet = book.sheet("Report")
sheet.each_row(values_only: true) { |values| p values }
book.close

Pass date_conversion: true to return Date/Time objects for numeric cells that carry a date numFmt style.

Writing

require "rbxl"

book  = Rbxl.new
sheet = book.add_sheet("Report")
sheet << ["id", "name", "score"]
sheet << [1, "alice", 100]
book.save("report.xlsx")

Native extension

Requiring "rbxl/native" after "rbxl" swaps the hot worksheet XML paths for a libxml2-backed C implementation with the same observable behavior. See the README for build requirements.

Defined Under Namespace

Modules: Native Classes: Cell, ClosedWorkbookError, EmptyCell, Error, ReadOnlyCell, ReadOnlyWorkbook, ReadOnlyWorksheet, Row, SharedStringsTooLargeError, SheetNotFoundError, UnsizedWorksheetError, WorkbookAlreadySavedError, WorksheetTooLargeError, WriteOnlyCell, WriteOnlyWorkbook, WriteOnlyWorksheet

Constant Summary collapse

VERSION =

Gem version string, tracked with semantic versioning.

"1.1.0"

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.max_shared_string_bytesInteger?

Returns configured shared-strings byte cap.

Returns:

  • (Integer, nil)

    configured shared-strings byte cap



84
85
86
# File 'lib/rbxl.rb', line 84

def max_shared_string_bytes
  @max_shared_string_bytes
end

.max_shared_stringsInteger?

Returns configured shared-strings count cap.

Returns:

  • (Integer, nil)

    configured shared-strings count cap



81
82
83
# File 'lib/rbxl.rb', line 81

def max_shared_strings
  @max_shared_strings
end

.max_worksheet_bytesInteger?

Returns per-worksheet streaming byte cap.

Returns:

  • (Integer, nil)

    per-worksheet streaming byte cap



87
88
89
# File 'lib/rbxl.rb', line 87

def max_worksheet_bytes
  @max_worksheet_bytes
end

Instance Attribute Details

#coordinateString (readonly)

Returns Excel-style coordinate such as “A1”.

Returns:

  • (String)

    Excel-style coordinate such as “A1”



12
# File 'lib/rbxl/read_only_cell.rb', line 12

ReadOnlyCell = Data.define(:coordinate, :value)

#valueObject? (readonly)

Returns decoded Ruby value (String, Numeric, Boolean, or nil).

Returns:

  • (Object, nil)

    decoded Ruby value (String, Numeric, Boolean, or nil)



12
# File 'lib/rbxl/read_only_cell.rb', line 12

ReadOnlyCell = Data.define(:coordinate, :value)

Class Method Details

.new(write_only: true) ⇒ Rbxl::WriteOnlyWorkbook

Creates a new workbook in write-only mode.

The write_only keyword defaults to true and exists to mark the save-once, append-only contract explicitly. Passing write_only: false raises NotImplementedError.

Parameters:

  • write_only (Boolean) (defaults to: true)

    retained for call-site clarity; must be true

Returns:

Raises:

  • (NotImplementedError)

    if write_only is not true



137
138
139
140
141
# File 'lib/rbxl.rb', line 137

def new(write_only: true)
  raise NotImplementedError, "read/write mode is not supported; pass write_only: true" unless write_only

  WriteOnlyWorkbook.new
end

.open(path, read_only: true, streaming: false, date_conversion: false) ⇒ Rbxl::ReadOnlyWorkbook

Opens an existing workbook in read-only row-by-row mode.

The read_only keyword defaults to true and exists to mark the intent explicitly at the call site. Passing read_only: false raises NotImplementedError; a read/write mode is not available.

With streaming: true, the native backend (when loaded) feeds worksheet XML to the parser in chunks pulled from the ZIP input stream instead of materializing the entire worksheet as one Ruby string. This keeps peak memory roughly independent of worksheet size and lets max_worksheet_bytes bound how much is inflated. Streaming mode is the same API and output shape — only the inflation strategy differs — and typically pays back a few percent of throughput on small sheets in exchange for the flat memory profile.

With date_conversion: true, numeric cells whose style points at a date/time numFmt (built-in ids 14–22, 27–36, 45–47, 50–58, or any custom format code containing a date/time token) are returned as Date, Time, or DateTime instead of a raw serial Float. The flag is off by default to preserve byte-for-byte behavior and skip the styles.xml parse for workbooks that don’t need it; enabling it disables the native fast path and routes reads through the Ruby worksheet parser.

Parameters:

  • path (String, #to_path)

    filesystem path to an .xlsx file

  • read_only (Boolean) (defaults to: true)

    retained for call-site clarity; must be true

  • streaming (Boolean) (defaults to: false)

    feed worksheet XML to the native parser in chunks instead of fully inflating the entry in advance. Ignored when the native extension is not loaded.

  • date_conversion (Boolean) (defaults to: false)

    convert numeric cells backed by a date/time numFmt to Date / Time / DateTime

Returns:

Raises:

  • (NotImplementedError)

    if read_only is not true



122
123
124
125
126
# File 'lib/rbxl.rb', line 122

def open(path, read_only: true, streaming: false, date_conversion: false)
  raise NotImplementedError, "read/write mode is not supported; pass read_only: true" unless read_only

  ReadOnlyWorkbook.open(path, streaming: streaming, date_conversion: date_conversion)
end