roo-xls 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rubocop.yml +17 -0
  4. data/.simplecov +4 -0
  5. data/.travis.yml +11 -0
  6. data/Gemfile +30 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +41 -0
  9. data/Rakefile +23 -0
  10. data/defaults.reek +11 -0
  11. data/lib/roo-xls.rb +11 -0
  12. data/lib/roo/xls/excel.rb +352 -0
  13. data/lib/roo/xls/excel_2003_xml.rb +294 -0
  14. data/lib/roo/xls/spreadsheet_extensions.rb +24 -0
  15. data/lib/roo/xls/version.rb +5 -0
  16. data/roo-xls.gemspec +27 -0
  17. data/spec/lib/roo/xls/excel2003xml_spec.rb +15 -0
  18. data/spec/lib/roo/xls/excel_spec.rb +17 -0
  19. data/spec/spec_helper.rb +2 -0
  20. data/test/files/1900_base.xls +0 -0
  21. data/test/files/1904_base.xls +0 -0
  22. data/test/files/Bibelbund.csv +3741 -0
  23. data/test/files/Bibelbund.xls +0 -0
  24. data/test/files/Bibelbund.xml +62518 -0
  25. data/test/files/bad_excel_date.xls +0 -0
  26. data/test/files/bbu.xls +0 -0
  27. data/test/files/bbu.xml +152 -0
  28. data/test/files/bode-v1.xls.zip +0 -0
  29. data/test/files/boolean.csv +2 -0
  30. data/test/files/boolean.xls +0 -0
  31. data/test/files/boolean.xml +112 -0
  32. data/test/files/borders.xls +0 -0
  33. data/test/files/borders.xml +144 -0
  34. data/test/files/bug-row-column-fixnum-float.xls +0 -0
  35. data/test/files/bug-row-column-fixnum-float.xml +127 -0
  36. data/test/files/comments.xls +0 -0
  37. data/test/files/datetime.xls +0 -0
  38. data/test/files/datetime.xml +150 -0
  39. data/test/files/datetime_floatconv.xls +0 -0
  40. data/test/files/datetime_floatconv.xml +148 -0
  41. data/test/files/emptysheets.xls +0 -0
  42. data/test/files/emptysheets.xml +105 -0
  43. data/test/files/excel2003.xml +21140 -0
  44. data/test/files/excel2003_namespace.xml +197 -0
  45. data/test/files/false_encoding.xls +0 -0
  46. data/test/files/false_encoding.xml +132 -0
  47. data/test/files/formula.xls +0 -0
  48. data/test/files/formula.xml +134 -0
  49. data/test/files/formula_parse_error.xls +0 -0
  50. data/test/files/formula_parse_error.xml +1833 -0
  51. data/test/files/link.csv +1 -0
  52. data/test/files/link.xls +0 -0
  53. data/test/files/matrix.xls +0 -0
  54. data/test/files/named_cells.xls +0 -0
  55. data/test/files/numbers1.ods +0 -0
  56. data/test/files/numbers1.xls +0 -0
  57. data/test/files/numbers1.xlsx +0 -0
  58. data/test/files/numbers1.xml +312 -0
  59. data/test/files/only_one_sheet.xls +0 -0
  60. data/test/files/only_one_sheet.xml +67 -0
  61. data/test/files/paragraph.xls +0 -0
  62. data/test/files/paragraph.xml +127 -0
  63. data/test/files/prova.xls +0 -0
  64. data/test/files/simple_spreadsheet.xls +0 -0
  65. data/test/files/simple_spreadsheet.xml +225 -0
  66. data/test/files/simple_spreadsheet_from_italo.xls +0 -0
  67. data/test/files/simple_spreadsheet_from_italo.xml +242 -0
  68. data/test/files/so_datetime.csv +8 -0
  69. data/test/files/style.xls +0 -0
  70. data/test/files/style.xml +154 -0
  71. data/test/files/time-test.csv +2 -0
  72. data/test/files/time-test.xls +0 -0
  73. data/test/files/time-test.xml +131 -0
  74. data/test/files/type_excel.ods +0 -0
  75. data/test/files/type_excel.xlsx +0 -0
  76. data/test/files/type_excelx.xls +0 -0
  77. data/test/files/type_openoffice.xls +0 -0
  78. data/test/files/whitespace.xls +0 -0
  79. data/test/files/whitespace.xml +184 -0
  80. data/test/rm_test.rb +7 -0
  81. data/test/test_excel_2003_xml.rb +41 -0
  82. data/test/test_helper.rb +57 -0
  83. data/test/test_roo_excel.rb +1093 -0
  84. metadata +278 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1123a00b02f4882fe61348d8ce2e4d291ee69e18
