thunderboltlabs-rubyXL 1.2.10.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.
- checksums.yaml +15 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +197 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/.DS_Store +0 -0
- data/lib/rubyXL/Hash.rb +60 -0
- data/lib/rubyXL/cell.rb +461 -0
- data/lib/rubyXL/color.rb +14 -0
- data/lib/rubyXL/parser.rb +471 -0
- data/lib/rubyXL/private_class.rb +265 -0
- data/lib/rubyXL/workbook.rb +450 -0
- data/lib/rubyXL/worksheet.rb +1493 -0
- data/lib/rubyXL/writer/app_writer.rb +62 -0
- data/lib/rubyXL/writer/calc_chain_writer.rb +33 -0
- data/lib/rubyXL/writer/content_types_writer.rb +77 -0
- data/lib/rubyXL/writer/core_writer.rb +51 -0
- data/lib/rubyXL/writer/root_rels_writer.rb +25 -0
- data/lib/rubyXL/writer/shared_strings_writer.rb +30 -0
- data/lib/rubyXL/writer/styles_writer.rb +407 -0
- data/lib/rubyXL/writer/theme_writer.rb +343 -0
- data/lib/rubyXL/writer/workbook_rels_writer.rb +59 -0
- data/lib/rubyXL/writer/workbook_writer.rb +77 -0
- data/lib/rubyXL/writer/worksheet_writer.rb +230 -0
- data/lib/rubyXL/zip.rb +20 -0
- data/lib/rubyXL.rb +10 -0
- data/rubyXL.gemspec +92 -0
- data/spec/lib/cell_spec.rb +385 -0
- data/spec/lib/color_spec.rb +14 -0
- data/spec/lib/hash_spec.rb +28 -0
- data/spec/lib/parser_spec.rb +66 -0
- data/spec/lib/workbook_spec.rb +51 -0
- data/spec/lib/worksheet_spec.rb +1782 -0
- metadata +179 -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.Default('Extension'=>'xml', 'ContentType'=>'application/xml')
|
23
|
+
unless @workbook.shared_strings.nil?
|
24
|
+
xml.Override('PartName'=>'/xl/sharedStrings.xml',
|
25
|
+
'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml")
|
26
|
+
end
|
27
|
+
if @workbook.macros.nil? && @workbook.drawings.nil?
|
28
|
+
xml.Override('PartName'=>'/xl/workbook.xml',
|
29
|
+
'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")
|
30
|
+
else
|
31
|
+
xml.Override('PartName'=>'/xl/workbook.xml',
|
32
|
+
'ContentType'=>"application/vnd.ms-excel.sheet.macroEnabled.main+xml")
|
33
|
+
end
|
34
|
+
xml.Override('PartName'=>"/xl/styles.xml",
|
35
|
+
'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml")
|
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
|
+
unless @workbook.macros.nil?
|
44
|
+
xml.Override('PartName'=>'/xl/vbaProject.bin',
|
45
|
+
'ContentType'=>'application/vnd.ms-office.vbaProject')
|
46
|
+
end
|
47
|
+
unless @workbook.printer_settings.nil?
|
48
|
+
xml.Default('Extension'=>'bin',
|
49
|
+
'ContentType'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings')
|
50
|
+
end
|
51
|
+
unless @workbook.drawings.nil?
|
52
|
+
xml.Default('Extension'=>'vml',
|
53
|
+
'ContentType'=>'application/vnd.openxmlformats-officedocument.vmlDrawing')
|
54
|
+
end
|
55
|
+
xml.Override('PartName'=>'/xl/theme/theme1.xml',
|
56
|
+
'ContentType'=>"application/vnd.openxmlformats-officedocument.theme+xml")
|
57
|
+
@workbook.worksheets.each_with_index do |sheet,i|
|
58
|
+
xml.Override('PartName'=>"/xl/worksheets/sheet#{i+1}.xml",
|
59
|
+
'ContentType'=>"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml")
|
60
|
+
end
|
61
|
+
xml.Override('PartName'=>'/docProps/core.xml',
|
62
|
+
'ContentType'=>"application/vnd.openxmlformats-package.core-properties+xml")
|
63
|
+
xml.Override('PartName'=>'/docProps/app.xml',
|
64
|
+
'ContentType'=>"application/vnd.openxmlformats-officedocument.extended-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,30 @@
|
|
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
|
+
# Excel doesn't care much about the contents of sharedStrings.xml -- it will fill it in, but the file has to exist and have a root node.
|
21
|
+
if @workbook.shared_strings_XML
|
22
|
+
contents = @workbook.shared_strings_XML
|
23
|
+
else
|
24
|
+
contents = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n"+'<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="0" uniqueCount="0"></sst>'
|
25
|
+
end
|
26
|
+
contents
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,407 @@
|
|
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
|
+
if !@workbook.cell_xfs[:xf].is_a?(Array)
|
78
|
+
@workbook.cell_xfs[:xf] = [@workbook.cell_xfs[:xf]]
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
style_id_corrector['0']=0
|
84
|
+
delete_list = []
|
85
|
+
i = 1
|
86
|
+
while(i < @workbook.cell_xfs[:xf].size) do
|
87
|
+
if style_id_corrector[i.to_s].nil?
|
88
|
+
style_id_corrector[i.to_s]= i
|
89
|
+
end
|
90
|
+
# style correction commented out until bug is fixed
|
91
|
+
j = i+1
|
92
|
+
while(j < @workbook.cell_xfs[:xf].size) do
|
93
|
+
if hash_equal(@workbook.cell_xfs[:xf][i],@workbook.cell_xfs[:xf][j]) #check if this is working
|
94
|
+
style_id_corrector[j.to_s] = i
|
95
|
+
delete_list << j
|
96
|
+
end
|
97
|
+
j += 1
|
98
|
+
end
|
99
|
+
i += 1
|
100
|
+
end
|
101
|
+
|
102
|
+
#go through delete list, if before delete_list index 0, offset 0, if before delete_list index 1, offset 1, etc.
|
103
|
+
delete_list.sort!
|
104
|
+
|
105
|
+
i = 1
|
106
|
+
offset = 0
|
107
|
+
offset_corrector = 0
|
108
|
+
delete_list << @workbook.cell_xfs[:xf].size
|
109
|
+
while offset < delete_list.size do
|
110
|
+
delete_index = delete_list[offset] - offset
|
111
|
+
|
112
|
+
while i <= delete_list[offset] do #if <= instead of <, fixes odd border but adds random cells with fill
|
113
|
+
if style_id_corrector[i.to_s] == i
|
114
|
+
style_id_corrector[i.to_s] -= offset# unless style_id_corrector[i.to_s].nil? #173 should equal 53, not 52?
|
115
|
+
end
|
116
|
+
|
117
|
+
i += 1
|
118
|
+
end
|
119
|
+
@workbook.cell_xfs[:xf].delete_at(delete_index)
|
120
|
+
offset += 1
|
121
|
+
end
|
122
|
+
|
123
|
+
@workbook.style_corrector = style_id_corrector
|
124
|
+
|
125
|
+
|
126
|
+
xml.fonts('count'=>@workbook.fonts.size) {
|
127
|
+
0.upto(@workbook.fonts.size-1) do |i|
|
128
|
+
font = @workbook.fonts[i.to_s]
|
129
|
+
unless font.nil?
|
130
|
+
font = font[:font]
|
131
|
+
xml.font {
|
132
|
+
xml.sz('val'=>font[:sz][:attributes][:val].to_s)
|
133
|
+
unless font[:b].nil?
|
134
|
+
xml.b
|
135
|
+
end
|
136
|
+
unless font[:i].nil?
|
137
|
+
xml.i
|
138
|
+
end
|
139
|
+
unless font[:u].nil?
|
140
|
+
xml.u
|
141
|
+
end
|
142
|
+
unless font[:strike].nil?
|
143
|
+
xml.strike
|
144
|
+
end
|
145
|
+
unless font[:color].nil?
|
146
|
+
unless font[:color][:attributes][:indexed].nil?
|
147
|
+
xml.color('indexed'=>font[:color][:attributes][:indexed])
|
148
|
+
else
|
149
|
+
unless font[:color][:attributes][:rgb].nil?
|
150
|
+
xml.color('rgb'=>font[:color][:attributes][:rgb])
|
151
|
+
else
|
152
|
+
unless font[:color][:attributes][:theme].nil?
|
153
|
+
xml.color('theme'=>font[:color][:attributes][:theme])
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
unless font[:family].nil?
|
159
|
+
xml.family('val'=>font[:family][:attributes][:val].to_s)
|
160
|
+
end
|
161
|
+
unless font[:scheme].nil?
|
162
|
+
xml.scheme('val'=>font[:scheme][:attributes][:val].to_s)
|
163
|
+
end
|
164
|
+
|
165
|
+
xml.name('val'=>font[:name][:attributes][:val].to_s)
|
166
|
+
}
|
167
|
+
end
|
168
|
+
end
|
169
|
+
}
|
170
|
+
|
171
|
+
xml.fills('count'=>@workbook.fills.size) {
|
172
|
+
0.upto(@workbook.fills.size-1) do |i|
|
173
|
+
fill = @workbook.fills[i.to_s]
|
174
|
+
unless fill.nil?
|
175
|
+
fill = fill[:fill]
|
176
|
+
xml.fill {
|
177
|
+
xml.patternFill('patternType'=>fill[:patternFill][:attributes][:patternType].to_s) {
|
178
|
+
unless fill[:patternFill][:fgColor].nil?
|
179
|
+
fgColor = fill[:patternFill][:fgColor][:attributes]
|
180
|
+
unless fgColor[:indexed].nil?
|
181
|
+
xml.fgColor('indexed'=>fgColor[:indexed].to_s)
|
182
|
+
else
|
183
|
+
unless fgColor[:rgb].nil?
|
184
|
+
xml.fgColor('rgb'=>fgColor[:rgb])
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
unless fill[:patternFill][:bgColor].nil?
|
189
|
+
bgColor = fill[:patternFill][:bgColor][:attributes]
|
190
|
+
unless bgColor[:indexed].nil?
|
191
|
+
xml.bgColor('indexed'=>bgColor[:indexed].to_s)
|
192
|
+
else
|
193
|
+
unless bgColor[:rgb].nil?
|
194
|
+
xml.bgColor('rgb'=>bgColor[:rgb])
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
}
|
199
|
+
}
|
200
|
+
end
|
201
|
+
end
|
202
|
+
}
|
203
|
+
|
204
|
+
xml.borders('count'=>@workbook.borders.size) {
|
205
|
+
0.upto(@workbook.borders.size-1) do |i|
|
206
|
+
border = @workbook.borders[i.to_s]
|
207
|
+
unless border.nil?
|
208
|
+
border = border[:border]
|
209
|
+
xml.border {
|
210
|
+
if border[:left][:attributes].nil?
|
211
|
+
xml.left
|
212
|
+
else
|
213
|
+
xml.left('style'=>border[:left][:attributes][:style]) {
|
214
|
+
unless border[:left][:color].nil?
|
215
|
+
color = border[:left][:color][:attributes]
|
216
|
+
unless color[:indexed].nil?
|
217
|
+
xml.color('indexed'=>color[:indexed])
|
218
|
+
else
|
219
|
+
unless color[:rgb].nil?
|
220
|
+
xml.color('rgb'=>color[:rgb])
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
}
|
225
|
+
end
|
226
|
+
if border[:right][:attributes].nil?
|
227
|
+
xml.right
|
228
|
+
else
|
229
|
+
xml.right('style'=>border[:right][:attributes][:style]) {
|
230
|
+
unless border[:right][:color].nil?
|
231
|
+
color = border[:right][:color][:attributes]
|
232
|
+
unless color[:indexed].nil?
|
233
|
+
xml.color('indexed'=>color[:indexed])
|
234
|
+
else
|
235
|
+
unless color[:rgb].nil?
|
236
|
+
xml.color('rgb'=>color[:rgb])
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
}
|
241
|
+
end
|
242
|
+
if border[:top][:attributes].nil?
|
243
|
+
xml.top
|
244
|
+
else
|
245
|
+
xml.top('style'=>border[:top][:attributes][:style]) {
|
246
|
+
unless border[:top][:color].nil?
|
247
|
+
color = border[:top][:color][:attributes]
|
248
|
+
unless color[:indexed].nil?
|
249
|
+
xml.color('indexed'=>color[:indexed])
|
250
|
+
else
|
251
|
+
unless color[:rgb].nil?
|
252
|
+
xml.color('rgb'=>color[:rgb])
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
}
|
257
|
+
end
|
258
|
+
if border[:bottom][:attributes].nil?
|
259
|
+
xml.bottom
|
260
|
+
else
|
261
|
+
xml.bottom('style'=>border[:bottom][:attributes][:style]) {
|
262
|
+
unless border[:bottom][:color].nil?
|
263
|
+
color = border[:bottom][:color][:attributes]
|
264
|
+
unless color[:indexed].nil?
|
265
|
+
xml.color('indexed'=>color[:indexed])
|
266
|
+
else
|
267
|
+
unless color[:rgb].nil?
|
268
|
+
xml.color('rgb'=>color[:rgb])
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
}
|
273
|
+
end
|
274
|
+
if border[:diagonal][:attributes].nil?
|
275
|
+
xml.diagonal
|
276
|
+
else
|
277
|
+
xml.diagonal('style'=>border[:diagonal][:attributes][:style]) {
|
278
|
+
unless border[:diagonal][:color].nil?
|
279
|
+
color = border[:diagonal][:color][:attributes]
|
280
|
+
unless color[:indexed].nil?
|
281
|
+
xml.color('indexed'=>color[:indexed])
|
282
|
+
else
|
283
|
+
unless color[:rgb].nil?
|
284
|
+
xml.color('rgb'=>color[:rgb])
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
}
|
289
|
+
end
|
290
|
+
}
|
291
|
+
end #unless border.nil?
|
292
|
+
end #0.upto(size)
|
293
|
+
}
|
294
|
+
|
295
|
+
xml.cellStyleXfs('count'=>@workbook.cell_style_xfs[:attributes][:count].to_s) {
|
296
|
+
@workbook.cell_style_xfs[:xf].each do |style|
|
297
|
+
style = @workbook.get_style_attributes(style)
|
298
|
+
xml.xf('numFmtId'=>style[:numFmtId].to_s,
|
299
|
+
'fontId'=>font_id_corrector[style[:fontId].to_s].to_s,
|
300
|
+
'fillId'=>fill_id_corrector[style[:fillId].to_s].to_s,
|
301
|
+
'borderId'=>border_id_corrector[style[:borderId].to_s].to_s)
|
302
|
+
end
|
303
|
+
}
|
304
|
+
|
305
|
+
xml.cellXfs('count'=>@workbook.cell_xfs[:xf].size) {
|
306
|
+
@workbook.cell_xfs[:xf].each do |xf_obj|
|
307
|
+
xf = @workbook.get_style_attributes(xf_obj)
|
308
|
+
|
309
|
+
xml.xf('numFmtId'=>xf[:numFmtId].to_s,
|
310
|
+
'fontId'=>font_id_corrector[xf[:fontId].to_s].to_s,
|
311
|
+
'fillId'=>fill_id_corrector[xf[:fillId].to_s].to_s,
|
312
|
+
'borderId'=>border_id_corrector[xf[:borderId].to_s].to_s,
|
313
|
+
'xfId'=>xf[:xfId].to_s,
|
314
|
+
'applyFont'=>xf[:applyFont].to_i.to_s, #0 if nil
|
315
|
+
'applyFill'=>xf[:applyFill].to_i.to_s,
|
316
|
+
'applyAlignment'=>xf[:applyAlignment].to_i.to_s,
|
317
|
+
'applyNumberFormat'=>xf[:applyNumberFormat].to_i.to_s) {
|
318
|
+
unless xf_obj.is_a?Array
|
319
|
+
unless xf_obj[:alignment].nil?
|
320
|
+
xml.alignment('horizontal'=>xf_obj[:alignment][:attributes][:horizontal].to_s,
|
321
|
+
'vertical'=>xf_obj[:alignment][:attributes][:vertical].to_s,
|
322
|
+
'wrapText'=>xf_obj[:alignment][:attributes][:wrapText].to_s)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
}
|
326
|
+
end
|
327
|
+
}
|
328
|
+
xml.cellStyles('count'=>@workbook.cell_styles[:attributes][:count].to_s) {
|
329
|
+
|
330
|
+
@workbook.cell_styles[:cellStyle].each do |style|
|
331
|
+
style = @workbook.get_style_attributes(style)
|
332
|
+
xml.cellStyle('name'=>style[:name].to_s,
|
333
|
+
'xfId'=>style[:xfId].to_s,
|
334
|
+
'builtinId'=>style[:builtinId].to_s)
|
335
|
+
end
|
336
|
+
}
|
337
|
+
xml.dxfs('count'=>'0')
|
338
|
+
xml.tableStyles('count'=>'0', 'defaultTableStyle'=>'TableStyleMedium9')
|
339
|
+
|
340
|
+
unless @colors.nil?
|
341
|
+
xml.colors {
|
342
|
+
unless @colors[:indexedColors].nil?
|
343
|
+
xml.indexedColors {
|
344
|
+
@colors[:indexedColors].each do |rgb_color|
|
345
|
+
xml.rgbColor rgb_color[:attributes][:rgb]
|
346
|
+
end
|
347
|
+
}
|
348
|
+
end
|
349
|
+
|
350
|
+
unless @colors[:mruColors].nil?
|
351
|
+
xml.mruColors {
|
352
|
+
@colors[:mruColors].each do |color|
|
353
|
+
xml.color color[:attributes][:rgb]
|
354
|
+
end
|
355
|
+
}
|
356
|
+
end
|
357
|
+
}
|
358
|
+
end
|
359
|
+
}
|
360
|
+
end
|
361
|
+
contents = builder.to_xml
|
362
|
+
contents = contents.gsub(/\n/,'')
|
363
|
+
contents = contents.gsub(/>(\s)+</,'><')
|
364
|
+
contents = contents.sub(/<\?xml version=\"1.0\"\?>/,'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+"\n")
|
365
|
+
contents
|
366
|
+
end
|
367
|
+
|
368
|
+
private
|
369
|
+
|
370
|
+
def hash_equal(h1,h2)
|
371
|
+
if h1.nil?
|
372
|
+
if h2.nil?
|
373
|
+
return true
|
374
|
+
else
|
375
|
+
return false
|
376
|
+
end
|
377
|
+
elsif h2.nil?
|
378
|
+
return false
|
379
|
+
end
|
380
|
+
if h1.size != h2.size
|
381
|
+
return false
|
382
|
+
end
|
383
|
+
|
384
|
+
h1.each do |k,v|
|
385
|
+
if (h1[k].is_a?String) || (h2[k].is_a?String)
|
386
|
+
if (h1.is_a?Hash) && (h2.is_a?Hash)
|
387
|
+
unless hash_equal(h1[k].to_s,h2[k].to_s)
|
388
|
+
return false
|
389
|
+
end
|
390
|
+
else
|
391
|
+
unless h1[k].to_s == h2[k].to_s
|
392
|
+
return false
|
393
|
+
end
|
394
|
+
end
|
395
|
+
else
|
396
|
+
unless h1[k] == h2[k]
|
397
|
+
return false
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
true
|
403
|
+
end
|
404
|
+
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|