roo 1.10.1 → 1.10.2

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 (136) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +38 -0
  4. data/History.txt +4 -4
  5. data/License.txt +20 -0
  6. data/Manifest.txt +68 -0
  7. data/README.markdown +109 -0
  8. data/Rakefile +5 -4
  9. data/bin/roo +0 -0
  10. data/examples/roo_soap_client.rb +53 -0
  11. data/examples/roo_soap_server.rb +29 -0
  12. data/examples/write_me.rb +33 -0
  13. data/lib/roo.rb +20 -61
  14. data/lib/roo/csv.rb +13 -11
  15. data/lib/roo/excel.rb +108 -219
  16. data/lib/roo/excel2003xml.rb +312 -0
  17. data/lib/roo/excelx.rb +205 -341
  18. data/lib/roo/generic_spreadsheet.rb +371 -268
  19. data/lib/roo/google.rb +64 -54
  20. data/lib/roo/openoffice.rb +101 -156
  21. data/lib/roo/roo_rails_helper.rb +5 -5
  22. data/lib/roo/worksheet.rb +18 -0
  23. data/roo.gemspec +43 -0
  24. data/scripts/txt2html +67 -0
  25. data/test/all_ss.rb +8 -10
  26. data/test/{1900_base.xls → files/1900_base.xls} +0 -0
  27. data/test/{1904_base.xls → files/1904_base.xls} +0 -0
  28. data/test/{Bibelbund.csv → files/Bibelbund.csv} +0 -0
  29. data/test/{Bibelbund.ods → files/Bibelbund.ods} +0 -0
  30. data/test/{Bibelbund.xls → files/Bibelbund.xls} +0 -0
  31. data/test/{Bibelbund.xlsx → files/Bibelbund.xlsx} +0 -0
  32. data/test/files/Bibelbund.xml +62518 -0
  33. data/test/{Bibelbund1.ods → files/Bibelbund1.ods} +0 -0
  34. data/test/{Pfand_from_windows_phone.xlsx → files/Pfand_from_windows_phone.xlsx} +0 -0
  35. data/test/files/bad_excel_date.xls +0 -0
  36. data/test/{bbu.ods → files/bbu.ods} +0 -0
  37. data/test/{bbu.xls → files/bbu.xls} +0 -0
  38. data/test/{bbu.xlsx → files/bbu.xlsx} +0 -0
  39. data/test/files/bbu.xml +152 -0
  40. data/test/{bode-v1.ods.zip → files/bode-v1.ods.zip} +0 -0
  41. data/test/{bode-v1.xls.zip → files/bode-v1.xls.zip} +0 -0
  42. data/test/{boolean.ods → files/boolean.ods} +0 -0
  43. data/test/{boolean.xls → files/boolean.xls} +0 -0
  44. data/test/{boolean.xlsx → files/boolean.xlsx} +0 -0
  45. data/test/files/boolean.xml +112 -0
  46. data/test/{borders.ods → files/borders.ods} +0 -0
  47. data/test/{borders.xls → files/borders.xls} +0 -0
  48. data/test/{borders.xlsx → files/borders.xlsx} +0 -0
  49. data/test/files/borders.xml +144 -0
  50. data/test/{bug-row-column-fixnum-float.xls → files/bug-row-column-fixnum-float.xls} +0 -0
  51. data/test/files/bug-row-column-fixnum-float.xml +127 -0
  52. data/test/{comments.ods → files/comments.ods} +0 -0
  53. data/test/{comments.xls → files/comments.xls} +0 -0
  54. data/test/{comments.xlsx → files/comments.xlsx} +0 -0
  55. data/test/{csvtypes.csv → files/csvtypes.csv} +0 -0
  56. data/test/{datetime.ods → files/datetime.ods} +0 -0
  57. data/test/{datetime.xls → files/datetime.xls} +0 -0
  58. data/test/{datetime.xlsx → files/datetime.xlsx} +0 -0
  59. data/test/files/datetime.xml +142 -0
  60. data/test/{datetime_floatconv.xls → files/datetime_floatconv.xls} +0 -0
  61. data/test/files/datetime_floatconv.xml +148 -0
  62. data/test/{dreimalvier.ods → files/dreimalvier.ods} +0 -0
  63. data/test/{emptysheets.ods → files/emptysheets.ods} +0 -0
  64. data/test/{emptysheets.xls → files/emptysheets.xls} +0 -0
  65. data/test/{emptysheets.xlsx → files/emptysheets.xlsx} +0 -0
  66. data/test/files/emptysheets.xml +105 -0
  67. data/test/files/excel2003.xml +21140 -0
  68. data/test/{false_encoding.xls → files/false_encoding.xls} +0 -0
  69. data/test/files/false_encoding.xml +132 -0
  70. data/test/{formula.ods → files/formula.ods} +0 -0
  71. data/test/{formula.xls → files/formula.xls} +0 -0
  72. data/test/{formula.xlsx → files/formula.xlsx} +0 -0
  73. data/test/files/formula.xml +134 -0
  74. data/test/files/formula_parse_error.xls +0 -0
  75. data/test/files/formula_parse_error.xml +1833 -0
  76. data/test/{formula_string_error.xlsx → files/formula_string_error.xlsx} +0 -0
  77. data/test/{html-escape.ods → files/html-escape.ods} +0 -0
  78. data/test/{matrix.ods → files/matrix.ods} +0 -0
  79. data/test/{matrix.xls → files/matrix.xls} +0 -0
  80. data/test/{named_cells.ods → files/named_cells.ods} +0 -0
  81. data/test/{named_cells.xls → files/named_cells.xls} +0 -0
  82. data/test/{named_cells.xlsx → files/named_cells.xlsx} +0 -0
  83. data/test/{no_spreadsheet_file.txt → files/no_spreadsheet_file.txt} +0 -0
  84. data/test/{numbers1.csv → files/numbers1.csv} +0 -0
  85. data/test/{numbers1.ods → files/numbers1.ods} +0 -0
  86. data/test/{numbers1.xls → files/numbers1.xls} +0 -0
  87. data/test/{numbers1.xlsx → files/numbers1.xlsx} +0 -0
  88. data/test/files/numbers1.xml +312 -0
  89. data/test/{only_one_sheet.ods → files/only_one_sheet.ods} +0 -0
  90. data/test/{only_one_sheet.xls → files/only_one_sheet.xls} +0 -0
  91. data/test/{only_one_sheet.xlsx → files/only_one_sheet.xlsx} +0 -0
  92. data/test/files/only_one_sheet.xml +67 -0
  93. data/test/{paragraph.ods → files/paragraph.ods} +0 -0
  94. data/test/{paragraph.xls → files/paragraph.xls} +0 -0
  95. data/test/{paragraph.xlsx → files/paragraph.xlsx} +0 -0
  96. data/test/files/paragraph.xml +127 -0
  97. data/test/{prova.xls → files/prova.xls} +0 -0
  98. data/test/{ric.ods → files/ric.ods} +0 -0
  99. data/test/{simple_spreadsheet.ods → files/simple_spreadsheet.ods} +0 -0
  100. data/test/{simple_spreadsheet.xls → files/simple_spreadsheet.xls} +0 -0
  101. data/test/{simple_spreadsheet.xlsx → files/simple_spreadsheet.xlsx} +0 -0
  102. data/test/files/simple_spreadsheet.xml +225 -0
  103. data/test/{simple_spreadsheet_from_italo.ods → files/simple_spreadsheet_from_italo.ods} +0 -0
  104. data/test/{simple_spreadsheet_from_italo.xls → files/simple_spreadsheet_from_italo.xls} +0 -0
  105. data/test/files/simple_spreadsheet_from_italo.xml +242 -0
  106. data/test/{so_datetime.csv → files/so_datetime.csv} +0 -0
  107. data/test/{style.ods → files/style.ods} +0 -0
  108. data/test/{style.xls → files/style.xls} +0 -0
  109. data/test/{style.xlsx → files/style.xlsx} +0 -0
  110. data/test/files/style.xml +154 -0
  111. data/test/{time-test.csv → files/time-test.csv} +0 -0
  112. data/test/{time-test.ods → files/time-test.ods} +0 -0
  113. data/test/{time-test.xls → files/time-test.xls} +0 -0
  114. data/test/{time-test.xlsx → files/time-test.xlsx} +0 -0
  115. data/test/files/time-test.xml +131 -0
  116. data/test/{type_excel.ods → files/type_excel.ods} +0 -0
  117. data/test/{type_excel.xlsx → files/type_excel.xlsx} +0 -0
  118. data/test/{type_excelx.ods → files/type_excelx.ods} +0 -0
  119. data/test/{type_excelx.xls → files/type_excelx.xls} +0 -0
  120. data/test/{type_openoffice.xls → files/type_openoffice.xls} +0 -0
  121. data/test/{type_openoffice.xlsx → files/type_openoffice.xlsx} +0 -0
  122. data/test/{whitespace.ods → files/whitespace.ods} +0 -0
  123. data/test/{whitespace.xls → files/whitespace.xls} +0 -0
  124. data/test/{whitespace.xlsx → files/whitespace.xlsx} +0 -0
  125. data/test/files/whitespace.xml +184 -0
  126. data/test/test_generic_spreadsheet.rb +257 -0
  127. data/test/test_helper.rb +167 -27
  128. data/test/test_roo.rb +1178 -930
  129. data/website/index.html +385 -0
  130. data/website/index.txt +423 -0
  131. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  132. data/website/stylesheets/screen.css +130 -0
  133. data/website/template.rhtml +48 -0
  134. metadata +151 -121
  135. data/README.txt +0 -110
  136. data/lib/roo/.csv.rb.swp +0 -0
