odf-spreadsheet 0.1.0

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.
@@ -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
+