odf-report 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +4 -2
- data/lib/odf-report.rb +3 -2
- data/lib/odf-report/field.rb +56 -0
- data/lib/odf-report/{hash_gsub.rb → fields.rb} +19 -12
- data/lib/odf-report/{file_ops.rb → file.rb} +43 -31
- data/lib/odf-report/images.rb +15 -11
- data/lib/odf-report/nested.rb +2 -12
- data/lib/odf-report/report.rb +20 -23
- data/lib/odf-report/section.rb +8 -11
- data/lib/odf-report/table.rb +14 -11
- data/lib/odf-report/version.rb +3 -0
- data/odf-report.gemspec +11 -22
- data/test/piriapolis.jpg +0 -0
- data/test/rails.png +0 -0
- data/test/test_nested_tables.odt +0 -0
- data/test/test_nested_tables.rb +39 -0
- data/test/test_sections.odt +0 -0
- data/test/test_sections.rb +39 -0
- data/test/test_sub_sections.odt +0 -0
- data/test/test_sub_sections.rb +57 -0
- data/test/test_tables.odt +0 -0
- data/test/test_tables.rb +62 -0
- metadata +46 -36
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Sandro Duarte
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
CHANGED
@@ -8,9 +8,11 @@ h2. NEW!
|
|
8
8
|
<pre>
|
9
9
|
ODF-REPORT have been internally refactored. It now uses Nokogiri for parsing the documents, instead of Regex.
|
10
10
|
|
11
|
-
This provides for a much greater flexibility. As a result,
|
11
|
+
This provides for a much greater flexibility. As a result, it was possible to implement nested sections and tables.
|
12
12
|
|
13
|
-
Now sections can be nested inside sections, with fields, tables and others sections
|
13
|
+
Now sections can be nested inside sections, with fields, tables and others sections
|
14
|
+
|
15
|
+
And now, tables can also be nested inside tables.
|
14
16
|
</pre>
|
15
17
|
|
16
18
|
h2. INSTALL
|
data/lib/odf-report.rb
CHANGED
@@ -4,8 +4,9 @@ require 'fileutils'
|
|
4
4
|
require 'nokogiri'
|
5
5
|
|
6
6
|
require File.expand_path('../odf-report/images', __FILE__)
|
7
|
-
require File.expand_path('../odf-report/
|
8
|
-
require File.expand_path('../odf-report/
|
7
|
+
require File.expand_path('../odf-report/field', __FILE__)
|
8
|
+
require File.expand_path('../odf-report/file', __FILE__)
|
9
|
+
require File.expand_path('../odf-report/fields', __FILE__)
|
9
10
|
require File.expand_path('../odf-report/nested', __FILE__)
|
10
11
|
require File.expand_path('../odf-report/section', __FILE__)
|
11
12
|
require File.expand_path('../odf-report/table', __FILE__)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ODFReport
|
2
|
+
|
3
|
+
class Field
|
4
|
+
|
5
|
+
DELIMITERS = ['[', ']']
|
6
|
+
|
7
|
+
def initialize(opts, &block)
|
8
|
+
@name = opts[:name]
|
9
|
+
@data_field = opts[:data_field]
|
10
|
+
|
11
|
+
unless @value = opts[:value]
|
12
|
+
|
13
|
+
if block_given?
|
14
|
+
@block = block
|
15
|
+
|
16
|
+
else
|
17
|
+
@block = lambda { |item| self.extract_value(item) }
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_value(data_item = nil)
|
25
|
+
@value || @block.call(data_item) || ''
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_placeholder
|
29
|
+
if DELIMITERS.is_a?(Array)
|
30
|
+
"#{DELIMITERS[0]}#{@name.to_s.upcase}#{DELIMITERS[1]}"
|
31
|
+
else
|
32
|
+
"#{DELIMITERS}#{@name.to_s.upcase}#{DELIMITERS}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def extract_value(data_item)
|
37
|
+
return unless data_item
|
38
|
+
|
39
|
+
key = @data_field || @name
|
40
|
+
|
41
|
+
if data_item.is_a?(Hash)
|
42
|
+
data_item[key] || data_item[key.to_s.downcase] || data_item[key.to_s.upcase] || data_item[key.to_s.downcase.to_sym]
|
43
|
+
|
44
|
+
elsif data_item.respond_to?(key.to_s.downcase.to_sym)
|
45
|
+
data_item.send(key.to_s.downcase.to_sym)
|
46
|
+
|
47
|
+
else
|
48
|
+
raise "Can't find field [#{key}] in this #{data_item.class}"
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -1,13 +1,26 @@
|
|
1
1
|
module ODFReport
|
2
2
|
|
3
|
-
module
|
3
|
+
module Fields
|
4
4
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
def field_replace!(_node, data_item = nil)
|
6
|
+
|
7
|
+
txt = _node.inner_html
|
8
|
+
|
9
|
+
@fields.each do |f|
|
10
|
+
val = f.get_value(data_item)
|
11
|
+
txt.gsub!(f.to_placeholder, sanitize(val))
|
10
12
|
end
|
13
|
+
|
14
|
+
_node.inner_html = txt
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def sanitize(txt)
|
21
|
+
txt = html_escape(txt)
|
22
|
+
txt = odf_linebreak(txt)
|
23
|
+
txt
|
11
24
|
end
|
12
25
|
|
13
26
|
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
@@ -22,12 +35,6 @@ module ODFReport
|
|
22
35
|
s.to_s.gsub("\n", "<text:line-break/>")
|
23
36
|
end
|
24
37
|
|
25
|
-
def node_hash_gsub!(_node, hash_of_values)
|
26
|
-
txt = _node.inner_html
|
27
|
-
hash_gsub!(txt, hash_of_values)
|
28
|
-
_node.inner_html = txt
|
29
|
-
end
|
30
|
-
|
31
38
|
end
|
32
39
|
|
33
40
|
end
|
@@ -1,62 +1,61 @@
|
|
1
1
|
module ODFReport
|
2
2
|
|
3
|
-
|
3
|
+
class File
|
4
4
|
|
5
|
-
|
5
|
+
attr_accessor :tmp_dir, :path
|
6
6
|
|
7
|
+
def initialize(template)
|
8
|
+
|
9
|
+
raise "Template [#{template}] not found." unless ::File.exists? template
|
10
|
+
|
11
|
+
@template = template
|
12
|
+
@tmp_dir = ::File.join(Dir.tmpdir, random_filename(:prefix=>'odt_'))
|
13
|
+
Dir.mkdir(@tmp_dir) unless ::File.exists? @tmp_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(dest)
|
7
17
|
if dest
|
8
18
|
FileUtils.cp(@template, dest)
|
9
|
-
|
19
|
+
@path = dest
|
10
20
|
else
|
11
21
|
FileUtils.cp(@template, @tmp_dir)
|
12
|
-
|
22
|
+
@path = "#{@tmp_dir}/#{::File.basename(@template)}"
|
13
23
|
end
|
14
|
-
|
15
|
-
return new_file
|
16
24
|
end
|
17
25
|
|
18
|
-
def
|
19
|
-
opts = {:chars => ('0'..'9').to_a + ('A'..'F').to_a + ('a'..'f').to_a,
|
20
|
-
:length => 24, :prefix => '', :suffix => '',
|
21
|
-
:verify => true, :attempts => 10}.merge(opts)
|
22
|
-
opts[:attempts].times do
|
23
|
-
filename = ''
|
24
|
-
opts[:length].times { filename << opts[:chars][rand(opts[:chars].size)] }
|
25
|
-
filename = opts[:prefix] + filename + opts[:suffix]
|
26
|
-
return filename unless opts[:verify] && File.exists?(filename)
|
27
|
-
end
|
28
|
-
nil
|
29
|
-
end
|
26
|
+
def update(*content_files, &block)
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
content_files.each do |content_file|
|
29
|
+
|
30
|
+
update_content_file(content_file) do |txt|
|
31
|
+
|
32
|
+
yield txt
|
33
|
+
|
34
|
+
end
|
37
35
|
|
38
|
-
def add_dir_to_zip(zip_file, dir, entry)
|
39
|
-
Zip::ZipFile.open(zip_file, true) do |z|
|
40
|
-
Dir["#{dir}/**/*"].each { |f| z.add("#{entry}/#{File.basename(f)}", f) }
|
41
36
|
end
|
37
|
+
|
42
38
|
end
|
43
39
|
|
44
|
-
|
40
|
+
private
|
41
|
+
|
42
|
+
def update_content_file(content_file, &block)
|
43
|
+
|
44
|
+
Zip::ZipFile.open(@path) do |z|
|
45
45
|
|
46
|
-
Zip::ZipFile.open(zip_file) do |z|
|
47
46
|
cont = "#{@tmp_dir}/#{content_file}"
|
48
47
|
|
49
48
|
z.extract(content_file, cont)
|
50
49
|
|
51
50
|
txt = ''
|
52
51
|
|
53
|
-
File.open(cont, "r") do |f|
|
52
|
+
::File.open(cont, "r") do |f|
|
54
53
|
txt = f.read
|
55
54
|
end
|
56
55
|
|
57
56
|
yield(txt)
|
58
57
|
|
59
|
-
File.open(cont, "w") do |f|
|
58
|
+
::File.open(cont, "w") do |f|
|
60
59
|
f.write(txt)
|
61
60
|
end
|
62
61
|
|
@@ -65,6 +64,19 @@ module ODFReport
|
|
65
64
|
|
66
65
|
end
|
67
66
|
|
67
|
+
def random_filename(opts={})
|
68
|
+
opts = {:chars => ('0'..'9').to_a + ('A'..'F').to_a + ('a'..'f').to_a,
|
69
|
+
:length => 24, :prefix => '', :suffix => '',
|
70
|
+
:verify => true, :attempts => 10}.merge(opts)
|
71
|
+
opts[:attempts].times do
|
72
|
+
filename = ''
|
73
|
+
opts[:length].times { filename << opts[:chars][rand(opts[:chars].size)] }
|
74
|
+
filename = opts[:prefix] + filename + opts[:suffix]
|
75
|
+
return filename unless opts[:verify] && ::File.exists?(filename)
|
76
|
+
end
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
68
80
|
end
|
69
81
|
|
70
82
|
end
|
data/lib/odf-report/images.rb
CHANGED
@@ -2,31 +2,35 @@ module ODFReport
|
|
2
2
|
|
3
3
|
module Images
|
4
4
|
|
5
|
+
IMAGE_DIR_NAME = "Pictures"
|
6
|
+
|
5
7
|
def find_image_name_matches(content)
|
6
8
|
|
7
9
|
@images.each_pair do |image_name, path|
|
8
10
|
if node = content.xpath("//draw:frame[@draw:name='#{image_name}']/draw:image").first
|
9
11
|
placeholder_path = node.attribute('href').value
|
10
|
-
@image_names_replacements[path] = File.basename(placeholder_path)
|
12
|
+
@image_names_replacements[path] = ::File.join(IMAGE_DIR_NAME, ::File.basename(placeholder_path))
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
16
|
end
|
15
17
|
|
16
|
-
def replace_images(
|
18
|
+
def replace_images(file)
|
19
|
+
|
20
|
+
return if @images.empty?
|
21
|
+
|
22
|
+
FileUtils.mkdir(::File.join(file.tmp_dir, IMAGE_DIR_NAME))
|
23
|
+
|
24
|
+
@image_names_replacements.each_pair do |path, template_image|
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
FileUtils.mkdir(File.join("#{@tmp_dir}", image_dir_name))
|
21
|
-
@image_names_replacements.each_pair do |path, template_image|
|
22
|
-
template_image_path = File.join(image_dir_name, template_image)
|
23
|
-
update_file_from_zip(new_file, template_image_path) do |content|
|
24
|
-
content.replace File.read(path)
|
25
|
-
end
|
26
|
+
file.update(template_image) do |content|
|
27
|
+
content.replace ::File.read(path)
|
26
28
|
end
|
29
|
+
|
27
30
|
end
|
28
31
|
|
29
|
-
end
|
32
|
+
end # replace_images
|
33
|
+
|
30
34
|
|
31
35
|
end
|
32
36
|
|
data/lib/odf-report/nested.rb
CHANGED
@@ -2,18 +2,8 @@ module ODFReport
|
|
2
2
|
|
3
3
|
module Nested
|
4
4
|
|
5
|
-
def
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
def get_fields_with_values(data_item)
|
10
|
-
|
11
|
-
fields_with_values = {}
|
12
|
-
@fields.each do |field_name, block1|
|
13
|
-
fields_with_values[field_name] = block1.call(data_item) || ''
|
14
|
-
end
|
15
|
-
|
16
|
-
fields_with_values
|
5
|
+
def replace_fields!(new_section, data_item)
|
6
|
+
field_replace!(new_section, data_item)
|
17
7
|
end
|
18
8
|
|
19
9
|
def get_collection_from_item(item, collection_field)
|
data/lib/odf-report/report.rb
CHANGED
@@ -1,28 +1,29 @@
|
|
1
1
|
module ODFReport
|
2
2
|
|
3
3
|
class Report
|
4
|
-
include
|
4
|
+
include Fields, Images
|
5
5
|
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :fields, :tables, :images, :sections, :file
|
7
7
|
|
8
8
|
def initialize(template_name, &block)
|
9
|
-
@template = template_name
|
10
9
|
|
11
|
-
@
|
10
|
+
@file = ODFReport::File.new(template_name)
|
11
|
+
|
12
|
+
@fields = []
|
12
13
|
@tables = []
|
13
14
|
@images = {}
|
14
15
|
@image_names_replacements = {}
|
15
16
|
@sections = []
|
16
17
|
|
17
|
-
@tmp_dir = File.join(Dir.tmpdir, random_filename(:prefix=>'odt_'))
|
18
|
-
Dir.mkdir(@tmp_dir) unless File.exists? @tmp_dir
|
19
|
-
|
20
18
|
yield(self)
|
21
19
|
|
22
20
|
end
|
23
21
|
|
24
|
-
def add_field(field_tag, value='')
|
25
|
-
|
22
|
+
def add_field(field_tag, value='', &block)
|
23
|
+
opts = {:name => field_tag, :value => value}
|
24
|
+
field = Field.new(opts, &block)
|
25
|
+
@fields << field
|
26
|
+
|
26
27
|
end
|
27
28
|
|
28
29
|
def add_table(table_name, collection, opts={}, &block)
|
@@ -47,29 +48,25 @@ class Report
|
|
47
48
|
|
48
49
|
def generate(dest = nil)
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
%w(content.xml styles.xml).each do |content_file|
|
53
|
-
|
54
|
-
update_file_from_zip(new_file, content_file) do |txt|
|
51
|
+
@file.create(dest)
|
55
52
|
|
56
|
-
|
53
|
+
@file.update('content.xml', 'styles.xml') do |txt|
|
57
54
|
|
58
|
-
|
59
|
-
replace_sections!(doc)
|
60
|
-
replace_tables!(doc)
|
55
|
+
parse_document(txt) do |doc|
|
61
56
|
|
62
|
-
|
57
|
+
replace_fields!(doc)
|
58
|
+
replace_sections!(doc)
|
59
|
+
replace_tables!(doc)
|
63
60
|
|
64
|
-
|
61
|
+
find_image_name_matches(doc)
|
65
62
|
|
66
63
|
end
|
67
64
|
|
68
65
|
end
|
69
66
|
|
70
|
-
replace_images(
|
67
|
+
replace_images(@file)
|
71
68
|
|
72
|
-
|
69
|
+
@file.path
|
73
70
|
|
74
71
|
end
|
75
72
|
|
@@ -82,7 +79,7 @@ private
|
|
82
79
|
end
|
83
80
|
|
84
81
|
def replace_fields!(content)
|
85
|
-
|
82
|
+
field_replace!(content)
|
86
83
|
end
|
87
84
|
|
88
85
|
def replace_tables!(content)
|
data/lib/odf-report/section.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ODFReport
|
2
2
|
|
3
3
|
class Section
|
4
|
-
include
|
4
|
+
include Fields, Nested
|
5
5
|
|
6
6
|
attr_accessor :fields, :tables, :data, :name, :collection_field, :parent
|
7
7
|
|
@@ -11,20 +11,17 @@ module ODFReport
|
|
11
11
|
@collection = opts[:collection]
|
12
12
|
@parent = opts[:parent]
|
13
13
|
|
14
|
-
@fields =
|
14
|
+
@fields = []
|
15
15
|
|
16
16
|
@tables = []
|
17
17
|
@sections = []
|
18
18
|
end
|
19
19
|
|
20
|
-
def add_field(name,
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
else
|
26
|
-
@fields[name] = lambda { |item| item.send(name)}
|
27
|
-
end
|
20
|
+
def add_field(name, data_field=nil, &block)
|
21
|
+
opts = {:name => name, :data_field => data_field}
|
22
|
+
field = Field.new(opts, &block)
|
23
|
+
@fields << field
|
24
|
+
|
28
25
|
end
|
29
26
|
|
30
27
|
def add_table(table_name, collection_field, opts={}, &block)
|
@@ -58,7 +55,7 @@ module ODFReport
|
|
58
55
|
@collection.each do |data_item|
|
59
56
|
new_section = template.dup
|
60
57
|
|
61
|
-
|
58
|
+
replace_fields!(new_section, data_item)
|
62
59
|
|
63
60
|
@tables.each do |t|
|
64
61
|
t.replace!(new_section, data_item)
|
data/lib/odf-report/table.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ODFReport
|
2
2
|
|
3
3
|
class Table
|
4
|
-
include
|
4
|
+
include Fields, Nested
|
5
5
|
|
6
6
|
attr_accessor :fields, :rows, :name, :collection_field, :data, :header, :parent, :tables
|
7
7
|
|
@@ -11,21 +11,19 @@ class Table
|
|
11
11
|
@collection = opts[:collection]
|
12
12
|
@parent = opts[:parent]
|
13
13
|
|
14
|
-
@fields =
|
14
|
+
@fields = []
|
15
15
|
@tables = []
|
16
16
|
|
17
17
|
@template_rows = []
|
18
18
|
@header = opts[:header] || false
|
19
|
+
@skip_if_empty = opts[:skip_if_empty] || false
|
19
20
|
end
|
20
21
|
|
21
|
-
def add_column(name,
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
else
|
27
|
-
@fields[name] = lambda { |item| item.send(name)}
|
28
|
-
end
|
22
|
+
def add_column(name, data_field=nil, &block)
|
23
|
+
opts = {:name => name, :data_field => data_field}
|
24
|
+
field = Field.new(opts, &block)
|
25
|
+
@fields << field
|
26
|
+
|
29
27
|
end
|
30
28
|
|
31
29
|
def add_table(table_name, collection_field, opts={}, &block)
|
@@ -46,13 +44,18 @@ class Table
|
|
46
44
|
|
47
45
|
populate!(row)
|
48
46
|
|
47
|
+
if (@skip_if_empty || !@header) && @collection.empty?
|
48
|
+
table.remove
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
49
52
|
@template_rows = table.xpath("table:table-row")
|
50
53
|
|
51
54
|
@collection.each do |data_item|
|
52
55
|
|
53
56
|
new_node = get_next_row
|
54
57
|
|
55
|
-
|
58
|
+
replace_fields!(new_node, data_item)
|
56
59
|
|
57
60
|
@tables.each do |t|
|
58
61
|
t.replace!(new_node, data_item)
|
data/odf-report.gemspec
CHANGED
@@ -1,36 +1,25 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "odf-report/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
4
6
|
s.name = %q{odf-report}
|
5
|
-
s.version =
|
7
|
+
s.version = ODFReport::VERSION
|
6
8
|
|
7
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
9
|
s.authors = ["Sandro Duarte"]
|
9
|
-
s.date = %q{2011-12-27}
|
10
10
|
s.description = %q{Generates ODF files, given a template (.odt) and data, replacing tags}
|
11
11
|
s.email = %q{sandrods@gmail.com}
|
12
|
-
s.extra_rdoc_files = ["lib/odf-report.rb", "README.textile"]
|
13
|
-
s.files = %w{lib/odf-report.rb odf-report.gemspec README.textile Manifest lib/odf-report/report.rb lib/odf-report/table.rb lib/odf-report/section.rb lib/odf-report/file_ops.rb lib/odf-report/hash_gsub.rb lib/odf-report/images.rb lib/odf-report/nested.rb }
|
14
12
|
s.has_rdoc = false
|
15
|
-
s.homepage = %q{}
|
16
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Odf-report", "--main", "README.textile"]
|
17
|
-
s.require_paths = ["lib"]
|
13
|
+
s.homepage = %q{https://github.com/sandrods/odf-report}
|
18
14
|
s.rubygems_version = %q{1.3.7}
|
19
15
|
s.summary = %q{Generates ODF files, given a template (.odt) and data, replacing tags}
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_runtime_dependency('rubyzip', "~> 0.9.4")
|
23
|
+
s.add_runtime_dependency('nokogiri', "~> 1.5.0")
|
24
24
|
|
25
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
26
|
-
s.add_runtime_dependency(%q<rubyzip>, [">= 0", ">= 0.9.4"])
|
27
|
-
s.add_runtime_dependency(%q<nokogiri>, [">= 0", ">= 1.5.0"])
|
28
|
-
else
|
29
|
-
s.add_dependency(%q<rubyzip>, [">= 0", ">= 0.9.4"])
|
30
|
-
s.add_dependency(%q<nokogiri>, [">= 0", ">= 1.5.0"])
|
31
|
-
end
|
32
|
-
else
|
33
|
-
s.add_dependency(%q<rubyzip>, [">= 0", ">= 0.9.4"])
|
34
|
-
s.add_dependency(%q<nokogiri>, [">= 0", ">= 1.5.0"])
|
35
|
-
end
|
36
25
|
end
|
data/test/piriapolis.jpg
ADDED
Binary file
|
data/test/rails.png
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require '../lib/odf-report'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
class Item
|
5
|
+
attr_accessor :name, :sid, :children
|
6
|
+
def initialize(_name, _sid, _children=[])
|
7
|
+
@name=_name
|
8
|
+
@sid=_sid
|
9
|
+
@children=_children
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
items = []
|
14
|
+
items << Item.new("LOST", '007', %w(sawyer juliet hurley locke jack freckles))
|
15
|
+
items << Item.new("ALIAS", '302', %w(sidney sloane jack michael marshal))
|
16
|
+
items << Item.new("GREY'S ANATOMY", '220', %w(meredith christina izzie alex george))
|
17
|
+
items << Item.new("BREAKING BAD", '556', %w(pollos gus mike heisenberg))
|
18
|
+
|
19
|
+
report = ODFReport::Report.new("test_nested_tables.odt") do |r|
|
20
|
+
|
21
|
+
r.add_field("TAG_01", Time.now)
|
22
|
+
r.add_field("TAG_02", "TAG-2 -> New tag")
|
23
|
+
|
24
|
+
r.add_table("TABLE_MAIN", items) do |s|
|
25
|
+
|
26
|
+
s.add_column('NAME') { |i| i.name }
|
27
|
+
|
28
|
+
s.add_column('SID', :sid)
|
29
|
+
|
30
|
+
s.add_table('TABLE_S1', :children, :header=>true) do |t|
|
31
|
+
t.add_column('NAME1') { |item| "-> #{item}" }
|
32
|
+
t.add_column('INV') { |item| item.to_s.reverse.upcase }
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
report.generate("./result/test_nested_tables.odt")
|
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require '../lib/odf-report'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
class Item
|
5
|
+
attr_accessor :name, :sid, :children
|
6
|
+
def initialize(_name, _sid, _children=[])
|
7
|
+
@name=_name
|
8
|
+
@sid=_sid
|
9
|
+
@children=_children
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
items = []
|
14
|
+
items << Item.new("LOST", '007', %w(sawyer juliet hurley locke jack freckles))
|
15
|
+
items << Item.new("ALIAS", '302', %w(sidney sloane jack michael marshal))
|
16
|
+
items << Item.new("GREY'S ANATOMY", '220', %w(meredith christina izzie alex george))
|
17
|
+
items << Item.new("BREAKING BAD", '556', %w(pollos gus mike heisenberg))
|
18
|
+
|
19
|
+
report = ODFReport::Report.new("test_sections.odt") do |r|
|
20
|
+
|
21
|
+
r.add_field("TAG_01", Time.now)
|
22
|
+
r.add_field("TAG_02", "TAG-2 -> New tag")
|
23
|
+
|
24
|
+
r.add_section("SECTION_01", items) do |s|
|
25
|
+
|
26
|
+
s.add_field('NAME') { |i| i.name }
|
27
|
+
|
28
|
+
s.add_field('SID', :sid)
|
29
|
+
|
30
|
+
s.add_table('TABLE_S1', :children, :header=>true) do |t|
|
31
|
+
t.add_column('NAME1') { |item| "-> #{item}" }
|
32
|
+
t.add_column('INV') { |item| item.to_s.reverse.upcase }
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
report.generate("./result/test_sections.odt")
|
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require '../lib/odf-report'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
class Item
|
5
|
+
attr_accessor :name, :sid, :children, :subs
|
6
|
+
def initialize(_name, _sid, _children=[], _subs=[])
|
7
|
+
@name=_name
|
8
|
+
@sid=_sid
|
9
|
+
@children=_children
|
10
|
+
@subs=_subs
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
subs1 = []
|
15
|
+
subs1 << Item.new("SAWYER", 1, %w(Your bones don't break))
|
16
|
+
subs1 << Item.new("HURLEY", 2, %w(Your cells react to bacteria and viruses))
|
17
|
+
subs1 << Item.new("LOCKE", 3, %W(Do you see any Teletubbies in here))
|
18
|
+
|
19
|
+
subs2 = []
|
20
|
+
subs2 << Item.new("SLOANE", 21, %w(Praesent hendrerit lectus sit amet))
|
21
|
+
subs2 << Item.new("JACK", 22, %w(Donec nec est eget dolor laoreet))
|
22
|
+
subs2 << Item.new("MICHAEL", 23, %W(Integer elementum massa at nulla placerat varius))
|
23
|
+
|
24
|
+
items = []
|
25
|
+
items << Item.new("LOST", '007', %w(sawyer juliet hurley locke jack freckles), subs1)
|
26
|
+
items << Item.new("ALIAS", '302', %w(sidney sloane jack michael marshal))
|
27
|
+
items << Item.new("GREY'S ANATOMY", '220', %w(meredith christina izzie alex george), subs2)
|
28
|
+
items << Item.new("BREAKING BAD", '556', %w(pollos gus mike heisenberg))
|
29
|
+
|
30
|
+
report = ODFReport::Report.new("test_sub_sections.odt") do |r|
|
31
|
+
|
32
|
+
r.add_field("TAG_01", Time.now)
|
33
|
+
r.add_field("TAG_02", "TAG-2 -> New tag")
|
34
|
+
|
35
|
+
r.add_section("SECTION_01", items) do |s|
|
36
|
+
|
37
|
+
s.add_field('NAME') { |i| i.name }
|
38
|
+
|
39
|
+
s.add_field('SID', :sid)
|
40
|
+
|
41
|
+
s.add_table('TABLE_S1', :children, :header=>true) do |t|
|
42
|
+
t.add_column('NAME1') { |item| "-> #{item}" }
|
43
|
+
t.add_column('INV') { |item| item.to_s.reverse.upcase }
|
44
|
+
end
|
45
|
+
|
46
|
+
s.add_section('SUB_01', :subs) do |r|
|
47
|
+
r.add_field("FIRST_NAME", :name)
|
48
|
+
r.add_table('IPSUM_TABLE', :children, :header => true) do |t|
|
49
|
+
t.add_column('IPSUM_ITEM') { |i| i }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
report.generate("./result/test_sub_sections.odt")
|
Binary file
|
data/test/test_tables.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require '../lib/odf-report'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
col1 = []
|
5
|
+
(1..40).each do |i|
|
6
|
+
col1 << {:name=>"name #{i}", :idx=>i, :address=>"this is address #{i}"}
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
col2 = []
|
11
|
+
col2 << OpenStruct.new({:name=>"josh harnet", :idx=>"02", :address=>"testing <&> ", :phone=>99025668, :zip=>"90420-002"})
|
12
|
+
col2 << OpenStruct.new({:name=>"sandro duarte", :idx=>"45", :address=>"address with &", :phone=>88774451, :zip=>"90490-002"})
|
13
|
+
col2 << OpenStruct.new({:name=>"ellen bicca", :idx=>"77", :address=>"<address with escaped html>", :phone=>77025668, :zip=>"94420-002"})
|
14
|
+
col2 << OpenStruct.new({:name=>"luiz garcia", 'idx'=>"88", :address=>"address with\nlinebreak", :phone=>27025668, :zip=>"94520-025"})
|
15
|
+
|
16
|
+
col3, col4, col5 = [], [], []
|
17
|
+
|
18
|
+
report = ODFReport::Report.new("test_tables.odt") do |r|
|
19
|
+
|
20
|
+
r.add_field("HEADER_FIELD", "This field was in the HEADER")
|
21
|
+
|
22
|
+
r.add_field("TAG_01", "New tag")
|
23
|
+
r.add_field("TAG_02", "TAG-2 -> New tag")
|
24
|
+
|
25
|
+
r.add_table("TABLE_01", col1, :header=>true) do |t|
|
26
|
+
t.add_column(:field_01, :idx)
|
27
|
+
t.add_column(:field_02, :name)
|
28
|
+
t.add_column(:address)
|
29
|
+
end
|
30
|
+
|
31
|
+
r.add_table("TABLE_02", col2) do |t|
|
32
|
+
t.add_column(:field_04, :idx)
|
33
|
+
t.add_column(:field_05, :name)
|
34
|
+
t.add_column(:field_06, 'address')
|
35
|
+
t.add_column(:field_07, :phone)
|
36
|
+
t.add_column(:field_08, :zip)
|
37
|
+
end
|
38
|
+
|
39
|
+
r.add_table("TABLE_03", col3, :header=>true) do |t|
|
40
|
+
t.add_column(:field_01, :idx)
|
41
|
+
t.add_column(:field_02, :name)
|
42
|
+
t.add_column(:field_03, :address)
|
43
|
+
end
|
44
|
+
|
45
|
+
r.add_table("TABLE_04", col4, :header=>true, :skip_if_empty => true) do |t|
|
46
|
+
t.add_column(:field_01, :idx)
|
47
|
+
t.add_column(:field_02, :name)
|
48
|
+
t.add_column(:field_03, :address)
|
49
|
+
end
|
50
|
+
|
51
|
+
r.add_table("TABLE_05", col5) do |t|
|
52
|
+
t.add_column(:field_01, :idx)
|
53
|
+
t.add_column(:field_02, :name)
|
54
|
+
t.add_column(:field_03, :address)
|
55
|
+
end
|
56
|
+
|
57
|
+
r.add_image("graphics1", File.join(Dir.pwd, 'piriapolis.jpg'))
|
58
|
+
r.add_image("graphics2", File.join(Dir.pwd, 'rails.png'))
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
report.generate("./result/test_tables.odt")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: odf-report
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,65 +9,65 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-29 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rubyzip
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153481300 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
- - ! '>='
|
19
|
+
- - ~>
|
23
20
|
- !ruby/object:Gem::Version
|
24
21
|
version: 0.9.4
|
25
22
|
type: :runtime
|
26
23
|
prerelease: false
|
27
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153481300
|
28
25
|
- !ruby/object:Gem::Dependency
|
29
26
|
name: nokogiri
|
30
|
-
requirement: &
|
27
|
+
requirement: &2153480700 !ruby/object:Gem::Requirement
|
31
28
|
none: false
|
32
29
|
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: '0'
|
36
|
-
- - ! '>='
|
30
|
+
- - ~>
|
37
31
|
- !ruby/object:Gem::Version
|
38
32
|
version: 1.5.0
|
39
33
|
type: :runtime
|
40
34
|
prerelease: false
|
41
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153480700
|
42
36
|
description: Generates ODF files, given a template (.odt) and data, replacing tags
|
43
37
|
email: sandrods@gmail.com
|
44
38
|
executables: []
|
45
39
|
extensions: []
|
46
|
-
extra_rdoc_files:
|
47
|
-
- lib/odf-report.rb
|
48
|
-
- README.textile
|
40
|
+
extra_rdoc_files: []
|
49
41
|
files:
|
50
|
-
-
|
51
|
-
-
|
52
|
-
- README.textile
|
42
|
+
- .gitignore
|
43
|
+
- MIT-LICENSE
|
53
44
|
- Manifest
|
54
|
-
-
|
55
|
-
- lib/odf-report
|
56
|
-
- lib/odf-report/
|
57
|
-
- lib/odf-report/
|
58
|
-
- lib/odf-report/
|
45
|
+
- README.textile
|
46
|
+
- lib/odf-report.rb
|
47
|
+
- lib/odf-report/field.rb
|
48
|
+
- lib/odf-report/fields.rb
|
49
|
+
- lib/odf-report/file.rb
|
59
50
|
- lib/odf-report/images.rb
|
60
51
|
- lib/odf-report/nested.rb
|
61
|
-
|
52
|
+
- lib/odf-report/report.rb
|
53
|
+
- lib/odf-report/section.rb
|
54
|
+
- lib/odf-report/table.rb
|
55
|
+
- lib/odf-report/version.rb
|
56
|
+
- odf-report.gemspec
|
57
|
+
- test/piriapolis.jpg
|
58
|
+
- test/rails.png
|
59
|
+
- test/test_nested_tables.odt
|
60
|
+
- test/test_nested_tables.rb
|
61
|
+
- test/test_sections.odt
|
62
|
+
- test/test_sections.rb
|
63
|
+
- test/test_sub_sections.odt
|
64
|
+
- test/test_sub_sections.rb
|
65
|
+
- test/test_tables.odt
|
66
|
+
- test/test_tables.rb
|
67
|
+
homepage: https://github.com/sandrods/odf-report
|
62
68
|
licenses: []
|
63
69
|
post_install_message:
|
64
|
-
rdoc_options:
|
65
|
-
- --line-numbers
|
66
|
-
- --inline-source
|
67
|
-
- --title
|
68
|
-
- Odf-report
|
69
|
-
- --main
|
70
|
-
- README.textile
|
70
|
+
rdoc_options: []
|
71
71
|
require_paths:
|
72
72
|
- lib
|
73
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -81,11 +81,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
81
|
requirements:
|
82
82
|
- - ! '>='
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: '
|
84
|
+
version: '0'
|
85
85
|
requirements: []
|
86
86
|
rubyforge_project:
|
87
87
|
rubygems_version: 1.8.10
|
88
88
|
signing_key:
|
89
|
-
specification_version:
|
89
|
+
specification_version: 3
|
90
90
|
summary: Generates ODF files, given a template (.odt) and data, replacing tags
|
91
|
-
test_files:
|
91
|
+
test_files:
|
92
|
+
- test/piriapolis.jpg
|
93
|
+
- test/rails.png
|
94
|
+
- test/test_nested_tables.odt
|
95
|
+
- test/test_nested_tables.rb
|
96
|
+
- test/test_sections.odt
|
97
|
+
- test/test_sections.rb
|
98
|
+
- test/test_sub_sections.odt
|
99
|
+
- test/test_sub_sections.rb
|
100
|
+
- test/test_tables.odt
|
101
|
+
- test/test_tables.rb
|