data/lib/roo/csv.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'csv'
3
+ require 'time'
3
4
 
4
5
  # The Csv class can read csv files (must be separated with commas) which then
5
6
  # can be handled like spreadsheets. This means you can access cells like A5
@@ -7,10 +8,9 @@ require 'csv'
7
8
  # The Csv class provides only string objects. If you want conversions to other
8
9
  # types you have to do it yourself.
9
10
 
10
- class Csv < GenericSpreadsheet
11
+ class Roo::Csv < Roo::GenericSpreadsheet
11
12
  def initialize(filename, packed=nil, file_warning=:error, tmpdir=nil)
12
13
  @filename = filename
13
- super()
14
14
  @cell = Hash.new
15
15
  @cell_type = Hash.new
16
16
  @cells_read = Hash.new
@@ -27,14 +27,14 @@ class Csv < GenericSpreadsheet
27
27
  end
28
28
 
29
29
  def cell(row, col, sheet=nil)
30
- sheet = @default_sheet unless sheet
30
+ sheet ||= @default_sheet
31
31
  read_cells(sheet) unless @cells_read[sheet]
32
32
  row,col = normalize(row,col)
33
33
  @cell[[row,col]]
34
34
  end
35
35
 
36
36
  def celltype(row, col, sheet=nil)
