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.
@@ -1,4 +1,5 @@
1
1
  require 'gdata/spreadsheet'
2
+ require 'xml'
2
3
 
3
4
  # overwrite some methods from the gdata-gem:
4
5
  module GData
@@ -45,7 +46,7 @@ XML
45
46
  def add_to_cell_roo(row,col,value, sheet_no=1)
46
47
  save_entry_roo(entry_roo(value,row,col), sheet_no)
47
48
  end
48
-
49
+
49
50
  #-- new
50
51
  def get_one_sheet
51
52
  path = "/feeds/cells/#{@spreadsheet_id}/1/private/full"
@@ -70,11 +71,13 @@ XML
70
71
  doc = Hpricot(request(path))
71
72
  return doc
72
73
  end
74
+
73
75
  end # class
74
76
  end # module
75
77
 
76
78
  class Google < GenericSpreadsheet
77
-
79
+ attr_accessor :date_format, :datetime_format
80
+
78
81
  # Creates a new Google spreadsheet object.
79
82
  def initialize(spreadsheetkey,user=nil,password=nil)
80
83
  @filename = spreadsheetkey
@@ -88,8 +91,8 @@ class Google < GenericSpreadsheet
88
91
  password = ENV['GOOGLE_PASSWORD']
89
92
  end
90
93
  @default_sheet = nil
91
- @cell = Hash.new
92
- @cell_type = Hash.new
94
+ @cell = Hash.new {|h,k| h[k]=Hash.new}
95
+ @cell_type = Hash.new {|h,k| h[k]=Hash.new}
93
96
  @formula = Hash.new
94
97
  @first_row = Hash.new
95
98
  @last_row = Hash.new
@@ -97,10 +100,12 @@ class Google < GenericSpreadsheet
97
100
  @last_column = Hash.new
98
101
  @cells_read = Hash.new
99
102
  @header_line = 1
100
-
103
+ @date_format = '%d/%m/%Y'
104
+ @datetime_format = '%d/%m/%Y %H:%M:%S'
105
+ @time_format = '%H:%M:%S'
101
106
  @gs = GData::Spreadsheet.new(spreadsheetkey)
102
107
  @gs.authenticate(user, password)
103
-
108
+ @sheetlist = @gs.sheetlist
104
109
  #-- ----------------------------------------------------------------------
105
110
  #-- TODO: Behandlung von Berechtigungen hier noch einbauen ???
106
111
  #-- ----------------------------------------------------------------------
@@ -112,32 +117,42 @@ class Google < GenericSpreadsheet
112
117
 
113
118
  # returns an array of sheet names in the spreadsheet
114
119
  def sheets
115
- return @gs.sheetlist
120
+ @sheetlist
116
121
  end
117
122
 
118
- # is String a date with format DD/MM/YYYY
119
- def Google.date?(string)
120
- return false if string.class == Float
121
- return true if string.class == Date
122
- return string.strip =~ /^([0-9]+)\/([0-9]+)\/([0-9]+)$/
123
+ def date?(string)
124
+ begin
125
+ Date.strptime(string, @date_format)
126
+ true
127
+ rescue
128
+ false
129
+ end
123
130
  end
124
131
 
125
132
  # is String a time with format HH:MM:SS?
126
- def Google.time?(string)
127
- return false if string.class == Float
128
- return true if string.class == Date
129
- return string.strip =~ /^([0-9]+):([0-9]+):([0-9]+)$/
133
+ def time?(string)
134
+ begin
135
+ DateTime.strptime(string, @time_format)
136
+ true
137
+ rescue
138
+ false
139
+ end
130
140
  end
131
141
 
132
- # is String a date+time with format DD/MM/YYYY HH:MM:SS
133
- def Google.datetime?(string)
134
- return false if string.class == Float
135
- return true if string.class == Date
136
- return string.strip =~ /^([0-9]+)\/([0-9]+)\/([0-9]+)\ ([0-9]+):([0-9]+):([0-9]+)$/
142
+ def datetime?(string)
143
+ begin
144
+ DateTime.strptime(string, @datetime_format)
145
+ true
146
+ rescue
147
+ false
148
+ end
137
149
  end
138
150
 
151
+ def numeric?(string)
152
+ string =~ /^[0-9]+[\.]*[0-9]*$/
153
+ end
139
154
 
