spreadsheetx 0.2.0 → 0.2.1

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
- 0.2.0
1
+ 0.2.1
data/lib/spreadsheetx.rb CHANGED
@@ -7,6 +7,7 @@ require 'fileutils'
7
7
  #
8
8
  require 'spreadsheetx/workbook'
9
9
  require 'spreadsheetx/worksheet'
10
+ require 'spreadsheetx/cell_format'
10
11
 
11
12
  module SpreadsheetX
12
13
 
@@ -0,0 +1,19 @@
1
+ module SpreadsheetX
2
+
3
+ # this object represents an existing cell format in the workbook
4
+ class CellFormat
5
+
6
+ attr_reader :id
7
+ attr_reader :format
8
+
9
+ def initialize(id, format)
10
+ @id = id
11
+ @format = format
12
+ end
13
+
14
+ def to_s
15
+ id.to_s
16
+ end
17
+
18
+ end
19
+ end
@@ -5,6 +5,7 @@ module SpreadsheetX
5
5
 
6
6
  attr_reader :path
7
7
  attr_reader :worksheets
8
+ attr_reader :formats
8
9
 
9
10
  # return a Workbook object which relates to an existing xlsx file on disk
10
11
  def initialize(path)
@@ -33,6 +34,26 @@ module SpreadsheetX
33
34
 
34
35
  end
35
36
 
37
+ # open the styles, to get the cell formats
38
+ archive.fopen('xl/styles.xml') do |f|
39
+
40
+ # read contents of this file
41
+ file_contents = f.read
42
+
43
+ #parse the XML and build the worksheets
44
+ @formats = []
45
+ # parse the XML and hold the doc
46
+ xml_doc = XML::Document.string(file_contents)
47
+ # set the default namespace
48
+ xml_doc.root.namespaces.default_prefix = 'spreadsheetml'
49
+
50
+ format_id = 0
51
+ xml_doc.find('spreadsheetml:numFmts/spreadsheetml:numFmt').each do |node|
52
+ @formats.push SpreadsheetX::CellFormat.new((format_id+=1), node['formatCode'])
53
+ end
54
+
55
+ end
56
+
36
57
  end
37
58
  end
38
59
 
@@ -54,6 +75,7 @@ module SpreadsheetX
54
75
 
55
76
  end
56
77
 
78
+
57
79
  end
58
80
 
59
81
  end
@@ -28,19 +28,37 @@ module SpreadsheetX
28
28
  end
29
29
 
30
30
  # update the value of a particular cell, if the row or cell doesnt exist in the XML, then it will be created
31
- def update_cell(col_number, row_number, val)
31
+ def update_cell(col_number, row_number, val, format=nil)
32
32
 
33
33
  cell_id = SpreadsheetX::Worksheet.cell_id(col_number, row_number)
34
+
35
+ val_is_a_date = (val.kind_of?(Date) || val.kind_of?(Time) || val.kind_of?(DateTime))
36
+
37
+ # if the val is nil or an empty string, then just delete the cell
38
+ if val.nil? || val == ''
39
+ if cell = @xml_doc.find_first("spreadsheetml:sheetData/spreadsheetml:row[@r=#{row_number}]/spreadsheetml:c[@r='#{cell_id}']")
40
+ cell.remove!
41
+ end
42
+ return
43
+ end
34
44
 
35
45
  row = @xml_doc.find_first("spreadsheetml:sheetData/spreadsheetml:row[@r=#{row_number}]")
36
46
 
37
47
  # was this row found
38
48
  unless row
49
+
39
50
  # build a new row
40
51
  row = XML::Node.new('row')
41
52
  row['r'] = row_number.to_s
42
- # add it to the other rows
43
- @xml_doc.find_first('spreadsheetml:sheetData') << row
53
+
54
+ # if there are no rows higher than this one, then add this row to the end of the sheetData
55
+ next_largest = @xml_doc.find_first("spreadsheetml:sheetData/spreadsheetml:row[@r>#{row_number}]")
56
+ if next_largest
57
+ next_largest.prev = row
58
+ else # there are no rows higher than this one
59
+ # add this row to the end of the sheetData
60
+ @xml_doc.find_first('spreadsheetml:sheetData') << row
61
+ end
44
62
  end
45
63
 
46
64
  cell = row.find_first("spreadsheetml:c[@r='#{cell_id}']")
@@ -49,30 +67,42 @@ module SpreadsheetX
49
67
  # build a new cell
50
68
  cell = XML::Node.new('c')
51
69
  cell['r'] = cell_id
52
- # add it to the other rows
70
+ # add it to the other cells in this row
53
71
  row << cell
54
72
  end
55
73
 
74
+ # are we setting a format
75
+ cell['s'] = format.to_s
76
+
77
+ # reset this attribute
78
+ cell['t'] = ''
79
+
56
80
  # create the node which represents the value in the cell