37
- sheet = @default_sheet unless sheet
37
+ sheet ||= @default_sheet
38
38
  read_cells(sheet) unless @cells_read[sheet]
39
39
  row,col = normalize(row,col)
40
40
  @cell_type[[row,col]]
@@ -46,17 +46,19 @@ class Csv < GenericSpreadsheet
46
46
 
47
47
  private
48
48
 
49
+ TYPE_MAP = {
50
+ String => :string,
51
+ Float => :float,
52
+ Date => :date,
53
+ DateTime => :datetime,
54
+ }
55
+
49
56
  def celltype_class(value)
50
- return {String => :string,
51
- Float => :float,
52
- Date => :date,
53
- DateTime => :datetime,
54
- }[value.class]
55
- raise "unknown type for #{value.inspect}"
57
+ TYPE_MAP[value.class]
56
58
  end
57
59
 
58
60
  def read_cells(sheet=nil)
59
- sheet = @default_sheet unless sheet
61
+ sheet ||= @default_sheet
60
62
  @cell_type = {} unless @cell_type
61
63
  @cell = {} unless @cell
62
64
  @first_row[sheet] = 1
data/lib/roo/excel.rb CHANGED
@@ -1,127 +1,35 @@
1
1
  require 'rubygems'
2
2
  require 'spreadsheet'
3
+ require 'iconv'
3
4
  #require 'lib/roo/generic_spreadsheet'
4
5
  #require 'parseexcel'
