class Xlsxrb::Elements::Cell
Represents a single cell in a worksheet. All row and column indices are 0-based.
@example Access cell properties
cell = sheet["A1"] cell.value # raw value cell.ref # "A1" cell.to_i # integer value cell.to_date # Date value
@api public
Attributes
untyped
untyped
untyped
untyped
untyped
untyped
untyped
untyped
untyped
untyped
untyped
untyped
Public Class Methods
(String letter) → Integer
Source
# File lib/xlsxrb/elements/cell.rb, line 433 def self.calculate_column_index(letter) letter.bytes.reduce(0) { |acc, b| (acc * 26) + (b - 64) } - 1 end
Pure calculation: converts an uppercase column letter string to a 0-based index.
@param letter [String] Uppercase column letter string (e.g. โAโ, โAAโ). @return [Integer] 0-based column index.
(Integer index) → String
Source
# File lib/xlsxrb/elements/cell.rb, line 398 def self.calculate_column_letter(index) result = +"" i = index loop do result.prepend(("A".ord + (i % 26)).chr) i = (i / 26) - 1 break if i.negative? end result end
Pure calculation: converts a 0-based column index to an Excel letter.
@param index [Integer] 0-based column index. @return [String] Excel column letter.
(String | Symbol | Integer letter) → Integer
Source
# File lib/xlsxrb/elements/cell.rb, line 447 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/) calculate_column_index(str.upcase) end
Converts a column letter (e.g. โAโ, :AA) to a 0-based column index.
@example
Cell.column_index("A") #=> 0 Cell.column_index(:AA) #=> 26
@param letter [String, Symbol, Integer] Column letter or integer index. @return [Integer] 0-based column index. @api public
(untyped index) → String
Source
# File lib/xlsxrb/elements/cell.rb, line 422 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] || calculate_column_letter(index) end
Converts a 0-based column index to an Excel letter (0 -> โAโ, 25 -> โZโ, 26 -> โAAโ).
@example
Cell.column_letter(0) #=> "A" Cell.column_letter(26) #=> "AA"
@param index [Integer] 0-based column index. @return [String] Excel column letter. @api public
(untyped row_index, untyped column_index, untyped value, ?untyped style_index, ?untyped formula, ?untyped raw_value, ?untyped format_code, ?untyped date1904) → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 51 def self.fast_create(row_index, column_index, value, style_index = nil, formula = nil, raw_value = nil, format_code = nil, date1904 = false) 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.instance_variable_set(:@hyperlink, nil) inst.instance_variable_set(:@comment, nil) inst.instance_variable_set(:@raw_value, raw_value) inst.instance_variable_set(:@format_code, format_code) inst.instance_variable_set(:@date1904, date1904 ? true : false) inst end
rubocop:disable Style/OptionalBooleanParameter
(row_index: untyped, column_index: untyped, ?value: untyped, ?formula: (Elements::Formula | String)?, ?style_index: (Integer | String)?, ?unmapped_data: Hash[untyped, untyped], ?errors: Array[String]?, ?hyperlink: (Hash[Symbol, untyped] | String | Elements::Hyperlink)?, ?comment: (Hash[Symbol, untyped] | String)?, ?raw_value: String?, ?format_code: String?, ?date1904: bool) → void
Source
# File lib/xlsxrb/elements/cell.rb, line 34 def initialize(row_index:, column_index:, value: nil, formula: nil, style_index: nil, unmapped_data: EMPTY_HASH, errors: nil, hyperlink: nil, comment: nil, raw_value: nil, format_code: nil, date1904: false) @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 @hyperlink = hyperlink @comment = comment @raw_value = raw_value @format_code = format_code @date1904 = date1904 ? true : false end
@param row_index [Integer] 0-based row index. @param column_index [Integer] 0-based column index. @param value [Object, nil] The cellโs value. @param formula [Elements::Formula, nil] Optional formula. @param style_index [Integer, String, nil] Style identifier. @param unmapped_data [Hash] Additional metadata. @param errors [Array<String>, nil] Validation errors. @param hyperlink [Hash, String, Elements::Hyperlink, nil] Optional hyperlink metadata or URL. @param comment [Hash, String, nil] Optional cell comment or note. @param raw_value [String, nil] Optional unparsed raw string value. @param format_code [String, nil] Optional OpenXML number/date format code. @param date1904 [Boolean] Whether the cell belongs to a 1904 date system workbook.
(String? ref) → [Integer, Integer]?
Source
# File lib/xlsxrb/elements/cell.rb, line 477 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_part = bytes.byteslice(i, len - i) return nil unless row_part.match?(/\A[1-9]\d*\z/) row = row_part.to_i - 1 [row, col - 1] end
Parses an Excel-style reference to [row_index, col_index] (both 0-based).
@example
Cell.parse_ref("A1") #=> [0, 0] Cell.parse_ref("C10") #=> [9, 2]
@param ref [String, nil] Excel cell reference. @return [Array(Integer, Integer), nil] 0-based [row_index, col_index]. @api public
(untyped row_index, untyped column_index) → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 511 def self.valid_coordinates?(row_index, column_index) row_index.instance_of?(Integer) && row_index >= 0 && row_index < 1_048_576 && column_index.instance_of?(Integer) && column_index >= 0 && column_index < 16_384 end
Returns whether the coordinates are within OOXML limits (row: 0..1,048,575, col: 0..16,383).
@param row_index [Integer] 0-based row index. @param column_index [Integer] 0-based column index. @return [Boolean]
(untyped value) → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 521 def self.valid_value?(value) case value when nil, String, Numeric, true, false, Date, Time, Formula, RichText, CellError true when Hash value.key?(:formula) else false end end
Returns whether the value type is supported by OOXML specifications.
@param value [Object] @return [Boolean]
(untyped row_index, untyped column_index, untyped value) → Array[String]
Source
# File lib/xlsxrb/elements/cell.rb, line 539 def self.validate(row_index, column_index, value) valid_val = valid_value?(value) return EMPTY_ERRORS if valid_coordinates?(row_index, column_index) && valid_val 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, Formula, RichText, CellError, or nil" unless valid_val errs end
Validates cell coordinates and value type against OOXML specifications.
@param row_index [Integer] @param column_index [Integer] @param value [Object] @return [Array<String>] List of errors.
Public Instance Methods
(untyped other) → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 69 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 && hyperlink == other.hyperlink && comment == other.comment && raw_value == other.raw_value && format_code == other.format_code end
rubocop:enable Style/OptionalBooleanParameter
(Symbol key) → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 251 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 :hyperlink then hyperlink when :url then url when :tooltip then tooltip when :comment then comment when :raw_value then raw_value when :format_code then format_code when :formatted_value then formatted_value when :format_type then format_type when :date_format then date_format? when :time_format then time_format? when :date1904 then date1904? when :type case value when String then "s" when true, false then "b" end end end
Access cell attributes by Symbol key.
@param key [Symbol] Attribute key (:value, :formula, :style_index, :ref, :column_index, :row_index, :type, :raw_value, :format_code, :formatted_value). @return [Object, nil] @api public
() → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 210 def comment? case comment when nil then false when Hash, String then !comment.empty? else true end end
Returns whether the cell contains a comment or note.
@return [Boolean] @api public
() → String?
Source
# File lib/xlsxrb/elements/cell.rb, line 223 def comment_text case comment when Hash txt = comment[:text] txt&.to_s when String comment.empty? ? nil : comment end end
Returns the plain text of the cell comment or note, or nil.
@return [String, nil] @api public
() → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 320 def content value end
Returns the cell value.
@return [Object, nil] @api public
() → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 311 def date1904? @date1904 ? true : false end
Returns whether the cellโs workbook uses the 1904 date system.
@return [Boolean] @api public
() → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 293 def date_format? format_code ? NumberFormatter.date_format?(format_code) : false end
Returns whether the cell has a date, datetime, or time format.
@return [Boolean] @api public
() → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 89 def deconstruct [row_index, column_index, value, formula, style_index, unmapped_data, errors, hyperlink, comment, raw_value, format_code] end
(untyped keys) → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 93 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, hyperlink: hyperlink, comment: comment, raw_value: raw_value, format_code: format_code } keys ? h.slice(*keys) : h end
() → Symbol?
Source
# File lib/xlsxrb/elements/cell.rb, line 284 def format_type format_code ? NumberFormatter.format_type(format_code) : nil end
Returns the classified format category for this cell (:date, :datetime, :time, :number, :text, :general, or nil).
@return [Symbol, nil] @api public
(?String? custom_format_code) → String?
Source
# File lib/xlsxrb/elements/cell.rb, line 239 def formatted_value(custom_format_code = nil) return nil if value.nil? NumberFormatter.format(value, custom_format_code || format_code) end
Returns the formatted string representation of the cell value according to its format code.
@param custom_format_code [String, nil] Optional format code override. @return [String, nil] @api public
() → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 139 def formula? if formula.is_a?(Formula) !formula.expression.nil? && !formula.expression.empty? else !formula.nil? && !formula.to_s.empty? end end
Returns whether the cell contains a formula.
@return [Boolean] @api public
() → String?
Source
# File lib/xlsxrb/elements/cell.rb, line 152 def formula_expression expr = formula.is_a?(Formula) ? formula.expression : formula return nil if expr.nil? str = expr.to_s str.empty? ? nil : str end
Returns the formula expression string without leading โ=โ, or nil.
@return [String, nil] @api public
() → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 85 def hash [row_index, column_index, value, formula, style_index, unmapped_data, errors, hyperlink, comment, raw_value, format_code].hash end
() → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 165 def link? case hyperlink when nil then false when Hash, String then !hyperlink.empty? else true end end
Returns whether the cell contains a hyperlink.
@return [Boolean] @api public
() → String
Source
# File lib/xlsxrb/elements/cell.rb, line 130 def ref "#{self.class.column_letter(column_index)}#{row_index + 1}" end
Returns the Excel-style reference (e.g. โA1โ, โB2โ).
@return [String] @api public
() → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 302 def time_format? format_code ? NumberFormatter.time_format?(format_code) : false end
Returns whether the cell has a time-only format.
@return [Boolean] @api public
(?date1904: bool?) → Date?
Source
# File lib/xlsxrb/elements/cell.rb, line 357 def to_date(date1904: nil) return value if value.is_a?(Date) d1904 = date1904.nil? ? date1904? : date1904 if value.is_a?(Numeric) Ooxml::Utils.serial_to_date(value, date1904: d1904) else begin Date.parse(value.to_s) rescue StandardError nil end end end
Converts the cell value (numeric serial date or date string) to Date.
@param date1904 [Boolean, nil] Whether to use the 1904 date system (defaults to cellโs date1904 setting). @return [Date, nil] @api public
() → Float
Source
# File lib/xlsxrb/elements/cell.rb, line 347 def to_f value.to_f end
Converts the cell value to Float.
@return [Float] @api public
() → Integer
Source
# File lib/xlsxrb/elements/cell.rb, line 338 def to_i value.to_i end
Converts the cell value to Integer.
@return [Integer] @api public
() → String
Source
# File lib/xlsxrb/elements/cell.rb, line 329 def to_s value.to_s end
Returns the string representation of the cell value.
@return [String] @api public
(?date1904: bool?) → Time?
Source
# File lib/xlsxrb/elements/cell.rb, line 378 def to_time(date1904: nil) return value if value.is_a?(Time) d1904 = date1904.nil? ? date1904? : date1904 if value.is_a?(Numeric) Ooxml::Utils.serial_to_datetime(value, date1904: d1904) else begin Time.parse(value.to_s) rescue StandardError nil end end end
Converts the cell value (numeric serial datetime or datetime string) to Time.
@param date1904 [Boolean, nil] Whether to use the 1904 date system (defaults to cellโs date1904 setting). @return [Time, nil] @api public
() → String?
Source
# File lib/xlsxrb/elements/cell.rb, line 196 def tooltip case hyperlink when Hash hyperlink[:tooltip]&.to_s when Elements::Hyperlink hyperlink.tooltip&.to_s end end
Returns the hyperlink tooltip (ScreenTip) text, or nil.
@return [String, nil] @api public
() → String?
Source
# File lib/xlsxrb/elements/cell.rb, line 179 def url case hyperlink when Hash u = hyperlink[:url] || hyperlink[:location] u&.to_s when String hyperlink.empty? ? nil : hyperlink when Elements::Hyperlink (hyperlink.url || hyperlink.location)&.to_s end end
Returns the hyperlink target URL or location string, or nil.
@return [String, nil] @api public
() → bool
Source
# File lib/xlsxrb/elements/cell.rb, line 121 def valid? errors.empty? end
Returns whether the cell is valid according to OOXML specifications.
@return [Boolean]
(**untyped changes) → untyped
Source
# File lib/xlsxrb/elements/cell.rb, line 100 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), hyperlink: changes.fetch(:hyperlink, hyperlink), comment: changes.fetch(:comment, comment), raw_value: changes.fetch(:raw_value, raw_value), format_code: changes.fetch(:format_code, format_code), date1904: changes.fetch(:date1904, @date1904 || false) ) end