140
- def Google.timestring_to_seconds(value)
155
+ def timestring_to_seconds(value)
141
156
  hms = value.split(':')
142
157
  hms[0].to_i*3600 + hms[1].to_i*60 + hms[2].to_i
143
158
  end
@@ -151,24 +166,21 @@ class Google < GenericSpreadsheet
151
166
  check_default_sheet #TODO: 2007-12-16
152
167
  read_cells(sheet) unless @cells_read[sheet]
153
168
  row,col = normalize(row,col)
169
+ value = @cell[sheet]["#{row},#{col}"]
154
170
  if celltype(row,col,sheet) == :date
155
- yyyy,mm,dd = @cell[sheet]["#{row},#{col}"].split('-')
156
171
  begin
157
- return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
172
+ return Date.strptime(value, @date_format)
158
173
  rescue ArgumentError
159
- raise "Invalid date parameter: #{yyyy}, #{mm}, #{dd}"
174
+ raise "Invalid Date #{sheet}[#{row},#{col}] #{value} using format '{@date_format}'"
160
175
  end
161
176
  elsif celltype(row,col,sheet) == :datetime
162
177
  begin
163
- date_part,time_part = @cell[sheet]["#{row},#{col}"].split(' ')
164
- yyyy,mm,dd = date_part.split('-')
165
- hh,mi,ss = time_part.split(':')
166
- return DateTime.civil(yyyy.to_i,mm.to_i,dd.to_i,hh.to_i,mi.to_i,ss.to_i)
178
+ return DateTime.strptime(value, @datetime_format)
167
179
  rescue ArgumentError
168
- raise "Invalid date parameter: #{yyyy}, #{mm}, #{dd}, #{hh}, #{mi}, #{ss}"
180
+ raise "Invalid DateTime #{sheet}[#{row},#{col}] #{value} using format '{@datetime_format}'"
169
181
  end
170
182
  end
171
- return @cell[sheet]["#{row},#{col}"]
183
+ return value
172
184
  end
173
185
 
174
186
  # returns the type of a cell:
@@ -291,8 +303,15 @@ class Google < GenericSpreadsheet
291
303
  end
292
304
  row,col = normalize(row,col)
293
305
  @gs.add_to_cell_roo(row,col,value,sheet_no)
306
+ # re-read the portion of the document that has changed
307
+ if @cells_read[sheet]
308
+ key = "#{row},#{col}"
309
+ (value, value_type) = determine_datatype(value.to_s)
310
+ @cell[sheet][key] = value
311
+ @cell_type[sheet][key] = value_type
312
+ end
294
313
  end
295
-
314
+
296
315
  # returns the first non-empty row in a sheet
297
316
  def first_row(sheet=nil)
298
317
  sheet = @default_sheet unless sheet
@@ -335,77 +354,52 @@ class Google < GenericSpreadsheet
335
354
 
336
355
  private
337
356
 
338
- # read all cells in a sheet
357
+ # read all cells in a sheet.
339
358
  def read_cells(sheet=nil)
340
359
  sheet = @default_sheet unless sheet
341
360
  raise RangeError, "illegal sheet <#{sheet}>" unless sheets.index(sheet)
342
361
  sheet_no = sheets.index(sheet)+1
