rubyXL 1.1.12 → 1.2.0

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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.12
1
+ 1.2.0
@@ -155,116 +155,136 @@ module RubyXL
155
155
  wb.worksheets[i] = Parser.create_matrix(wb, i, files)
156
156
  j = i+1
157
157
 
158
+ namespaces = files[j].root.namespaces()
158
159
  unless @data_only
159
- hash = Hash.xml_node_to_hash(files[j].root)
160
-
161
- wb.worksheets[i].sheet_view = hash[:sheetViews][:sheetView]
160
+ sheet_views_node= files[j].xpath('/xmlns:worksheet/xmlns:sheetViews[xmlns:sheetView]',namespaces).first
161
+ wb.worksheets[i].sheet_view = Hash.xml_node_to_hash(sheet_views_node)[:sheetView]
162
162
 
163
163
  ##col styles##
164
- col_data = hash[:cols]
165
- unless col_data.nil?
166
- wb.worksheets[i].cols=col_data[:col]
164
+ cols_node_set = files[j].xpath('/xmlns:worksheet/xmlns:cols/xmlns:col',namespaces)
165
+ unless cols_node_set.empty?
166
+ wb.worksheets[i].cols= cols_node_set.map(&:attributes)
167
167
  end
168
168
  ##end col styles##
169
169
 
170
170
  ##merge_cells##
171
- merge_data = hash[:mergeCells]
172
- unless merge_data.nil?
173
- wb.worksheets[i].merged_cells = merge_data[:mergeCell]
171
+ merge_cells_node = files[j].xpath('/xmlns:worksheet/xmlns:mergeCells[xmlns:mergeCell]',namespaces)
172
+ unless merge_cells_node.empty?
173
+ wb.worksheets[i].merged_cells = Hash.xml_node_to_hash(merge_cells_node.first)[:mergeCell]
174
174
  end
175
175
  ##end merge_cells##
176
176
 
177
177
  ##sheet_view pane##
178
- pane_data = hash[:sheetViews][:sheetView][:pane]
178
+ pane_data = wb.worksheets[i].sheet_view[:pane]
179
179
  wb.worksheets[i].pane = pane_data
180
180
  ##end sheet_view pane##
181
181
 
182
182
  ##data_validation##
183
- data_validation = hash[:dataValidations]
184
- unless data_validation.nil?
185
- data_validation = data_validation[:dataValidation]
183
+ data_validations_node = files[j].xpath('/xmlns:worksheet/xmlns:dataValidations[xmlns:dataValidation]',namespaces)
184
+ unless data_validations_node.empty?
185
+ wb.worksheets[i].validations = Hash.xml_node_to_hash(data_validations_node.first)[:dataValidation]
186
+ else
187
+ wb.worksheets[i].validations=nil
186
188
  end
187
- wb.worksheets[i].validations = data_validation
188
189
  ##end data_validation##
189
190
 
190
191
  #extLst
191
- wb.worksheets[i].extLst = hash[:extLst]
192
+ ext_list_node=files[j].xpath('/xmlns:worksheet/xmlns:extLst',namespaces)
193
+ unless ext_list_node.empty?
194
+ wb.worksheets[i].extLst = Hash.xml_node_to_hash(ext_list_node.first)
195
+ else
196
+ wb.worksheets[i].extLst=nil
197
+ end
192
198
  #extLst
193
199
 
194
200
  ##legacy drawing##
195
- drawing = hash[:legacyDrawing]
196
- wb.worksheets[i].legacy_drawing = drawing
201
+ legacy_drawing_node = files[j].xpath('/xmlns:worksheet/xmlns:legacyDrawing',namespaces)
202
+ unless legacy_drawing_node.empty?
203
+ wb.worksheets[i].legacy_drawing = Hash.xml_node_to_hash(legacy_drawing_node.first)
204
+ else
205
+ wb.worksheets[i].legacy_drawing = nil
206
+ end
197
207
  ##end legacy drawing
198
208
  end
199
209
 
