Class: Xlsxrb::Elements::Worksheet
- Inherits:
-
Data
- Object
- Data
- Xlsxrb::Elements::Worksheet
- Includes:
- Enumerable
- Defined in:
- lib/xlsxrb/elements/worksheet.rb
Overview
Represents a single worksheet in a workbook.
Instance Attribute Summary collapse
-
#charts ⇒ Object
readonly
Returns the value of attribute charts.
-
#columns ⇒ Object
readonly
Returns the value of attribute columns.
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#rows ⇒ Object
readonly
Returns the value of attribute rows.
-
#unmapped_data ⇒ Object
readonly
Returns the value of attribute unmapped_data.
Class Method Summary collapse
Instance Method Summary collapse
- #[](ref) ⇒ Object
-
#cell_value(ref) ⇒ Object
Returns cell value at Excel-style reference (e.g. "A1").
- #cells ⇒ Object
- #cells_hash ⇒ Object
- #each ⇒ Object
- #each_cell ⇒ Object
- #each_row ⇒ Object
- #first_row ⇒ Object
-
#initialize(name:, rows: [], columns: [], charts: [], unmapped_data: {}, errors: nil) ⇒ Worksheet
constructor
A new instance of Worksheet.
- #last_row ⇒ Object
-
#row_at(index) ⇒ Object
Returns the row at the given 0-based index, or nil.
-
#update_cell(ref, value: nil, style_index: nil, formula: nil) ⇒ Worksheet
Returns a new Worksheet with the specified cell updated.
- #valid? ⇒ Boolean
Constructor Details
#initialize(name:, rows: [], columns: [], charts: [], unmapped_data: {}, errors: nil) ⇒ Worksheet
Returns a new instance of Worksheet.
11 12 13 14 15 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 11 def initialize(name:, rows: [], columns: [], charts: [], unmapped_data: {}, errors: nil) computed_errors = errors || self.class.validate(name, rows) super(name: name, rows: rows.freeze, columns: columns.freeze, charts: charts.freeze, unmapped_data: unmapped_data, errors: computed_errors.freeze) end |
Instance Attribute Details
#charts ⇒ Object (readonly)
Returns the value of attribute charts
8 9 10 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 8 def charts @charts end |
#columns ⇒ Object (readonly)
Returns the value of attribute columns
8 9 10 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 8 def columns @columns end |
#errors ⇒ Object (readonly)
Returns the value of attribute errors
8 9 10 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 8 def errors @errors end |
#name ⇒ Object (readonly)
Returns the value of attribute name
8 9 10 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 8 def name @name end |
#rows ⇒ Object (readonly)
Returns the value of attribute rows
8 9 10 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 8 def rows @rows end |
#unmapped_data ⇒ Object (readonly)
Returns the value of attribute unmapped_data
8 9 10 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 8 def unmapped_data @unmapped_data end |
Class Method Details
.validate(name, rows) ⇒ Object
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 127 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
#[](ref) ⇒ Object
33 34 35 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 33 def [](ref) cells_hash[ref.to_s.upcase] end |
#cell_value(ref) ⇒ Object
Returns cell value at Excel-style reference (e.g. "A1").
73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 73 def cell_value(ref) parsed = Cell.parse_ref(ref) return nil unless parsed row_idx, col_idx = parsed row = row_at(row_idx) return nil unless row cell = row.cell_at(col_idx) cell&.value end |
#cells ⇒ Object
28 29 30 31 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 28 def cells # Ensure ordered traversal cells_hash.values.sort_by { |c| [c.row_index, c.column_index] } end |
#cells_hash ⇒ Object
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 17 def cells_hash h = {} rows.each do |r| r.cells.each do |c| ref = "#{Cell.column_letter(c.column_index)}#{c.row_index + 1}" h[ref] = c end end h end |
#each ⇒ Object
37 38 39 40 41 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 37 def each(&) return to_enum(:each) unless block_given? cells.each(&) end |
#each_cell ⇒ Object
43 44 45 46 47 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 43 def each_cell(&) return to_enum(:each_cell) unless block_given? cells.each(&) end |
#each_row ⇒ Object
49 50 51 52 53 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 49 def each_row(&) return to_enum(:each_row) unless block_given? rows.each(&) end |
#first_row ⇒ Object
64 65 66 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 64 def first_row rows.min_by(&:index) end |
#last_row ⇒ Object
68 69 70 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 68 def last_row rows.max_by(&:index) end |
#row_at(index) ⇒ Object
Returns the row at the given 0-based index, or nil.
60 61 62 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 60 def row_at(index) rows.find { |r| r.index == index } end |
#update_cell(ref, value: nil, style_index: nil, formula: nil) ⇒ Worksheet
Returns a new Worksheet with the specified cell updated.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 92 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
55 56 57 |
# File 'lib/xlsxrb/elements/worksheet.rb', line 55 def valid? errors.empty? end |