5
- CHARGUESS = begin
6
- require 'charguess'
7
- true
8
- rescue LoadError => e
9
- false
10
- end
11
-
12
- # The Spreadsheet library has a bug in handling Excel
13
- # base dates so if the file is a 1904 base date then
14
- # dates are off by a day. 1900 base dates work fine
15
- module Spreadsheet
16
- module Excel
17
- class Row < Spreadsheet::Row
18
- def _date data # :nodoc:
19
- return data if data.is_a?(Date)
20
- date = @worksheet.date_base + data.to_i
21
- if LEAP_ERROR > @worksheet.date_base
22
- date -= 1
23
- end
24
- date
25
- end
26
- public :_datetime
27
- end
28
- end
29
- end
30
-
31
- #=====================================================================
32
- # TODO:
33
- # redefinition of this method, the method in the spreadsheet gem has a bug
34
- # redefinition can be removed, if spreadsheet does it in the correct way
35
- module Spreadsheet
36
- module Excel
37
- class Row < Spreadsheet::Row
38
- def _datetime data # :nodoc:
39
- return data if data.is_a?(DateTime)
40
- base = @worksheet.date_base
41
- date = base + data.to_f
42
- hour = (data % 1) * 24
43
- min = (hour % 1) * 60
44
- sec = ((min % 1) * 60).round
45
- min = min.floor
46
- hour = hour.floor
47
- if sec > 59
48
- sec = 0
49
- min += 1
50
- end
51
- if min > 59
52
- min = 0
53
- hour += 1
54
- end
55
- if hour > 23
56
- hour = 0
57
- date += 1
58
- end
59
- if LEAP_ERROR > base
60
- date -= 1
61
- end
62
- DateTime.new(date.year, date.month, date.day, hour, min, sec)
63
- end
64
- end
65
- end
66
- end
67
- #=====================================================================
68
-
69
- # ruby-spreadsheet has a font object so we're extending it
70
- # with our own functionality but still providing full access
71
- # to the user for other font information
72
- module ExcelFontExtensions
73
- def bold?(*args)
74
- #From ruby-spreadsheet doc: 100 <= weight <= 1000, bold => 700, normal => 400
75
- case weight
76
- when 700
77
- true
78
- else
79
- false
80
- end
81
- end
82
-
83
- def italic?
84
- italic
85
- end
86
-
87
- def underline?
88
- underline != :none
6
+ CHARGUESS =
7
+ begin
8
+ require 'charguess'
9
+ true
10
+ rescue LoadError
11
+ false
89
12
  end
90
13
 
91
- end
92
-
93
14
  # Class for handling Excel-Spreadsheets
94
- class Excel < GenericSpreadsheet
95
-
96
- EXCEL_NO_FORMULAS = 'Formulas are not supported for excel spreadsheets.'
15
+ class Roo::Excel < Roo::GenericSpreadsheet
97
16
 
98
17
  # Creates a new Excel spreadsheet object.
99
18
  # Parameter packed: :zip - File is a zip-file
100
19
  def initialize(filename, packed = nil, file_warning = :error)
101
- super()
102
- @file_warning = file_warning
103
- file_type_check(filename,'.xls','an Excel',packed)
104
- @tmpdir = GenericSpreadsheet.next_tmpdir
105
- @tmpdir = File.join(ENV['ROO_TMP'], @tmpdir) if ENV['ROO_TMP']
106
- unless File.exists?(@tmpdir)
107
- FileUtils::mkdir(@tmpdir)
108
- end
109
- filename = open_from_uri(filename) if filename[0,7] == "http://"
110
- filename = open_from_stream(filename[7..-1]) if filename[0,7] == "stream:"
111
- filename = unzip(filename) if packed and packed == :zip
112
- @filename = filename
113
- unless File.file?(@filename)
114
- FileUtils::rm_r(@tmpdir)
115
- raise IOError, "file #{@filename} does not exist"
116
- end
117
- begin
20
+ file_type_check(filename,'.xls','an Excel', file_warning, packed)
21
+ make_tmpdir do |tmpdir|
22
+ filename = open_from_uri(filename, tmpdir) if uri?(filename)
23
+ filename = open_from_stream(filename[7..-1], tmpdir) if filename[0,7] == "stream:"
24
+ filename = unzip(filename, tmpdir) if packed == :zip
25
+
26
+ @filename = filename
27
+ unless File.file?(@filename)
28
+ raise IOError, "file #{@filename} does not exist"
29
+ end
118
30
  @workbook = Spreadsheet.open(filename)
119
- rescue Ole::Storage::FormatError
120
- FileUtils::rm_r(@tmpdir)
121
- raise # nach aussen weiterhin sichtbar
122
31
  end
123
32
  @default_sheet = self.sheets.first
124
- FileUtils::rm_r(@tmpdir)
125
33
  @cell = Hash.new
126
34
  @cell_type = Hash.new
127
35
  @formula = Hash.new
@@ -134,6 +42,10 @@ class Excel < GenericSpreadsheet
134
42
  @fonts = Hash.new