200
- row_data = files[j].css('sheetData row')
210
+
211
+ row_data = files[j].xpath('/xmlns:worksheet/xmlns:sheetData/xmlns:row[xmlns:c[xmlns:v]]',namespaces)
212
+ row_data.each do |row|
213
+ unless @data_only
214
+ ##row styles##
215
+ row_style = '0'
216
+ row_attributes = row.attributes
217
+ unless row_attributes['s'].nil?
218
+ row_style = row_attributes['s'].value
219
+ end
201
220
 
202
- if(row_data.to_s != "")
203
- row_data.each do |row|
221
+ wb.worksheets[i].row_styles[row_attributes['r'].content] = { :style => row_style }
204
222
 
205
- unless @data_only
206
- ##row styles##
207
- unless row.css('c').nil?
208
- row_style = '0'
209
- unless row.attribute('s').nil?
210
- row_style = row.attribute('s').value.to_s
211
- end
212
-
213
- wb.worksheets[i].row_styles[row.attribute('r').to_s] = { :style => row_style.to_s }
214
-
215
- unless row.attribute('ht').to_s == ""
216
- wb.worksheets[i].change_row_height(Integer(row.attribute('r').to_s)-1,
217
- Float(row.attribute('ht').to_s))
218
- end
219
- end
220
- ##end row styles##
223
+ unless row_attributes['ht'].content == ""
224
+ wb.worksheets[i].change_row_height(Integer(row_attributes['r'].content)-1,
225
+ Float(row_attributes['ht'].content))
221
226
  end
227
+ ##end row styles##
228
+ end
222
229
 
223
- row = row.css('c')
224
- row.each do |value|
225
- cell_index = Parser.convert_to_index(value.attribute('r').to_s)
226
- style_index = nil
227
-
228
- data_type = value.attribute('t').to_s
229
-
230
- if (value.css('v').to_s == "") || (value.css('v').children.to_s == "") #no data
231
- cell_data = nil
232
- elsif data_type == 's' #shared string
233
- str_index = Integer(value.css('v').children.to_s)
234
- cell_data = shared_strings[str_index].to_s
235
- elsif data_type=='str' #raw string
236
- cell_data = value.css('v').children.to_s
237
- elsif data_type=='e' #error
238
- cell_data = value.css('v').children.to_s
239
- else# (value.css('v').to_s != "") && (value.css('v').children.to_s != "") #is number
240
- data_type = ''
241
- if(value.css('v').children.to_s =~ /\./) #is float
242
- cell_data = Float(value.css('v').children.to_s)
243
- else
244
- cell_data = Integer(value.css('v').children.to_s)
245
- end
246
- end
247
- cell_formula = nil
248
- fmla_css = value.css('f')
249
- if(fmla_css.to_s != "")
250
- cell_formula = fmla_css.children.to_s
251
- cell_formula_attr = {}
252
- cell_formula_attr['t'] = fmla_css.attribute('t').to_s if fmla_css.attribute('t')
253
- cell_formula_attr['ref'] = fmla_css.attribute('ref').to_s if fmla_css.attribute('ref')
254
- cell_formula_attr['si'] = fmla_css.attribute('si').to_s if fmla_css.attribute('si')
255
- end
230
+ c_row = row.search('./xmlns:c[xmlns:v]')
231
+ c_row.each do |value|
232
+ value_attributes= value.attributes
233
+ cell_index = Parser.convert_to_index(value_attributes['r'].content)
234
+ style_index = nil
256
235
 
257
- unless @data_only
258
- style_index = value['s'].to_i #nil goes to 0 (default)
236
+ data_type = value_attributes['t'].content if value_attributes['t']
237
+ element_hash ={}
238
+ value.children.each do |node|
239
+ element_hash["#{node.name()}_element"]=node
240
+ end
241
+ # v is the value element that is part of the cell
242
+ if element_hash["v_element"]
243
+ v_element_content = element_hash["v_element"].content
244
+ else
245
+ v_element_content=""
246
+ end
247
+ if v_element_content =="" #no data
248
+ cell_data = nil
249
+ elsif data_type == 's' #shared string
250
+ str_index = Integer(v_element_content)
251
+ cell_data = shared_strings[str_index].to_s
252
+ elsif data_type=='str' #raw string
253
+ cell_data = v_element_content
254
+ elsif data_type=='e' #error
255
+ cell_data = v_element_content
256
+ else# (value.css('v').to_s != "") && (value.css('v').children.to_s != "") #is number
257
+ data_type = ''
258
+ if(v_element_content =~ /\./) #is float
259
+ cell_data = Float(v_element_content)
259
260
  else
