Class: Creeker::Styles::Converter

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/creeker/styles/converter.rb

Constant Summary collapse

DATE_TYPES =

The heart of typecasting. The ruby type is determined either explicitly from the cell xml or implicitly from the cell style, and this method expects that work to have been done already. This, then, takes the type we determined it to be and casts the cell value to that type.

types:

  • s: shared string (see #shared_string)

  • n: number (cast to a float)

  • b: boolean

  • str: string

  • inlineStr: string

  • ruby symbol: for when type has been determined by style

options:

  • shared_strings: needed for ā€˜sā€™ (shared string) type

  • base_date: from what date to begin, see method #base_date

[:date, :time, :date_time].to_set

Constants included from Constants

Creeker::Styles::Constants::NumFmtMap

Class Method Summary collapse

Class Method Details

.call(value, type, style, options = {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/creeker/styles/converter.rb', line 27

def self.call(value, type, style, options = {})
  return nil if value.nil? || value.empty?

  # Sometimes the type is dictated by the style alone
  if type.nil? || (type == 'n' && DATE_TYPES.include?(style))
    type = style
  end

  case type

  ##
  # There are few built-in types
  ##

  when 's' # shared string
    options[:shared_strings][value.to_i]
  when 'n' # number
    value.to_f
  when 'b'
    value.to_i == 1
  when 'str'
    value
  when 'inlineStr'
    value

  ##
  # Type can also be determined by a style,
  # detected earlier and cast here by its standardized symbol
  ##

  when :string, :unsupported
    value
  when :fixnum
    value.to_i
  when :float, :percentage
    value.to_f
  when :date, :time, :date_time
    convert_date(value, options)
  when :bignum
    convert_bignum(value)

  ## Nothing matched
  else
    value
  end
end

.convert_bignum(value) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/creeker/styles/converter.rb', line 92

def self.convert_bignum(value)
  if defined?(BigDecimal)
    BigDecimal.new(value)
  else
    value.to_f
  end
end

.convert_date(value, options) ⇒ Object

the trickiest. note that all these formats can vary on whether they actually contain a date, time, or datetime.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/creeker/styles/converter.rb', line 76

def self.convert_date(value, options)
  value                        = value.to_f
  days_since_date_system_start = value.to_i
  fraction_of_24               = value - days_since_date_system_start

  # http://stackoverflow.com/questions/10559767/how-to-convert-ms-excel-date-from-float-to-date-format-in-ruby
  date = options.fetch(:base_date, Date.new(1899, 12, 30)) + days_since_date_system_start

  if fraction_of_24 > 0 # there is a time associated
    seconds = (fraction_of_24 * 86400).round
    return Time.utc(date.year, date.month, date.day) + seconds
  else
    return date
  end
end