roo 1.2.3 → 1.3.5
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.
- data/{README.txt → README.markdown} +11 -5
- data/lib/roo/excel.rb +141 -92
- data/lib/roo/excelx.rb +132 -127
- data/lib/roo/google.rb +84 -90
- data/lib/roo/openoffice.rb +136 -139
- data/lib/roo/roo_rails_helper.rb +1 -0
- data/lib/roo/version.rb +2 -2
- data/test/Bibelbund.xlsx +0 -0
- data/test/boolean.ods +0 -0
- data/test/boolean.xls +0 -0
- data/test/boolean.xlsx +0 -0
- data/test/datetime_floatconv.xls +0 -0
- data/test/false_encoding.xls +0 -0
- data/test/html-escape.ods +0 -0
- data/test/no_spreadsheet_file.txt +1 -1
- data/test/paragraph.ods +0 -0
- data/test/paragraph.xls +0 -0
- data/test/paragraph.xlsx +0 -0
- data/test/style.ods +0 -0
- data/test/style.xls +0 -0
- data/test/style.xlsx +0 -0
- data/test/test_roo.rb +440 -281
- metadata +69 -72
- data/License.txt +0 -20
- data/Manifest.txt +0 -68
- data/Rakefile +0 -171
- data/base64include.rb +0 -149
- data/examples/roo_soap_client.rb +0 -53
- data/examples/roo_soap_server.rb +0 -29
- data/examples/write_me.rb +0 -33
- data/scripts/txt2html +0 -67
- data/setup.rb +0 -1585
- data/website/index.html +0 -385
- data/website/index.txt +0 -423
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -130
- data/website/template.rhtml +0 -48
@@ -1,11 +1,17 @@
|
|
1
|
-
README for
|
2
|
-
==============
|
1
|
+
# README for Roo
|
3
2
|
|
4
|
-
|
3
|
+
This is now the official roo repository and I'll be making a release on RubyForge in the next few weeks.
|
5
4
|
|
6
|
-
sudo gem install roo
|
7
5
|
|
8
|
-
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
# Run the following if you haven't done so before:
|
9
|
+
gem sources -a http://gems.github.com/
|
10
|
+
|
11
|
+
# Install the gem:
|
12
|
+
sudo gem install hmcgowan-roo
|
13
|
+
|
14
|
+
## Usage:
|
9
15
|
|
10
16
|
require 'rubygems'
|
11
17
|
require 'roo'
|
data/lib/roo/excel.rb
CHANGED
@@ -1,16 +1,33 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
1
|
+
require 'spreadsheet'
|
2
|
+
CHARGUESS = begin
|
3
|
+
require 'charguess'
|
4
|
+
true
|
5
|
+
rescue LoadError => e
|
6
|
+
false
|
7
|
+
end
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
# ruby-spreadsheet has a font object so we're extending it
|
10
|
+
# with our own functionality but still providing full access
|
11
|
+
# to the user for other font information
|
12
|
+
module ExcelFontExtensions
|
13
|
+
def bold?(*args)
|
14
|
+
#From ruby-spreadsheet doc: 100 <= weight <= 1000, bold => 700, normal => 400
|
15
|
+
case weight
|
16
|
+
when 700
|
17
|
+
true
|
18
|
+
else
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def italic?
|
24
|
+
italic
|
13
25
|
end
|
26
|
+
|
27
|
+
def underline?
|
28
|
+
underline != :none
|
29
|
+
end
|
30
|
+
|
14
31
|
end
|
15
32
|
|
16
33
|
# Class for handling Excel-Spreadsheets
|
@@ -37,7 +54,7 @@ class Excel < GenericSpreadsheet
|
|
37
54
|
unless File.file?(@filename)
|
38
55
|
raise IOError, "file #{@filename} does not exist"
|
39
56
|
end
|
40
|
-
@workbook = Spreadsheet
|
57
|
+
@workbook = Spreadsheet.open(filename)
|
41
58
|
@default_sheet = nil
|
42
59
|
# no need to set default_sheet if there is only one sheet in the document
|
43
60
|
if self.sheets.size == 1
|
@@ -57,25 +74,14 @@ class Excel < GenericSpreadsheet
|
|
57
74
|
@last_column = Hash.new
|
58
75
|
@header_line = 1
|
59
76
|
@cells_read = Hash.new
|
77
|
+
@fonts = Hash.new
|
60
78
|
end
|
61
79
|
|
62
80
|
# returns an array of sheet names in the spreadsheet
|
63
81
|
def sheets
|
64
82
|
result = []
|
65
|
-
|
66
|
-
|
67
|
-
# TODO: is there a better way to do conversion?
|
68
|
-
if CHARGUESS
|
69
|
-
encoding = CharGuess::guess(@workbook.worksheet(i).name)
|
70
|
-
encoding = 'unicode' unless encoding
|
71
|
-
|
72
|
-
|
73
|
-
result << Iconv.new('utf-8',encoding).iconv(
|
74
|
-
@workbook.worksheet(i).name
|
75
|
-
)
|
76
|
-
else
|
77
|
-
result << platform_specific_iconv(@workbook.worksheet(i).name)
|
78
|
-
end
|
83
|
+
@workbook.worksheets.each do |worksheet|
|
84
|
+
result << normalize_string(worksheet.name)
|
79
85
|
end
|
80
86
|
return result
|
81
87
|
end
|
@@ -169,6 +175,14 @@ class Excel < GenericSpreadsheet
|
|
169
175
|
raise EXCEL_NO_FORMULAS
|
170
176
|
end
|
171
177
|
|
178
|
+
# Given a cell, return the cell's font
|
179
|
+
def font(row, col, sheet=nil)
|
180
|
+
sheet = @default_sheet unless sheet
|
181
|
+
read_cells(sheet) unless @cells_read[sheet]
|
182
|
+
row,col = normalize(row,col)
|
183
|
+
@fonts[sheet][[row,col]]
|
184
|
+
end
|
185
|
+
|
172
186
|
# shows the internal representation of all cells
|
173
187
|
# mainly for debugging purposes
|
174
188
|
def to_s(sheet=nil)
|
@@ -218,14 +232,10 @@ class Excel < GenericSpreadsheet
|
|
218
232
|
# converts name of a sheet to index (0,1,2,..)
|
219
233
|
def sheet_no(name)
|
220
234
|
return name-1 if name.kind_of?(Fixnum)
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
@workbook.worksheet(i).name)
|
226
|
-
#Iconv.new('utf-8','unicode').iconv(
|
227
|
-
# @workbook.worksheet(i).name
|
228
|
-
# )
|
235
|
+
i = 0
|
236
|
+
@workbook.worksheets.each do |worksheet|
|
237
|
+
return i if name == normalize_string(worksheet.name)
|
238
|
+
i += 1
|
229
239
|
end
|
230
240
|
raise StandardError, "sheet '#{name}' not found"
|
231
241
|
end
|
@@ -249,7 +259,16 @@ class Excel < GenericSpreadsheet
|
|
249
259
|
}
|
250
260
|
! content
|
251
261
|
end
|
252
|
-
|
262
|
+
|
263
|
+
def normalize_string(value)
|
264
|
+
value = every_second_null?(value) ? remove_every_second_null(value) : value
|
265
|
+
if CHARGUESS && encoding = CharGuess::guess(value)
|
266
|
+
Iconv.new('utf-8', encoding)
|
267
|
+
else
|
268
|
+
platform_specific_iconv(value)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
253
272
|
def platform_specific_iconv(value)
|
254
273
|
case RUBY_PLATFORM.downcase
|
255
274
|
when /darwin/
|
@@ -291,19 +310,22 @@ class Excel < GenericSpreadsheet
|
|
291
310
|
end
|
292
311
|
|
293
312
|
# helper function to set the internal representation of cells
|
294
|
-
def set_cell_values(sheet,
|
313
|
+
def set_cell_values(sheet,row,col,i,v,vt,formula,tr,font)
|
295
314
|
#key = "#{y},#{x+i}"
|
296
|
-
key = [
|
315
|
+
key = [row,col+i]
|
297
316
|
@cell_type[sheet] = {} unless @cell_type[sheet]
|
298
317
|
@cell_type[sheet][key] = vt
|
299
318
|
@formula[sheet] = {} unless @formula[sheet]
|
300
319
|
@formula[sheet][key] = formula if formula
|
301
320
|
@cell[sheet] = {} unless @cell[sheet]
|
321
|
+
@fonts[sheet] = {} unless @fonts[sheet]
|
322
|
+
@fonts[sheet][key] = font
|
323
|
+
|
302
324
|
case vt # @cell_type[sheet][key]
|
303
325
|
when :float
|
304
326
|
@cell[sheet][key] = v.to_f
|
305
327
|
when :string
|
306
|
-
@cell[sheet][key] =
|
328
|
+
@cell[sheet][key] = v
|
307
329
|
when :date
|
308
330
|
@cell[sheet][key] = v
|
309
331
|
when :datetime
|
@@ -328,63 +350,90 @@ class Excel < GenericSpreadsheet
|
|
328
350
|
end
|
329
351
|
|
330
352
|
worksheet = @workbook.worksheet(sheet_no(sheet))
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
case cell.type
|
342
|
-
when :numeric
|
343
|
-
vt = :float
|
344
|
-
v = cell.to_f
|
345
|
-
when :text
|
346
|
-
vt = :string
|
347
|
-
str_v = cell.to_s('utf-8')
|
348
|
-
when :date
|
349
|
-
if cell.to_s.to_f < 1.0
|
350
|
-
vt = :time
|
351
|
-
f = cell.to_s.to_f*24.0*60.0*60.0
|
352
|
-
secs = f.round
|
353
|
-
h = (secs / 3600.0).floor
|
354
|
-
secs = secs - 3600*h
|
355
|
-
m = (secs / 60.0).floor
|
356
|
-
secs = secs - 60*m
|
357
|
-
s = secs
|
358
|
-
v = h*3600+m*60+s
|
359
|
-
else
|
360
|
-
if cell.datetime.hour != 0 or
|
361
|
-
cell.datetime.min != 0 or
|
362
|
-
cell.datetime.sec != 0 or
|
363
|
-
cell.datetime.msec != 0
|
364
|
-
vt = :datetime
|
365
|
-
v = cell.datetime
|
366
|
-
else
|
367
|
-
vt = :date
|
368
|
-
v = cell.date
|
369
|
-
v = sprintf("%04d-%02d-%02d",v.year,v.month,v.day)
|
370
|
-
end
|
371
|
-
end
|
372
|
-
else
|
373
|
-
vt = cell.type.to_s.downcase.to_sym
|
374
|
-
v = nil
|
375
|
-
end # case
|
376
|
-
formula = tr = nil #TODO:???
|
377
|
-
set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v)
|
378
|
-
end # if cell
|
379
|
-
|
380
|
-
x += 1
|
353
|
+
row_index=1
|
354
|
+
worksheet.each(0) do |row|
|
355
|
+
(0..row.size).each do |cell_index|
|
356
|
+
cell = row.at(cell_index)
|
357
|
+
next if cell.nil? #skip empty cells
|
358
|
+
next if cell.class == Spreadsheet::Formula
|
359
|
+
if date_or_time?(row, cell_index)
|
360
|
+
vt, v = read_cell_date_or_time(row, cell_index)
|
361
|
+
else
|
362
|
+
vt, v = read_cell(row, cell_index)
|
381
363
|
end
|
382
|
-
|
383
|
-
|
384
|
-
|
364
|
+
formula = tr = nil #TODO:???
|
365
|
+
col_index = cell_index + 1
|
366
|
+
font = row.format(cell_index).font
|
367
|
+
font.extend(ExcelFontExtensions)
|
368
|
+
set_cell_values(sheet,row_index,col_index,0,v,vt,formula,tr,font)
|
369
|
+
end #row
|
370
|
+
row_index += 1
|
371
|
+
end # worksheet
|
385
372
|
@cells_read[sheet] = true
|
386
373
|
end
|
387
|
-
|
374
|
+
|
375
|
+
# Test the cell to see if it's a valid date/time.
|
376
|
+
def date_or_time?(row, idx)
|
377
|
+
format = row.format(idx)
|
378
|
+
if format.date_or_time?
|
379
|
+
cell = row.at(idx)
|
380
|
+
true if Float(cell) > 0 rescue false
|
381
|
+
else
|
382
|
+
false
|
383
|
+
end
|
384
|
+
end
|
385
|
+
private :date_or_time?
|
386
|
+
|
387
|
+
# Read the date-time cell and convert to,
|
388
|
+
# the date-time values for Roo
|
389
|
+
def read_cell_date_or_time(row, idx)
|
390
|
+
cell = row.at(idx).to_s.to_f
|
391
|
+
if cell < 1.0
|
392
|
+
value_type = :time
|
393
|
+
f = cell*24.0*60.0*60.0
|
394
|
+
secs = f.round
|
395
|
+
h = (secs / 3600.0).floor
|
396
|
+
secs = secs - 3600*h
|
397
|
+
m = (secs / 60.0).floor
|
398
|
+
secs = secs - 60*m
|
399
|
+
s = secs
|
400
|
+
value = h*3600+m*60+s
|
401
|
+
else
|
402
|
+
datetime = row.datetime(idx)
|
403
|
+
if datetime.hour != 0 or
|
404
|
+
datetime.min != 0 or
|
405
|
+
datetime.sec != 0
|
406
|
+
value_type = :datetime
|
407
|
+
value = datetime
|
408
|
+
else
|
409
|
+
value_type = :date
|
410
|
+
value = row.date(idx)
|
411
|
+
value = sprintf("%04d-%02d-%02d",value.year,value.month,value.day)
|
412
|
+
end
|
413
|
+
end
|
414
|
+
return value_type, value
|
415
|
+
end
|
416
|
+
private :read_cell_date_or_time
|
417
|
+
|
418
|
+
# Read the cell and based on the class,
|
419
|
+
# return the values for Roo
|
420
|
+
def read_cell(row, idx)
|
421
|
+
cell = row.at(idx)
|
422
|
+
case cell
|
423
|
+
when Float, Integer, Fixnum, Bignum
|
424
|
+
value_type = :float
|
425
|
+
value = cell.to_f
|
426
|
+
when String, TrueClass, FalseClass
|
427
|
+
value_type = :string
|
428
|
+
value = cell.to_s
|
429
|
+
else
|
430
|
+
value_type = cell.class.to_s.downcase.to_sym
|
431
|
+
value = nil
|
432
|
+
end # case
|
433
|
+
return value_type, value
|
434
|
+
end
|
435
|
+
private :read_cell
|
436
|
+
|
388
437
|
#TODO: testing only
|
389
438
|
# def inject_null_characters(str)
|
390
439
|
# if str.class != String
|
data/lib/roo/excelx.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'rubygems'
|
3
|
-
require 'rexml/document'
|
1
|
+
require 'xml'
|
4
2
|
require 'fileutils'
|
5
3
|
require 'zip/zipfilesystem'
|
6
4
|
require 'date'
|
@@ -102,26 +100,27 @@ class Excelx < GenericSpreadsheet
|
|
102
100
|
@file_nr = @@nr
|
103
101
|
extract_content(@filename)
|
104
102
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_workbook.xml"))
|
105
|
-
@workbook_doc =
|
103
|
+
@workbook_doc = XML::Parser.io(file).parse
|
106
104
|
file.close
|
107
105
|
@shared_table = []
|
108
106
|
if File.exist?(File.join(@tmpdir, @file_nr.to_s+'_roo_sharedStrings.xml'))
|
109
107
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+'_roo_sharedStrings.xml'))
|
110
|
-
@sharedstring_doc =
|
108
|
+
@sharedstring_doc = XML::Parser.io(file).parse
|
111
109
|
file.close
|
112
110
|
read_shared_strings(@sharedstring_doc)
|
113
111
|
end
|
114
112
|
@styles_table = []
|
113
|
+
@style_definitions = Array.new { |h,k| h[k] = {} }
|
115
114
|
if File.exist?(File.join(@tmpdir, @file_nr.to_s+'_roo_styles.xml'))
|
116
115
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+'_roo_styles.xml'))
|
117
|
-
@styles_doc =
|
116
|
+
@styles_doc = XML::Parser.io(file).parse
|
118
117
|
file.close
|
119
118
|
read_styles(@styles_doc)
|
120
119
|
end
|
121
120
|
@sheet_doc = []
|
122
121
|
@sheet_files.each_with_index do |item, i|
|
123
122
|
file = File.new(item)
|
124
|
-
@sheet_doc[i] =
|
123
|
+
@sheet_doc[i] = XML::Parser.io(file).parse
|
125
124
|
file.close
|
126
125
|
end
|
127
126
|
ensure
|
@@ -163,7 +162,6 @@ class Excelx < GenericSpreadsheet
|
|
163
162
|
yyyy,mm,dd = date_part.split('-')
|
164
163
|
hh,mi,ss = time_part.split(':')
|
165
164
|
return DateTime.civil(yyyy.to_i,mm.to_i,dd.to_i,hh.to_i,mi.to_i,ss.to_i)
|
166
|
-
|
167
165
|
end
|
168
166
|
@cell[sheet][[row,col]]
|
169
167
|
end
|
@@ -189,6 +187,33 @@ class Excelx < GenericSpreadsheet
|
|
189
187
|
row,col = normalize(row,col)
|
190
188
|
formula(row,col) != nil
|
191
189
|
end
|
190
|
+
|
191
|
+
class Font
|
192
|
+
attr_accessor :bold, :italic, :underline
|
193
|
+
|
194
|
+
def bold?
|
195
|
+
@bold == true
|
196
|
+
end
|
197
|
+
|
198
|
+
def italic?
|
199
|
+
@italic == true
|
200
|
+
end
|
201
|
+
|
202
|
+
def underline?
|
203
|
+
@underline == true
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Given a cell, return the cell's style
|
208
|
+
def font(row, col, sheet=nil)
|
209
|
+
sheet = @default_sheet unless sheet
|
210
|
+
read_cells(sheet) unless @cells_read[sheet]
|
211
|
+
row,col = normalize(row,col)
|
212
|
+
s_attribute = @s_attribute[sheet][[row,col]]
|
213
|
+
s_attribute ||= 0
|
214
|
+
s_attribute = s_attribute.to_i
|
215
|
+
@style_definitions[s_attribute]
|
216
|
+
end
|
192
217
|
|
193
218
|
# set a cell to a certain value
|
194
219
|
# (this will not be saved back to the spreadsheet file!)
|
@@ -260,18 +285,11 @@ class Excelx < GenericSpreadsheet
|
|
260
285
|
# returns an array of sheet names in the spreadsheet
|
261
286
|
def sheets
|
262
287
|
return_sheets = []
|
263
|
-
@workbook_doc.
|
264
|
-
|
265
|
-
if el.name == "sheets"
|
266
|
-
el.each_element do |sheet|
|
267
|
-
return_sheets << sheet.attributes['name']
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
288
|
+
@workbook_doc.find("//*[local-name()='sheet']").each do |sheet|
|
289
|
+
return_sheets << sheet.attributes.to_h['name']
|
271
290
|
end
|
272
291
|
return_sheets
|
273
292
|
end
|
274
|
-
|
275
293
|
# shows the internal representation of all cells
|
276
294
|
# for debugging purposes
|
277
295
|
def to_s(sheet=nil)
|
@@ -376,82 +394,62 @@ class Excelx < GenericSpreadsheet
|
|
376
394
|
raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
|
377
395
|
raise RangeError unless self.sheets.include? sheet
|
378
396
|
n = self.sheets.index(sheet)
|
379
|
-
@sheet_doc[n].
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
#puts cell.name
|
403
|
-
if tmp_type == :time or tmp_type == :datetime #2008-07-26
|
404
|
-
#p cell.text
|
405
|
-
# p cell.text.to_f if cell.text.include? "22606.5120"
|
406
|
-
if cell.text.to_f >= 1.0 # 2008-07-26
|
407
|
-
# puts ">= 1.0" if cell.text.include? "22606.5120"
|
408
|
-
# puts "cell.text.to_f: #{cell.text.to_f}" if cell.text.include? "22606.5120"
|
409
|
-
#puts "cell.text.to_f.floor: #{cell.text.to_f.floor}" if cell.text.include? "22606.5120"
|
410
|
-
if (cell.text.to_f - cell.text.to_f.floor).abs > 0.000001 #TODO:
|
411
|
-
# puts "abs ist groesser" if cell.text.include? "22606.5120"
|
412
|
-
# @cell[sheet][key] = DateTime.parse(tr.attributes['date-value'])
|
413
|
-
tmp_type = :datetime
|
414
|
-
|
415
|
-
else
|
416
|
-
#puts ":date"
|
417
|
-
tmp_type = :date # 2008-07-26
|
418
|
-
end
|
419
|
-
else
|
420
|
-
#puts "<1.0"
|
421
|
-
end # 2008-07-26
|
422
|
-
end # 2008-07-26
|
423
|
-
excelx_type = [:numeric_or_formula,format]
|
424
|
-
excelx_value = cell.text
|
425
|
-
if tmp_type == :shared
|
426
|
-
vt = :string
|
427
|
-
str_v = @shared_table[cell.text.to_i]
|
428
|
-
excelx_type = :string
|
429
|
-
elsif tmp_type == :date
|
430
|
-
vt = :date
|
431
|
-
v = cell.text
|
432
|
-
elsif tmp_type == :time
|
433
|
-
vt = :time
|
434
|
-
v = cell.text
|
435
|
-
elsif tmp_type == :datetime
|
436
|
-
vt = :datetime
|
437
|
-
v = cell.text
|
438
|
-
elsif tmp_type == :formula
|
439
|
-
vt = :formula
|
440
|
-
v = cell.text.to_f #TODO: !!!!
|
441
|
-
else
|
442
|
-
vt = :float
|
443
|
-
v = cell.text
|
444
|
-
end
|
445
|
-
#puts "vt: #{vt}" if cell.text.include? "22606.5120"
|
446
|
-
x,y = split_coordinate(row.attributes['r'])
|
447
|
-
tr=nil #TODO: ???s
|
448
|
-
set_cell_values(sheet,x,y,0,v,vt,formula,tr,str_v,excelx_type,excelx_value,s_attribute)
|
449
|
-
end
|
450
|
-
end
|
451
|
-
end
|
397
|
+
@sheet_doc[n].find("//*[local-name()='c']").each do |c|
|
398
|
+
s_attribute = c.attributes.to_h['s'].to_i # should be here
|
399
|
+
if (c.attributes.to_h['t'] == 's')
|
400
|
+
tmp_type = :shared
|
401
|
+
elsif (c.attributes.to_h['t'] == 'b')
|
402
|
+
tmp_type = :boolean
|
403
|
+
else
|
404
|
+
# s_attribute = c.attributes.to_h['s'].to_i # was here
|
405
|
+
format = attribute2format(s_attribute)
|
406
|
+
tmp_type = format2type(format)
|
407
|
+
end
|
408
|
+
formula = nil
|
409
|
+
c.each_element do |cell|
|
410
|
+
if cell.name == 'f'
|
411
|
+
formula = cell.content
|
412
|
+
end
|
413
|
+
if cell.name == 'v'
|
414
|
+
if tmp_type == :time or tmp_type == :datetime
|
415
|
+
if cell.content.to_f >= 1.0
|
416
|
+
if (cell.content.to_f - cell.content.to_f.floor).abs > 0.000001
|
417
|
+
tmp_type = :datetime
|
418
|
+
else
|
419
|
+
tmp_type = :date
|
452
420
|
end
|
453
|
-
|
421
|
+
else
|
422
|
+
end
|
423
|
+
end
|
424
|
+
excelx_type = [:numeric_or_formula,format]
|
425
|
+
excelx_value = cell.content
|
426
|
+
if tmp_type == :shared
|
427
|
+
vt = :string
|
428
|
+
str_v = @shared_table[cell.content.to_i]
|
429
|
+
excelx_type = :string
|
430
|
+
elsif tmp_type == :boolean
|
431
|
+
vt = :boolean
|
432
|
+
cell.content.to_i == 1 ? v = 'TRUE' : v = 'FALSE'
|
433
|
+
elsif tmp_type == :date
|
434
|
+
vt = :date
|
435
|
+
v = cell.content
|
436
|
+
elsif tmp_type == :time
|
437
|
+
vt = :time
|
438
|
+
v = cell.content
|
439
|
+
elsif tmp_type == :datetime
|
440
|
+
vt = :datetime
|
441
|
+
v = cell.content
|
442
|
+
elsif tmp_type == :formula
|
443
|
+
vt = :formula
|
444
|
+
v = cell.content.to_f #TODO: !!!!
|
445
|
+
else
|
446
|
+
vt = :float
|
447
|
+
v = cell.content
|
454
448
|
end
|
449
|
+
#puts "vt: #{vt}" if cell.text.include? "22606.5120"
|
450
|
+
x,y = split_coordinate(c.attributes.to_h['r'])
|
451
|
+
tr=nil #TODO: ???s
|
452
|
+
set_cell_values(sheet,x,y,0,v,vt,formula,tr,str_v,excelx_type,excelx_value,s_attribute)
|
455
453
|
end
|
456
454
|
end
|
457
455
|
end
|
@@ -467,17 +465,9 @@ class Excelx < GenericSpreadsheet
|
|
467
465
|
def check_default_sheet
|
468
466
|
sheet_found = false
|
469
467
|
raise ArgumentError, "Error: default_sheet not set" if @default_sheet == nil
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
el.each_element do |sheet|
|
474
|
-
if @default_sheet == sheet.attributes['name']
|
475
|
-
sheet_found = true
|
476
|
-
end
|
477
|
-
end
|
478
|
-
end
|
479
|
-
end
|
480
|
-
end
|
468
|
+
|
469
|
+
sheet_found = true if sheets.include?(@default_sheet)
|
470
|
+
|
481
471
|
if ! sheet_found
|
482
472
|
raise RangeError, "sheet '#{@default_sheet}' not found"
|
483
473
|
end
|
@@ -537,18 +527,21 @@ class Excelx < GenericSpreadsheet
|
|
537
527
|
|
538
528
|
# read the shared strings xml document
|
539
529
|
def read_shared_strings(doc)
|
540
|
-
doc.
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
end
|
530
|
+
doc.find("//*[local-name()='si']").each do |si|
|
531
|
+
shared_table_entry = ''
|
532
|
+
si.each_element do |elem|
|
533
|
+
if (elem.name == 'r')
|
534
|
+
elem.each_element do |r_elem|
|
535
|
+
if (r_elem.name == 't')
|
536
|
+
shared_table_entry << r_elem.content
|
548
537
|
end
|
549
538
|
end
|
550
539
|
end
|
540
|
+
if (elem.name == 't')
|
541
|
+
shared_table_entry = elem.content
|
542
|
+
end
|
551
543
|
end
|
544
|
+
@shared_table << shared_table_entry
|
552
545
|
end
|
553
546
|
end
|
554
547
|
|
@@ -556,28 +549,40 @@ class Excelx < GenericSpreadsheet
|
|
556
549
|
def read_styles(doc)
|
557
550
|
@numFmts = []
|
558
551
|
@cellXfs = []
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
552
|
+
fonts = []
|
553
|
+
|
554
|
+
doc.find("//*[local-name()='numFmt']").each do |numFmt|
|
555
|
+
numFmtId = numFmt.attributes.to_h['numFmtId']
|
556
|
+
formatCode = numFmt.attributes.to_h['formatCode']
|
557
|
+
@numFmts << [numFmtId, formatCode]
|
558
|
+
end
|
559
|
+
doc.find("//*[local-name()='fonts']").each do |fonts_el|
|
560
|
+
fonts_el.each_element do |font_el|
|
561
|
+
if font_el.name == 'font'
|
562
|
+
font = Excelx::Font.new
|
563
|
+
font_el.each_element do |font_sub_el|
|
564
|
+
case font_sub_el.name
|
565
|
+
when 'b'
|
566
|
+
font.bold = true
|
567
|
+
when 'i'
|
568
|
+
font.italic = true
|
569
|
+
when 'u'
|
570
|
+
font.underline = true
|
575
571
|
end
|
576
|
-
end
|
577
572
|
end
|
573
|
+
fonts << font
|
578
574
|
end
|
579
575
|
end
|
580
576
|
end
|
577
|
+
|
578
|
+
doc.find("//*[local-name()='cellXfs']").each do |xfs|
|
579
|
+
xfs.each do |xf|
|
580
|
+
numFmtId = xf.attributes.to_h['numFmtId']
|
581
|
+
@cellXfs << [numFmtId]
|
582
|
+
fontId = xf.attributes.to_h['fontId'].to_i
|
583
|
+
@style_definitions << fonts[fontId]
|
584
|
+
end
|
585
|
+
end
|
581
586
|
end
|
582
587
|
|
583
588
|
# convert internal excelx attribute to a format
|