260
- style_index = 0
261
+ cell_data = Integer(v_element_content)
261
262
  end
263
+ end
264
+ cell_formula = nil
265
+ fmla_css = element_hash["f_element"]
266
+ if fmla_css && fmla_css.content
267
+ fmla_css_content= fmla_css.content
268
+ if(fmla_css_content != "")
269
+ cell_formula = fmla_css_content
270
+ cell_formula_attr = {}
271
+ fmla_css_attributes = fmla_css.attributes
272
+ cell_formula_attr['t'] = fmla_css_attributes['t'].content if fmla_css_attributes['t']
273
+ cell_formula_attr['ref'] = fmla_css_attributes['ref'].content if fmla_css_attributes['ref']
274
+ cell_formula_attr['si'] = fmla_css_attributes['si'].content if fmla_css_attributes['si']
275
+ end
276
+ end
262
277
 
263
- wb.worksheets[i].sheet_data[cell_index[0]][cell_index[1]] =
264
- Cell.new(wb.worksheets[i],cell_index[0],cell_index[1],cell_data,cell_formula,
265
- data_type,style_index,cell_formula_attr)
266
- cell = wb.worksheets[i].sheet_data[cell_index[0]][cell_index[1]]
278
+ unless @data_only
279
+ style_index = value['s'].to_i #nil goes to 0 (default)
280
+ else
281
+ style_index = 0
267
282
  end
283
+
284
+ wb.worksheets[i].sheet_data[cell_index[0]][cell_index[1]] =
285
+ Cell.new(wb.worksheets[i],cell_index[0],cell_index[1],cell_data,cell_formula,
286
+ data_type,style_index,cell_formula_attr)
287
+ cell = wb.worksheets[i].sheet_data[cell_index[0]][cell_index[1]]
268
288
  end
269
289
  end
270
290
  end
@@ -288,13 +308,13 @@ module RubyXL
288
308
 
289
309
  files = Hash.new
290
310
 
291
- files['app'] = Nokogiri::XML.parse(File.read(File.join(dir_path,'docProps','app.xml')))
292
- files['core'] = Nokogiri::XML.parse(File.read(File.join(dir_path,'docProps','core.xml')))
311
+ files['app'] = Nokogiri::XML.parse(File.open(File.join(dir_path,'docProps','app.xml'),'r'))
312
+ files['core'] = Nokogiri::XML.parse(File.open(File.join(dir_path,'docProps','core.xml'),'r'))
293
313
 
294
- files['workbook'] = Nokogiri::XML.parse(File.read(File.join(dir_path,'xl','workbook.xml')))
314
+ files['workbook'] = Nokogiri::XML.parse(File.open(File.join(dir_path,'xl','workbook.xml'),'r'))
295
315
 
296
316
  if(File.exist?(File.join(dir_path,'xl','sharedStrings.xml')))
297
- files['sharedString'] = Nokogiri::XML.parse(File.read(File.join(dir_path,'xl','sharedStrings.xml')))
317
+ files['sharedString'] = Nokogiri::XML.parse(File.open(File.join(dir_path,'xl','sharedStrings.xml'),'r'))
298
318
  end
299
319
 
300
320
  unless @data_only
@@ -352,7 +372,7 @@ module RubyXL
352
372
  files['vbaProject'] = File.open(File.join(dir_path,"xl","vbaProject.bin"),'rb').read
353
373
  end
354
374
 
355
- files['styles'] = Nokogiri::XML.parse(File.read(File.join(dir_path,'xl','styles.xml')))
375
+ files['styles'] = Nokogiri::XML.parse(File.open(File.join(dir_path,'xl','styles.xml'),'r'))
356
376
  end
