rubyXL 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/Gemfile +16 -0
  2. data/Gemfile.lock +34 -0
  3. data/LICENSE.txt +20 -0
  4. data/README +0 -0
  5. data/README.rdoc +19 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/lib/.DS_Store +0 -0
  9. data/lib/Hash.rb +60 -0
  10. data/lib/cell.rb +360 -0
  11. data/lib/color.rb +14 -0
  12. data/lib/parser.rb +413 -0
  13. data/lib/private_class.rb +182 -0
  14. data/lib/rubyXL.rb +9 -0
  15. data/lib/test.html +1 -0
  16. data/lib/tests/test.rb +110 -0
  17. data/lib/tests/test10.rb +16 -0
  18. data/lib/tests/test2.rb +118 -0
  19. data/lib/tests/test3.rb +76 -0
  20. data/lib/tests/test4.rb +92 -0
  21. data/lib/tests/test5.rb +90 -0
  22. data/lib/tests/test6.rb +50 -0
  23. data/lib/tests/test7.rb +48 -0
  24. data/lib/tests/test8.rb +12 -0
  25. data/lib/tests/test9.rb +60 -0
  26. data/lib/workbook.rb +336 -0
  27. data/lib/worksheet.rb +1245 -0
  28. data/lib/writer/app_writer.rb +62 -0
  29. data/lib/writer/calc_chain_writer.rb +33 -0
  30. data/lib/writer/content_types_writer.rb +77 -0
  31. data/lib/writer/core_writer.rb +51 -0
  32. data/lib/writer/root_rels_writer.rb +25 -0
  33. data/lib/writer/shared_strings_writer.rb +44 -0
  34. data/lib/writer/styles_writer.rb +376 -0
  35. data/lib/writer/theme_writer.rb +346 -0
  36. data/lib/writer/workbook_rels_writer.rb +59 -0
  37. data/lib/writer/workbook_writer.rb +77 -0
  38. data/lib/writer/worksheet_writer.rb +208 -0
  39. data/lib/zip.rb +20 -0
  40. data/pkg/rubyXL-1.0.4.gem +0 -0
  41. data/rubyXL.gemspec +106 -0
  42. data/spec/lib/cell_spec.rb +359 -0
  43. data/spec/lib/color_spec.rb +14 -0
  44. data/spec/lib/hash_spec.rb +28 -0
  45. data/spec/lib/parser_spec.rb +49 -0
  46. data/spec/lib/workbook_spec.rb +51 -0
  47. data/spec/lib/worksheet_spec.rb +1650 -0
  48. metadata +222 -0