57
- if val.kind_of? String
81
+
82
+ # numeric types
83
+ if val.kind_of?(Integer) || val.kind_of?(Float) || val.kind_of?(Fixnum)
84
+
85
+ cell_value = XML::Node.new('v')
86
+ cell_value.content = val.to_s
87
+
88
+ # if we are using a format, then dates are stored as floats, otherwise they get caught by string use a string
89
+ elsif format && val_is_a_date
58
90
 
91
+ cell_value = XML::Node.new('v')
92
+ # dates are stored as flaots, otherwise use a string
93
+ cell_value.content = (val.to_time.to_f / (60*60*24)).to_s
94
+
95
+ else # assume its a string
96
+
59
97
  # put the strings inline to make life easier
60
98
  cell['t'] = 'inlineStr'
61
99
 
62
- # the string node looke like <is><t>string</t></is>
100
+ # the string node looks like <is><t>string</t></is>
63
101
  is = XML::Node.new('is')
64
102
  t = XML::Node.new('t')
65
- t.content = val
103
+ t.content = val_is_a_date ? val.to_time.strftime('%Y-%m-%d %H:%M:%S') : val.to_s
66
104
 
67
105
  cell_value = ( is << t )
68
-
69
- else
70
-
71
- # incase this was an inline string, clear out this attribute
72
- cell['t'] = ''
73
-
74
- cell_value = XML::Node.new('v')
75
- cell_value.content = val.to_s
76
106
 
77
107
  end
78
108
 
@@ -94,7 +124,7 @@ module SpreadsheetX
94
124
 
95
125
  # returns the xml representation of this worksheet
96
126
  def to_s
97
- @xml_doc.to_s
127
+ @xml_doc.to_s(:indent => false).gsub(/\n/,"\r\n")
98
128
  end
99
129
 
100
130
  # turns a cell address into its excel name, 1,1 = A1 2,3 = C2 etc.
@@ -27,7 +27,7 @@ describe "Spreadsheetx" do
27
27
  empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
28
28
  workbook = SpreadsheetX.open(empty_xlsx_file)
29
29
 
30
- workbook.worksheets.last.row_count.should == 4
30
+ workbook.worksheets.last.row_count.should == 8
31
31
 
32
32
  end
33
33
 
@@ -107,6 +107,7 @@ describe "Spreadsheetx" do
107
107
  workbook = SpreadsheetX.open(empty_xlsx_file)
108
108
 
109
109
  workbook.worksheets.last.update_cell(9, 9, Time.now)
110
+ workbook.worksheets.last.update_cell(1, 4, 'A string')
110
111
  workbook.worksheets.last.update_cell(9, 10, 'A string')
111
112
  workbook.worksheets.last.update_cell(9, 11, 10.3)
112
113
  workbook.worksheets.last.update_cell(9, 12, 53)
@@ -116,7 +117,35 @@ describe "Spreadsheetx" do
116
117
  workbook.save(new_xlsx_file)
117
118
 
118
119
  end
120
+
121
+ it "can read and return a list of number formats currently in the document" do
122
+
123
+ # a valid xlsx file used for testing
124
+ empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
125
+ workbook = SpreadsheetX.open(empty_xlsx_file)
126
+
127
+ workbook.formats.count.should == 3
128
+ workbook.formats.first.id.to_i.should > 0
129
+ puts workbook.formats.first.format.should == '[$-F400]h:mm:ss\ AM/PM'
130
+
131
+ new_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec_various_content.xlsx"
132
+ workbook.save(new_xlsx_file)
133
+
134
+ end
135
+
136
+
137
+ it "can set formats on cells" do
138
+
139
+ # a valid xlsx file used for testing
140
+ empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
141
+ workbook = SpreadsheetX.open(empty_xlsx_file)
119
142
 
143
+ date_format = workbook.formats.first
144
+ workbook.worksheets.last.update_cell(1, 8, Time.now, date_format)
145
+
146
+ new_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec_cell_format.xlsx"
147
+ workbook.save(new_xlsx_file)
120
148
 
149
+ end
121
150
 
122
151
  end
data/spreadsheetx.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{spreadsheetx}
8
- s.version = "0.2.0"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Craig Ulliott"]
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "lib/spreadsheetx.rb",
29
+ "lib/spreadsheetx/cell_format.rb",
29
30
  "lib/spreadsheetx/workbook.rb",
30
31
  "lib/spreadsheetx/worksheet.rb",
31
32
  "spec/spec_helper.rb",
data/templates/spec.xlsx CHANGED
Binary file
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: spreadsheetx
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.0
5
+ version: 0.2.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Craig Ulliott
@@ -98,6 +98,7 @@ files:
98
98
  - Rakefile
99
99
  - VERSION
100
100
  - lib/spreadsheetx.rb
101
+ - lib/spreadsheetx/cell_format.rb
101
102
  - lib/spreadsheetx/workbook.rb
102
103
  - lib/spreadsheetx/worksheet.rb
103
104
  - spec/spec_helper.rb
@@ -118,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
119
  requirements:
119
120
  - - ">="
120
121
  - !ruby/object:Gem::Version
121
- hash: -772800674702882304
122
+ hash: 3923025067229430193
122
123
  segments:
123
124
  - 0
124
125
  version: "0"