343
- doc = @gs.fulldoc(sheet_no)
344
- (doc/"gs:cell").each {|item|
362
+ xml = @gs.fulldoc(sheet_no).to_s
363
+ doc = XML::Parser.string(xml).parse
364
+ doc.find("//*[local-name()='cell']").each do |item|
345
365
  row = item['row']
346
366
  col = item['col']
347
- value = item['inputvalue']
348
- numericvalue = item['numericvalue']
349
- if value[0,1] == '='
350
- formula = value
367
+ key = "#{row},#{col}"
368
+ string_value = item['inputvalue'] || item['inputValue']
369
+ numeric_value = item['numericvalue'] || item['numericValue']
370
+ (value, value_type) = determine_datatype(string_value, numeric_value)
371
+ @cell[sheet][key] = value unless value == "" or value == nil
372
+ @cell_type[sheet][key] = value_type
373
+ @formula[sheet] = {} unless @formula[sheet]
374
+ @formula[sheet][key] = string_value if value_type == :formula
375
+ end
376
+ @cells_read[sheet] = true
377
+ end
378
+
379
+ def determine_datatype(val, numval=nil)
380
+ if val[0,1] == '='
381
+ ty = :formula
382
+ if numeric?(numval)
383
+ val = numval.to_f
351
384
  else
352
- formula = nil
385
+ val = numval
353
386
  end
354
- @cell_type[sheet] = {} unless @cell_type[sheet]
355
- if formula
356
- ty = :formula
357
- if numeric?(numericvalue)
358
- value = numericvalue.to_f
359
- else
360
- value = numericvalue
361
- end
362
- elsif Google.date?(value)
363
- ty = :date
364
- elsif Google.datetime?(value)
387
+ else
388
+ if datetime?(val)
365
389
  ty = :datetime
366
- elsif numeric?(value) # or o.class ???
390
+ elsif date?(val)
391
+ ty = :date
392
+ elsif numeric?(val)
367
393
  ty = :float
368
- value = value.to_f
369
- elsif Google.time?(value)
394
+ val = val.to_f
395
+ elsif time?(val)
370
396
  ty = :time
371
- value = Google.timestring_to_seconds(value)
397
+ val = timestring_to_seconds(val)
372
398
  else
373
399
  ty = :string
374
400
  end
375
- key = "#{row},#{col}"
376
- @cell[sheet] = {} unless @cell[sheet]
377
- if ty == :date
378
- dd,mm,yyyy = value.split('/')
379
- @cell[sheet][key] = sprintf("%04d-%02d-%02d",yyyy.to_i,mm.to_i,dd.to_i)
380
- elsif ty == :datetime
381
- date_part,time_part = value.split(' ')
382
- dd,mm,yyyy = date_part.split('/')
383
- hh,mi,ss = time_part.split(':')
384
- @cell[sheet][key] = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
385
- yyyy.to_i,mm.to_i,dd.to_i,hh.to_i,mi.to_i,ss.to_i)
386
- else
387
- @cell[sheet][key] = value unless value == "" or value == nil
388
- end
389
- @cell_type[sheet][key] = ty # Openoffice.oo_type_2_roo_type(vt)
390
- @formula[sheet] = {} unless @formula[sheet]
391
- @formula[sheet][key] = formula if formula
392
- }
393
- @cells_read[sheet] = true
401
+ end
402
+ return val, ty
394
403
  end
395
-
396
- def numeric?(string)
397
- string =~ /^[0-9]+[\.]*[0-9]*$/
398
- end
399
-
400
- # convert string DD/MM/YYYY into a Date-object
401
- #TODO: was ist mit verschiedenen Typen der Datumseingabe bei Google?
402
- def Google.to_date(string)
403
- if string.strip =~ /^([0-9]+)\/([0-9]+)\/([0-9]+)$/
404
- return Date.new($3.to_i,$2.to_i,$1.to_i)
405
- else
406
- return nil
407
- end
408
- end
409
-
410
-
404
+
411
405
  end # class
@@ -1,10 +1,9 @@
1
-
2
- require 'rubygems'
3
- require 'rexml/document'
1
+ require 'xml'
4
2
  require 'fileutils'
5
3
  require 'zip/zipfilesystem'
6
4
  require 'date'
7
5
  require 'base64'
6
+ require 'cgi'
8
7
 
9
8
  class Openoffice < GenericSpreadsheet
10
9
 
@@ -37,7 +36,7 @@ class Openoffice < GenericSpreadsheet
37
36
  @file_nr = @@nr
38
37
  extract_content
39
38
  file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_content.xml"))
40
- @doc = REXML::Document.new file
39
+ @doc = XML::Parser.io(file).parse
41
40
  file.close
42
41
  ensure
43
42
  #if ENV["roo_local"] != "thomas-p"
@@ -56,6 +55,9 @@ class Openoffice < GenericSpreadsheet
56
55
  @last_row = Hash.new
57
56
  @first_column = Hash.new
58
57
  @last_column = Hash.new
58
+ @style = Hash.new
59
+ @style_defaults = Hash.new { |h,k| h[k] = [] }
60
+ @style_definitions = Hash.new
59
61
  @header_line = 1
60
62
  end
61
63
 
@@ -107,7 +109,32 @@ class Openoffice < GenericSpreadsheet
107
109
  row,col = normalize(row,col)
