Class: Xlsxrb::Elements::Cell
- Inherits:
-
Object
- Object
- Xlsxrb::Elements::Cell
- Defined in:
- lib/xlsxrb/elements/cell.rb,
sig/generated/xlsxrb/elements/cell.rbs
Overview
Represents a single cell in a worksheet. All row and column indices are 0-based.
Instance Attribute Summary collapse
- #column_index ⇒ Object readonly
- #errors ⇒ Object readonly
- #formula ⇒ Object readonly
- #row_index ⇒ Object readonly
- #style_index ⇒ Object readonly
- #unmapped_data ⇒ Object readonly
- #value ⇒ Object readonly
Class Method Summary collapse
-
.column_index(letter) ⇒ Integer
Converts a column letter (e.g. "A", :AA) to a 0-based column index.
-
.column_letter(index) ⇒ String
Converts a 0-based column index to an Excel letter (0 -> "A", 25 -> "Z", 26 -> "AA").
- .fast_create(row_index, column_index, value, style_index = nil, formula = nil) ⇒ Object
-
.parse_ref(ref) ⇒ Array(Integer, Integer)?
Parses an Excel-style reference to [row_index, col_index] (both 0-based).
-
.validate(row_index, column_index, value) ⇒ Array<String>
Validates cell coordinates and value type against OOXML specifications.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#[](key) ⇒ Object?
Access cell attributes by Symbol key.
-
#content ⇒ Object?
Returns the cell value.
- #deconstruct ⇒ Object
- #deconstruct_keys(keys) ⇒ Object
- #hash ⇒ Object
-
#initialize(row_index:, column_index:, value: nil, formula: nil, style_index: nil, unmapped_data: EMPTY_HASH, errors: nil) ⇒ Cell
constructor
: (row_index: untyped, column_index: untyped, ?value: untyped, ?formula: (Elements::Formula | String)?, ?style_index: (Integer | String)?, ?unmapped_data: Hash[untyped, untyped], ?errors: Array?) -> void.
-
#ref ⇒ String
Returns the Excel-style reference (e.g. "A1", "B2").
-
#to_date ⇒ Date?
Converts the cell value (numeric serial date or date string) to Date.
-
#to_f ⇒ Float
Converts the cell value to Float.
-
#to_i ⇒ Integer
Converts the cell value to Integer.
-
#to_s ⇒ String
Returns the string representation of the cell value.
-
#to_time ⇒ Time?
Converts the cell value (numeric serial datetime or datetime string) to Time.
-
#valid? ⇒ Boolean
Returns whether the cell is valid according to OOXML specifications.
- #with(**changes) ⇒ Object
Constructor Details
#initialize(row_index:, column_index:, value: nil, formula: nil, style_index: nil, unmapped_data: EMPTY_HASH, errors: nil) ⇒ Cell
: (row_index: untyped, column_index: untyped, ?value: untyped, ?formula: (Elements::Formula | String)?, ?style_index: (Integer | String)?, ?unmapped_data: Hash[untyped, untyped], ?errors: Array?) -> void
29 30 31 32 33 34 35 36 37 38 |
# File 'lib/xlsxrb/elements/cell.rb', line 29 def initialize(row_index:, column_index:, value: nil, formula: nil, style_index: nil, unmapped_data: EMPTY_HASH, errors: nil) @row_index = row_index @column_index = column_index @value = value @formula = formula @style_index = style_index @unmapped_data = unmapped_data || EMPTY_HASH computed_errors = errors || self.class.validate(row_index, column_index, value) @errors = computed_errors.frozen? ? computed_errors : computed_errors.freeze end |
Instance Attribute Details
#column_index ⇒ Object (readonly)
19 20 21 |
# File 'lib/xlsxrb/elements/cell.rb', line 19 def column_index @column_index end |
#errors ⇒ Object (readonly)
19 20 21 |
# File 'lib/xlsxrb/elements/cell.rb', line 19 def errors @errors end |
#formula ⇒ Object (readonly)
19 20 21 |
# File 'lib/xlsxrb/elements/cell.rb', line 19 def formula @formula end |
#row_index ⇒ Object (readonly)
19 20 21 |
# File 'lib/xlsxrb/elements/cell.rb', line 19 def row_index @row_index end |
#style_index ⇒ Object (readonly)
19 20 21 |
# File 'lib/xlsxrb/elements/cell.rb', line 19 def style_index @style_index end |
#unmapped_data ⇒ Object (readonly)
19 20 21 |
# File 'lib/xlsxrb/elements/cell.rb', line 19 def unmapped_data @unmapped_data end |
#value ⇒ Object (readonly)
19 20 21 |
# File 'lib/xlsxrb/elements/cell.rb', line 19 def value @value end |
Class Method Details
.column_index(letter) ⇒ Integer
Converts a column letter (e.g. "A", :AA) to a 0-based column index.
: (String | Symbol | Integer letter) -> Integer
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/xlsxrb/elements/cell.rb', line 251 def self.column_index(letter) if letter.is_a?(Integer) raise ArgumentError, "Column index must be >= 0, got #{letter}" if letter.negative? return letter end str = letter.to_s if str.match?(/\A-?\d+\z/) val = str.to_i raise ArgumentError, "Column index must be >= 0, got #{val}" if val.negative? return val end raise ArgumentError, "Invalid column letter: #{letter.inspect}" unless str.match?(/\A[a-zA-Z]+\z/) str.upcase.chars.reduce(0) { |acc, c| (acc * 26) + (c.ord - "A".ord + 1) } - 1 end |
.column_letter(index) ⇒ String
Converts a 0-based column index to an Excel letter (0 -> "A", 25 -> "Z", 26 -> "AA").
: (untyped index) -> String
226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/xlsxrb/elements/cell.rb', line 226 def self.column_letter(index) raise ArgumentError, "Column index must be a non-negative Integer, got #{index.inspect}" unless index.is_a?(Integer) && index >= 0 @column_letters[index] || begin result = +"" i = index loop do result.prepend(("A".ord + (i % 26)).chr) i = (i / 26) - 1 break if i.negative? end result end end |
.fast_create(row_index, column_index, value, style_index = nil, formula = nil) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/xlsxrb/elements/cell.rb', line 40 def self.fast_create(row_index, column_index, value, style_index = nil, formula = nil) inst = allocate inst.instance_variable_set(:@row_index, row_index) inst.instance_variable_set(:@column_index, column_index) inst.instance_variable_set(:@value, value) inst.instance_variable_set(:@formula, formula) inst.instance_variable_set(:@style_index, style_index) inst.instance_variable_set(:@unmapped_data, EMPTY_HASH) inst.instance_variable_set(:@errors, EMPTY_ERRORS) inst end |
.parse_ref(ref) ⇒ Array(Integer, Integer)?
Parses an Excel-style reference to [row_index, col_index] (both 0-based).
: (String? ref) -> [Integer, Integer]?
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/xlsxrb/elements/cell.rb', line 281 def self.parse_ref(ref) return nil unless ref bytes = ref.b len = bytes.bytesize col = 0 i = 0 while i < len b = bytes.getbyte(i) if b.between?(65, 90) col = (col * 26) + (b - 64) i += 1 elsif b.between?(97, 122) col = (col * 26) + (b - 96) i += 1 else break end end return nil if i.zero? || i == len row = bytes.byteslice(i, len - i).to_i - 1 [row, col - 1] end |
.validate(row_index, column_index, value) ⇒ Array<String>
Validates cell coordinates and value type against OOXML specifications.
: (untyped row_index, untyped column_index, untyped value) -> Array
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/xlsxrb/elements/cell.rb', line 313 def self.validate(row_index, column_index, value) if row_index.is_a?(Integer) && row_index >= 0 && row_index < 1_048_576 && column_index.is_a?(Integer) && column_index >= 0 && column_index < 16_384 && (value.nil? || value.is_a?(String) || value.is_a?(Numeric) || value == true || value == false || value.is_a?(Date) || value.is_a?(Time) || value.is_a?(Formula) || (value.is_a?(Hash) && value.key?(:formula)) || value.is_a?(RichText) || value.is_a?(CellError)) return EMPTY_ERRORS end errs = [] errs << "row_index must be a non-negative Integer (got #{row_index.inspect})" if !row_index.is_a?(Integer) || row_index.negative? errs << "column_index must be a non-negative Integer (got #{column_index.inspect})" if !column_index.is_a?(Integer) || column_index.negative? errs << "row_index must be < 1048576 (got #{row_index}, max row is 1048575)" if row_index.is_a?(Integer) && row_index >= 1_048_576 errs << "column_index must be < 16384 (got #{column_index}, max column is XFD=16383)" if column_index.is_a?(Integer) && column_index >= 16_384 errs << "unsupported value type: #{value.class} (#{value.inspect}) — supported types: String, Numeric, true/false, Date, Time, or nil" unless value.nil? || value.is_a?(String) || value.is_a?(Numeric) || value == true || value == false || value.is_a?(Date) || value.is_a?(Time) errs end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/xlsxrb/elements/cell.rb', line 52 def ==(other) other.is_a?(Cell) && row_index == other.row_index && column_index == other.column_index && value == other.value && formula == other.formula && style_index == other.style_index && unmapped_data == other.unmapped_data && errors == other.errors end |
#[](key) ⇒ Object?
Access cell attributes by Symbol key.
: (Symbol key) -> untyped
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/xlsxrb/elements/cell.rb', line 113 def [](key) case key when :value then value when :formula formula.is_a?(Formula) ? formula.expression : formula when :style_index then style_index when :ref then ref when :column_index then column_index when :row_index then row_index when :type case value when String then "s" when true, false then "b" end end end |
#content ⇒ Object?
Returns the cell value.
: () -> untyped
135 136 137 |
# File 'lib/xlsxrb/elements/cell.rb', line 135 def content value end |
#deconstruct ⇒ Object
68 69 70 |
# File 'lib/xlsxrb/elements/cell.rb', line 68 def deconstruct [row_index, column_index, value, formula, style_index, unmapped_data, errors] end |
#deconstruct_keys(keys) ⇒ Object
72 73 74 75 76 |
# File 'lib/xlsxrb/elements/cell.rb', line 72 def deconstruct_keys(keys) h = { row_index: row_index, column_index: column_index, value: value, formula: formula, style_index: style_index, unmapped_data: unmapped_data, errors: errors } keys ? h.slice(*keys) : h end |
#hash ⇒ Object
64 65 66 |
# File 'lib/xlsxrb/elements/cell.rb', line 64 def hash [row_index, column_index, value, formula, style_index, unmapped_data, errors].hash end |
#ref ⇒ String
Returns the Excel-style reference (e.g. "A1", "B2").
: () -> String
103 104 105 |
# File 'lib/xlsxrb/elements/cell.rb', line 103 def ref "#{self.class.column_letter(column_index)}#{row_index + 1}" end |
#to_date ⇒ Date?
Converts the cell value (numeric serial date or date string) to Date.
: () -> Date?
171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/xlsxrb/elements/cell.rb', line 171 def to_date return value if value.is_a?(Date) if value.is_a?(Numeric) Ooxml::Utils.serial_to_date(value) else begin Date.parse(value.to_s) rescue StandardError nil end end end |
#to_f ⇒ Float
Converts the cell value to Float.
: () -> Float
162 163 164 |
# File 'lib/xlsxrb/elements/cell.rb', line 162 def to_f value.to_f end |
#to_i ⇒ Integer
Converts the cell value to Integer.
: () -> Integer
153 154 155 |
# File 'lib/xlsxrb/elements/cell.rb', line 153 def to_i value.to_i end |
#to_s ⇒ String
Returns the string representation of the cell value.
: () -> String
144 145 146 |
# File 'lib/xlsxrb/elements/cell.rb', line 144 def to_s value.to_s end |
#to_time ⇒ Time?
Converts the cell value (numeric serial datetime or datetime string) to Time.
: () -> Time?
190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/xlsxrb/elements/cell.rb', line 190 def to_time return value if value.is_a?(Time) if value.is_a?(Numeric) Ooxml::Utils.serial_to_datetime(value) else begin Time.parse(value.to_s) rescue StandardError nil end end end |
#valid? ⇒ Boolean
Returns whether the cell is valid according to OOXML specifications.
: () -> bool
94 95 96 |
# File 'lib/xlsxrb/elements/cell.rb', line 94 def valid? errors.empty? end |
#with(**changes) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/xlsxrb/elements/cell.rb', line 78 def with(**changes) self.class.new( row_index: changes.fetch(:row_index, row_index), column_index: changes.fetch(:column_index, column_index), value: changes.fetch(:value, value), formula: changes.fetch(:formula, formula), style_index: changes.fetch(:style_index, style_index), unmapped_data: changes.fetch(:unmapped_data, unmapped_data), errors: changes.fetch(:errors, errors) ) end |