simonmenke-xlsx 0.0.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/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-08-27
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Simon Menke
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,28 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ config/hoe.rb
7
+ config/requirements.rb
8
+ lib/xlsx.rb
9
+ lib/xlsx/cell.rb
10
+ lib/xlsx/formatter.rb
11
+ lib/xlsx/sheet.rb
12
+ lib/xlsx/version.rb
13
+ lib/xlsx/workbook.rb
14
+ script/console
15
+ script/destroy
16
+ script/generate
17
+ script/txt2html
18
+ setup.rb
19
+ tasks/deployment.rake
20
+ tasks/environment.rake
21
+ tasks/website.rake
22
+ test/test_helper.rb
23
+ test/test_xlsx.rb
24
+ website/index.html
25
+ website/index.txt
26
+ website/javascripts/rounded_corners_lite.inc.js
27
+ website/stylesheets/screen.css
28
+ website/template.html.erb
data/README.txt ADDED
@@ -0,0 +1,64 @@
1
+ = xlsx
2
+
3
+ * http://github.com/simonmenke/xlsx
4
+
5
+ == DESCRIPTION:
6
+
7
+ This little gem writes MS Excel 2007 xlsx files.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * write XLSX files.
12
+
13
+ == SYNOPSIS:
14
+
15
+ require 'rubygems'
16
+ require 'xlsx'
17
+
18
+ workbook = XLSX::Workbook.new
19
+ workbook.add_sheet("My sheet") do |sheet|
20
+
21
+ sheet[0,0] = 'ID'
22
+ sheet[0,1] = 'VALUE'
23
+
24
+ sheet[1,0] = 3
25
+ sheet[1,1] = 'Hello'
26
+
27
+ end
28
+
29
+ workbook.dump('~/data.xlsx') # write the file
30
+ workbook.build # or get the data
31
+
32
+ == REQUIREMENTS:
33
+
34
+ * builder >= 2.1.2
35
+ * rubyzip >= 0.9.1
36
+
37
+ == INSTALL:
38
+
39
+ * sudo gem install simonmenke-xlsx
40
+
41
+ == LICENSE:
42
+
43
+ (The MIT License)
44
+
45
+ Copyright (c) 2008 Simon Menke
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of this software and associated documentation files (the
49
+ 'Software'), to deal in the Software without restriction, including
50
+ without limitation the rights to use, copy, modify, merge, publish,
51
+ distribute, sublicense, and/or sell copies of the Software, and to
52
+ permit persons to whom the Software is furnished to do so, subject to
53
+ the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be
56
+ included in all copies or substantial portions of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
59
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
60
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
61
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
62
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
63
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
64
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
data/config/hoe.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'xlsx/version'
2
+
3
+ AUTHOR = 'Simon Menke' # can also be an array of Authors
4
+ EMAIL = "simon@5xm.org"
5
+ DESCRIPTION = "Write xlsx files."
6
+ GEM_NAME = 'xlsx' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'xlsx' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+ EXTRA_DEPENDENCIES = [
11
+ ['builder', '>= 2.1.2'],
12
+ ['rubyzip', '>= 0.9.1']
13
+ # ['activesupport', '>= 1.3.1']
14
+ ] # An array of rubygem dependencies [name, version]
15
+
16
+ @config_file = "~/.rubyforge/user-config.yml"
17
+ @config = nil
18
+ RUBYFORGE_USERNAME = "luinithil"
19
+ def rubyforge_username
20
+ unless @config
21
+ begin
22
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
23
+ rescue
24
+ puts <<-EOS
25
+ ERROR: No rubyforge config file found: #{@config_file}
26
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
27
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
28
+ EOS
29
+ exit
30
+ end
31
+ end
32
+ RUBYFORGE_USERNAME.replace @config["username"]
33
+ end
34
+
35
+
36
+ REV = nil
37
+ # UNCOMMENT IF REQUIRED:
38
+ # REV = YAML.load(`svn info`)['Revision']
39
+ VERS = XLSX::VERSION::STRING + (REV ? ".#{REV}" : "")
40
+ RDOC_OPTS = ['--quiet', '--title', 'xlsx documentation',
41
+ "--opname", "index.html",
42
+ "--line-numbers",
43
+ "--main", "README",
44
+ "--inline-source"]
45
+
46
+ class Hoe
47
+ def extra_deps
48
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
49
+ @extra_deps
50
+ end
51
+ end
52
+
53
+ # Generate all the Rake tasks
54
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
55
+ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
56
+ p.developer(AUTHOR, EMAIL)
57
+ p.description = DESCRIPTION
58
+ p.summary = DESCRIPTION
59
+ p.url = HOMEPATH
60
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
61
+ p.test_globs = ["test/**/test_*.rb"]
62
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
63
+
64
+ # == Optional
65
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
66
+ #p.extra_deps = EXTRA_DEPENDENCIES
67
+
68
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
69
+ end
70
+
71
+ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
72
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
73
+ $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
74
+ $hoe.rsync_args = '-av --delete --ignore-errors'
75
+ $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -0,0 +1,15 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
data/lib/xlsx/cell.rb ADDED
@@ -0,0 +1,37 @@
1
+
2
+ module XLSX
3
+ class Cell # :nodoc:
4
+
5
+ def self.type_of(value)
6
+ return 's' if value.is_a? String
7
+ return 'n' if value.is_a? Integer
8
+ return 'n' if value.respond_to? :to_i
9
+ return 's' if value.respond_to? :to_s
10
+ return 's' # default
11
+ end
12
+
13
+ def self.storage_hash(row, column)
14
+ Digest::SHA1.hexdigest("#{row}-#{column}")
15
+ end
16
+
17
+ attr_accessor :sheet, :type, :value, :row, :column
18
+
19
+ def initialize(sheet, row, column)
20
+ @sheet, @row, @column = sheet, row.to_i, column.to_i
21
+ end
22
+
23
+ def storage_hash
24
+ @storage_hash ||= self.class.storage_hash(row, column)
25
+ end
26
+
27
+ def <=>(other)
28
+ return(0) unless other.is_a?(::XLSX::Cell)
29
+ order = (self.row <=> other.row)
30
+ order = (self.column <=> other.column) if order == 0
31
+ order
32
+ rescue
33
+ 0
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,375 @@
1
+
2
+ module XLSX
3
+ class Formatter # :nodoc:
4
+
5
+ def self.build(workbook)
6
+ self.new(workbook).build_workbook
7
+ end
8
+
9
+ def self.dump(workbook, output_path=nil)
10
+ self.new(workbook, output_path).dump_workbook
11
+ end
12
+
13
+ attr_accessor :output_path
14
+ attr_accessor :tmp_path
15
+ attr_accessor :workbook
16
+ attr_accessor :zip_file
17
+
18
+ def initialize(workbook, output_path=nil)
19
+ @workbook, @output_path = workbook, output_path
20
+ end
21
+
22
+ def build_workbook
23
+ data = File.open(dump_workbook).read
24
+ File.unlink(@output_path)
25
+ data
26
+ end
27
+
28
+ def dump_workbook
29
+ in_zip_file do
30
+
31
+ mkdir("_rels")
32
+ mkdir("docProps")
33
+ mkdir("xl")
34
+ mkdir("xl/_rels")
35
+ mkdir("xl/worksheets")
36
+
37
+ build_content_types_xml_file
38
+ build_docProps_app_xml_file
39
+ build_docProps_core_xml_file
40
+ build_xl__rels_workbook_xml_rels_file
41
+ build_xl_sharedStrings_xml_file
42
+ build_xl_styles_xml_file
43
+ build_xl_workbook_xml_file
44
+ build_xl_worksheets_sheet_xml_files
45
+
46
+ end
47
+ end
48
+
49
+ def build_xl_worksheets_sheet_xml_files
50
+ @workbook.sheets.each do |sheet|
51
+ dump_xml("xl/worksheets/sheet#{sheet.id}.xml") do |xml|
52
+
53
+ rows = sheet.data.values.sort.inject([]) do |rows, cell|
54
+ if rows.last.nil? or (rows.last.first != cell.row)
55
+ rows.push([cell.row, []])
56
+ end
57
+ rows.last.last.push(cell)
58
+ rows
59
+ end
60
+
61
+ column_counts = rows.collect { |row| row.last.size }
62
+ max_column_count = column_counts.max
63
+
64
+
65
+ xml.worksheet({'xmlns' => "http://schemas.openxmlformats.org/spreadsheetml/2006/main"}) do
66
+ xml.sheetViews do
67
+ xml.sheetView({ 'workbookViewId' => "0", 'zoomScale' => "100" }) do
68
+ xml.selection({ 'activeCell' => 'A1', 'sqref' => 'A1' })
69
+ end
70
+ end
71
+ xml.sheetFormatPr({ 'defaultColWidth' => "13.2307692307692", 'defaultRowHeight' => "13", 'customHeight' => "true" })
72
+ xml.cols do
73
+ xml.col({ 'min' => '1', 'max' => max_column_count.to_s, 'width' => "13.2307692307692", 'customWidth' => "1" })
74
+ end
75
+ xml.sheetData do
76
+ rows.each do |row|
77
+ xml.row({ 'r' => row.first.to_s, 'ht' => '12.1' }) do
78
+ row.last.each do |cell|
79
+ xml.c({ 'r' => "#{letter_column_name(cell.column+1)}#{row.first + 1}", 't' => cell.type }) do
80
+ xml.v(cell.value.to_s)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ xml.headerFooter do
87
+ xml.oddHeader("&C&A", { 'xml:space' => "preserve" })
88
+ xml.oddHeader("&C&\"Arial\"&10Page &P", { 'xml:space' => "preserve" })
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+
96
+ def build_content_types_xml_file(sheets=[])
97
+ dump_xml("[Content_Types].xml") do |xml|
98
+ xml.Types({'xmlns' => "http://schemas.openxmlformats.org/package/2006/content-types"}) do
99
+ xml.Default({'Extension' => 'jpeg', 'ContentType' => 'image/jpeg'})
100
+ xml.Default({'Extension' => 'jpg', 'ContentType' => 'image/jpeg'})
101
+ xml.Default({'Extension' => 'gif', 'ContentType' => 'image/gif'})
102
+ xml.Default({'Extension' => 'png', 'ContentType' => 'image/png'})
103
+ xml.Default({'Extension' => 'wmf', 'ContentType' => 'image/x-emf'})
104
+ xml.Default({'Extension' => 'emf', 'ContentType' => 'image/x-emf'})
105
+ xml.Default({'Extension' => 'tif', 'ContentType' => 'image/tiff'})
106
+ xml.Default({'Extension' => 'tiff', 'ContentType' => 'image/tiff'})
107
+ xml.Default({'Extension' => 'bin', 'ContentType' => 'application/vnd.openxmlformats-officedocument.oleObject'})
108
+ xml.Default({'Extension' => 'rels', 'ContentType' => 'application/vnd.openxmlformats-package.relationships+xml'})
109
+ xml.Default({'Extension' => 'xml', 'ContentType' => 'application/xml'})
110
+ xml.Default({'Extension' => 'vml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.vmlDrawing'})
111
+
112
+ xml.Override({'PartName' => '/xl/theme/theme1.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.theme+xml'})
113
+ xml.Override({'PartName' => '/xl/workbook.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'})
114
+ xml.Override({'PartName' => '/xl/sharedStrings.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'})
115
+ xml.Override({'PartName' => '/docProps/core.xml', 'ContentType' => 'application/vnd.openxmlformats-package.core-properties+xml'})
116
+ xml.Override({'PartName' => '/docProps/app.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.extended-properties+xml'})
117
+ xml.Override({'PartName' => '/docProps/custom.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.custom-properties+xml'})
118
+ xml.Override({'PartName' => '/xl/styles.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'})
119
+ xml.Override({'PartName' => '/xl/connections.xml', 'ContentType' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml'})
120
+
121
+ @workbook.sheets.each do |sheet|
122
+ xml.Override({'PartName' => "/xl/worksheets/sheet#{sheet.id}.xml", 'ContentType' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'})
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ def build_docProps_app_xml_file
129
+ dump_xml("docProps/app.xml") do |xml|
130
+ xml.Properties({
131
+ 'xmlns' => 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties',
132
+ 'xmlns:vt' => 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes',
133
+ 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/'
134
+ }) do
135
+ xml.DocSecurity("1")
136
+ xml.Application("RbXLSX")
137
+ xml.TotalTime("1")
138
+ end
139
+ end
140
+ end
141
+
142
+ def build_docProps_core_xml_file
143
+ dump_xml("docProps/core.xml") do |xml|
144
+ xml.cp :coreProperties, { 'xmlns:cp' => 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties', 'xmlns:dcmitype' => 'http://purl.org/dc/dcmitype/' } do
145
+ xml.dcterms :created, '2008-08-25T14:50:39Z', { 'xmlns:dcterms' => 'http://purl.org/dc/terms/', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:type' => 'dcterms:W3CDTF' }
146
+ xml.dcterms :modified, '2008-08-25T14:51:32Z', { 'xmlns:dcterms' => 'http://purl.org/dc/terms/', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:type' => 'dcterms:W3CDTF' }
147
+ xml.dc :language, 'en', { 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/' }
148
+ xml.cp :revision, '2'
149
+ end
150
+ end
151
+ end
152
+
153
+ def build_xl_sharedStrings_xml_file
154
+ dump_xml("xl/sharedStrings.xml") do |xml|
155
+ xml.sst({ 'xmlns' => 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', 'count' => @workbook.strings.size.to_s, 'uniqueCount' => @workbook.strings.size.to_s }) do
156
+ @workbook.strings.each do |string|
157
+ xml.si { xml.t string.to_s, { 'xml:space' => 'preserve' } }
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ def build_xl_styles_xml_file
164
+ dump_xml("xl/styles.xml") do |xml|
165
+ xml.styleSheet({ 'xmlns' => 'http://schemas.openxmlformats.org/spreadsheetml/2006/main' }) do
166
+
167
+ xml.numFmts({ 'count' => '3' }) do
168
+ xml.numFmt({ 'numFmtId' => '1', 'formatCode' => '0.##' })
169
+ xml.numFmt({ 'numFmtId' => '3', 'formatCode' => '[$$-409]#,##0.00;[$$-409][Red]-#,##0.00' })
170
+ end
171
+
172
+ xml.fonts({ 'count' => '1' }) do
173
+ xml.font do
174
+ xml.sz({ 'val' => '10' })
175
+ xml.name({ 'val' => 'Arial' })
176
+ end
177
+ xml.font do
178
+ xml.b
179
+ xml.i
180
+ xml.u({ 'val' => 'single' })
181
+ end
182
+ xml.font do
183
+ xml.b
184
+ xml.i
185
+ xml.sz({ 'val' => '16' })
186
+ end
187
+ end
188
+
189
+ xml.fills do
190
+ xml.fill do
191
+ xml.patternFill({ 'patternType' => 'none' })
192
+ end
193
+ xml.fill do
194
+ xml.patternFill({ 'patternType' => 'gray125' })
195
+ end
196
+ xml.fill do
197
+ xml.patternFill({ 'patternType' => 'none' })
198
+ end
199
+ xml << "$-$"
200
+ xml.fill do
201
+ xml.patternFill({ 'patternType' => 'none' })
202
+ end
203
+ xml.fill do
204
+ xml.patternFill({ 'patternType' => 'none' })
205
+ end
206
+ end
207
+
208
+ xml.borders do
209
+ xml.border do
210
+ xml.left
211
+ xml.right
212
+ xml.top
213
+ xml.bottom
214
+ xml.diagonal
215
+ end
216
+ xml.border do
217
+ xml.left
218
+ xml.right
219
+ xml.top
220
+ xml.bottom
221
+ xml.diagonal
222
+ end
223
+ xml.border do
224
+ xml.left
225
+ xml.right
226
+ xml.top
227
+ xml.bottom
228
+ xml.diagonal
229
+ end
230
+ xml.border do
231
+ xml.left
232
+ xml.right
233
+ xml.top
234
+ xml.bottom
235
+ xml.diagonal
236
+ end
237
+ end
238
+
239
+ xml.cellStyleXfs({ 'count' => '6' }) do
240
+ xml.xf({ 'numFmtId' => '0', 'fontId' => '0', 'fillId' => '0', 'borderId' => '0' })
241
+ xml.xf({ 'numFmtId' => '0', 'fontId' => '0', 'fillId' => '0', 'borderId' => '0' })
242
+ xml.xf({ 'numFmtId' => '0', 'fillId' => '0', 'borderId' => '0', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '2' })
243
+ xml.xf({ 'numFmtId' => '3', 'fillId' => '0', 'borderId' => '0', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '2' })
244
+ xml.xf({ 'numFmtId' => '0', 'fillId' => '0', 'borderId' => '0', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '3', 'applyAlignment' => '1' }) do
245
+ xml.alignment({ 'horizontal' => 'center' })
246
+ end
247
+ xml.xf({ 'numFmtId' => '0', 'fillId' => '0', 'borderId' => '0', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '3', 'applyAlignment' => '1' }) do
248
+ xml.alignment({ 'horizontal' => 'center', 'textRotation' => '90' })
249
+ end
250
+ end
251
+
252
+ xml.cellXfs({ 'count' => '1' }) do
253
+ xml.xf({ 'numFmtId' => '0', 'fontId' => '0', 'fillId' => '0', 'borderId' => '0', 'xfId' => '0' })
254
+ xml.xf({ 'numFmtId' => '0', 'fontId' => '0', 'fillId' => '0', 'borderId' => '0', 'xfId' => '1' })
255
+ xml.xf({ 'numFmtId' => '0', 'fillId' => '0', 'borderId' => '0', 'xfId' => '2', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '2' })
256
+ xml.xf({ 'numFmtId' => '3', 'fillId' => '0', 'borderId' => '0', 'xfId' => '3', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '2' })
257
+ xml.xf({ 'numFmtId' => '0', 'fillId' => '0', 'borderId' => '0', 'xfId' => '4', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '3', 'applyAlignment' => '1' }) do
258
+ xml.alignment({ 'horizontal' => 'center' })
259
+ end
260
+ xml.xf({ 'numFmtId' => '0', 'fillId' => '0', 'borderId' => '0', 'xfId' => '5', 'applyFont' => '1', 'ZMIENNA_contentFontsCount' => '0', 'ZMIENNA_styleFontsCount' => '2', 'fontId' => '3', 'applyAlignment' => '1' }) do
261
+ xml.alignment({ 'horizontal' => 'center', 'textRotation' => '90' })
262
+ end
263
+ end
264
+
265
+ xml.cellStyles do
266
+ xml.cellStyle({ 'xfId' => '1', 'name' => 'Default' })
267
+ xml.cellStyle({ 'xfId' => '2', 'name' => 'Result' })
268
+ xml.cellStyle({ 'xfId' => '3', 'name' => 'Result2' })
269
+ xml.cellStyle({ 'xfId' => '4', 'name' => 'Heading' })
270
+ xml.cellStyle({ 'xfId' => '5', 'name' => 'Heading1' })
271
+ end
272
+
273
+ xml.dxfs({ 'xmlns:config' => 'urn:oasis:names:tc:opendocument:xmlns:config:1.0', 'xmlns:fo' => 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0', 'count' => '3' }) do
274
+ xml.dxf do
275
+ xml.font do
276
+ xml.condense({ 'val' => '0' })
277
+ xml.extend({ 'val' => '0' })
278
+ xml.color({ 'rgb' => 'FF9C0006' })
279
+ end
280
+ xml.fill do
281
+ xml.patternFill do
282
+ xml.bgColor({ 'rgb' => 'FFFFC7CE' })
283
+ end
284
+ end
285
+ end
286
+ end
287
+
288
+ xml.tableStyles({ 'count' => '0', 'defaultTableStyle' => 'TableStyleMedium9', 'defaultPivotStyle' => 'PivotStyleLight16' })
289
+
290
+ end
291
+ end
292
+ end
293
+
294
+ def build_xl_workbook_xml_file(sheets=[])
295
+ dump_xml("xl/workbook.xml") do |xml|
296
+ xml.workbook({ 'xmlns' => 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
297
+ 'xmlns:r' => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' }) do
298
+ xml.bookViews do
299
+ xml.workbookView({ 'activeTab' => '0' })
300
+ end
301
+ xml.sheets do
302
+ @workbook.sheets.each do |sheet|
303
+ xml.sheet({ 'name' => sheet.name, 'sheetId' => (sheet.id).to_s,'r:id' => sheet.hash })
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end
309
+
310
+ def build_xl__rels_workbook_xml_rels_file
311
+ dump_xml("xl/_rels/workbook.xml.rels") do |xml|
312
+ xml.Relationships({ 'xmlns' => 'http://schemas.openxmlformats.org/package/2006/relationships' }) do
313
+
314
+ xml.Relationship({ 'Id' => 'rId1', 'Target' => 'styles.xml',
315
+ 'Type' => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles' })
316
+
317
+ xml.Relationship({ 'Id' => 'rId2', 'Target' => 'sharedStrings.xml',
318
+ 'Type' => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings' })
319
+
320
+ xml.Relationship({ 'Id' => 'rId3', 'Target' => 'connections.xml',
321
+ 'Type' => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/connections' })
322
+
323
+ @workbook.sheets.each do |sheet|
324
+ xml.Relationship({ 'Id' => sheet.hash,
325
+ 'Type' => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
326
+ 'Target' => "worksheets/sheet#{sheet.id}.xml" })
327
+ end
328
+ end
329
+ end
330
+ end
331
+
332
+
333
+ private
334
+
335
+ def letter_column_name(i)
336
+ s = ""
337
+ i = i.to_i
338
+ while i > 26
339
+ r = i % 27
340
+ i = i / 27
341
+ s = (r == 0 ? s : (r + 64).chr + s)
342
+ end
343
+ (i == 0 ? s : (i + 64).chr + s)
344
+ end
345
+
346
+ def build_xml(options={})
347
+ xml= Builder::XmlMarkup.new(options)
348
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
349
+ yield(xml)
350
+ xml.target!
351
+ end
352
+
353
+ def dump_xml(path, &block)
354
+ @zip_file.file.open(path, "w") do |f|
355
+ f.write(build_xml(&block))
356
+ end
357
+ end
358
+
359
+ def in_zip_file
360
+ @output_path = File.join(Dir.tmpdir, "xlsx_#{Time.now.to_i}.xlsx") if @output_path.nil?
361
+ File.unlink(@output_path) if File.exist?(@output_path)
362
+ Zip::ZipFile.open(@output_path, Zip::ZipFile::CREATE) do |zip_file|
363
+ @zip_file = zip_file
364
+ yield
365
+ @zip_file = nil
366
+ end
367
+ @output_path
368
+ end
369
+
370
+ def mkdir(path)
371
+ @zip_file.dir.mkdir(path)
372
+ end
373
+
374
+ end
375
+ end
data/lib/xlsx/sheet.rb ADDED
@@ -0,0 +1,47 @@
1
+
2
+ module XLSX
3
+ class Sheet
4
+
5
+ attr_accessor :name # the name of this sheet
6
+ attr_accessor :id, :hash, :workbook # :nodoc:
7
+ attr_accessor :data # :nodoc:
8
+
9
+ def initialize # :nodoc:
10
+ @data = Hash.new
11
+ end
12
+
13
+ # Set the value of a cell
14
+ def []=(row, column, value)
15
+ set_cell(row, column, value)
16
+ end
17
+
18
+ # Get the value of a cell
19
+ def [](row, column)
20
+ cell = get_cell(row, column)
21
+ return nil if cell.nil?
22
+
23
+ case cell.type
24
+ when 's' then @workbook.strings[cell.value]
25
+ when 'n' then cell.value
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def get_cell(row, column) # :nodoc:
32
+ hash = ::XLSX::Cell.storage_hash(row, column)
33
+ @data[hash] ||= ::XLSX::Cell.new(self, row, column)
34
+ end
35
+
36
+ def set_cell(row, column, value) # :nodoc:
37
+ cell = get_cell(row, column)
38
+ cell.type = ::XLSX::Cell.type_of(value)
39
+
40
+ case cell.type
41
+ when 's' then cell.value = @workbook.register_string(value)
42
+ when 'n' then cell.value = value
43
+ end
44
+ end
45
+
46
+ end
47
+ end