roo-xls 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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