odf-spreadsheet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
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.
@@ -0,0 +1,11 @@
1
+ MIT-LICENSE
2
+ Manifest
3
+ README
4
+ Rakefile
5
+ lib/spreadsheet.rb
6
+ lib/spreadsheet/builder.rb
7
+ lib/spreadsheet/builder_xml_builder.rb
8
+ lib/spreadsheet/libxml_xml_builder.rb
9
+ lib/spreadsheet/template_handler.rb
10
+ samples/rich.rb
11
+ samples/simple.rb
data/README ADDED
@@ -0,0 +1,50 @@
1
+ Spreadsheet
2
+ ===========
3
+
4
+ Library to generate OpenDocument Spreadsheet documents.
5
+
6
+ Example
7
+ =======
8
+
9
+ sheet = Spreadsheet::Builder.new
10
+ sheet.spreadsheet do
11
+ sheet.table 'Time report (simple)' do
12
+ sheet.row {
13
+ sheet.cell 'Developing spreadsheet library'
14
+ sheet.cell 80.0
15
+ }
16
+ sheet.row {
17
+ sheet.cell 'Writing spreadsheet library documentation'
18
+ sheet.cell 2.0
19
+ }
20
+ end
21
+
22
+ sheet.table 'Time report (rich)' do
23
+ sheet.column :width => '4in'
24
+ sheet.column :width => '0.5in'
25
+
26
+ sheet.header {
27
+ sheet.row {
28
+ sheet.cell 'Time report', :span => 2, :style => 'title'
29
+ }
30
+ sheet.row {
31
+ sheet.cell 'Activity', :align => :left
32
+ sheet.cell 'Hours'
33
+ }
34
+ }
35
+
36
+ sheet.row {
37
+ sheet.string_cell 'Developing spreadsheet library'
38
+ sheet.numeric_cell 80.0
39
+ }
40
+ sheet.row {
41
+ sheet.string_cell 'Writing spreadsheet library documentation'
42
+ sheet.numeric_cell 2.0
43
+ }
44
+ end
45
+ end
46
+
47
+ File.open('time_report.ods', 'wb') { |f| f.write sheet.content! }
48
+
49
+
50
+ Copyright (c) 2009 Maxim Kulkin, released under the MIT license
@@ -0,0 +1,31 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'echoe'
5
+
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Test the spreadsheet plugin.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.libs << 'test'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = true
15
+ end
16
+
17
+ desc 'Generate documentation for the spreadsheet plugin.'
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'Spreadsheet'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ Echoe.new('odf-spreadsheet', '0.1.0') do |gem|
27
+ gem.description = "Library to generate OpenDocument (ODF) Spreadsheet documents."
28
+ gem.url = "http://github.com/maximkulkin/spreadsheet"
29
+ gem.author = "Maxim Kulkin"
30
+ gem.email = "maxim.kulkin@gmail.com"
31
+ end
@@ -0,0 +1,19 @@
1
+ require 'spreadsheet/builder'
2
+
3
+ Spreadsheet::XmlBuilder = begin
4
+ require 'spreadsheet/libxml_xml_builder'
5
+ Spreadsheet::LibxmlXmlBuilder
6
+ rescue LoadError
7
+ require 'spreadsheet/builder_xml_builder'
8
+ Spreadsheet::BuilderXmlBuilder
9
+ end
10
+
11
+ if defined?(RAILS_ENV)
12
+ require 'action_view'
13
+
14
+ Mime::Type.register 'application/vnd.oasis.opendocument.spreadsheet', :spreadsheet
15
+
16
+ ActionView::Template.register_template_handler :rsheet, Spreadsheet::TemplateHandler
17
+ ActionView::Template.exempt_from_layout :rsheet
18
+ end
19
+
@@ -0,0 +1,304 @@
1
+ require 'zipruby'
2
+
3
+ module Spreadsheet
4
+
5
+ class Builder
6
+ def initialize
7
+ @xml = XmlBuilder.new
8
+ end
9
+
10
+ def content!
11
+ finish
12
+ end
13
+
14
+ def spreadsheet
15
+ @styles = {}
16
+ @tables = []
17
+
18
+ @xml = XmlBuilder.new
19
+ @xml.tag! 'office:body' do
20
+ @xml.tag! 'office:spreadsheet' do
21
+ yield if block_given?
22
+
23
+ @xml.tag! 'table:database-ranges' do
24
+ for table_metadata in @tables
25
+ start_address = cell_address(table_metadata[:hrows], 1)
26
+ end_address = cell_address(table_metadata[:hrows]+table_metadata[:drows], table_metadata[:columns])
27
+ @xml.tag! 'table:database-range', 'table:target-range-address' => "'#{table_metadata[:title]}':.#{start_address}:'#{table_metadata[:title]}'.#{end_address}", 'table:display-filter-buttons' => 'true'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def table(*args)
35
+ options = args.last.is_a?(Hash) ? args.pop : {}
36
+ title = args.first || "Sheet #{@tables.size+1}"
37
+ # TODO: ensure table title is unique
38
+ attrs = { 'table:name' => title }
39
+
40
+ @tables << { :title => title, :columns => 0, :hrows => 0, :drows => 0 }
41
+
42
+ @xml.tag!('table:table', attrs) { yield if block_given? }
43
+ end
44
+
45
+ def column(options={})
46
+ style_name = nil
47
+ style_name = style(:column, :width => options[:width]) if options[:width]
48
+ @xml.tag! 'table:table-column', 'table:style-name' => style_name
49
+
50
+ @tables.last[:columns] += 1
51
+ end
52
+
53
+ def row(*args)
54
+ @tables.last[ @in_header ? :hrows : :drows ] += 1
55
+
56
+ options = args.last.is_a?(Hash) ? args.pop : {}
57
+ attrs = {}
58
+ attrs = attrs.merge('table:style-name' => options.delete(:style)) if options.has_key?(:style)
59
+
60
+ @xml.tag!('table:table-row', attrs) { yield if block_given? }
61
+ end
62
+
63
+ def header
64
+ @in_header = true
65
+ @xml.tag!('table:table-header-rows') { yield if block_given? }
66
+ @in_header = nil
67
+ end
68
+
69
+ def cell(*args)
70
+ options = (args.last.kind_of?(Hash) ? args.pop : {})
71
+ if args.size > 1
72
+ type = args.shift
73
+ value = args.first
74
+ elsif args.size == 1
75
+ value = args.first
76
+ type = case value
77
+ when Numeric then :float
78
+ when Date then :date
79
+ when true, false then :boolean
80
+ else :string
81
+ end
82
+ else
83
+ type = :string
84
+ value = ''
85
+ end
86
+
87
+ attrs = { 'office:value-type' => type }
88
+ style_name = options.delete(:style) || (@in_header ? 'header' : type)
89
+ if options[:align] || options[:background]
90
+ style_name = style(:cell, :parent => style_name,
91
+ :align => options[:align],
92
+ :background => options[:background])
93
+ end
94
+ attrs.update('table:style-name' => style_name)
95
+ attrs.update('table:number-columns-spanned' => options[:span]) if options[:span]
96
+ attrs.update('table:number-rows-spanned' => options[:rowspan]) if options[:rowspan]
97
+
98
+ value = value ? 'true' : 'false' if type == :boolean
99
+
100
+ if options[:formula]
101
+ attrs['table:formula'] = options[:formula]
102
+ else
103
+ if type == :float
104
+ attrs['office:value'] = value
105
+ else
106
+ attrs["office:#{type}-value"] = value
107
+ end
108
+ end
109
+
110
+ @xml.tag! 'table:table-cell', attrs
111
+ end
112
+
113
+ def string_cell(*args)
114
+ cell :string, *args
115
+ end
116
+
117
+ def numeric_cell(*args)
118
+ cell :float, *args
119
+ end
120
+
121
+ def date_cell(*args)
122
+ cell :date, *args
123
+ end
124
+
125
+ def boolean_cell(*args)
126
+ value = args.shift
127
+ options = args.last.is_a?(Hash) ? args.last : {}
128
+ options[:align] ||= :center
129
+ cell(:string, (value ? 'Да' : 'Нет'), options)
130
+ end
131
+
132
+ private
133
+
134
+ def style(family, options={})
135
+ @styles[family] ||= {}
136
+ styles = @styles[family]
137
+ return styles[options] if styles.has_key?(options)
138
+ styles[options] = short_style_name(family)+styles.size.to_s
139
+ end
140
+
141
+ def short_style_name(family)
142
+ case family
143
+ when :table then 'ta'
144
+ when :row then 'ro'
145
+ when :cell then 'ce'
146
+ when :column then 'co'
147
+ else 'st'
148
+ end
149
+ end
150
+
151
+ def cell_address(row, column)
152
+ letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
153
+ address = ''
154
+ column -= 1
155
+ while column > 0
156
+ address = letters[column%26, 1] + address
157
+ column /= 26
158
+ end
159
+ address + row.to_s
160
+ end
161
+
162
+ def finish
163
+ output = ''
164
+
165
+ Zip::Archive.open_buffer(output, Zip::CREATE) do |io|
166
+ io.add_buffer 'mimetype', 'application/vnd.oasis.opendocument.spreadsheet'
167
+ io.add_buffer 'styles.xml', styles_content
168
+ io.add_buffer 'settings.xml', settings_content
169
+ io.add_buffer 'content.xml', body_content
170
+ io.add_buffer 'META-INF/manifest.xml', manifest_content
171
+ end
172
+
173
+ output
174
+ end
175
+
176
+ def manifest_content
177
+ xml = XmlBuilder.new
178
+ xml.tag! 'manifest:manifest',
179
+ 'xmlns:manifest' => 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0' do
180
+
181
+ xml.tag! 'manifest:file-entry', 'manifest:full-path' => '/',
182
+ 'manifest:media-type' => 'application/vnd.oasis.opendocument.spreadsheet'
183
+ xml.tag! 'manifest:file-entry', 'manifest:full-path' => 'content.xml',
184
+ 'manifest:media-type' => 'text/xml'
185
+ xml.tag! 'manifest:file-entry', 'manifest:full-path' => 'styles.xml',
186
+ 'manifest:media-type' => 'text/xml'
187
+ xml.tag! 'manifest:file-entry', 'manifest:full-path' => 'settings.xml',
188
+ 'manifest:media-type' => 'text/xml'
189
+ end
190
+ xml.to_s
191
+ end
192
+
193
+ def settings_content
194
+ xml = XmlBuilder.new
195
+ xml.tag! 'office:document-settings',
196
+ 'office:version' => '1.0',
197
+ 'xmlns:office' => 'urn:oasis:names:tc:opendocument:xmlns:office:1.0',
198
+ 'xmlns:config' => 'urn:oasis:names:tc:opendocument:xmlns:config:1.0',
199
+ 'xmlns:ooo' => 'http://openoffice.org/2004/office' do
200
+
201
+ xml.tag! 'office:settings' do
202
+ xml.tag! 'config:config-item-set', 'config:name' => 'ooo:view-settings' do
203
+ xml.tag! 'config:config-item-map-indexed', 'config:name' => 'Views' do
204
+ xml.tag! 'config:config-item-map-entry' do
205
+ xml.tag! 'config:config-item', {'config:name' => 'ViewId', 'config:type' => 'string'}, 'View1'
206
+ xml.tag! 'config:config-item-map-named', 'config:name' => 'Tables' do
207
+ for table_metadata in @tables
208
+ xml.tag! 'config:config-item-map-entry', 'config:name' => table_metadata[:title] do
209
+ xml.tag! 'config:config-item', {'config:name' => 'VerticalSplitMode', 'config:type' => 'short'}, '2'
210
+ xml.tag! 'config:config-item', {'config:name' => 'VerticalSplitPosition', 'config:type' => 'int'}, table_metadata[:hrows].to_s
211
+ xml.tag! 'config:config-item', {'config:name' => 'PositionBottom', 'config:type' => 'int'}, table_metadata[:hrows].to_s
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
220
+ xml.to_s
221
+ end
222
+
223
+ def body_content
224
+ xml = XmlBuilder.new
225
+ xml.tag! 'office:document-content',
226
+ 'xmlns:office' => 'urn:oasis:names:tc:opendocument:xmlns:office:1.0',
227
+ 'xmlns:table' => 'urn:oasis:names:tc:opendocument:xmlns:table:1.0',
228
+ 'xmlns:text' => 'urn:oasis:names:tc:opendocument:xmlns:text:1.0',
229
+ 'xmlns:style' => 'urn:oasis:names:tc:opendocument:xmlns:style:1.0',
230
+ 'xmlns:fo' => 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0' do
231
+
232
+ xml.tag! 'office:automatic-styles' do
233
+ for options, name in (@styles[:column] || {})
234
+ xml.tag! 'style:style', 'style:name' => name, 'style:family' => 'table-column' do
235
+ attrs = {}
236
+ attrs['style:column-width'] = options[:width] if options.key? :width
237
+ xml.tag! 'style:table-column-properties', attrs unless attrs.empty?
238
+ end
239
+ end
240
+
241
+ for options, name in (@styles[:cell] || {})
242
+ xml.tag! 'style:style', 'style:name' => name, 'style:family' => 'table-cell', 'style:parent-style-name' => options[:parent] do
243
+ attrs = {}
244
+ attrs['fo:background-color'] = options[:background] if options[:background]
245
+ attrs['style:text-align-source'] = 'fix' if options[:align]
246
+ xml.tag! 'style:table-cell-properties', attrs unless attrs.empty?
247
+
248
+ attrs = {}
249
+ attrs['fo:text-align'] = options[:align] if options[:align]
250
+ xml.tag! 'style:paragraph-properties', attrs unless attrs.empty?
251
+ end
252
+ end
253
+ end
254
+
255
+ xml.import! @xml
256
+
257
+ end
258
+ xml.to_s
259
+ end
260
+
261
+ def styles_content
262
+ xml = XmlBuilder.new
263
+ xml.tag! 'office:document-styles',
264
+ 'office:version' => '1.0',
265
+ 'xmlns:office' => 'urn:oasis:names:tc:opendocument:xmlns:office:1.0',
266
+ 'xmlns:datastyle' => 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0',
267
+ 'xmlns:style' => 'urn:oasis:names:tc:opendocument:xmlns:style:1.0',
268
+ 'xmlns:fo' => 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0' do
269
+
270
+ xml.tag! 'office:styles' do
271
+ xml.tag! 'style:style', 'style:name' => 'text', 'style:family' => 'table-cell', 'style:data-style-name' => 'text' do
272
+ xml.tag! 'style:table-cell-properties', 'style:text-align-source' => 'fix'
273
+ end
274
+
275
+ xml.tag! 'style:style', 'style:name' => 'numeric', 'style:family' => 'table-cell', 'style:data-style-name' => 'numeric' do
276
+ xml.tag! 'style:table-cell-properties', 'style:text-align-source' => 'fix'
277
+ xml.tag! 'style:paragraph-properties', 'fo:text-align' => 'right'
278
+ xml.tag! 'number:number'
279
+ end
280
+
281
+ [:date, :boolean].each do |value_type|
282
+ xml.tag! 'style:style', 'style:name' => value_type, 'style:family' => 'table-cell', 'style:data-style-name' => value_type do
283
+ xml.tag! 'style:table-cell-properties', 'style:text-align-source' => 'fix'
284
+ xml.tag! 'style:paragraph-properties', 'fo:text-align' => 'center'
285
+ end
286
+ end
287
+
288
+ xml.tag! 'style:style', 'style:name' => 'header', 'style:family' => 'table-cell' do
289
+ xml.tag! 'style:table-cell-properties', 'fo:background-color' => '#cccccc', 'style:text-align-source' => 'fix'
290
+ xml.tag! 'style:paragraph-properties', 'fo:text-align' => 'center'
291
+ end
292
+
293
+ xml.tag! 'style:style', 'style:name' => 'title', 'style:family' => 'table-cell' do
294
+ xml.tag! 'style:table-cell-properties', 'style:text-align-source' => 'fix'
295
+ xml.tag! 'style:text-properties', 'fo:font-size' => '20pt', 'fo:font-weight' => 'bold'
296
+ xml.tag! 'style:paragraph-properties', 'fo:text-align' => 'center'
297
+ end
298
+ end
299
+ end
300
+ xml.to_s
301
+ end
302
+ end
303
+
304
+ end
@@ -0,0 +1,24 @@
1
+ require 'builder'
2
+
3
+ module Spreadsheet
4
+ class BuilderXmlBuilder
5
+ def initialize
6
+ @xml = ::Builder::XmlMarkup.new
7
+ end
8
+
9
+ def tag!(name, attrs={}, content=nil)
10
+ @xml.tag!(name, attrs) do
11
+ @xml.text!(content) if content
12
+ yield if block_given?
13
+ end
14
+ end
15
+
16
+ def import!(builder)
17
+ @xml << builder.to_s
18
+ end
19
+
20
+ def to_s
21
+ @xml.to_s
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+ require 'libxml'
2
+ LibXML::XML.indent_tree_output = true
3
+
4
+ module Spreadsheet
5
+ class LibxmlXmlBuilder
6
+ def initialize
7
+ @document = LibXML::XML::Document.new
8
+ @node = nil
9
+ end
10
+
11
+ def tag!(name, attrs={}, content=nil)
12
+ node = LibXML::XML::Node.new(name.to_s)
13
+ node << content.to_s if content
14
+ attrs.each { |k, v| LibXML::XML::Attr.new(node, k.to_s, v.to_s) }
15
+ if @document.root
16
+ @node << node
17
+ else
18
+ @node = node
19
+ @document.root = node
20
+ end
21
+ if block_given?
22
+ node, @node = @node, node
23
+ yield
24
+ @node = node
25
+ end
26
+ end
27
+
28
+ def import!(builder)
29
+ @node << @document.import(builder.root)
30
+ end
31
+
32
+ def to_s
33
+ @document.to_s
34
+ end
35
+
36
+ protected
37
+
38
+ def root
39
+ @document.root
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ module Spreadsheet
2
+ class TemplateHandler < ActionView::TemplateHandler
3
+ include ActionView::TemplateHandlers::Compilable
4
+
5
+ def compile(template)
6
+ "sheet = ::Spreadsheet::Builder.new;" +
7
+ "sheet.spreadsheet { "+template.source+" };" +
8
+ "sheet.content;"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{odf-spreadsheet}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Maxim Kulkin"]
9
+ s.date = %q{2010-02-14}
10
+ s.description = %q{Library to generate OpenDocument (ODF) Spreadsheet documents.}
11
+ s.email = %q{maxim.kulkin@gmail.com}
12
+ s.extra_rdoc_files = ["README", "lib/spreadsheet.rb", "lib/spreadsheet/builder.rb", "lib/spreadsheet/builder_xml_builder.rb", "lib/spreadsheet/libxml_xml_builder.rb", "lib/spreadsheet/template_handler.rb"]
13
+ s.files = ["MIT-LICENSE", "Manifest", "README", "Rakefile", "lib/spreadsheet.rb", "lib/spreadsheet/builder.rb", "lib/spreadsheet/builder_xml_builder.rb", "lib/spreadsheet/libxml_xml_builder.rb", "lib/spreadsheet/template_handler.rb", "samples/rich.rb", "samples/simple.rb", "odf-spreadsheet.gemspec"]
14
+ s.homepage = %q{http://github.com/maximkulkin/spreadsheet}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Odf-spreadsheet", "--main", "README"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{odf-spreadsheet}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Library to generate OpenDocument (ODF) Spreadsheet documents.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ $LOAD_PATH << File.dirname(__FILE__)+"/../lib"
2
+
3
+ require 'rubygems'
4
+ require 'spreadsheet'
5
+
6
+ sheet = Spreadsheet::Builder.new
7
+ sheet.spreadsheet do
8
+ sheet.table 'Rich time report' do
9
+ sheet.column :width => '4in'
10
+ sheet.column :width => '0.5in'
11
+
12
+ sheet.header {
13
+ sheet.row {
14
+ sheet.cell 'Time report', :span => 2, :style => 'title'
15
+ }
16
+ sheet.row {
17
+ sheet.cell 'Activity', :align => :left
18
+ sheet.cell 'Hours'
19
+ }
20
+ }
21
+
22
+ sheet.row {
23
+ sheet.string_cell 'Developing spreadsheet library'
24
+ sheet.numeric_cell 80.0
25
+ }
26
+ sheet.row {
27
+ sheet.string_cell 'Writing spreadsheet library documentation'
28
+ sheet.numeric_cell 2.0
29
+ }
30
+ end
31
+ end
32
+
33
+ File.open('rich_time_report.ods', 'wb') { |f| f.write sheet.content! }
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH << File.dirname(__FILE__)+"/../lib"
2
+
3
+ require 'rubygems'
4
+ require 'spreadsheet'
5
+
6
+ sheet = Spreadsheet::Builder.new
7
+ sheet.spreadsheet do
8
+ sheet.table 'Simple time report' do
9
+ sheet.row {
10
+ sheet.cell 'Developing spreadsheet library'
11
+ sheet.cell 80.0
12
+ }
13
+ sheet.row {
14
+ sheet.cell 'Writing spreadsheet library documentation'
15
+ sheet.cell 2.0
16
+ }
17
+ end
18
+ end
19
+
20
+ File.open('simple_time_report.ods', 'wb') { |f| f.write sheet.content! }
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: odf-spreadsheet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Maxim Kulkin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-14 00:00:00 +03:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Library to generate OpenDocument (ODF) Spreadsheet documents.
17
+ email: maxim.kulkin@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - lib/spreadsheet.rb
25
+ - lib/spreadsheet/builder.rb
26
+ - lib/spreadsheet/builder_xml_builder.rb
27
+ - lib/spreadsheet/libxml_xml_builder.rb
28
+ - lib/spreadsheet/template_handler.rb
29
+ files:
30
+ - MIT-LICENSE
31
+ - Manifest
32
+ - README
33
+ - Rakefile
34
+ - lib/spreadsheet.rb
35
+ - lib/spreadsheet/builder.rb
36
+ - lib/spreadsheet/builder_xml_builder.rb
37
+ - lib/spreadsheet/libxml_xml_builder.rb
38
+ - lib/spreadsheet/template_handler.rb
39
+ - samples/rich.rb
40
+ - samples/simple.rb
41
+ - odf-spreadsheet.gemspec
42
+ has_rdoc: true
43
+ homepage: http://github.com/maximkulkin/spreadsheet
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --line-numbers
49
+ - --inline-source
50
+ - --title
51
+ - Odf-spreadsheet
52
+ - --main
53
+ - README
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "1.2"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: odf-spreadsheet
71
+ rubygems_version: 1.3.5
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Library to generate OpenDocument (ODF) Spreadsheet documents.
75
+ test_files: []
76
+