xlsx 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/LICENSE +22 -0
- data/README +12 -0
- data/lib/xlsx.rb +27 -0
- data/lib/xlsx/cell.rb +54 -0
- data/lib/xlsx/row.rb +55 -0
- data/lib/xlsx/workbook.rb +328 -0
- data/lib/xlsx/worksheet.rb +63 -0
- metadata +82 -0
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')
|
data/lib/xlsx.rb
ADDED
@@ -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'
|
data/lib/xlsx/cell.rb
ADDED
@@ -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
|
data/lib/xlsx/row.rb
ADDED
@@ -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
|
+
|