Class: SimpleXlsxReader::Loader

Inherits:
Struct
  • Object
show all
Defined in:
lib/simple_xlsx_reader/loader.rb,
lib/simple_xlsx_reader/loader/sheet_parser.rb,
lib/simple_xlsx_reader/loader/workbook_parser.rb,
lib/simple_xlsx_reader/loader/style_types_parser.rb,
lib/simple_xlsx_reader/loader/shared_strings_parser.rb

Defined Under Namespace

Classes: SharedStringsParser, SheetParser, StyleTypesParser, WorkbookParser, ZipReader

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#base_dateObject

Returns the value of attribute base_date.



5
6
7
# File 'lib/simple_xlsx_reader/loader.rb', line 5

def base_date
  @base_date
end

#shared_stringsObject

Returns the value of attribute shared_strings.



5
6
7
# File 'lib/simple_xlsx_reader/loader.rb', line 5

def shared_strings
  @shared_strings
end

#sheet_parsersObject

Returns the value of attribute sheet_parsers.



5
6
7
# File 'lib/simple_xlsx_reader/loader.rb', line 5

def sheet_parsers
  @sheet_parsers
end

#sheet_tocObject

Returns the value of attribute sheet_toc.



5
6
7
# File 'lib/simple_xlsx_reader/loader.rb', line 5

def sheet_toc
  @sheet_toc
end

#string_or_ioObject

Returns the value of attribute string_or_io

Returns:

  • (Object)

    the current value of string_or_io



4
5
6
# File 'lib/simple_xlsx_reader/loader.rb', line 4

def string_or_io
  @string_or_io
end

#style_typesObject

Returns the value of attribute style_types.



5
6
7
# File 'lib/simple_xlsx_reader/loader.rb', line 5

def style_types
  @style_types
end

Class Method Details

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

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



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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/simple_xlsx_reader/loader.rb', line 120

def self.cast(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' && %i[date time date_time].include?(style))
    type = style
  end

  casted =
    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
    ##

    # no type encoded with the the General format defaults to a number type
    when nil, :string
      retval = Integer(value, exception: false)
      retval ||= Float(value, exception: false)
      retval ||= value
      retval
    when :unsupported
      value
    when :fixnum
      value.to_i
    when :float
      value.to_f
    when :percentage
      value.to_f
    # the trickiest. note that  all these formats can vary on
    # whether they actually contain a date, time, or datetime.
    when :date, :time, :date_time
      value = Float(value)
      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_SYSTEM_1900) + days_since_date_system_start

      if fraction_of_24 > 0 # there is a time associated
        seconds = (fraction_of_24 * 86_400).round
        return Time.utc(date.year, date.month, date.day) + seconds
      else
        return date
      end
    when :bignum
      if defined?(BigDecimal)
        BigDecimal(value)
      else
        value.to_f
      end

    ##
    # Beats me
    ##

    else
      value
    end

  if options[:url]
    Hyperlink.new(options[:url], casted)
  else
    casted
  end
end

Instance Method Details

#init_sheetsObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/simple_xlsx_reader/loader.rb', line 7

def init_sheets
  ZipReader.new(
    string_or_io: string_or_io,
    loader: self
  ).read

  sheet_toc.each_with_index.map do |(sheet_name, _sheet_number), i|
    # sheet_number is *not* the index into xml.sheet_parsers
    SimpleXlsxReader::Document::Sheet.new(
      name: sheet_name,
      sheet_parser: sheet_parsers[i]
    )
  end
end