135
43
  end
136
44
 
45
+ def encoding=(codepage)
46
+ @workbook.encoding = codepage
47
+ end
48
+
137
49
  # returns an array of sheet names in the spreadsheet
138
50
  def sheets
139
51
  @workbook.worksheets.collect {|worksheet| normalize_string(worksheet.name)}
@@ -141,8 +53,9 @@ class Excel < GenericSpreadsheet
141
53
 
142
54
  # returns the content of a cell. The upper left corner is (1,1) or ('A',1)
143
55
  def cell(row,col,sheet=nil)
144
- sheet = @default_sheet unless sheet
145
- raise ArgumentError unless sheet
56
+ sheet ||= @default_sheet
57
+ validate_sheet!(sheet)
58
+
146
59
  read_cells(sheet) unless @cells_read[sheet]
147
60
  raise "should be read" unless @cells_read[sheet]
148
61
  row,col = normalize(row,col)
@@ -170,18 +83,14 @@ class Excel < GenericSpreadsheet
170
83
  # * :time
171
84
  # * :datetime
172
85
  def celltype(row,col,sheet=nil)
173
- sheet = @default_sheet unless sheet
86
+ sheet ||= @default_sheet
174
87
  read_cells(sheet) unless @cells_read[sheet]
175
88
  row,col = normalize(row,col)
176
89
  begin
177
90
  if @formula[sheet] and @formula[sheet][[row,col]]
178
- return :formula
179
- else
180
- if @cell_type[sheet] and @cell_type[sheet][[row,col]]
181
- return @cell_type[sheet][[row,col]]
182
- else
183
- return nil
184
- end
91
+ :formula
92
+ elsif @cell_type[sheet]
93
+ @cell_type[sheet][[row,col]]
185
94
  end
186
95
  rescue
187
96
  puts "Error in sheet #{sheet}, row #{row}, col #{col}"
@@ -206,36 +115,20 @@ class Excel < GenericSpreadsheet
206
115
 
207
116
  # Given a cell, return the cell's font
208
117
  def font(row, col, sheet=nil)
209
- sheet = @default_sheet unless sheet
118
+ sheet ||= @default_sheet
210
119
  read_cells(sheet) unless @cells_read[sheet]
211
120
  row,col = normalize(row,col)
212
121
  @fonts[sheet][[row,col]]
213
- end
214
-
122
+ end
123
+
215
124
  # shows the internal representation of all cells
216
125
  # mainly for debugging purposes
217
126
  def to_s(sheet=nil)
218
- sheet = @default_sheet unless sheet
127
+ sheet ||= @default_sheet
219
128
  read_cells(sheet) unless @cells_read[sheet]
220
129
  @cell[sheet].inspect
221
130
  end
222
131
 
223
- # returns the row,col values of the labelled cell
224
- # (nil,nil) if label is not defined
225
- # sheet parameter is not really needed because label names are global
226
- # to the whole spreadsheet
227
- def label(labelname,sheet=nil)
228
- sheet = @default_sheet unless sheet
229
- read_cells(sheet) unless @cells_read[sheet]
230
- if @labels.has_key? labelname
231
- return @labels[labelname][1].to_i,
232
- GenericSpreadsheet.letter_to_number(@labels[labelname][2]),
233
- @labels[labelname][0]
234
- else
235
- return nil,nil,nil
236
- end
237
- end
238
-
239
132
  private
240
133
 
241
134
  # converts name of a sheet to index (0,1,2,..)
@@ -249,26 +142,6 @@ class Excel < GenericSpreadsheet
249
142
  raise StandardError, "sheet '#{name}' not found"
250
143
  end
251
144
 
252
- def empty_row?(row)
253
- content = false
254
- row.compact.each {|elem|
255
- if elem != ''
256
- content = true
257
- end
258
- }
259
- ! content
260
- end
261
-
262
- def empty_column?(col)
263
- content = false
264
- col.compact.each {|elem|
265
- if elem != ''
266
- content = true
267
- end
268
- }
269
- ! content
270
- end
271
-
272
145
  def normalize_string(value)
273
146
  value = every_second_null?(value) ? remove_every_second_null(value) : value
274
147
  if CHARGUESS && encoding = CharGuess::guess(value)
@@ -277,18 +150,17 @@ class Excel < GenericSpreadsheet
277
150
  platform_specific_iconv(value)
278
151
  end