357
377
 
358
378
  @num_sheets = files['workbook'].css('sheets').children.size
@@ -362,7 +382,7 @@ module RubyXL
362
382
  i=1
363
383
  1.upto(@num_sheets) do
364
384
  filename = 'sheet'+i.to_s
365
- files[i] = Nokogiri::XML.parse(File.read(File.join(dir_path,'xl','worksheets',filename+'.xml')))
385
+ files[i] = Nokogiri::XML.parse(File.open(File.join(dir_path,'xl','worksheets',filename+'.xml'),'r'))
366
386
  i=i+1
367
387
  end
368
388
 
@@ -47,7 +47,7 @@ module RubyXL
47
47
  @calc_chain = nil #unnecessary?
48
48
  @num_strings = 0 #num strings total
49
49
  @size = 0 #num strings in shared_strings array
50
- @date1904 = date1904
50
+ @date1904 = date1904 > 0
51
51
  @external_links = nil
52
52
  @style_corrector = nil
53
53
  @drawings = nil
@@ -78,6 +78,9 @@ module RubyXL
78
78
  #filepath of xlsx file (including file itself)
79
79
  def write(filepath=@filepath)
80
80
  validate_before_write
81
+ if !(filepath =~ /(.+)\.xls(x|m)/)
82
+ raise "Only xlsx and xlsm files are supported. Unsupported type for file: #{filepath}"
83
+ end
81
84
  dirpath = ''
82
85
  extension = 'xls'
83
86
  if(filepath =~ /((.|\s)*)\.xls(x|m)$/)
@@ -197,7 +200,7 @@ module RubyXL
197
200
  compare_date = DateTime.parse('December 31, 1899')
198
201
  end
199
202
  # add one day to compare date for erroneous 1900 leap year compatibility
200
- date.ajd - (compare_date.ajd + 1)
203
+ date.ajd + 1 - compare_date.ajd
201
204
  end
202
205
 
203
206
  def num_to_date(num)
@@ -207,8 +210,8 @@ module RubyXL
207
210
  else
208
211
  compare_date = DateTime.parse('December 31, 1899')
209
212
  end
210
- # add one day to compare date for erroneous 1900 leap year compatibility
211
- compare_date + 1 + num
213
+ # subtract one day to compare date for erroneous 1900 leap year compatibility
214
+ compare_date - 1 + num
212
215
  end
213
216
 
214
217
  #gets style object from style array given index
@@ -60,8 +60,11 @@ class Worksheet < PrivateClass
60
60
 
61
61
  # makes array of hashes in table_hash[:table]
62
62
  # as well as hash of arrays in table_hash[header]
63
- while !cell.nil? && !cell.value.nil?
64
- table_hash[header] << cell.value
63
+ table_index = current_row - original_row
64
+ cell_test= (!cell.nil? && !cell.value.nil?)
65
+ while cell_test || !table_hash[:table][table_index].empty?
66
+
67
+ table_hash[header] << (cell_test ? cell.value : nil)
65
68
 
66
69
  table_index = current_row - original_row
67
70
 
@@ -69,7 +72,7 @@ class Worksheet < PrivateClass
69
72
  table_hash[:table][table_index] = {}
70
73
  end
71
74
 
72
- table_hash[:table][table_index][header] = cell.value
75
+ table_hash[:table][table_index][header] = cell.value if cell_test
73
76
 
74
77
  current_row += 1
75
78
  if @sheet_data[current_row].nil?
@@ -77,6 +80,7 @@ class Worksheet < PrivateClass
77
80
  else
78
81
  cell = @sheet_data[current_row][index]
79
82
  end
83
+ cell_test= (!cell.nil? && !cell.value.nil?)
80
84
  end
81
85
  end
82
86
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rubyXL}
8
- s.version = "1.1.12"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Vivek Bhagwat"]
12
- s.date = %q{2011-11-29}
12
+ s.date = %q{2012-01-06}
13
13
  s.description = %q{rubyXL is a gem which allows the parsing, creation, and manipulation of Microsoft Excel (.xlsx/.xlsm) Documents}
