Class: Xlsxrb::Elements::Worksheet
- Inherits:
-
Object
- Object
- Xlsxrb::Elements::Worksheet
- Defined in:
- lib/xlsxrb/elements/worksheet.rb,
sig/generated/xlsxrb/elements/worksheet.rbs
Overview
Represents a single fully parsed, in-memory worksheet in a workbook. Provides coordinate random access (sheet), row lookups (row_at), and immutable cell updates (update_cell).
Instance Attribute Summary collapse
- #charts ⇒ Object readonly
- #columns ⇒ Object readonly
- #errors ⇒ Object readonly
- #name ⇒ Object readonly
- #rows ⇒ Object readonly
- #unmapped_data ⇒ Object readonly
Class Method Summary collapse
-
.validate(name, rows) ⇒ Array<String>
Validates worksheet name and rows against OOXML limits.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
(also: #eql?)
Compare worksheets for equality.
-
#deconstruct_keys(_keys) ⇒ Hash[Symbol, untyped]
Support pattern matching.
-
#each {|row| ... } ⇒ Enumerator, void
Iterate over rows in the worksheet.
-
#each_cell {|cell| ... } ⇒ Enumerator, void
Iterate over all cells across rows.
-
#each_row {|row| ... } ⇒ Enumerator, void
Iterate over rows in the worksheet.
-
#hash ⇒ Integer
: () -> Integer.
- #initialize(name:, rows: [], columns: [], charts: [], unmapped_data: {}, errors: nil) ⇒ Worksheet constructor
-
#load ⇒ Elements::Worksheet
(also: #to_worksheet)
Returns self when load is called on an already in-memory Worksheet.
-
#update_cell(ref, value: nil, style_index: nil, formula: nil) ⇒ Worksheet
Returns a new Worksheet with the specified cell updated.
-
#valid? ⇒ Boolean
Returns whether the worksheet is valid according to OOXML specifications.
-
#with(**changes) ⇒ Worksheet
Returns a new Worksheet with attributes replaced (Data-like behavior).
Constructor Details
#initialize(name:, rows: [], columns: [], charts: [], unmapped_data: {}, errors: nil) ⇒ Worksheet
29 30 31 32 33 34 35 36 37 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 29 def initialize(name:, rows: [], columns: [], charts: [], unmapped_data: {}, errors: nil) @name = name @rows = (rows || []).freeze @columns = (columns || []).freeze @charts = (charts || []).freeze @unmapped_data = (unmapped_data || {}).freeze computed_errors = errors || self.class.validate(@name, @rows) @errors = computed_errors.freeze end |
Instance Attribute Details
#charts ⇒ Object (readonly)
20 21 22 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 20 def charts @charts end |
#columns ⇒ Object (readonly)
20 21 22 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 20 def columns @columns end |
#errors ⇒ Object (readonly)
20 21 22 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 20 def errors @errors end |
#name ⇒ Object (readonly)
20 21 22 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 20 def name @name end |
#rows ⇒ Object (readonly)
20 21 22 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 20 def rows @rows end |
#unmapped_data ⇒ Object (readonly)
20 21 22 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 20 def unmapped_data @unmapped_data end |
Class Method Details
.validate(name, rows) ⇒ Array<String>
Validates worksheet name and rows against OOXML limits.
: (untyped name, untyped rows) -> Array
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 206 def self.validate(name, rows) errs = [] if name.nil? || !name.is_a?(String) || name.empty? errs << "worksheet name must be a non-empty String (got #{name.inspect})" else errs << "worksheet name cannot exceed 31 characters (got #{name.size})" if name.size > 31 errs << "worksheet name cannot contain \\, /, ?, *, [, or ]" if name.match?(%r{[\\/?*\[\]]}) end errs << "rows must be an Array (got #{rows.class})" unless rows.is_a?(Array) if rows.is_a?(Array) indices = rows.map(&:index) if indices.uniq.size != indices.size dups = indices.select { |i| indices.count(i) > 1 }.uniq errs << "duplicate row index: #{dups.join(", ")} — row indices within a sheet must be unique" end end errs end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
Compare worksheets for equality. : (untyped other) -> bool
178 179 180 181 182 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 178 def ==(other) return false unless other.is_a?(Worksheet) name == other.name && rows == other.rows && columns == other.columns && charts == other.charts end |
#deconstruct_keys(_keys) ⇒ Hash[Symbol, untyped]
Support pattern matching. : (Array?) -> Hash[Symbol, untyped]
172 173 174 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 172 def deconstruct_keys(_keys) { name: name, rows: rows, columns: columns, charts: charts, unmapped_data: unmapped_data, errors: errors } end |
#each {|row| ... } ⇒ Enumerator, void
Iterate over rows in the worksheet.
: () { (Elements::Row) -> void } -> void : | () -> Enumerator[Elements::Row, void]
52 53 54 55 56 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 52 def each(&) return to_enum(:each) unless block_given? rows.each(&) end |
#each_cell {|cell| ... } ⇒ Enumerator, void
Iterate over all cells across rows.
: () { (Elements::Cell) -> void } -> void : | () -> Enumerator[Elements::Cell, void]
85 86 87 88 89 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 85 def each_cell(&) return to_enum(:each_cell) unless block_given? cells.each(&) end |
#each_row {|row| ... } ⇒ Enumerator, void
Iterate over rows in the worksheet.
: () { (Elements::Row) -> void } -> void : | () -> Enumerator[Elements::Row, void]
71 72 73 74 75 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 71 def each_row(&) return to_enum(:each_row) unless block_given? rows.each(&) end |
#hash ⇒ Integer
: () -> Integer
186 187 188 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 186 def hash [self.class, name, rows, columns, charts].hash end |
#load ⇒ Elements::Worksheet Also known as: to_worksheet
Returns self when load is called on an already in-memory Worksheet.
: () -> Elements::Worksheet
195 196 197 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 195 def load self end |
#update_cell(ref, value: nil, style_index: nil, formula: nil) ⇒ Worksheet
Returns a new Worksheet with the specified cell updated.
: (String ref, ?value: untyped, ?style_index: Integer | String | nil, ?formula: Elements::Formula?) -> Elements::Worksheet
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 111 def update_cell(ref, value: nil, style_index: nil, formula: nil) parsed = Cell.parse_ref(ref) raise ArgumentError, "invalid cell reference: #{ref}" unless parsed row_idx, col_idx = parsed existing_row = row_at(row_idx) if existing_row existing_cell = existing_row.cell_at(col_idx) new_cell = if existing_cell existing_cell.with( value: value || existing_cell.value, style_index: style_index || existing_cell.style_index, formula: formula || existing_cell.formula ) else Cell.new(row_index: row_idx, column_index: col_idx, value: value, style_index: style_index, formula: formula) end # Replace cell in the existing row new_cells = existing_row.cells.reject { |c| c.column_index == col_idx } new_cells << new_cell new_cells.sort_by!(&:column_index) new_row = existing_row.with(cells: new_cells) new_rows = rows.map { |r| r.index == row_idx ? new_row : r } else # Row doesn't exist, create it new_cell = Cell.new(row_index: row_idx, column_index: col_idx, value: value, style_index: style_index, formula: formula) new_row = Row.new(index: row_idx, cells: [new_cell]) new_rows = (rows + [new_row]).sort_by!(&:index) end with(rows: new_rows) end |
#valid? ⇒ Boolean
Returns whether the worksheet is valid according to OOXML specifications.
: () -> bool
95 96 97 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 95 def valid? errors.empty? end |
#with(**changes) ⇒ Worksheet
Returns a new Worksheet with attributes replaced (Data-like behavior).
: (**untyped) -> Elements::Worksheet
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 152 def with(**changes) new_name = changes.key?(:name) ? changes[:name] : name new_rows = changes.key?(:rows) ? changes[:rows] : rows new_cols = changes.key?(:columns) ? changes[:columns] : columns new_charts = changes.key?(:charts) ? changes[:charts] : charts new_unmapped = changes.key?(:unmapped_data) ? changes[:unmapped_data] : unmapped_data new_errors = changes.key?(:errors) ? changes[:errors] : errors self.class.new( name: new_name, rows: new_rows, columns: new_cols, charts: new_charts, unmapped_data: new_unmapped, errors: new_errors ) end |