279
152
  end
280
-
153
+
281
154
  def platform_specific_iconv(value)
282
- case RUBY_PLATFORM.downcase
283
- when /darwin/
284
- result = Iconv.new('utf-8','utf-8').iconv(value)
285
- when /solaris/
286
- result = Iconv.new('utf-8','utf-8').iconv(value)
287
- when /mswin32/
288
- result = Iconv.new('utf-8','iso-8859-1').iconv(value)
289
- else
290
- result = value
291
- end # case
155
+ result =
156
+ case RUBY_PLATFORM.downcase
157
+ when /darwin|solaris/
158
+ Iconv.new('utf-8','utf-8').iconv(value)
159
+ when /mswin32/
160
+ Iconv.new('utf-8','iso-8859-1').iconv(value)
161
+ else
162
+ value
163
+ end
292
164
  if every_second_null?(result)
293
165
  result = remove_every_second_null(result)
294
166
  end
@@ -299,10 +171,8 @@ class Excel < GenericSpreadsheet
299
171
  result = true
300
172
  return false if str.length < 2
301
173
  0.upto(str.length/2-1) do |i|
302
- c = str[i*2,1]
303
- n = str[i*2+1,1]
304
- if n != "\000"
305
- result = false
174
+ if str[i*2+1,1] != "\000"
175
+ result = false
306
176
  break
307
177
  end
308
178
  end
@@ -319,62 +189,81 @@ class Excel < GenericSpreadsheet
319
189
  end
320
190
 
321
191
  # helper function to set the internal representation of cells
322
- def set_cell_values(sheet,row,col,i,v,vt,formula,tr,font)
192
+ def set_cell_values(sheet,row,col,i,v,value_type,formula,tr,font)
323
193
  #key = "#{y},#{x+i}"
324
194
  key = [row,col+i]
325
195
  @cell_type[sheet] = {} unless @cell_type[sheet]
326
- @cell_type[sheet][key] = vt
196
+ @cell_type[sheet][key] = value_type
327
197
  @formula[sheet] = {} unless @formula[sheet]
328
198
  @formula[sheet][key] = formula if formula
329
199
  @cell[sheet] = {} unless @cell[sheet]
330
200
  @fonts[sheet] = {} unless @fonts[sheet]
331
201
  @fonts[sheet][key] = font
332
-
333
- case vt
334
- when :float
335
- @cell[sheet][key] = v.to_f
336
- when :string
337
- @cell[sheet][key] = v
338
- when :date
339
- @cell[sheet][key] = v
340
- when :datetime
341
- @cell[sheet][key] = DateTime.new(v.year,v.month,v.day,v.hour,v.min,v.sec)
342
- when :percentage
343
- @cell[sheet][key] = v.to_f
344
- when :time
345
- @cell[sheet][key] = v
346
- else
347
- @cell[sheet][key] = v
202
+
203
+ @cell[sheet][key] =
204
+ case value_type
205
+ when :float
206
+ v.to_f
207
+ when :string
208
+ v
209
+ when :date
210
+ v
211
+ when :datetime
212
+ @cell[sheet][key] = DateTime.new(v.year,v.month,v.day,v.hour,v.min,v.sec)
213
+ when :percentage
214
+ v.to_f
215
+ when :time
216
+ v
217
+ else
218
+ v
219
+ end
220
+ end
221
+
222
+ # ruby-spreadsheet has a font object so we're extending it
223
+ # with our own functionality but still providing full access
224
+ # to the user for other font information
225
+ module ExcelFontExtensions
226
+ def bold?(*args)
227
+ #From ruby-spreadsheet doc: 100 <= weight <= 1000, bold => 700, normal => 400
228
+ weight == 700
229
+ end
230
+
231
+ def italic?
232
+ italic
233
+ end
234
+
235
+ def underline?
236
+ underline != :none
348
237
  end
349
238
  end
350
239
 
351
240
  # read all cells in the selected sheet
352
241
  def read_cells(sheet=nil)
353
- sheet = @default_sheet unless sheet
354
- raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
355
- raise RangeError unless self.sheets.include? sheet
356
-
242
+ sheet ||= @default_sheet
243
+ validate_sheet!(sheet)
244
+
357
245
  if @cells_read[sheet]
358
246
  raise "sheet #{sheet} already read"
359
247
  end
360
-
248
+
361
249
  worksheet = @workbook.worksheet(sheet_no(sheet))