4
+ data.tar.gz: 08219e99656723cb9d1d0c22439285985eb98cb5
5
+ SHA512:
6
+ metadata.gz: 36d6728ac2bc30d611630220a91e16ae9dd7a37138cf10c60fec43794881a196218a7a9b8bcf69e08867e5ad54defed15f5514d72941f00b038a543d8bfb23b7
7
+ data.tar.gz: 0f3d5a35a4c83e19c964375cd0c1dc458bdad69b88d495b07b23595e2f0da506f4eebbc06c9222af37c3c009436543fd34d682cdafec4ba1f908f68cb4b4bbe2
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .idea
16
+ .DS_Store
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ AllCops:
2
+ Include:
3
+ - '**/Rakefile'
4
+ Exclude:
5
+ - 'spec/**/*'
6
+ Metrics/LineLength:
7
+ Max: 99
8
+ Style/FileName:
9
+ Enabled: false
10
+ Style/ModuleFunction:
11
+ Enabled: false
12
+ Style/Encoding:
13
+ Enabled: false
14
+ Documentation:
15
+ Enabled: false
16
+ Metrics/MethodLength:
17
+ Max: 15
data/.simplecov ADDED
@@ -0,0 +1,4 @@
1
+ SimpleCov.start do
2
+ add_filter 'spec'
3
+ add_filter 'test'
4
+ end
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1
5
+ - ruby-head
6
+ - jruby-19mode # JRuby in 1.9 mode
7
+ - rbx-2
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: ruby-head
11
+ bundler_args: --without local_development
data/Gemfile ADDED
@@ -0,0 +1,30 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in roo-xls.gemspec
4
+ gemspec
5
+
6
+ if ENV['TRAVIS']
7
+ gem 'roo', '>= 2.0.0beta1', github: 'roo-rb/roo'
8
+ else
9
+ gem 'roo', '>= 2.0.0beta1', path: ::File.expand_path('../../roo', __FILE__)
10
+ end
11
+
12
+ group :test do
13
+ # additional testing libs
14
+ gem 'webmock'
15
+ gem 'shoulda'
16
+ gem 'rspec', '>= 3.0.0'
17
+ gem 'simplecov', '>= 0.9.0', :require => false
18
+ gem 'coveralls', :require => false
19
+ end
20
+
21
+ group :local_development do
22
+ gem 'terminal-notifier-guard', require: false if RUBY_PLATFORM.downcase.include?('darwin')
23
+ gem 'guard-rspec', '>= 4.3.1' ,require: false
24
+ gem 'guard-bundler', require: false
25
+ gem 'guard-preek', require: false
26
+ gem 'guard-rubocop', require: false
27
+ gem 'guard-reek', git: 'https://github.com/pericles/guard-reek', require: false
28
+ gem 'pry'
29
+ gem 'transpec'
30
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008-2014 Thomas Preymesser, Ben Woosley
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Roo::Xls [![BuildStatus](https://travis-ci.org/roo-rb/roo-xls.svg)](https://travis-ci.org/roo-rb/roo-xls)[![Code Climate](https://codeclimate.com/github/roo-rb/roo-xls/badges/gpa.svg)](https://codeclimate.com/github/roo-rb/roo-xls)[![Coverage Status](https://coveralls.io/repos/roo-rb/roo-xls/badge.svg?branch=master)](https://coveralls.io/r/roo-rb/roo-xls?branch=master)
2
+
3
+ This library extends Roo to add support for handling class Excel files, including:
4
+
5
+ * .xls files
6
+ * .xml files in the SpreadsheetML format (circa 2003)
7
+
8
+ There is no support for formulas in Roo for .xls files - you can get the result
9
+ of a formula but not the formula itself.
10
+
11
+ ## License
12
+
13
+ While Roo and Roo::Xls are licensed under the MIT / Expat license, please note that the 'spreadsheet' gem [is released under](https://github.com/zdavatz/spreadsheet/blob/master/LICENSE.txt) the GPLv3 license.
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'roo-xls'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install roo-xls
30
+
31
+ ## Usage
32
+
33
+ TODO: Write usage instructions here
34
+
35
+ ## Contributing
36
+
37
+ 1. Fork it ( https://github.com/[my-github-username]/roo-xls/fork )
38
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
39
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
40
+ 4. Push to the branch (`git push origin my-new-feature`)
41
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/testtask'
4
+ require 'rspec/core/rake_task'
5
+ require 'coveralls/rake/task'
6
+
7
+ # Test unit
8
+ Rake::TestTask.new do |t|
9
+ t.libs << 'test'
10
+ t.test_files = FileList['test/test*.rb']
11
+ t.verbose = true
12
+ end
13
+
14
+ # RSpec
15
+ RSpec::Core::RakeTask.new(:spec)
16
+
17
+ # Coveralls
18
+ Coveralls::RakeTask.new
19
+
20
+ default_task = [:test, :spec]
21
+ default_task << 'coveralls:push' if ENV['TRAVIS']
22
+
23
+ task default: default_task
data/defaults.reek ADDED
@@ -0,0 +1,11 @@
1
+ ---
2
+ NestedIterators:
3
+ max_allowed_nesting: 2
4
+ UtilityFunction:
5
+ enabled: false
6
+ IrresponsibleModule:
7
+ enabled: false
8
+ DuplicateMethodCall:
9
+ max_calls: 5
10
+ FeatureEnvy:
11
+ enabled: false
data/lib/roo-xls.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'roo'
2
+
3
+ module Roo
4
+ autoload :Excel, 'roo/xls/excel'
5
+ autoload :Excel2003XML, 'roo/xls/excel_2003_xml'
6
+
7
+ CLASS_FOR_EXTENSION.merge!(
8
+ xls: Roo::Excel,
9
+ xml: Roo::Excel2003XML
10
+ )
11
+ end
@@ -0,0 +1,352 @@
1
+ require 'roo/xls/version'
2
+ require 'roo/base'
3
+ require 'spreadsheet'
4
+
5
+ module Roo
6
+ # Class for handling Excel-Spreadsheets
7
+ class Excel < Roo::Base
8
+ FORMULAS_MESSAGE = 'the spreadsheet gem does not support forumulas, so roo can not.'
9
+ CHARGUESS =
10
+ begin
11
+ require 'charguess'
12
+ true
13
+ rescue LoadError
14
+ false
15
+ end
16
+
17
+ attr_reader :workbook
18
+
19
+ # Creates a new Excel spreadsheet object.
20
+ # Parameter packed: :zip - File is a zip-file
21
+ def initialize(filename, options = {})
22
+ packed = options[:packed]
23
+ file_warning = options[:file_warning] || :error
24
+ mode = options[:mode] || 'rb+'
25
+
26
+ file_type_check(filename, '.xls', 'an Excel', file_warning, packed)
27
+ make_tmpdir do |tmpdir|
28
+ filename = download_uri(filename, tmpdir) if uri?(filename)
29
+ filename = open_from_stream(filename[7..-1], tmpdir) if filename.is_a?(::String) && filename[0, 7] == 'stream:'
30
+ filename = unzip(filename, tmpdir) if packed == :zip
31
+
32
+ @filename = filename
33
+ unless File.file?(@filename)
34
+ fail IOError, "file #{@filename} does not exist"
35
+ end
36
+ @workbook = ::Spreadsheet.open(filename, mode)
37
+ end
38
+ super(filename, options)
39
+ @formula = {}
40
+ @fonts = {}
41
+ end
42
+
43
+ attr_reader :workbook
44
+
45
+ def worksheets
46
+ @worksheets ||= workbook.worksheets
47
+ end
48
+
49
+ def encoding=(codepage)
50
+ @workbook.encoding = codepage
51
+ end
52
+
53
+ # returns an array of sheet names in the spreadsheet
54
+ def sheets
55
+ @sheets ||= worksheets.collect { |worksheet| normalize_string(worksheet.name) }
56
+ end
57
+
58
+ # this method lets you find the worksheet with the most data
59
+ def longest_sheet
60
+ sheet(worksheets.inject do|m, o|
61
+ o.row_count > m.row_count ? o : m
62
+ end.name)
63
+ end
64
+
65
+ # returns the content of a cell. The upper left corner is (1,1) or ('A',1)
66
+ def cell(row, col, sheet = default_sheet)
67
+ validate_sheet!(sheet)
68
+
69
+ read_cells(sheet)
70
+ fail 'should be read' unless @cells_read[sheet]
71
+ row, col = normalize(row, col)
72
+ if celltype(row, col, sheet) == :date
73
+ yyyy, mm, dd = @cell[sheet][[row, col]].split('-')
74
+ return Date.new(yyyy.to_i, mm.to_i, dd.to_i)
75
+ end
76
+ if celltype(row, col, sheet) == :string
77
+ return platform_specific_encoding(@cell[sheet][[row, col]])
78
+ else
79
+ if @cell[sheet] && @cell[sheet][[row, col]]
80
+ return @cell[sheet][[row, col]]
81
+ else
82
+ return nil
83
+ end
84
+ end
85
+ end
86
+
87
+ # returns the type of a cell:
88
+ # * :float
89
+ # * :string,
90
+ # * :date
91
+ # * :percentage
92
+ # * :formula
93
+ # * :time
94
+ # * :datetime
95
+ def celltype(row, col, sheet = default_sheet)
96
+ read_cells(sheet)
97
+ row, col = normalize(row, col)
98
+ begin
99
+ if @formula[sheet] && @formula[sheet][[row, col]]
100
+ :formula
101
+ elsif @cell_type[sheet]
102
+ @cell_type[sheet][[row, col]]
103
+ end
104
+ rescue
105
+ puts "Error in sheet #{sheet}, row #{row}, col #{col}"
106
+ raise
107
+ end
108
+ end
109
+
110
+ # returns NO formula in excel spreadsheets
111
+ def formula(_row, _col, _sheet = nil)
112
+ fail NotImplementedError, FORMULAS_MESSAGE
113
+ end
114
+ alias_method :formula?, :formula
115
+
116
+ # returns NO formulas in excel spreadsheets
117
+ def formulas(_sheet = nil)
118
+ fail NotImplementedError, FORMULAS_MESSAGE
119
+ end
120
+
121
+ # Given a cell, return the cell's font
122
+ def font(row, col, sheet = default_sheet)
123
+ read_cells(sheet)
124
+ row, col = normalize(row, col)
125
+ @fonts[sheet][[row, col]]
126
+ end
127
+
128
+ # shows the internal representation of all cells
129
+ # mainly for debugging purposes
130
+ def to_s(sheet = default_sheet)
131
+ read_cells(sheet)
132
+ @cell[sheet].inspect
133
+ end
134
+
135
+ private
136
+
137
+ # converts name of a sheet to index (0,1,2,..)
138
+ def sheet_no(name)
139
+ return name - 1 if name.is_a?(Fixnum)
140
+ i = 0
141
+ worksheets.each do |worksheet|
142
+ return i if name == normalize_string(worksheet.name)
143
+ i += 1
144
+ end
145
+ fail StandardError, "sheet '#{name}' not found"
146
+ end
147
+
148
+ def normalize_string(value)
149
+ value = every_second_null?(value) ? remove_every_second_null(value) : value
150
+ if CHARGUESS && encoding = CharGuess.guess(value)
151
+ encoding.encode Encoding::UTF_8
152
+ else
153
+ platform_specific_encoding(value)
154
+ end
155
+ end
156
+
157
+ def platform_specific_encoding(value)
158
+ result =
159
+ case RUBY_PLATFORM.downcase
160
+ when /darwin|solaris/
161
+ value.encode Encoding::UTF_8
162
+ when /mswin32/
163
+ value.encode Encoding::ISO_8859_1
164
+ else
165
+ value
166
+ end
167
+ if every_second_null?(result)
168
+ result = remove_every_second_null(result)
169
+ end
170
+ result
171
+ end
172
+
173
+ def every_second_null?(str)
174
+ result = true
175
+ return false if str.length < 2
176
+ 0.upto(str.length / 2 - 1) do |i|
177
+ if str[i * 2 + 1, 1] != "\000"
178
+ result = false
179
+ break
180
+ end
181
+ end
182
+ result
183
+ end
184
+
185
+ def remove_every_second_null(str)
186
+ result = ''
187
+ 0.upto(str.length / 2 - 1) do |i|
188
+ c = str[i * 2, 1]
189
+ result += c
190
+ end
191
+ result
192
+ end
193
+
194
+ # helper function to set the internal representation of cells
195
+ def set_cell_values(sheet, row, col, i, v, value_type, formula, _tr, font)
196
+ # key = "#{y},#{x+i}"
197
+ key = [row, col + i]
198
+ @cell_type[sheet] = {} unless @cell_type[sheet]
199
+ @cell_type[sheet][key] = value_type
200
+ @formula[sheet] = {} unless @formula[sheet]
201
+ @formula[sheet][key] = formula if formula
202
+ @cell[sheet] = {} unless @cell[sheet]
203
+ @fonts[sheet] = {} unless @fonts[sheet]
204
+ @fonts[sheet][key] = font
205
+
206
+ @cell[sheet][key] =
207
+ case value_type
208
+ when :float
209
+ v.to_f
210
+ when :string
211
+ v
212
+ when :date
213
+ v
214
+ when :datetime
215
+ @cell[sheet][key] = DateTime.new(v.year, v.month, v.day, v.hour, v.min, v.sec)
216
+ when :percentage
217
+ v.to_f
218
+ when :time
219
+ v
220
+ else
221
+ v
222
+ end
223
+ end
224
+
225
+ # ruby-spreadsheet has a font object so we're extending it
226
+ # with our own functionality but still providing full access
227
+ # to the user for other font information
228
+ module ExcelFontExtensions
229
+ def bold?(*_args)
230
+ # From ruby-spreadsheet doc: 100 <= weight <= 1000, bold => 700, normal => 400
231
+ weight == 700
232
+ end
233
+
234
+ def italic?
235
+ italic
236
+ end
237
+
238
+ def underline?
239
+ underline != :none
240
+ end
241
+ end
242
+
243
+ # read all cells in the selected sheet
244
+ def read_cells(sheet = default_sheet)
245
+ validate_sheet!(sheet)
246
+ return if @cells_read[sheet]
247
+
248
+ worksheet = @workbook.worksheet(sheet_no(sheet))
249
+ row_index = 1
250
+ worksheet.each(0) do |row|
251
+ (0..row.size).each do |cell_index|
252
+ cell = row.at(cell_index)
253
+ next if cell.nil? # skip empty cells
254
+ next if cell.class == ::Spreadsheet::Formula && cell.value.nil? # skip empty formula cells
255
+ value_type, v =
256
+ if date_or_time?(row, cell_index)
257
+ read_cell_date_or_time(row, cell_index)
258
+ else
259
+ read_cell(row, cell_index)
260
+ end
261
+ formula = tr = nil # TODO:???
262
+ col_index = cell_index + 1
263
+ font = row.format(cell_index).font
264
+ font.extend(ExcelFontExtensions)
265
+ set_cell_values(sheet, row_index, col_index, 0, v, value_type, formula, tr, font)
266
+ end # row
267
+ row_index += 1
268
+ end # worksheet
269
+ @cells_read[sheet] = true
270
+ end
271
+
272
+ # Get the contents of a cell, accounting for the
273
+ # way formula stores the value
274
+ def read_cell_content(row, idx)
275
+ cell = row.at(idx)
276
+ cell = row[idx] if row[idx].class == ::Spreadsheet::Link
277
+ cell = cell.value if cell.class == ::Spreadsheet::Formula
278
+ cell
279
+ end
280
+
281
+ # Test the cell to see if it's a valid date/time.
282
+ def date_or_time?(row, idx)
283
+ format = row.format(idx)
284
+ if format.date_or_time?
285
+ cell = read_cell_content(row, idx)
286
+ true if Float(cell) > 0 rescue false
287
+ else
288
+ false
289
+ end
290
+ end
291
+
292
+ # Read the date-time cell and convert to,
293
+ # the date-time values for Roo
294
+ def read_cell_date_or_time(row, idx)
295
+ cell = read_cell_content(row, idx)
296
+ cell = cell.to_s.to_f
297
+ if cell < 1.0
298
+ value_type = :time
299
+ f = cell * 24.0 * 60.0 * 60.0
300
+ secs = f.round
301
+ h = (secs / 3600.0).floor
302
+ secs = secs - 3600 * h
303
+ m = (secs / 60.0).floor
304
+ secs = secs - 60 * m
305
+ s = secs
306
+ value = h * 3600 + m * 60 + s
307
+ else
308
+ if row.at(idx).class == ::Spreadsheet::Formula
309
+ datetime = row.send(:_datetime, cell)
310
+ else
311
+ datetime = row.datetime(idx)
312
+ end
313
+ if datetime.hour != 0 ||
314
+ datetime.min != 0 ||
315
+ datetime.sec != 0
316
+ value_type = :datetime
317
+ value = datetime
318
+ else
319
+ value_type = :date
320
+ if row.at(idx).class == ::Spreadsheet::Formula
321
+ value = row.send(:_date, cell)
322
+ else
323
+ value = row.date(idx)
324
+ end
325
+ value = sprintf('%04d-%02d-%02d', value.year, value.month, value.day)
326
+ end
327
+ end
328
+ [value_type, value]
329
+ end
330
+
331
+ # Read the cell and based on the class,
332
+ # return the values for Roo
333
+ def read_cell(row, idx)
334
+ cell = read_cell_content(row, idx)
335
+ case cell
336
+ when Float, Integer, Fixnum, Bignum
337
+ value_type = :float
338
+ value = cell.to_f
339
+ when ::Spreadsheet::Link
340
+ value_type = :link
341
+ value = cell
342
+ when String, TrueClass, FalseClass
343
+ value_type = :string
344
+ value = cell.to_s
345
+ else
346
+ value_type = cell.class.to_s.downcase.to_sym
347
+ value = nil
348
+ end # case
349
+ [value_type, value]
350
+ end
351
+ end
352
+ end