roo 1.10.1 → 1.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +38 -0
- data/History.txt +4 -4
- data/License.txt +20 -0
- data/Manifest.txt +68 -0
- data/README.markdown +109 -0
- data/Rakefile +5 -4
- data/bin/roo +0 -0
- data/examples/roo_soap_client.rb +53 -0
- data/examples/roo_soap_server.rb +29 -0
- data/examples/write_me.rb +33 -0
- data/lib/roo.rb +20 -61
- data/lib/roo/csv.rb +13 -11
- data/lib/roo/excel.rb +108 -219
- data/lib/roo/excel2003xml.rb +312 -0
- data/lib/roo/excelx.rb +205 -341
- data/lib/roo/generic_spreadsheet.rb +371 -268
- data/lib/roo/google.rb +64 -54
- data/lib/roo/openoffice.rb +101 -156
- data/lib/roo/roo_rails_helper.rb +5 -5
- data/lib/roo/worksheet.rb +18 -0
- data/roo.gemspec +43 -0
- data/scripts/txt2html +67 -0
- data/test/all_ss.rb +8 -10
- data/test/{1900_base.xls → files/1900_base.xls} +0 -0
- data/test/{1904_base.xls → files/1904_base.xls} +0 -0
- data/test/{Bibelbund.csv → files/Bibelbund.csv} +0 -0
- data/test/{Bibelbund.ods → files/Bibelbund.ods} +0 -0
- data/test/{Bibelbund.xls → files/Bibelbund.xls} +0 -0
- data/test/{Bibelbund.xlsx → files/Bibelbund.xlsx} +0 -0
- data/test/files/Bibelbund.xml +62518 -0
- data/test/{Bibelbund1.ods → files/Bibelbund1.ods} +0 -0
- data/test/{Pfand_from_windows_phone.xlsx → files/Pfand_from_windows_phone.xlsx} +0 -0
- data/test/files/bad_excel_date.xls +0 -0
- data/test/{bbu.ods → files/bbu.ods} +0 -0
- data/test/{bbu.xls → files/bbu.xls} +0 -0
- data/test/{bbu.xlsx → files/bbu.xlsx} +0 -0
- data/test/files/bbu.xml +152 -0
- data/test/{bode-v1.ods.zip → files/bode-v1.ods.zip} +0 -0
- data/test/{bode-v1.xls.zip → files/bode-v1.xls.zip} +0 -0
- data/test/{boolean.ods → files/boolean.ods} +0 -0
- data/test/{boolean.xls → files/boolean.xls} +0 -0
- data/test/{boolean.xlsx → files/boolean.xlsx} +0 -0
- data/test/files/boolean.xml +112 -0
- data/test/{borders.ods → files/borders.ods} +0 -0
- data/test/{borders.xls → files/borders.xls} +0 -0
- data/test/{borders.xlsx → files/borders.xlsx} +0 -0
- data/test/files/borders.xml +144 -0
- data/test/{bug-row-column-fixnum-float.xls → files/bug-row-column-fixnum-float.xls} +0 -0
- data/test/files/bug-row-column-fixnum-float.xml +127 -0
- data/test/{comments.ods → files/comments.ods} +0 -0
- data/test/{comments.xls → files/comments.xls} +0 -0
- data/test/{comments.xlsx → files/comments.xlsx} +0 -0
- data/test/{csvtypes.csv → files/csvtypes.csv} +0 -0
- data/test/{datetime.ods → files/datetime.ods} +0 -0
- data/test/{datetime.xls → files/datetime.xls} +0 -0
- data/test/{datetime.xlsx → files/datetime.xlsx} +0 -0
- data/test/files/datetime.xml +142 -0
- data/test/{datetime_floatconv.xls → files/datetime_floatconv.xls} +0 -0
- data/test/files/datetime_floatconv.xml +148 -0
- data/test/{dreimalvier.ods → files/dreimalvier.ods} +0 -0
- data/test/{emptysheets.ods → files/emptysheets.ods} +0 -0
- data/test/{emptysheets.xls → files/emptysheets.xls} +0 -0
- data/test/{emptysheets.xlsx → files/emptysheets.xlsx} +0 -0
- data/test/files/emptysheets.xml +105 -0
- data/test/files/excel2003.xml +21140 -0
- data/test/{false_encoding.xls → files/false_encoding.xls} +0 -0
- data/test/files/false_encoding.xml +132 -0
- data/test/{formula.ods → files/formula.ods} +0 -0
- data/test/{formula.xls → files/formula.xls} +0 -0
- data/test/{formula.xlsx → files/formula.xlsx} +0 -0
- data/test/files/formula.xml +134 -0
- data/test/files/formula_parse_error.xls +0 -0
- data/test/files/formula_parse_error.xml +1833 -0
- data/test/{formula_string_error.xlsx → files/formula_string_error.xlsx} +0 -0
- data/test/{html-escape.ods → files/html-escape.ods} +0 -0
- data/test/{matrix.ods → files/matrix.ods} +0 -0
- data/test/{matrix.xls → files/matrix.xls} +0 -0
- data/test/{named_cells.ods → files/named_cells.ods} +0 -0
- data/test/{named_cells.xls → files/named_cells.xls} +0 -0
- data/test/{named_cells.xlsx → files/named_cells.xlsx} +0 -0
- data/test/{no_spreadsheet_file.txt → files/no_spreadsheet_file.txt} +0 -0
- data/test/{numbers1.csv → files/numbers1.csv} +0 -0
- data/test/{numbers1.ods → files/numbers1.ods} +0 -0
- data/test/{numbers1.xls → files/numbers1.xls} +0 -0
- data/test/{numbers1.xlsx → files/numbers1.xlsx} +0 -0
- data/test/files/numbers1.xml +312 -0
- data/test/{only_one_sheet.ods → files/only_one_sheet.ods} +0 -0
- data/test/{only_one_sheet.xls → files/only_one_sheet.xls} +0 -0
- data/test/{only_one_sheet.xlsx → files/only_one_sheet.xlsx} +0 -0
- data/test/files/only_one_sheet.xml +67 -0
- data/test/{paragraph.ods → files/paragraph.ods} +0 -0
- data/test/{paragraph.xls → files/paragraph.xls} +0 -0
- data/test/{paragraph.xlsx → files/paragraph.xlsx} +0 -0
- data/test/files/paragraph.xml +127 -0
- data/test/{prova.xls → files/prova.xls} +0 -0
- data/test/{ric.ods → files/ric.ods} +0 -0
- data/test/{simple_spreadsheet.ods → files/simple_spreadsheet.ods} +0 -0
- data/test/{simple_spreadsheet.xls → files/simple_spreadsheet.xls} +0 -0
- data/test/{simple_spreadsheet.xlsx → files/simple_spreadsheet.xlsx} +0 -0
- data/test/files/simple_spreadsheet.xml +225 -0
- data/test/{simple_spreadsheet_from_italo.ods → files/simple_spreadsheet_from_italo.ods} +0 -0
- data/test/{simple_spreadsheet_from_italo.xls → files/simple_spreadsheet_from_italo.xls} +0 -0
- data/test/files/simple_spreadsheet_from_italo.xml +242 -0
- data/test/{so_datetime.csv → files/so_datetime.csv} +0 -0
- data/test/{style.ods → files/style.ods} +0 -0
- data/test/{style.xls → files/style.xls} +0 -0
- data/test/{style.xlsx → files/style.xlsx} +0 -0
- data/test/files/style.xml +154 -0
- data/test/{time-test.csv → files/time-test.csv} +0 -0
- data/test/{time-test.ods → files/time-test.ods} +0 -0
- data/test/{time-test.xls → files/time-test.xls} +0 -0
- data/test/{time-test.xlsx → files/time-test.xlsx} +0 -0
- data/test/files/time-test.xml +131 -0
- data/test/{type_excel.ods → files/type_excel.ods} +0 -0
- data/test/{type_excel.xlsx → files/type_excel.xlsx} +0 -0
- data/test/{type_excelx.ods → files/type_excelx.ods} +0 -0
- data/test/{type_excelx.xls → files/type_excelx.xls} +0 -0
- data/test/{type_openoffice.xls → files/type_openoffice.xls} +0 -0
- data/test/{type_openoffice.xlsx → files/type_openoffice.xlsx} +0 -0
- data/test/{whitespace.ods → files/whitespace.ods} +0 -0
- data/test/{whitespace.xls → files/whitespace.xls} +0 -0
- data/test/{whitespace.xlsx → files/whitespace.xlsx} +0 -0
- data/test/files/whitespace.xml +184 -0
- data/test/test_generic_spreadsheet.rb +257 -0
- data/test/test_helper.rb +167 -27
- data/test/test_roo.rb +1178 -930
- data/website/index.html +385 -0
- data/website/index.txt +423 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +130 -0
- data/website/template.rhtml +48 -0
- metadata +151 -121
- data/README.txt +0 -110
- 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
|
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
|
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
|
-
|
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
|
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 =
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
145
|
-
|
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
|
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
|
-
|
179
|
-
|
180
|
-
|
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
|
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
|
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
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
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
|
-
|
303
|
-
|
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,
|
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] =
|
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
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
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
|
354
|
-
|
355
|
-
|
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
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
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,
|
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
|
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
|
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
|
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'
|