362
250
  row_index=1
363
- worksheet.each(0) do |row|
251
+ worksheet.each(0) do |row|
364
252
  (0..row.size).each do |cell_index|
365
253
  cell = row.at(cell_index)
366
254
  next if cell.nil? #skip empty cells
367
255
  next if cell.class == Spreadsheet::Formula && cell.value.nil? # skip empty formula cells
368
- if date_or_time?(row, cell_index)
369
- vt, v = read_cell_date_or_time(row, cell_index)
370
- else
371
- vt, v = read_cell(row, cell_index)
372
- end
256
+ value_type, v =
257
+ if date_or_time?(row, cell_index)
258
+ read_cell_date_or_time(row, cell_index)
259
+ else
260
+ read_cell(row, cell_index)
261
+ end
373
262
  formula = tr = nil #TODO:???
374
263
  col_index = cell_index + 1
375
264
  font = row.format(cell_index).font
376
265
  font.extend(ExcelFontExtensions)
377
- set_cell_values(sheet,row_index,col_index,0,v,vt,formula,tr,font)
266
+ set_cell_values(sheet,row_index,col_index,0,v,value_type,formula,tr,font)
378
267
  end #row
379
268
  row_index += 1
380
269
  end # worksheet
@@ -388,8 +277,8 @@ class Excel < GenericSpreadsheet
388
277
  cell = cell.value if cell.class == Spreadsheet::Formula
389
278
  cell
390
279
  end
391
-
392
- # Test the cell to see if it's a valid date/time.
280
+
281
+ # Test the cell to see if it's a valid date/time.
393
282
  def date_or_time?(row, idx)
394
283
  format = row.format(idx)
395
284
  if format.date_or_time?
@@ -397,11 +286,11 @@ class Excel < GenericSpreadsheet
397
286
  true if Float(cell) > 0 rescue false
398
287
  else
399
288
  false
400
- end
289
+ end
401
290
  end
402
291
  private :date_or_time?
403
-
404
- # Read the date-time cell and convert to,
292
+
293
+ # Read the date-time cell and convert to,
405
294
  # the date-time values for Roo
406
295
  def read_cell_date_or_time(row, idx)
407
296
  cell = read_cell_content(row, idx)
@@ -418,10 +307,10 @@ class Excel < GenericSpreadsheet
418
307
  value = h*3600+m*60+s
419
308
  else
420
309
  if row.at(idx).class == Spreadsheet::Formula
421
- datetime = row._datetime(cell)
310
+ datetime = row.send(:_datetime, cell)
422
311
  else
423
312
  datetime = row.datetime(idx)
424
- end
313
+ end
425
314
  if datetime.hour != 0 or
426
315
  datetime.min != 0 or
427
316
  datetime.sec != 0
@@ -430,23 +319,23 @@ class Excel < GenericSpreadsheet
430
319
  else
431
320
  value_type = :date
432
321
  if row.at(idx).class == Spreadsheet::Formula
433
- value = row._date(cell)
322
+ value = row.send(:_date, cell)
434
323
  else
435
324
  value = row.date(idx)
436
- end
325
+ end
437
326
  value = sprintf("%04d-%02d-%02d",value.year,value.month,value.day)
438
327
  end
439
- end
328
+ end
440
329
  return value_type, value
441
330
  end
442
331
  private :read_cell_date_or_time
443
-
444
- # Read the cell and based on the class,
332
+
333
+ # Read the cell and based on the class,
445
334
  # return the values for Roo
446
335
  def read_cell(row, idx)
447
336
  cell = read_cell_content(row, idx)
448
337
  case cell
449
- when Float, Integer, Fixnum, Bignum
338
+ when Float, Integer, Fixnum, Bignum
450
339
  value_type = :float
451
340
  value = cell.to_f
452
341
  when String, TrueClass, FalseClass
@@ -462,7 +351,7 @@ class Excel < GenericSpreadsheet
462
351
 
463
352
  def wait_for_version_080
464
353
  if Spreadsheet::VERSION<='0.8.0'
465
- raise EXCEL_NO_FORMULAS+
354
+ raise 'Formulas are not supported for excel spreadsheets.' +
466
355
  " We have to wait for the 0.8.0 version of the Spreadsheet gem (currently used version is #{Spreadsheet::VERSION})"
467
356
  else
468
357
  raise 'Thomas should implement formulas from Spreadsheet gem'