14
14
  s.email = %q{bhagwat.vivek@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -196,9 +196,18 @@ describe RubyXL::Cell do
196
196
  it 'should return the value of a date' do
197
197
  date = Date.parse('January 1, 2011')
198
198
  @cell.change_contents(date)
199
- @cell.should_receive(:is_date?).once.and_return(true)
199
+ @cell.should_receive(:is_date?).any_number_of_times.and_return(true)
200
200
  @cell.value.should == date
201
201
  end
202
+
203
+ it 'should convert date numbers correctly' do
204
+ date = 41019
205
+ @cell.change_contents(date)
206
+ @cell.should_receive(:is_date?).any_number_of_times.and_return(true)
207
+ puts @cell.value
208
+ puts Date.parse('April 20, 2012')
209
+ @cell.value.should == Date.parse('April 20, 2012')
210
+ end
202
211
  end
203
212
 
204
213
  describe '.change_contents' do
@@ -211,7 +220,7 @@ describe RubyXL::Cell do
211
220
  it 'should cause cell value to match a date that is passed in' do
212
221
  date = Date.parse('January 1, 2011')
213
222
  @cell.change_contents(date)
214
- @cell.should_receive(:is_date?).once.and_return(true)
223
+ @cell.should_receive(:is_date?).any_number_of_times.and_return(true)
215
224
  @cell.value.should == date
216
225
  @cell.formula.should == nil
217
226
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyXL
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 1
9
- - 12
10
- version: 1.1.12
8
+ - 2
9
+ - 0
10
+ segments_generated: true
11
+ version: 1.2.0
11
12
  platform: ruby
12
13
  authors:
13
14
  - Vivek Bhagwat
@@ -15,7 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-11-29 00:00:00 -05:00
19
+ date: 2012-01-06 00:00:00 -05:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -28,6 +29,7 @@ dependencies:
28
29
  hash: 3
29
30
  segments:
30
31
  - 0
32
+ segments_generated: true
31
33
  version: "0"
32
34
  name: shoulda
33
35
  requirement: *id001
@@ -44,6 +46,7 @@ dependencies:
44
46
  - 1
45
47
  - 0
46
48
  - 0
49
+ segments_generated: true
47
50
  version: 1.0.0
48
51
  name: bundler
49
52
  requirement: *id002
@@ -60,6 +63,7 @@ dependencies:
60
63
  - 1
61
64
  - 6
62
65
  - 0
66
+ segments_generated: true
63
67
  version: 1.6.0
64
68
  name: jeweler
65
69
  requirement: *id003
@@ -74,6 +78,7 @@ dependencies:
74
78
  hash: 3
75
79
  segments:
76
80
  - 0
81
+ segments_generated: true
77
82
  version: "0"
78
83
  name: rcov
79
84
  requirement: *id004
@@ -90,6 +95,7 @@ dependencies:
90
95
  - 1
91
96
  - 4
92
97
  - 4
98
+ segments_generated: true
93
99
  version: 1.4.4
94
100
  name: nokogiri
95
101
  requirement: *id005
@@ -106,6 +112,7 @@ dependencies:
106
112
  - 0
107
113
  - 9
108
114
  - 4
115
+ segments_generated: true
109
116
  version: 0.9.4
110
117
  name: rubyzip
111
118
  requirement: *id006
@@ -122,6 +129,7 @@ dependencies:
122
129
  - 1
123
130
  - 3
124
131
  - 4
132
+ segments_generated: true
125
133
  version: 1.3.4
126
134
  name: rspec
127
135
  requirement: *id007
@@ -187,6 +195,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
187
195
  hash: 3
188
196
  segments:
189
197
  - 0
198
+ segments_generated: true
190
199
  version: "0"
191
200
  required_rubygems_version: !ruby/object:Gem::Requirement
192
201
  none: false
@@ -196,6 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
205
  hash: 3
197
206
  segments:
198
207
  - 0
208
+ segments_generated: true
199
209
  version: "0"
200
210
  requirements: []
201
211