rubyXL 1.0.4

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.
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