spreadsheetx 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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"