xlsx 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 2009 Brian Buchanan. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,12 @@
1
+ This is a work-in-progress.
2
+
3
+ Right now, just a small subset of the Spreadsheet gem's API is implemented:
4
+
5
+ require 'xlsx'
6
+
7
+ workbook = XLSX::Workbook.new
8
+ worksheet = workbook.create_worksheet :name => 'My Sheet'
9
+ worksheet.update_row(0, 'A1', 'A2', 'A3')
10
+ worksheet.update_row(1, 'B1', 'B2', 'B3')
11
+ worksheet.update_row(2, 5, 6, 7)
12
+ worksheet.write('my_spreadsheet.xlsx')
@@ -0,0 +1,27 @@
1
+ # Copyright (C) 2009 Brian Buchanan. All rights reserved.
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ # 1. Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ # SUCH DAMAGE.
23
+
24
+ require 'xlsx/workbook'
25
+ require 'xlsx/worksheet'
26
+ require 'xlsx/row'
27
+ require 'xlsx/cell'
@@ -0,0 +1,54 @@
1
+ # Copyright (C) 2009 Brian Buchanan. All rights reserved.
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ # 1. Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ # SUCH DAMAGE.
23
+
24
+ module XLSX
25
+ class Cell
26
+ attr_reader :row_number
27
+ attr_reader :col_number
28
+ attr_accessor :value
29
+
30
+ def initialize(row_number, col_number, value)
31
+ @row_number = row_number
32
+ @col_number = col_number
33
+ @value = value
34
+ end
35
+
36
+ def name
37
+ XLSX::Cell.cell_name(@row_number, @col_number)
38
+ end
39
+
40
+ def self.cell_name(row_number, col_number)
41
+ raise "Column #{col_number} out of range" if col_number > 701
42
+
43
+ if col_number <= 25
44
+ col_name = ''
45
+ else
46
+ c = col_number / 26
47
+ col_name = (?A + c - 1).chr
48
+ col_number = col_number % 26
49
+ end
50
+ col_name += (?A + col_number).chr
51
+ "#{col_name}#{row_number + 1}"
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,55 @@
1
+ # Copyright (C) 2009 Brian Buchanan. All rights reserved.
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ # 1. Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ # SUCH DAMAGE.
23
+
24
+ module XLSX
25
+ class Row
26
+ include Enumerable
27
+
28
+ attr_reader :row_number, :min_col, :max_col
29
+
30
+ def initialize(worksheet, row_number)
31
+ @worksheet = worksheet
32
+ @row_number = row_number
33
+ @cells = {}
34
+ @min_col = 0
35
+ @max_col = 0
36
+ end
37
+
38
+ def []=(col_number, value)
39
+ raise "Column number must be a non-negative integer." unless col_number.is_a?(Integer) && col_number >= 0
40
+ @cells[col_number] = XLSX::Cell.new(@row_number, col_number, value)
41
+ @min_col = col_number if col_number < @min_col
42
+ @max_col = col_number if col_number > @max_col
43
+ end
44
+
45
+ def each
46
+ @cells.keys.sort.each do |col_no|
47
+ yield @cells[col_no]
48
+ end
49
+ end
50
+
51
+ def last
52
+ @cells[@cells.keys.sort.last]
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,328 @@
1
+ # Copyright (C) 2009 Brian Buchanan. All rights reserved.
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ # 1. Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ # SUCH DAMAGE.
23
+
24
+ require 'builder'
25
+ require 'zip/zip'
26
+
27
+ module XLSX
28
+ class Workbook
29
+ def initialize(filename=nil)
30
+ @filename = filename
31
+ @sheets = []
32
+ end
33
+
34
+ def worksheet(sheet_no)
35
+ @sheets[sheet_no]
36
+ end
37
+
38
+ def create_worksheet(params)
39
+ params[:name] ||= "Sheet #{@sheets.size + 1}"
40
+ ws = XLSX::Worksheet.new(self, params)
41
+ @sheets << ws
42
+ ws
43
+ end
44
+
45
+ def write(filename=nil)
46
+ @strings_count = 0
47
+ @strings = []
48
+
49
+ filename ||= @filename
50
+ File.unlink(filename) if File.exists?(filename)
51
+ Zip::ZipFile.open(filename, Zip::ZipFile::CREATE) do |zipfile|
52
+ zipfile.get_output_stream("[Content_Types].xml") { |f| write_content_types(f) }
53
+ zipfile.get_output_stream("_rels/.rels") { |f| write_root_rels(f) }
54
+ zipfile.get_output_stream("docProps/app.xml") { |f| write_app_properties(f) }
55
+ zipfile.get_output_stream("docProps/core.xml") { |f| write_core_properties(f) }
56
+ zipfile.get_output_stream("xl/_rels/workbook.xml.rels") { |f| write_workbook_rels(f) }
57
+ zipfile.get_output_stream("xl/workbook.xml") { |f| write_workbook(f) }
58
+ zipfile.get_output_stream("xl/styles.xml") { |f| write_styles(f) }
59
+
60
+ 0.upto(@sheets.size - 1) do |sheet_no|
61
+ zipfile.get_output_stream("xl/worksheets/sheet#{sheet_no + 1}.xml") { |f| write_worksheet(@sheets[sheet_no], f) }
62
+ end
63
+
64
+ zipfile.get_output_stream("xl/sharedStrings.xml") { |f| write_shared_strings(f) }
65
+ end
66
+ end
67
+
68
+ private
69
+ def write_content_types(f)
70
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
71
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8'
72
+ x.Types :xmlns => XMLNS_CONTENT_TYPES do |types|
73
+ types.Override :PartName => '/docProps/app.xml', :ContentType => CT_EXTPROP
74
+ 1.upto(@sheets.size) do |sheet_no|
75
+ types.Override :PartName => "/xl/worksheets/sheet#{sheet_no}.xml", :ContentType => CT_SS_WORKSHEET
76
+ end
77
+ types.Override :PartName => '/xl/workbook.xml', :ContentType => CT_SS_MAIN
78
+ types.Override :PartName => '/docProps/core.xml', :ContentType => CT_COREPROP
79
+ types.Default :Extension => 'xml', :ContentType => 'application/xml'
80
+ types.Override :PartName => '/xl/styles.xml', :ContentType => CT_SS_STYLES
81
+ types.Override :PartName => '/xl/sharedStrings.xml', :ContentType => CT_SS_SHAREDSTRINGS
82
+ types.Default :Extension => 'rels', :ContentType => CT_RELATIONSHIPS
83
+ end
84
+ end
85
+
86
+ def write_root_rels(f)
87
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
88
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8', :standalone => 'yes'
89
+ x.Relationships :xmlns => XMLNS_RELATIONSHIPS do |rels|
90
+ rels.Relationship :Id => 'rId3', :Type => REL_TYPE_EXTPROP, :Target => 'docProps/app.xml'
91
+ rels.Relationship :Id => 'rId1', :Type => REL_TYPE_OFFICEDOC, :Target => 'xl/workbook.xml'
92
+ rels.Relationship :Id => 'rId2', :Type => REL_TYPE_COREPROP, :Target => 'docProps/core.xml'
93
+ end
94
+ end
95
+
96
+ def write_core_properties(f)
97
+ modified_at = Time.now.utc
98
+
99
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
100
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8', :standalone => 'yes'
101
+ x.cp :coreProperties, 'xmlns:cp' => XMLNS_COREPROP, 'xmlns:dc' => XMLNS_DC,
102
+ 'xmlns:dcterms' => XMLNS_DCTERMS, 'xmlns:dcmitype' => XMLNS_DCMITYPE,
103
+ 'xmlns:xsi' => XMLNS_XSI do |cp|
104
+ cp.dc :creator, 'ruby-xlsx'
105
+ cp.cp :lastModifiedBy, 'ruby-xlsx'
106
+ cp.dcterms(:created, { 'xsi:type' => 'dcterms:W3CDTF' },
107
+ modified_at.strftime('%Y-%m-%dT%H:%M:%SZ'))
108
+ cp.dcterms(:modified, { 'xsi:type' => 'dcterms:W3CDTF' },
109
+ modified_at.strftime('%Y-%m-%dT%H:%M:%SZ'))
110
+ end
111
+ end
112
+
113
+ def write_app_properties(f)
114
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
115
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8', :standalone => 'yes'
116
+ x.Properties 'xmlns' => XMLNS_EXTPROP, 'xmlns:vt' => XMLNS_VT do |prop|
117
+ prop.Application 'Microsoft Macintosh Excel'
118
+ prop.DocSecurity '0'
119
+ prop.ScaleCrop 'false'
120
+ prop.HeadingPairs do |hp|
121
+ hp.vt :vector, :size => '2', :baseType => 'variant' do |v|
122
+ v.vt :variant do |var|
123
+ var.vt :lpstr, 'Worksheets'
124
+ end
125
+ v.vt :variant do |var|
126
+ var.vt :i4, @sheets.size.to_s
127
+ end
128
+ end
129
+ end
130
+ prop.TitlesOfParts do |t|
131
+ t.vt :vector, :size => @sheets.size.to_s, :baseType => 'lpstr' do |v|
132
+ @sheets.each do |sheet|
133
+ v.vt :lpstr, sheet.title
134
+ end
135
+ end
136
+ end
137
+ prop.Company ''
138
+ prop.LinksUpToDate 'false'
139
+ prop.SharedDoc 'false'
140
+ prop.HyperlinksChanged 'false'
141
+ prop.AppVersion '12.0000'
142
+ end
143
+ end
144
+
145
+ def write_workbook_rels(f)
146
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
147
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8', :standalone => 'yes'
148
+ x.Relationships :xmlns => XMLNS_RELATIONSHIPS do |rels|
149
+ id = 1
150
+ 1.upto(@sheets.size) do |sheet_no|
151
+ rels.Relationship :Id => "rId#{id}", :Type => REL_TYPE_WORKSHEET, :Target => "worksheets/sheet#{sheet_no}.xml"
152
+ id += 1
153
+ end
154
+ rels.Relationship :Id => "rId#{id}", :Type => REL_TYPE_STYLES, :Target => 'styles.xml'
155
+ id += 1
156
+ rels.Relationship :Id => "rId#{id}", :Type => REL_TYPE_CONNECTIONS, :Target => 'connections.xml'
157
+ id += 1
158
+ rels.Relationship :Id => "rId#{id}", :Type => REL_TYPE_SHAREDSTRINGS, :Target => 'sharedStrings.xml'
159
+ end
160
+ end
161
+
162
+ def write_workbook(f)
163
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
164
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8', :standalone => 'yes'
165
+ x.workbook :xmlns => XMLNS_SSXML_MAIN, 'xmlns:r' => XMLNS_OD_RELATIONSHIPS do |wb|
166
+ wb.fileVersion :appName => 'xl', :lastEdited => '4', :lowestEdited => '4', :rupBuild => '4505'
167
+ wb.workbookPr :date1904 => '1', :showInkAnnotation => '0', :autoCompressPictures => '0'
168
+ wb.bookViews do |bv|
169
+ bv.workbookView :tabRatio => '500', :xWindow => '-20', :yWindow => '-20', :windowWidth => '47120', :windowHeight => '30680', :activeTab => '1'
170
+ end
171
+ x.sheets do |sheets|
172
+ 1.upto(@sheets.count) do |sheet_no|
173
+ sheet = @sheets[sheet_no - 1]
174
+ sheets.sheet :name => sheet.title, :sheetId => sheet_no.to_s,
175
+ 'r:id' => "rId#{sheet_no}"
176
+ end
177
+ end
178
+ x.calcPr :calcId => '130407', :concurrentCalc => '0'
179
+ x.extLst do |exts|
180
+ exts.ext 'xmlns:mx' => XMLNS_MAC_EXCEL, :uri => XMLNS_MAC_EXCEL do |mx|
181
+ mx.mx :ArchID, :Flags => '2'
182
+ end
183
+ end
184
+ end
185
+ end
186
+
187
+ def write_worksheet(sheet, f)
188
+ min_col = sheet.rows.map { |r| r.min_col }.min + 1
189
+ max_col = sheet.rows.map { |r| r.max_col }.max + 1
190
+ spans = "#{min_col}:#{max_col}"
191
+ dimension = "#{XLSX::Cell.cell_name(sheet.min_row + 1, min_col)}:#{XLSX::Cell.cell_name(sheet.max_row + 1, max_col)}"
192
+
193
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
194
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8', :standalone => 'yes'
195
+ f.write("\n")
196
+ x.worksheet 'xmlns:mc' => XMLNS_MARKUP_COMPATIBILITY,
197
+ 'mc:PreserveAttributes' => 'mv:*',
198
+ 'mc:Ignorable' => 'mv',
199
+ 'xmlns:r' => XMLNS_OD_RELATIONSHIPS,
200
+ 'xmlns:mv' => XMLNS_MAC_VML,
201
+ 'xmlns' => XMLNS_SSXML_MAIN do |ws|
202
+ ws.dimension :ref => dimension
203
+ ws.sheetViews do |sviews|
204
+ sviews.sheetView :workbookViewId => '0' do |sv|
205
+ sv.selection :activeCell => 'A1', :sqref => 'A1'
206
+ end
207
+ end
208
+ ws.sheetFormatPr :defaultRowHeight => '13', :baseColWidth => '10'
209
+ ws.sheetData do |sd|
210
+ sheet.rows.each do |row|
211
+ cells = row.to_a
212
+ sd.row :r => (row.row_number + 1).to_s, :spans => spans do |r|
213
+ row.each do |cell|
214
+ value = cell.value
215
+ c_params = { :r => cell.name }
216
+ c_params[:t] = 's' unless value.is_a?(Numeric)
217
+ r.c c_params do |c|
218
+ case value
219
+ when Numeric
220
+ c.v(value.to_s)
221
+ else
222
+ @strings << value.to_s
223
+ @strings_count += 1
224
+ c.v((@strings.size - 1).to_s)
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+ ws.sheetCalcPr :fullCalcOnLoad => '1'
232
+ ws.phoneticPr :fontId => '1', :type => 'noConversion'
233
+ ws.pageMargins :left => '0.75', :bottom => '1', :header => '0.5', :footer => '0.5', :right => '0.75', :top => '1'
234
+ ws.pageSetup :horizontalDpi => '4294967292', :orientation => 'portrait', :verticalDpi => '4294967292'
235
+ end
236
+ end
237
+
238
+ def write_shared_strings(f)
239
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
240
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8'
241
+ x.sst :count => @strings_count, :uniqueCount => @strings.size, :xmlns => XMLNS_SSXML_MAIN do |sst|
242
+ @strings.each do |string|
243
+ sst.si do |si|
244
+ si.t string
245
+ # Unnecessary?
246
+ # si.phoneticPr :fontId => '1', :type => 'noConversion'
247
+ end
248
+ end
249
+ end
250
+ end
251
+
252
+ def write_styles(f)
253
+ x = Builder::XmlMarkup.new(:target => f, :indent => 0)
254
+ x.instruct! 'xml', :version => '1.0', :encoding => 'UTF-8'
255
+ x.styleSheet :xmlns => XMLNS_SSXML_MAIN do |ss|
256
+ ss.fonts :count => '2' do |fonts|
257
+ fonts.font do |font|
258
+ font.sz :val => '10'
259
+ font.name :val => 'Verdana'
260
+ end
261
+ fonts.font do |font|
262
+ font.sz :val => '8'
263
+ font.name :val => 'Verdana'
264
+ end
265
+ end
266
+ ss.fills :count => '2' do |fills|
267
+ fills.fill { |fill| fill.patternFill :patternType => 'none' }
268
+ fills.fill { |fill| fill.patternFill :patternType => 'gray125' }
269
+ end
270
+ ss.borders :count => '1' do |borders|
271
+ borders.border do |b|
272
+ b.left
273
+ b.right
274
+ b.top
275
+ b.bottom
276
+ b.diagonal
277
+ end
278
+ end
279
+ ss.cellStyleXfs :count => 1 do |cs|
280
+ cs.xf :fontId => '0', :numFmtId => '0', :borderId => '0', :fillId => '0'
281
+ end
282
+ ss.cellXfs :count => 1 do |cs|
283
+ cs.xf :fontId => '0', :numFmtId => '0', :borderId => '0', :xfId => '0', :fillId => '0'
284
+ end
285
+ ss.cellStyles :count => 1 do |cs|
286
+ cs.cellStyle :name => 'Normal', :xfId => '0', :builtinId => '0'
287
+ end
288
+ ss.dxfs :count => '0'
289
+ ss.tableStyles :count => '0', :defaultTableStyle => 'TableStyleMedium9'
290
+ end
291
+ end
292
+
293
+ XMLNS_RELATIONSHIPS = 'http://schemas.openxmlformats.org/package/2006/relationships'
294
+ XMLNS_COREPROP = 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'
295
+ XMLNS_EXTPROP = 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'
296
+ XMLNS_VT = 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'
297
+ XMLNS_DC = 'http://purl.org/dc/elements/1.1/'
298
+ XMLNS_DCTERMS = 'http://purl.org/dc/terms/'
299
+ XMLNS_DCMITYPE = 'http://purl.org/dc/dcmitype/'
300
+ XMLNS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'
301
+ XMLNS_SSXML_MAIN = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'
302
+ XMLNS_OD_RELATIONSHIPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
303
+ XMLNS_MAC_EXCEL = 'http://schemas.microsoft.com/office/mac/excel/2008/main'
304
+ XMLNS_CONTENT_TYPES = 'http://schemas.openxmlformats.org/package/2006/content-types'
305
+ XMLNS_MARKUP_COMPATIBILITY = 'http://schemas.openxmlformats.org/markup-compatibility/2006'
306
+ XMLNS_MAC_VML = 'urn:schemas-microsoft-com:mac:vml'
307
+
308
+ CT_EXTPROP = 'application/vnd.openxmlformats-officedocument.extended-properties+xml'
309
+ CT_SS_WORKSHEET = 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'
310
+ CT_SS_MAIN = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'
311
+ CT_COREPROP = 'application/vnd.openxmlformats-package.core-properties+xml'
312
+ CT_THEME = 'application/vnd.openxmlformats-officedocument.theme+xml'
313
+ CT_SS_STYLES = 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'
314
+ CT_SS_SHAREDSTRINGS = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'
315
+ CT_RELATIONSHIPS = 'application/vnd.openxmlformats-package.relationships+xml'
316
+
317
+ REL_TYPE_EXTPROP = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'
318
+ REL_TYPE_OFFICEDOC = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument'
319
+ REL_TYPE_THUMBNAIL = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail'
320
+ REL_TYPE_COREPROP = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties'
321
+ REL_TYPE_STYLES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles'
322
+ REL_TYPE_WORKSHEET = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet'
323
+ REL_TYPE_THEME = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme'
324
+ REL_TYPE_CONNECTIONS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/connections'
325
+ REL_TYPE_SHAREDSTRINGS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings'
326
+
327
+ end
328
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright (C) 2009 Brian Buchanan. All rights reserved.
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ # 1. Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ # SUCH DAMAGE.
23
+
24
+ module XLSX
25
+ class Worksheet
26
+ attr_accessor :title
27
+ attr_reader :min_row, :max_row
28
+
29
+ def initialize(workbook, params={})
30
+ @workbook = workbook
31
+ @title = params[:name] || ''
32
+ @rows = {}
33
+ @min_row = 0
34
+ @max_row = 0
35
+ end
36
+
37
+ def row(row_number)
38
+ @rows[row_number]
39
+ end
40
+
41
+ def rows
42
+ @rows.keys.sort.map { |n| @rows[n] }
43
+ end
44
+
45
+ def update_row(row_number, *values)
46
+ row = get_row(row_number)
47
+ 0.upto(values.length - 1) do |col|
48
+ row[col] = values[col]
49
+ end
50
+ row
51
+ end
52
+
53
+ def get_row(row_number)
54
+ raise "Row number must be a non-negative integer" unless row_number.is_a?(Integer) && row_number >= 0
55
+ r = row(row_number)
56
+ return r unless r.nil?
57
+
58
+ @min_row = row_number if row_number < @min_row
59
+ @max_row = row_number if row_number > @max_row
60
+ @rows[row_number] = Row.new(self, row_number)
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xlsx
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Brian Buchanan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-10-21 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: builder
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.1.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rubyzip
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.1
34
+ version:
35
+ description: XLSX is a Ruby library for writing simple XLSX-format Excel documents.
36
+ email: bwb@holo.org
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README
43
+ - LICENSE
44
+ files:
45
+ - README
46
+ - LICENSE
47
+ - lib/xlsx.rb
48
+ - lib/xlsx/workbook.rb
49
+ - lib/xlsx/worksheet.rb
50
+ - lib/xlsx/row.rb
51
+ - lib/xlsx/cell.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/bwbuchanan/xlsx
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --inline-source
59
+ - --charset=UTF-8
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.3.5
78
+ signing_key:
79
+ specification_version: 2
80
+ summary: XLSX is a Ruby library for writing simple XLSX-format Excel documents.
81
+ test_files: []
82
+