108
110
  formula(row,col) != nil
109
111
  end
112
+
113
+ class Font
114
+ attr_accessor :bold, :italic, :underline
115
+
116
+ def bold?
117
+ @bold == 'bold'
118
+ end
119
+
120
+ def italic?
121
+ @italic == 'italic'
122
+ end
123
+
124
+ def underline?
125
+ @underline != nil
126
+ end
127
+ end
110
128
 
129
+ # Given a cell, return the cell's style
130
+ def font(row, col, sheet=nil)
131
+ sheet = @default_sheet unless sheet
132
+ read_cells(sheet) unless @cells_read[sheet]
133
+ row,col = normalize(row,col)
134
+ style_name = @style[sheet][[row,col]] || @style_defaults[sheet][col - 1] || 'Default'
135
+ @style_definitions[style_name]
136
+ end
137
+
111
138
  # set a cell to a certain value
112
139
  # (this will not be saved back to the spreadsheet file!)
113
140
  def set(row,col,value,sheet=nil) #:nodoc:
@@ -145,31 +172,14 @@ class Openoffice < GenericSpreadsheet
145
172
  end
146
173
  end
147
174
 
148
- # returns an array of sheet names in the spreadsheet
149
175
  def sheets
150
176
  return_sheets = []
151
- oo_document_count = 0
152
- @doc.each_element do |oo_document|
153
- oo_document_count += 1
154
- oo_element_count = 0
155
- oo_document.each_element do |oo_element|
156
- oo_element_count += 1
157
- if oo_element.name == "body"
158
- oo_element.each_element do |be|
159
- if be.name == "spreadsheet"
160
- be.each_element do |se|
161
- if se.name == "table"
162
- return_sheets << se.attributes['name']
163
- end
164
- end
165
- end
166
- end
167
- end
168
- end
177
+ @doc.find("//*[local-name()='table']").each do |sheet|
178
+ return_sheets << sheet.attributes['name']
169
179
  end
170
180
  return_sheets
171
181
  end
172
-
182
+
173
183
  # version of the openoffice document
174
184
  # at 2007 this is always "1.0"
175
185
  def officeversion
@@ -211,32 +221,34 @@ class Openoffice < GenericSpreadsheet
211
221
 
212
222
  # read the version of the OO-Version
213
223
  def oo_version
214
- @doc.each_element do |oo_document|
215
- @officeversion = oo_document.attributes['version']
224
+ @doc.find("//*[local-name()='document-content']").each do |office|
225
+ @officeversion = office.attributes['version']
216
226
  end
217
227
  end
218
228
 
219
229
  # helper function to set the internal representation of cells
220
- def set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v)
221
- key = [y,x+i]
230
+ def set_cell_values(sheet,x,y,i,v,vt,formula,table_cell,str_v,style_name)
231
+ key = [y,x+i]
222
232
  @cell_type[sheet] = {} unless @cell_type[sheet]
223
233
  @cell_type[sheet][key] = Openoffice.oo_type_2_roo_type(vt)
224
234
  @formula[sheet] = {} unless @formula[sheet]
225
235
  @formula[sheet][key] = formula if formula
226
236
  @cell[sheet] = {} unless @cell[sheet]
237
+ @style[sheet] = {} unless @style[sheet]
238
+ @style[sheet][key] = style_name
227
239
  case @cell_type[sheet][key]
228
240
  when :float
229
241
  @cell[sheet][key] = v.to_f
230
242
  when :string
231
243
  @cell[sheet][key] = str_v
232
244
  when :date
233
- if tr.attributes['date-value'].size != "XXXX-XX-XX".size
245
+ if table_cell.attributes['date-value'].size != "XXXX-XX-XX".size
234
246
  #-- dann ist noch eine Uhrzeit vorhanden
235
247
  #-- "1961-11-21T12:17:18"
236
- @cell[sheet][key] = DateTime.parse(tr.attributes['date-value'])
248
+ @cell[sheet][key] = DateTime.parse(table_cell.attributes['date-value'])
237
249
  @cell_type[sheet][key] = :datetime
238
250
  else
239
- @cell[sheet][key] = tr.attributes['date-value']
251
+ @cell[sheet][key] = table_cell.attributes['date-value']
240
252
  end
241
253
  when :percentage