@@ -0,0 +1,62 @@
1
+ # require File.expand_path(File.join(File.dirname(__FILE__),'workbook'))
2
+ # require File.expand_path(File.join(File.dirname(__FILE__),'worksheet'))
3
+ # require File.expand_path(File.join(File.dirname(__FILE__),'cell'))
4
+ # require File.expand_path(File.join(File.dirname(__FILE__),'color'))
5
+ require 'rubygems'
6
+ require 'nokogiri'
7
+
8
+ module RubyXL
9
+ module Writer
10
+ class AppWriter
11
+ attr_accessor :dirpath, :filepath, :workbook
12
+
13
+ def initialize(dirpath, wb)
14
+ @dirpath = dirpath
15
+ @filepath = dirpath+'/docProps/app.xml'
16
+ @workbook = wb
17
+ end
18
+
19
+ def write()
20
+
21
+ builder = Nokogiri::XML::Builder.new do |xml|
22
+ xml.Properties('xmlns' => 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties',
23
+ 'xmlns:vt'=>'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes') {
24
+ xml.Application @workbook.application
25
+ xml.DocSecurity '0'
26
+ xml.ScaleCrop 'false'
27
+ xml.HeadingPairs {
28
+ xml['vt'].vector(:size => '2', :baseType => 'variant') {
29
+ xml['vt'].variant {
30
+ xml['vt'].lpstr 'Worksheets'
31
+ }
32
+ xml['vt'].variant {
33
+ xml['vt'].i4 @workbook.worksheets.size.to_s()
34
+ }
35
+ }
36
+ }
37
+ xml.TitlesOfParts {
38
+ xml['vt'].vector(:size=>@workbook.worksheets.size.to_s(), :baseType=>"lpstr") {
39
+ @workbook.worksheets.each do |sheet|
40
+ xml['vt'].lpstr sheet.sheet_name
41
+ end
42
+ }
43
+ }
44
+ xml.Company @workbook.company
45
+ xml.LinksUpToDate 'false'
46
+ xml.SharedDoc 'false'
47
+ xml.HyperlinksChanged 'false'
48
+ xml.AppVersion @workbook.appversion
49
+ }
50
+ end
51
+ contents = builder.to_xml
52
+ if(contents =~ /xmlns:vt=\"(.*)\" xmlns=\"(.*)\"/)
53
+ contents.sub(/xmlns:vt=\"(.*)\" xmlns=\"(.*)\"<A/,'xmlns="'+$2+'" xmlns:vt="'+$1+'"<A')
54
+ end
55
+ contents = contents.gsub(/\n/,'')
56
+ contents = contents.gsub(/>(\s)+</,'><')
57
+ contents = contents.sub(/<\?xml version=\"1.0\"\?>/,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n")
58
+ contents
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,33 @@
1
+ # require File.expand_path(File.join(File.dirname(__FILE__),'workbook'))
2
+ # require File.expand_path(File.join(File.dirname(__FILE__),'worksheet'))
3
+ # require File.expand_path(File.join(File.dirname(__FILE__),'cell'))
4
+ # require File.expand_path(File.join(File.dirname(__FILE__),'color'))
5
+ require 'rubygems'
6
+ require 'nokogiri'
7
+
8
+ module RubyXL
9
+ module Writer
10
+
11
+
12
+ #TODO
13
+ class CalcChainWriter
14
+ attr_accessor :dirpath, :filepath, :workbook
15
+
16
+ def initialize(dirpath, wb)
17
+ @dirpath = dirpath
18
+ @workbook = wb
19
+ @filepath = dirpath + '/xl/calcChain.xml'
20
+ end
21
+
22
+ def write()
23
+ contents = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n"
24
+ contents += ''
25
+ # file = File.new(@filepath, 'w+')
26
+ # file.write(contents)
27
+ # file.close
28
+ contents
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,77 @@
1
+ # require File.expand_path(File.join(File.dirname(__FILE__),'workbook'))
2
+ # require File.expand_path(File.join(File.dirname(__FILE__),'worksheet'))
3
+ # require File.expand_path(File.join(File.dirname(__FILE__),'cell'))
4
+ # require File.expand_path(File.join(File.dirname(__FILE__),'color'))
5
+ require 'rubygems'
6
+ require 'nokogiri'
7
+
8
+
9
+ module RubyXL
10
+ module Writer
11
+ class ContentTypesWriter
12
+ attr_accessor :dirpath, :filepath, :workbook
13
+ def initialize(dirpath, wb)
14
+ @dirpath = dirpath
15
+ @workbook = wb
16
+ @filepath = dirpath + '/[Content_Types].xml'
17
+ end
18
+
19
+ def write()
20
+ builder = Nokogiri::XML::Builder.new do |xml|
21
+ xml.Types('xmlns'=>"http://schemas.openxmlformats.org/package/2006/content-types") {
22
+ xml.Override('PartName'=>'/docProps/app.xml',
23
+ 'ContentType'=>"application/vnd.openxmlformats-officedocument.extended-properties+xml")
24
+ unless @workbook.shared_strings.nil?
25
+ xml.Override('PartName'=>'/xl/sharedStrings.xml',
26
+ 'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml")
27
+ end
28
+ xml.Default('Extension'=>'xml', 'ContentType'=>'application/xml')
29
+ if @workbook.macros.nil? && @workbook.drawings.nil?
30
+ xml.Override('PartName'=>'/xl/workbook.xml',
31
+ 'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")
32
+ else
33
+ xml.Override('PartName'=>'/xl/workbook.xml',
34
+ 'ContentType'=>"application/vnd.ms-excel.sheet.macroEnabled.main+xml")
35
+ end
36
+ xml.Default('Extension'=>'rels','ContentType'=>'application/vnd.openxmlformats-package.relationships+xml')
37
+ unless @workbook.external_links.nil?
38
+ 1.upto(@workbook.external_links.size-1) do |i|
39
+ xml.Override('PartName'=>"/xl/externalLinks/externalLink#{i}.xml",
40
+ 'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml")
41
+ end
42
+ end
43
+ xml.Override('PartName'=>"/xl/styles.xml",
44
+ 'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml")
45
+ unless @workbook.macros.nil?
46
+ xml.Override('PartName'=>'/xl/vbaProject.bin',
47
+ 'ContentType'=>'application/vnd.ms-office.vbaProject')
48
+ end
49
+ unless @workbook.printer_settings.nil?
50
+ xml.Default('Extension'=>'bin',
51
+ 'ContentType'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings')
52
+ end
53
+ unless @workbook.drawings.nil?
54
+ xml.Default('Extension'=>'vml',
55
+ 'ContentType'=>'application/vnd.openxmlformats-officedocument.vmlDrawing')
56
+ end
57
+ xml.Override('PartName'=>'/xl/theme/theme1.xml',
58
+ 'ContentType'=>"application/vnd.openxmlformats-officedocument.theme+xml")
59
+ @workbook.worksheets.each_with_index do |sheet,i|
60
+ xml.Override('PartName'=>"/xl/worksheets/sheet#{i+1}.xml",
61
+ 'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml")
62
+ end
63
+ xml.Override('PartName'=>'/docProps/core.xml',
64
+ 'ContentType'=>"application/vnd.openxmlformats-package.core-properties+xml")
65
+ }
66
+ end
67
+
68
+ contents = builder.to_xml
69
+ contents = contents.gsub(/\n/,'')
70
+ contents = contents.gsub(/>(\s)+</,'><')
71
+ contents = contents.sub(/<\?xml version=\"1.0\"\?>/,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n")
72
+
73
+ contents
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,51 @@
1
+ # require File.expand_path(File.join(File.dirname(__FILE__),'workbook'))
2
+ # require File.expand_path(File.join(File.dirname(__FILE__),'worksheet'))
3
+ # require File.expand_path(File.join(File.dirname(__FILE__),'cell'))
4
+ # require File.expand_path(File.join(File.dirname(__FILE__),'color'))
5
+ require 'rubygems'
6
+ require 'nokogiri'
7
+
8
+ module RubyXL
9
+ module Writer
10
+ class CoreWriter
11
+ attr_accessor :dirpath, :filepath, :workbook
12
+
13
+ def initialize(dirpath, wb)
14
+ @dirpath = dirpath
15
+ @workbook = wb
16
+ @filepath = @dirpath + '/docProps/core.xml'
17
+ end
18
+
19
+ def write()
20
+ builder = Nokogiri::XML::Builder.new do |xml|
21
+ xml.coreProperties('xmlns:cp'=>"http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
22
+ 'xmlns:dc'=>"http://purl.org/dc/elements/1.1/", 'xmlns:dcterms'=>"http://purl.org/dc/terms/",
23
+ 'xmlns:dcmitype'=>"http://purl.org/dc/dcmitype/", 'xmlns:xsi'=>"http://www.w3.org/2001/XMLSchema-instance") {
24
+ xml['dc'].creator @workbook.creator.to_s
25
+ xml['cp'].lastModifiedBy @workbook.modifier.to_s
26
+ xml['dcterms'].created('xsi:type' => 'dcterms:W3CDTF') do
27
+ @workbook.created_at
28
+ end
29
+
30
+ xml['dcterms'].modified('xsi:type' => 'dcterms:W3CDTF')
31
+ }
32
+ end
33
+
34
+ contents = builder.to_xml
35
+ contents = contents.gsub(/coreProperties/,'cp:coreProperties')
36
+ contents = contents.gsub(/\n/,'')
37
+ contents = contents.gsub(/>(\s)+</,'><')
38
+
39
+ #seems hack-y..
40
+ contents = contents.gsub(/<dcterms:created xsi:type=\"dcterms:W3CDTF\"\/>/,
41
+ '<dcterms:created xsi:type="dcterms:W3CDTF">'+@workbook.created_at+'</dcterms:created>')
42
+ contents = contents.gsub(/<dcterms:modified xsi:type=\"dcterms:W3CDTF\"\/>/,
43
+ '<dcterms:modified xsi:type="dcterms:W3CDTF">'+@workbook.modified_at+'</dcterms:modified>')
44
+
45
+ contents = contents.sub(/<\?xml version=\"1.0\"\?>/,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n")
46
+
47
+ return contents
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ # require File.expand_path(File.join(File.dirname(__FILE__),'workbook'))
2
+ # require File.expand_path(File.join(File.dirname(__FILE__),'worksheet'))
3
+ # require File.expand_path(File.join(File.dirname(__FILE__),'cell'))
4
+ # require File.expand_path(File.join(File.dirname(__FILE__),'color'))
5
+ require 'rubygems'
6
+ require 'nokogiri'
7
+
8
+ module RubyXL
9
+ module Writer
10
+ class RootRelsWriter
11
+ attr_accessor :dirpath, :workbook
12
+
13
+ def initialize(dirpath, wb)
14
+ @dirpath = dirpath
15
+ @wb = wb
16
+ end
17
+
18
+ def write()
19
+ contents = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
20
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>'
21
+ contents
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ # require File.expand_path(File.join(File.dirname(__FILE__),'workbook'))
2
+ # require File.expand_path(File.join(File.dirname(__FILE__),'worksheet'))
3
+ # require File.expand_path(File.join(File.dirname(__FILE__),'cell'))
4
+ # require File.expand_path(File.join(File.dirname(__FILE__),'color'))
5
+ require 'rubygems'
6
+ require 'nokogiri'
7
+
8
+ module RubyXL
9
+ module Writer
10
+ class SharedStringsWriter
11
+ attr_accessor :dirpath, :filepath, :workbook
12
+
13
+ def initialize(dirpath,wb)
14
+ @dirpath = dirpath
15
+ @workbook = wb
16
+ @filepath = dirpath + '/xl/sharedStrings.xml'
17
+ end
18
+
19
+ def write()
20
+ # contents = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n"
21
+
22
+ # builder = Nokogiri::XML::Builder.new do |xml|
23
+ # xml.sst('xmlns'=>"http://schemas.openxmlformats.org/spreadsheetml/2006/main",
24
+ # 'count'=>@workbook.numStrings,
25
+ # 'uniqueCount'=>@workbook.size) {
26
+ # i = 0
27
+ # 0.upto(@workbook.size-1).each do |i|
28
+ # xml.si {
29
+ # xml.t @workbook.sharedStrings[i].to_s
30
+ # xml.phoneticPr('fontId'=>'1', 'type'=>'noConversion')
31
+ # }
32
+ # end
33
+ # }
34
+ # end
35
+ # contents = builder.to_xml
36
+ # contents = contents.gsub(/\n/,'')
37
+ # contents = contents.gsub(/>(\s)+</,'><')
38
+ # contents = contents.sub(/<\?xml version=\"1.0\"\?>/,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n")
39
+ contents = @workbook.shared_strings_XML
40
+ contents
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,376 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+
4
+ module RubyXL
5
+ module Writer
6
+ class StylesWriter
7
+ attr_accessor :dirpath, :filepath, :workbook
8
+
9
+ def initialize(dirpath, wb)
10
+ @dirpath = dirpath
11
+ @workbook = wb
12
+ @filepath = @dirpath + '/xl/styles.xml'
13
+ end
14
+
15
+ def write()
16
+ font_id_corrector = {}
17
+ fill_id_corrector = {}
18
+ border_id_corrector = {}
19
+ style_id_corrector = {}
20
+
21
+ builder = Nokogiri::XML::Builder.new do |xml|
22
+ xml.styleSheet('xmlns'=>"http://schemas.openxmlformats.org/spreadsheetml/2006/main") {
23
+ unless @workbook.num_fmts.nil? || @workbook.num_fmts[:attributes].nil?
24
+ xml.numFmts('count'=>@workbook.num_fmts[:attributes][:count].to_s) {
25
+ @workbook.num_fmts[:numFmt].each do |fmt|
26
+ attributes = fmt[:attributes]
27
+ xml.numFmt('numFmtId'=>attributes[:numFmtId].to_s,
28
+ 'formatCode'=>attributes[:formatCode].to_s)
29
+ end
30
+ }
31
+ end
32
+
33
+ offset = 0
34
+ #default font should stay the same
35
+ font_id_corrector['0']=0
36
+ 1.upto(@workbook.fonts.size-1) do |i|
37
+ font_id_corrector[i.to_s] = i-offset
38
+ if @workbook.fonts[i.to_s][:count] == 0
39
+ @workbook.fonts[i.to_s] = nil
40
+ font_id_corrector[i.to_s] = nil
41
+ offset += 1
42
+ end
43
+ end
44
+
45
+
46
+ offset = 0
47
+ #STARTS AT 2 because excel is stupid
48
+ #and it seems to hard code access the first
49
+ #2 styles.............
50
+ fill_id_corrector['0']=0
51
+ fill_id_corrector['1']=1
52
+ 2.upto(@workbook.fills.size-1) do |i|
53
+ fill_id_corrector[i.to_s] = i-offset
54
+ if @workbook.fills[i.to_s][:count] == 0
55
+ @workbook.fills[i.to_s] = nil
56
+ fill_id_corrector[i.to_s] = nil
57
+ offset += 1
58
+ end
59
+ end
60
+
61
+ #sets index to itself as init correction
62
+ #if items deleted, indexes adjusted
63
+ #that id 'corrects' to nil
64
+ offset = 0
65
+
66
+ #default border should stay the same
67
+ border_id_corrector['0'] = 0
68
+ 1.upto(@workbook.borders.size-1) do |i|
69
+ border_id_corrector[i.to_s] = i-offset
70
+ if @workbook.borders[i.to_s][:count] == 0
71
+ @workbook.borders[i.to_s] = nil
72
+ border_id_corrector[i.to_s] = nil
73
+ offset += 1
74
+ end
75
+ end
76
+
77
+ offset = 0
78
+ style_id_corrector['0']=0
79
+ 1.upto(@workbook.cell_xfs[:xf].size) do |i|
80
+ style_id_corrector[i.to_s]= i-offset
81
+ #offset here
82
+ (i+1).upto(@workbook.cell_xfs[:xf].size) do |j|
83
+ unless i == j
84
+ if hash_equal(@workbook.cell_xfs[:xf][i],@workbook.cell_xfs[:xf][j])
85
+ # puts "found match #{i}, #{j}"
86
+ @workbook.cell_xfs[:xf].delete_at(i)
87
+ style_id_corrector.delete(i.to_s)
88
+ offset += 1
89
+ end
90
+ end
91
+ end
92
+ end
93
+ @workbook.style_corrector = style_id_corrector
94
+
95
+ xml.fonts('count'=>@workbook.fonts.size) {
96
+ 0.upto(@workbook.fonts.size-1) do |i|
97
+ font = @workbook.fonts[i.to_s]
98
+ unless font.nil?
99
+ font = font[:font]
100
+ xml.font {
101
+ xml.sz('val'=>font[:sz][:attributes][:val].to_s)
102
+ unless font[:b].nil?
103
+ xml.b
104
+ end
105
+ unless font[:i].nil?
106
+ xml.i
107
+ end
108
+ unless font[:u].nil?
109
+ xml.u
110
+ end
111
+ unless font[:strike].nil?
112
+ xml.strike
113
+ end
114
+ unless font[:color].nil?
115
+ unless font[:color][:attributes][:indexed].nil?
116
+ xml.color('indexed'=>font[:color][:attributes][:indexed])
117
+ else
118
+ unless font[:color][:attributes][:rgb].nil?
119
+ xml.color('rgb'=>font[:color][:attributes][:rgb])
120
+ else
121
+ unless font[:color][:attributes][:theme].nil?
122
+ xml.color('theme'=>font[:color][:attributes][:theme])
123
+ end
124
+ end
125
+ end
126
+ end
127
+ unless font[:family].nil?
128
+ xml.family('val'=>font[:family][:attributes][:val].to_s)
129
+ end
130
+ unless font[:scheme].nil?
131
+ xml.scheme('val'=>font[:scheme][:attributes][:val].to_s)
132
+ end
133
+
134
+ xml.name('val'=>font[:name][:attributes][:val].to_s)
135
+ }
136
+ end
137
+ end
138
+ }
139
+
140
+ xml.fills('count'=>@workbook.fills.size) {
141
+ 0.upto(@workbook.fills.size-1) do |i|
142
+ fill = @workbook.fills[i.to_s]
143
+ unless fill.nil?
144
+ fill = fill[:fill]
145
+ xml.fill {
146
+ xml.patternFill('patternType'=>fill[:patternFill][:attributes][:patternType].to_s) {
147
+ unless fill[:patternFill][:fgColor].nil?
148
+ fgColor = fill[:patternFill][:fgColor][:attributes]
149
+ unless fgColor[:indexed].nil?
150
+ xml.fgColor('indexed'=>fgColor[:indexed].to_s)
151
+ else
152
+ unless fgColor[:rgb].nil?
153
+ xml.fgColor('rgb'=>fgColor[:rgb])
154
+ end
155
+ end
156
+ end
157
+ unless fill[:patternFill][:bgColor].nil?
158
+ bgColor = fill[:patternFill][:bgColor][:attributes]
159
+ unless bgColor[:indexed].nil?
160
+ xml.bgColor('indexed'=>bgColor[:indexed].to_s)
161
+ else
162
+ unless bgColor[:rgb].nil?
163
+ xml.bgColor('rgb'=>bgColor[:rgb])
164
+ end
165
+ end
166
+ end
167
+ }
168
+ }
169
+ end
170
+ end
171
+ }
172
+
173
+ xml.borders('count'=>@workbook.borders.size) {
174
+ 0.upto(@workbook.borders.size-1) do |i|
175
+ border = @workbook.borders[i.to_s]
176
+ unless border.nil?
177
+ border = border[:border]
178
+ xml.border {
179
+ if border[:left][:attributes].nil?
180
+ xml.left
181
+ else
182
+ xml.left('style'=>border[:left][:attributes][:style]) {
183
+ unless border[:left][:color].nil?
184
+ color = border[:left][:color][:attributes]
185
+ unless color[:indexed].nil?
186
+ xml.color('indexed'=>color[:indexed])
187
+ else
188
+ unless color[:rgb].nil?
189
+ xml.color('rgb'=>color[:rgb])
190
+ end
191
+ end
192
+ end
193
+ }
194
+ end
195
+ if border[:right][:attributes].nil?
196
+ xml.right
197
+ else
198
+ xml.right('style'=>border[:right][:attributes][:style]) {
199
+ unless border[:right][:color].nil?
200
+ color = border[:right][:color][:attributes]
201
+ unless color[:indexed].nil?
202
+ xml.color('indexed'=>color[:indexed])
203
+ else
204
+ unless color[:rgb].nil?
205
+ xml.color('rgb'=>color[:rgb])
206
+ end
207
+ end
208
+ end
209
+ }
210
+ end
211
+ if border[:top][:attributes].nil?
212
+ xml.top
213
+ else
214
+ xml.top('style'=>border[:top][:attributes][:style]) {
215
+ unless border[:top][:color].nil?
216
+ color = border[:top][:color][:attributes]
217
+ unless color[:indexed].nil?
218
+ xml.color('indexed'=>color[:indexed])
219
+ else
220
+ unless color[:rgb].nil?
221
+ xml.color('rgb'=>color[:rgb])
222
+ end
223
+ end
224
+ end
225
+ }
226
+ end
227
+ if border[:bottom][:attributes].nil?
228
+ xml.bottom
229
+ else
230
+ xml.bottom('style'=>border[:bottom][:attributes][:style]) {
231
+ unless border[:bottom][:color].nil?
232
+ color = border[:bottom][:color][:attributes]
233
+ unless color[:indexed].nil?
234
+ xml.color('indexed'=>color[:indexed])
235
+ else
236
+ unless color[:rgb].nil?
237
+ xml.color('rgb'=>color[:rgb])
238
+ end
239
+ end
240
+ end
241
+ }
242
+ end
243
+ if border[:diagonal][:attributes].nil?
244
+ xml.diagonal
245
+ else
246
+ xml.diagonal('style'=>border[:diagonal][:attributes][:style]) {
247
+ unless border[:diagonal][:color].nil?
248
+ color = border[:diagonal][:color][:attributes]
249
+ unless color[:indexed].nil?
250
+ xml.color('indexed'=>color[:indexed])
251
+ else
252
+ unless color[:rgb].nil?
253
+ xml.color('rgb'=>color[:rgb])
254
+ end
255
+ end
256
+ end
257
+ }
258
+ end
259
+ }
260
+ end #unless border.nil?
261
+ end #0.upto(size)
262
+ }
263
+
264
+ xml.cellStyleXfs('count'=>@workbook.cell_style_xfs[:attributes][:count].to_s) {
265
+ @workbook.cell_style_xfs[:xf].each do |style|
266
+ style = @workbook.get_style_attributes(style)
267
+ xml.xf('numFmtId'=>style[:numFmtId].to_s,
268
+ 'fontId'=>font_id_corrector[style[:fontId].to_s].to_s,
269
+ 'fillId'=>fill_id_corrector[style[:fillId].to_s].to_s,
270
+ 'borderId'=>border_id_corrector[style[:borderId].to_s].to_s)
271
+ end
272
+ }
273
+
274
+ xml.cellXfs('count'=>@workbook.cell_xfs[:xf].size) {
275
+ @workbook.cell_xfs[:xf].each do |xf_obj|
276
+ xf = @workbook.get_style_attributes(xf_obj)
277
+
278
+ xml.xf('numFmtId'=>xf[:numFmtId].to_s,
279
+ 'fontId'=>font_id_corrector[xf[:fontId].to_s].to_s,
280
+ 'fillId'=>fill_id_corrector[xf[:fillId].to_s].to_s,
281
+ 'borderId'=>border_id_corrector[xf[:borderId].to_s].to_s,
282
+ 'xfId'=>xf[:xfId].to_s,
283
+ 'applyFont'=>Integer(xf[:applyFont]).to_s, #0 if nil
284
+ 'applyFill'=>Integer(xf[:applyFill]).to_s,
285
+ 'applyAlignment'=>Integer(xf[:applyAlignment]).to_s,
286
+ 'applyNumberFormat'=>Integer(xf[:applyNumberFormat]).to_s) {
287
+ unless xf_obj.is_a?Array
288
+ unless xf_obj[:alignment].nil?
289
+ xml.alignment('horizontal'=>xf_obj[:alignment][:attributes][:horizontal].to_s,
290
+ 'vertical'=>xf_obj[:alignment][:attributes][:vertical].to_s,
291
+ 'wrapText'=>xf_obj[:alignment][:attributes][:wrapText].to_s)
292
+ end
293
+ end
294
+ }
295
+ end
296
+ }
297
+ xml.cellStyles('count'=>@workbook.cell_styles[:attributes][:count].to_s) {
298
+
299
+ @workbook.cell_styles[:cellStyle].each do |style|
300
+ style = @workbook.get_style_attributes(style)
301
+ xml.cellStyle('name'=>style[:name].to_s,
302
+ 'xfId'=>style[:xfId].to_s,
303
+ 'builtinId'=>style[:builtinId].to_s)
304
+ end
305
+ }
306
+ xml.dxfs('count'=>'0')
307
+ xml.tableStyles('count'=>'0', 'defaultTableStyle'=>'TableStyleMedium9')
308
+
309
+ unless @colors.nil?
310
+ xml.colors {
311
+ unless @colors[:indexedColors].nil?
312
+ xml.indexedColors {
313
+ @colors[:indexedColors].each do |rgb_color|
314
+ xml.rgbColor rgb_color[:attributes][:rgb]
315
+ end
316
+ }
317
+ end
318
+
319
+ unless @colors[:mruColors].nil?
320
+ xml.mruColors {
321
+ @colors[:mruColors].each do |color|
322
+ xml.color color[:attributes][:rgb]
323
+ end
324
+ }
325
+ end
326
+ }
327
+ end
328
+ }
329
+ end
330
+ contents = builder.to_xml
331
+ contents = contents.gsub(/\n/,'')
332
+ contents = contents.gsub(/>(\s)+</,'><')
333
+ contents = contents.sub(/<\?xml version=\"1.0\"\?>/,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n")
334
+ contents
335
+ end
336
+
337
+ private
338
+
339
+ def hash_equal(h1,h2)
340
+ if h1.nil?
341
+ if h2.nil?
342
+ return true
343
+ else
344
+ return false
345
+ end
346
+ elsif h2.nil?
347
+ return false
348
+ end
349
+ if h1.size != h2.size
350
+ return false
351
+ end
352
+
353
+ h1.each do |k,v|
354
+ if (h1[k].is_a?String) || (h2[k].is_a?String)
355
+ if (h1.is_a?Hash) && (h2.is_a?Hash)
356
+ unless hash_equal(h1[k].to_s,h2[k].to_s)
357
+ return false
358
+ end
359
+ else
360
+ unless h1[k].to_s == h2[k].to_s
361
+ return false
362
+ end
363
+ end
364
+ else
365
+ unless h1[k] == h2[k]
366
+ return false
367
+ end
368
+ end
369
+ end
370
+
371
+ true
372
+ end
373
+
374
+ end
375
+ end
376
+ end