242
254
  @cell[sheet][key] = v.to_f
@@ -258,130 +270,115 @@ class Openoffice < GenericSpreadsheet
258
270
  sheet_found = false
259
271
  raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
260
272
  raise RangeError unless self.sheets.include? sheet
261
- oo_document_count = 0
262
- @doc.each_element do |oo_document|
263
- # @officeversion = oo_document.attributes['version']
264
- oo_document_count += 1
265
- oo_element_count = 0
266
- oo_document.each_element do |oo_element|
267
- oo_element_count += 1
268
- if oo_element.name == "body"
269
- oo_element.each_element do |be|
270
- if be.name == "spreadsheet"
271
- be.each_element do |se|
272
- if se.name == "table"
273
- if se.attributes['name']==sheet
274
- sheet_found = true
275
- x=1
276
- y=1
277
- se.each_element do |te|
278
- if te.name == "table-column"
279
- rep = te.attributes["number-columns-repeated"]
280
- elsif te.name == "table-row"
281
- if te.attributes['number-rows-repeated']
282
- skip_y = te.attributes['number-rows-repeated'].to_i
283
- y = y + skip_y - 1 # minus 1 because this line will be counted as a line element
284
- end
285
- te.each_element do |tr|
286
- if tr.name == 'table-cell'
287
- skip = tr.attributes['number-columns-repeated']
288
- formula = tr.attributes['formula']
289
- vt = tr.attributes['value-type']
290
- v = tr.attributes['value']
291
- if vt == 'string'
292
- str_v = ''
293
- # insert \n if there is more than one paragraph
294
- para_count = 0
295
- tr.each_element do |str|
296
- if str.name == 'p'
297
- v = str.text
298
- str_v += "\n" if para_count > 0
299
- para_count += 1
300
- if str.children.size > 1
301
- str_v = children_to_string(str.children)
302
- else
303
- str.children.each {|child|
304
- str_v = str_v + child.to_s #.text
305
- }
306
- end
307
- str_v.gsub!(/&quot;/,'"')
308
- str_v.gsub!(/&amp;/,'&')
309
- str_v.gsub!(/&apos;/,"'")
310
- end # == 'p'
311
- end
312
- elsif vt == 'time'
313
- tr.each_element do |str|
314
- if str.name == 'p'
315
- v = str.text
316
- end
317
- end
318
- elsif vt == '' or vt == nil
319
- #
320
- elsif vt == 'date'
321
- #
322
- elsif vt == 'percentage'
323
- #
324
- elsif vt == 'float'
325
- #
326
- elsif vt == 'boolean'
327
- #
328
- else
329
- # raise "unknown type #{vt}"
330
- end
331
- if skip
332
- if v != nil or tr.attributes['date-value']
333
- 0.upto(skip.to_i-1) do |i|
334
- set_cell_values(sheet,x,y,i,v,vt,formula,tr,str_v)
335
- end
336
- end
337
- x += (skip.to_i - 1)
338
- end # if skip
339
- set_cell_values(sheet,x,y,0,v,vt,formula,tr,str_v)
340
- x += 1
341
- end
342
- end
343
- y += 1
344
- x = 1
273
+
274
+ @doc.find("//*[local-name()='table']").each do |ws|
275
+ if sheet == ws.attributes['name']
276
+ sheet_found = true
277
+ col = 1
278
+ row = 1
279
+ ws.each_element do |table_element|
280
+ case table_element.name
281
+ when 'table-column'
282
+ @style_defaults[sheet] << table_element.attributes['default-cell-style-name']
283
+ when 'table-row'
284
+ if table_element.attributes['number-rows-repeated']
285
+ skip_row = table_element.attributes['number-rows-repeated'].to_i
286
+ row = row + skip_row - 1
287
+ end
288
+ table_element.each_element do |cell|
289
+ skip_col = cell.attributes['number-columns-repeated']
290
+ formula = cell.attributes['formula']
291
+ vt = cell.attributes['value-type']
292
+ v = cell.attributes['value']
293
+ style_name = cell.attributes['style-name']
294
+ if vt == 'string'
295
+ str_v = ''
296
+ # insert \n if there is more than one paragraph
297
+ para_count = 0
298
+ cell.each_element do |str|
299
+ if str.name == 'p'
300
+ v = str.content
301
+ str_v += "\n" if para_count > 0
302
+ para_count += 1
303
+ if str.children.size > 1
304
+ str_v += children_to_string(str.children)
305
+ else
306
+ str.children.each do |child|
307
+ str_v += child.content #.text
345
308
  end
346
309
  end
347
- end # sheet
310
+ str_v.gsub!(/&apos;/,"'") # special case not supported by unescapeHTML
311
+ str_v = CGI.unescapeHTML(str_v)
312
+ end # == 'p'
313
+ end
314
+ elsif vt == 'time'
315
+ cell.each_element do |str|
316
+ if str.name == 'p'
317
+ v = str.content
318
+ end
348
319
  end
320
+ elsif vt == '' or vt == nil
321
+ #
322
+ elsif vt == 'date'
323
+ #
324
+ elsif vt == 'percentage'
325
+ #
326
+ elsif vt == 'float'
327
+ #
328
+ elsif vt == 'boolean'
329
+ v = cell.attributes['boolean-value']
330
+ #
331
+ else
332
+ # raise "unknown type #{vt}"
349
333
  end
350
- end
334
+ if skip_col
335
+ if v != nil or cell.attributes['date-value']
336
+ 0.upto(skip_col.to_i-1) do |i|
337
+ set_cell_values(sheet,col,row,i,v,vt,formula,cell,str_v,style_name)
338
+ end
339
+ end
340
+ col += (skip_col.to_i - 1)
341
+ end # if skip
342
+ set_cell_values(sheet,col,row,0,v,vt,formula,cell,str_v,style_name)
343
+ col += 1
344
+ end
345
+ row += 1
346
+ col = 1
351
347
  end
352
348
  end
353
349
  end
354
350
  end
351
+
352
+ @doc.find("//*[local-name()='automatic-styles']").each do |style|
353
+ read_styles(style)
354
+ end
355
355
  if !sheet_found
356
356
  raise RangeError
357
357
  end
358
358
  @cells_read[sheet] = true
359
359
  end
360
360
 
361
+ def read_styles(style_elements)
362
+ @style_definitions['Default'] = Openoffice::Font.new
363
+ style_elements.each do |style|
364
+ next unless style.name == 'style'
365
+ style_name = style.attributes['name']
366
+ style.each do |properties|
367
+ font = Openoffice::Font.new
368
+ font.bold = properties.attributes['font-weight']
369
+ font.italic = properties.attributes['font-style']
370
+ font.underline = properties.attributes['text-underline-style']
371
+ @style_definitions[style_name] = font
372
+ end
373
+ end
374
+ end
375
+
361
376
  # Checks if the default_sheet exists. If not an RangeError exception is
362
377
  # raised
363
378
  def check_default_sheet
364
379
  sheet_found = false
365
380
  raise ArgumentError, "Error: default_sheet not set" if @default_sheet == nil
366
- @doc.each_element do |oo_document|
367
- oo_element_count = 0
368
- oo_document.each_element do |oo_element|
369
- oo_element_count += 1
370
- if oo_element.name == "body"
371
- oo_element.each_element do |be|
372
- if be.name == "spreadsheet"
373
- be.each_element do |se|
374
- if se.name == "table"
375
- if se.attributes['name'] == @default_sheet
376
- sheet_found = true
377
- end # sheet
378
- end
379
- end
380
- end
381
- end
382
- end
383
- end
384
- end
381
+ sheet_found = true if sheets.include?(@default_sheet)
385
382
  if ! sheet_found
386
383
  raise RangeError, "sheet '#{@default_sheet}' not found"
387
384
  end
@@ -437,8 +434,8 @@ class Openoffice < GenericSpreadsheet
437
434
  def children_to_string(children)
438
435
  result = ''
439
436
  children.each {|child|
440
- if child.class == REXML::Text
441
- result = result + child.to_s
437
+ if child.text?
438
+ result = result + child.content
442
439
  else
443
440
  if child.name == 's'
444
441
  compressed_spaces = child.attributes['c'].to_i
@@ -448,7 +445,7 @@ class Openoffice < GenericSpreadsheet
448
445
  end
449
446
  result = result + " "*compressed_spaces
450
447
  else
451
- result = result + child.to_s
448
+ result = result + child.content
452
449
  end
453
450
  end
454
451
  }