ruport 1.2.3 → 1.4.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.
- data/Rakefile +2 -4
- data/examples/centered_pdf_text_box.rb +2 -6
- data/examples/pdf_report_with_common_base.rb +2 -5
- data/examples/png_embed.rb +3 -8
- data/examples/simple_templating_example.rb +7 -7
- data/examples/tattle_rubygems_version.rb +0 -3
- data/lib/ruport/data/grouping.rb +11 -10
- data/lib/ruport/data/record.rb +3 -1
- data/lib/ruport/data/table.rb +0 -14
- data/lib/ruport/formatter/csv.rb +10 -15
- data/lib/ruport/formatter/html.rb +4 -6
- data/lib/ruport/formatter/pdf.rb +50 -91
- data/lib/ruport/formatter/template.rb +33 -15
- data/lib/ruport/formatter/text.rb +22 -26
- data/lib/ruport/formatter.rb +27 -11
- data/lib/ruport/renderer/grouping.rb +0 -6
- data/lib/ruport/renderer/table.rb +0 -4
- data/lib/ruport/renderer.rb +64 -78
- data/lib/ruport.rb +7 -4
- data/test/csv_formatter_test.rb +8 -8
- data/test/grouping_test.rb +10 -10
- data/test/helpers.rb +2 -0
- data/test/html_formatter_test.rb +5 -5
- data/test/pdf_formatter_test.rb +23 -14
- data/test/record_test.rb +5 -0
- data/test/renderer_test.rb +103 -47
- data/test/table_test.rb +111 -138
- data/test/template_test.rb +12 -1
- data/test/text_formatter_test.rb +12 -14
- metadata +69 -88
- data/lib/ruport/acts_as_reportable.rb +0 -378
- data/lib/ruport/query/sql_split.rb +0 -33
- data/lib/ruport/query.rb +0 -232
- data/test/acts_as_reportable_test.rb +0 -272
- data/test/query_test.rb +0 -259
- data/test/sql_split_test.rb +0 -20
data/Rakefile
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require "rake/rdoctask"
|
2
2
|
require "rake/testtask"
|
3
3
|
require "rake/gempackagetask"
|
4
|
-
#
|
5
4
|
|
6
|
-
RUPORT_VERSION = "1.
|
5
|
+
RUPORT_VERSION = "1.4.0"
|
7
6
|
|
8
7
|
begin
|
9
8
|
require "rubygems"
|
@@ -33,9 +32,8 @@ spec = Gem::Specification.new do |spec|
|
|
33
32
|
spec.extra_rdoc_files = %w{README LICENSE AUTHORS}
|
34
33
|
spec.rdoc_options << '--title' << 'Ruport Documentation' <<
|
35
34
|
'--main' << 'README' << '-q'
|
36
|
-
spec.add_dependency('transaction-simple', "=1.4.0")
|
37
35
|
spec.add_dependency('fastercsv', '>= 1.1.0')
|
38
|
-
spec.add_dependency('pdf-writer', '
|
36
|
+
spec.add_dependency('pdf-writer', '= 1.1.7')
|
39
37
|
spec.author = "Gregory Brown"
|
40
38
|
spec.email = " gregory.t.brown@gmail.com"
|
41
39
|
spec.rubyforge_project = "ruport"
|
@@ -8,13 +8,9 @@ require "ruport"
|
|
8
8
|
#
|
9
9
|
class Document < Ruport::Renderer
|
10
10
|
|
11
|
-
#
|
11
|
+
# Will throw an error if these options are not set at rendering time
|
12
12
|
required_option :text, :author
|
13
13
|
|
14
|
-
# allows this option to be set directly on a renderer instance,
|
15
|
-
# and creates a reader for it if a header() method does not already exist
|
16
|
-
option :heading
|
17
|
-
|
18
14
|
# The renderer will look for a build_document_body() method on the formatter,
|
19
15
|
# but silently skip this stage if it is missing
|
20
16
|
stage :document_body
|
@@ -84,4 +80,4 @@ took flesh. To be great is to be misunderstood. . . .
|
|
84
80
|
EOS
|
85
81
|
end
|
86
82
|
|
87
|
-
puts a
|
83
|
+
puts a
|
@@ -19,12 +19,9 @@ class ClientRenderer < Ruport::Renderer
|
|
19
19
|
prepare :standard_report
|
20
20
|
stage :company_header, :client_header, :client_body, :client_footer
|
21
21
|
finalize :standard_report
|
22
|
-
option :example
|
23
22
|
|
24
23
|
def setup
|
25
24
|
data.rename_columns { |c| c.to_s.titleize }
|
26
|
-
# this lets us omit the options prefix in the formatter
|
27
|
-
formatter.class.opt_reader(:example)
|
28
25
|
end
|
29
26
|
end
|
30
27
|
|
@@ -58,7 +55,7 @@ class ClientPDF < CompanyPDFBase
|
|
58
55
|
|
59
56
|
def build_client_header
|
60
57
|
pad(10) do
|
61
|
-
add_text "Specific Report Header with example=#{example}",
|
58
|
+
add_text "Specific Report Header with example=#{options.example}",
|
62
59
|
:justification => :center, :font_size => 12
|
63
60
|
end
|
64
61
|
end
|
@@ -72,4 +69,4 @@ table = Table([:a,:b,:c]) << [1,2,3] << [4,5,6]
|
|
72
69
|
|
73
70
|
File.open("example.pdf","w") do |f|
|
74
71
|
f << ClientRenderer.render_pdf(:data => table,:example => "apple")
|
75
|
-
end
|
72
|
+
end
|
data/examples/png_embed.rb
CHANGED
@@ -2,9 +2,6 @@ require "rubygems"
|
|
2
2
|
require "ruport"
|
3
3
|
|
4
4
|
class RoadmapRenderer < Ruport::Renderer
|
5
|
-
|
6
|
-
option :image_file
|
7
|
-
|
8
5
|
stage :roadmap_image, :roadmap_text_body
|
9
6
|
finalize :roadmap
|
10
7
|
end
|
@@ -12,7 +9,6 @@ end
|
|
12
9
|
class HTMLRoadmap < Ruport::Formatter
|
13
10
|
|
14
11
|
renders :html, :for => RoadmapRenderer
|
15
|
-
opt_reader :image_file
|
16
12
|
|
17
13
|
def layout
|
18
14
|
output << "<html><body>\n"
|
@@ -21,7 +17,7 @@ class HTMLRoadmap < Ruport::Formatter
|
|
21
17
|
end
|
22
18
|
|
23
19
|
def build_roadmap_image
|
24
|
-
output << "<img src='#{image_file}'/>"
|
20
|
+
output << "<img src='#{options.image_file}'/>"
|
25
21
|
end
|
26
22
|
|
27
23
|
def build_roadmap_text_body
|
@@ -33,10 +29,9 @@ end
|
|
33
29
|
class PDFRoadmap < Ruport::Formatter::PDF
|
34
30
|
|
35
31
|
renders :pdf, :for => RoadmapRenderer
|
36
|
-
opt_reader :image_file
|
37
32
|
|
38
33
|
def build_roadmap_image
|
39
|
-
center_image_in_box image_file, :x => 0, :y => 200,
|
34
|
+
center_image_in_box options.image_file, :x => 0, :y => 200,
|
40
35
|
:width => 624, :height => 432
|
41
36
|
move_cursor_to 80
|
42
37
|
end
|
@@ -56,4 +51,4 @@ formats = [:html, :pdf]
|
|
56
51
|
formats.each do |format|
|
57
52
|
RoadmapRenderer.render(format, :image_file => "roadmap.png",
|
58
53
|
:file => "roadmap.#{format}")
|
59
|
-
end
|
54
|
+
end
|
@@ -1,24 +1,24 @@
|
|
1
1
|
require "ruport"
|
2
2
|
|
3
|
-
Ruport::Formatter::Template.create(:simple) do |
|
4
|
-
|
3
|
+
Ruport::Formatter::Template.create(:simple) do |format|
|
4
|
+
format.page = {
|
5
5
|
:size => "LETTER",
|
6
6
|
:layout => :landscape
|
7
7
|
}
|
8
|
-
|
8
|
+
format.text = {
|
9
9
|
:font_size => 16
|
10
10
|
}
|
11
|
-
|
11
|
+
format.table = {
|
12
12
|
:font_size => 16,
|
13
13
|
:show_headings => false
|
14
14
|
}
|
15
|
-
|
15
|
+
format.column = {
|
16
16
|
:alignment => :center,
|
17
17
|
}
|
18
|
-
|
18
|
+
format.heading = {
|
19
19
|
:alignment => :right
|
20
20
|
}
|
21
|
-
|
21
|
+
format.grouping = {
|
22
22
|
:style => :separated
|
23
23
|
}
|
24
24
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
# A dump of the database for this example can be found in ./data/tattle.dump
|
2
2
|
|
3
|
-
|
4
3
|
require "active_record"
|
5
4
|
require "ruport"
|
6
5
|
|
7
|
-
|
8
6
|
# Update with your connection parameters
|
9
7
|
ActiveRecord::Base.establish_connection(
|
10
8
|
:adapter => 'mysql',
|
@@ -37,4 +35,3 @@ sorted_table = rubygems_versions.sort_rows_by("count", :order => :descending)
|
|
37
35
|
sorted_table.reduce { |r| r["platform"] !~ /darwin/i }
|
38
36
|
g = Grouping(sorted_table, :by => "platform", :order => "name")
|
39
37
|
puts g.to_pdf
|
40
|
-
|
data/lib/ruport/data/grouping.rb
CHANGED
@@ -79,6 +79,12 @@ module Ruport::Data
|
|
79
79
|
|
80
80
|
alias_method :==, :eql?
|
81
81
|
|
82
|
+
protected
|
83
|
+
|
84
|
+
attr_writer :name, :subgroups #:nodoc:
|
85
|
+
|
86
|
+
private
|
87
|
+
|
82
88
|
# Creates subgroups for the group based on the supplied column name. Each
|
83
89
|
# subgroup is a hash whose keys are the unique values in the column.
|
84
90
|
#
|
@@ -93,23 +99,18 @@ module Ruport::Data
|
|
93
99
|
if @subgroups.empty?
|
94
100
|
@subgroups = grouped_data(group_column)
|
95
101
|
else
|
96
|
-
@subgroups.each {|name,group|
|
102
|
+
@subgroups.each {|name,group|
|
103
|
+
group.send(:create_subgroups, group_column)
|
104
|
+
}
|
97
105
|
end
|
98
106
|
end
|
99
107
|
|
100
|
-
protected
|
101
|
-
|
102
|
-
attr_writer :name, :subgroups #:nodoc:
|
103
|
-
|
104
|
-
private
|
105
|
-
|
106
108
|
def grouped_data(group_column) #:nodoc:
|
107
109
|
data = {}
|
108
110
|
group_names = column(group_column).uniq
|
109
111
|
columns = column_names.dup
|
110
112
|
columns.delete(group_column)
|
111
113
|
group_names.each do |name|
|
112
|
-
# FIXME - this doesn't seem to reduce the data set
|
113
114
|
group_data = sub_table(columns) {|r|
|
114
115
|
r.send(group_column) == name
|
115
116
|
}
|
@@ -172,7 +173,7 @@ module Ruport::Data
|
|
172
173
|
@data = data.to_group.send(:grouped_data, cols.shift)
|
173
174
|
cols.each do |col|
|
174
175
|
@data.each do |name,group|
|
175
|
-
group.create_subgroups
|
176
|
+
group.send(:create_subgroups, col)
|
176
177
|
end
|
177
178
|
end
|
178
179
|
end
|
@@ -378,7 +379,7 @@ module Kernel
|
|
378
379
|
#
|
379
380
|
# Example:
|
380
381
|
#
|
381
|
-
# a = [[1,2,3],[4,5,6]]
|
382
|
+
# a = Table(%w[a b c], :data => [[1,2,3],[4,5,6]])
|
382
383
|
# b = Grouping(a, :by => "a") #=> creates a new grouping on column "a"
|
383
384
|
#
|
384
385
|
def Grouping(*args)
|
data/lib/ruport/data/record.rb
CHANGED
data/lib/ruport/data/table.rb
CHANGED
@@ -824,17 +824,3 @@ module Kernel
|
|
824
824
|
return table
|
825
825
|
end
|
826
826
|
end
|
827
|
-
|
828
|
-
class Array
|
829
|
-
|
830
|
-
# Converts an array to a Ruport::Data::Table object, ready to
|
831
|
-
# use in your reports.
|
832
|
-
#
|
833
|
-
# Example:
|
834
|
-
# [[1,2],[3,4]].to_table(%w[a b])
|
835
|
-
#
|
836
|
-
def to_table(column_names=nil,&b)
|
837
|
-
Ruport::Data::Table.new({:data => self, :column_names => column_names},&b)
|
838
|
-
end
|
839
|
-
|
840
|
-
end
|
data/lib/ruport/formatter/csv.rb
CHANGED
@@ -32,16 +32,11 @@ module Ruport
|
|
32
32
|
renders :csv, :for => [ Renderer::Row, Renderer::Table,
|
33
33
|
Renderer::Group, Renderer::Grouping ]
|
34
34
|
|
35
|
-
opt_reader :show_table_headers,
|
36
|
-
:format_options,
|
37
|
-
:show_group_headers,
|
38
|
-
:style
|
39
|
-
|
40
35
|
# Hook for setting available options using a template. See the template
|
41
36
|
# documentation for the available options and their format.
|
42
37
|
def apply_template
|
43
|
-
apply_table_format_template(template.
|
44
|
-
apply_grouping_format_template(template.
|
38
|
+
apply_table_format_template(template.table)
|
39
|
+
apply_grouping_format_template(template.grouping)
|
45
40
|
|
46
41
|
options.format_options ||= template.format_options
|
47
42
|
end
|
@@ -52,22 +47,22 @@ module Ruport
|
|
52
47
|
# This method does not do anything if options.show_table_headers is false
|
53
48
|
# or the Data::Table has no column names.
|
54
49
|
def build_table_header
|
55
|
-
unless data.column_names.empty? || !show_table_headers
|
56
|
-
render_row data.column_names, :format_options => format_options
|
50
|
+
unless data.column_names.empty? || !options.show_table_headers
|
51
|
+
render_row data.column_names, :format_options => options.format_options
|
57
52
|
end
|
58
53
|
end
|
59
54
|
|
60
55
|
# Calls the row renderer for each row in the Data::Table
|
61
56
|
def build_table_body
|
62
57
|
render_data_by_row { |r|
|
63
|
-
r.options.format_options = format_options
|
58
|
+
r.options.format_options = options.format_options
|
64
59
|
}
|
65
60
|
end
|
66
61
|
|
67
62
|
# Produces CSV output for a data row.
|
68
63
|
def build_row
|
69
64
|
require "fastercsv"
|
70
|
-
output << FCSV.generate_line(data,format_options || {})
|
65
|
+
output << FCSV.generate_line(data,options.format_options || {})
|
71
66
|
end
|
72
67
|
|
73
68
|
# Renders the header for a group using the group name.
|
@@ -86,14 +81,14 @@ module Ruport
|
|
86
81
|
# column names.
|
87
82
|
#
|
88
83
|
def build_grouping_header
|
89
|
-
unless style == :inline
|
84
|
+
unless options.style == :inline
|
90
85
|
output << "#{data.grouped_by}," << grouping_columns
|
91
86
|
end
|
92
87
|
end
|
93
88
|
|
94
89
|
# Determines the proper style to use and renders the Grouping.
|
95
90
|
def build_grouping_body
|
96
|
-
case style
|
91
|
+
case options.style
|
97
92
|
when :inline
|
98
93
|
render_inline_grouping(options)
|
99
94
|
when :justified, :raw
|
@@ -112,9 +107,9 @@ module Ruport
|
|
112
107
|
|
113
108
|
def render_justified_or_raw_grouping
|
114
109
|
data.each do |_,group|
|
115
|
-
output << "#{group.name}" if style == :justified
|
110
|
+
output << "#{group.name}" if options.style == :justified
|
116
111
|
group.each do |row|
|
117
|
-
output << "#{group.name if style == :raw}," << row.to_csv
|
112
|
+
output << "#{group.name if options.style == :raw}," << row.to_csv
|
118
113
|
end
|
119
114
|
output << "\n"
|
120
115
|
end
|
@@ -28,13 +28,11 @@ module Ruport
|
|
28
28
|
renders :html, :for => [ Renderer::Row, Renderer::Table,
|
29
29
|
Renderer::Group, Renderer::Grouping ]
|
30
30
|
|
31
|
-
opt_reader :show_table_headers, :show_group_headers, :style
|
32
|
-
|
33
31
|
# Hook for setting available options using a template. See the template
|
34
32
|
# documentation for the available options and their format.
|
35
33
|
def apply_template
|
36
|
-
apply_table_format_template(template.
|
37
|
-
apply_grouping_format_template(template.
|
34
|
+
apply_table_format_template(template.table)
|
35
|
+
apply_grouping_format_template(template.grouping)
|
38
36
|
end
|
39
37
|
|
40
38
|
# Generates table headers based on the column names of your Data::Table.
|
@@ -43,7 +41,7 @@ module Ruport
|
|
43
41
|
# or the Data::Table has no column names.
|
44
42
|
def build_table_header
|
45
43
|
output << "\t<table>\n"
|
46
|
-
unless data.column_names.empty? || !show_table_headers
|
44
|
+
unless data.column_names.empty? || !options.show_table_headers
|
47
45
|
output << "\t\t<tr>\n\t\t\t<th>" +
|
48
46
|
data.column_names.join("</th>\n\t\t\t<th>") +
|
49
47
|
"</th>\n\t\t</tr>\n"
|
@@ -89,7 +87,7 @@ module Ruport
|
|
89
87
|
# renders them using the group renderer.
|
90
88
|
#
|
91
89
|
def build_grouping_body
|
92
|
-
case style
|
90
|
+
case options.style
|
93
91
|
when :inline
|
94
92
|
render_inline_grouping(options)
|
95
93
|
when :justified
|
data/lib/ruport/formatter/pdf.rb
CHANGED
@@ -39,41 +39,13 @@ module Ruport
|
|
39
39
|
# Grouping:
|
40
40
|
# * style (:inline,:justified,:separated,:offset)
|
41
41
|
#
|
42
|
-
class Formatter::PDF < Formatter
|
43
|
-
|
44
|
-
module PDFWriterMemoryPatch #:nodoc:
|
45
|
-
unless self.class.instance_methods.include?("_post_transaction_rewind")
|
46
|
-
def _post_transaction_rewind
|
47
|
-
@objects.each { |e| e.instance_variable_set(:@parent,self) }
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
module PDFSimpleTableOrderingPatch #:nodoc:
|
53
|
-
def __find_table_max_width__(pdf)
|
54
|
-
#p "this actually gets called"
|
55
|
-
max_width = PDF::Writer::OHash.new(-1)
|
42
|
+
class Formatter::PDF < Formatter
|
56
43
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
w = pdf.text_width(row[name].to_s, @font_size)
|
63
|
-
w *= PDF::SimpleTable::WIDTH_FACTOR
|
64
|
-
|
65
|
-
max_width[name] = w if w > max_width[name]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
@cols.each do |name, column|
|
70
|
-
title = column.heading.title if column.heading
|
71
|
-
title ||= column.name
|
72
|
-
w = pdf.text_width(title, @heading_font_size)
|
73
|
-
w *= PDF::SimpleTable::WIDTH_FACTOR
|
74
|
-
max_width[name] = w if w > max_width[name]
|
75
|
-
end
|
76
|
-
max_width
|
44
|
+
module PDFWriterProxy #:nodoc:
|
45
|
+
def method_missing(id,*args)
|
46
|
+
super(id,*args)
|
47
|
+
rescue
|
48
|
+
pdf_writer.send(id,*args)
|
77
49
|
end
|
78
50
|
end
|
79
51
|
|
@@ -82,11 +54,15 @@ module Ruport
|
|
82
54
|
|
83
55
|
attr_writer :pdf_writer
|
84
56
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
57
|
+
|
58
|
+
# If you use this macro in your formatter, Ruport will automatically forward
|
59
|
+
# calls to the underlying PDF::Writer, for any methods that are not wrapped
|
60
|
+
# or redefined.
|
61
|
+
def self.proxy_to_pdf_writer
|
62
|
+
include PDFWriterProxy
|
63
|
+
end
|
64
|
+
|
65
|
+
save_as_binary_file
|
90
66
|
|
91
67
|
def initialize
|
92
68
|
Ruport.quiet do
|
@@ -98,12 +74,12 @@ module Ruport
|
|
98
74
|
# Hook for setting available options using a template. See the template
|
99
75
|
# documentation for the available options and their format.
|
100
76
|
def apply_template
|
101
|
-
apply_page_format_template(template.
|
102
|
-
apply_text_format_template(template.
|
103
|
-
apply_table_format_template(template.
|
104
|
-
apply_column_format_template(template.
|
105
|
-
apply_heading_format_template(template.
|
106
|
-
apply_grouping_format_template(template.
|
77
|
+
apply_page_format_template(template.page)
|
78
|
+
apply_text_format_template(template.text)
|
79
|
+
apply_table_format_template(template.table)
|
80
|
+
apply_column_format_template(template.column)
|
81
|
+
apply_heading_format_template(template.heading)
|
82
|
+
apply_grouping_format_template(template.grouping)
|
107
83
|
end
|
108
84
|
|
109
85
|
# Returns the current PDF::Writer object or creates a new one if it has not
|
@@ -111,9 +87,8 @@ module Ruport
|
|
111
87
|
#
|
112
88
|
def pdf_writer
|
113
89
|
@pdf_writer ||= options.formatter ||
|
114
|
-
::PDF::Writer.new( :paper => paper_size || "LETTER",
|
115
|
-
:orientation => paper_orientation || :portrait)
|
116
|
-
@pdf_writer.extend(PDFWriterMemoryPatch)
|
90
|
+
::PDF::Writer.new( :paper => options.paper_size || "LETTER",
|
91
|
+
:orientation => options.paper_orientation || :portrait)
|
117
92
|
end
|
118
93
|
|
119
94
|
# Calls the draw_table method.
|
@@ -142,7 +117,7 @@ module Ruport
|
|
142
117
|
# Determines which style to use and renders the main body for
|
143
118
|
# Renderer::Grouping.
|
144
119
|
def build_grouping_body
|
145
|
-
case style
|
120
|
+
case options.style
|
146
121
|
when :inline
|
147
122
|
render_inline_grouping(options.to_hash.merge(:formatter => pdf_writer,
|
148
123
|
:skip_finalize_table => true))
|
@@ -170,7 +145,7 @@ module Ruport
|
|
170
145
|
# add_text("Hello Joe") #renders at 14pt
|
171
146
|
# add_text("Hello Mike",:font_size => 16) # renders at 16pt
|
172
147
|
def add_text(text, format_opts={})
|
173
|
-
format_opts = text_format.merge(format_opts) if text_format
|
148
|
+
format_opts = options.text_format.merge(format_opts) if options.text_format
|
174
149
|
pdf_writer.text(text, format_opts)
|
175
150
|
end
|
176
151
|
|
@@ -245,25 +220,6 @@ module Ruport
|
|
245
220
|
move_cursor_to(opts.y - opts.height)
|
246
221
|
end
|
247
222
|
|
248
|
-
# Adds an image to every page. The color and size won't be modified,
|
249
|
-
# but it will be centered.
|
250
|
-
#
|
251
|
-
def watermark(imgpath)
|
252
|
-
x = pdf_writer.absolute_left_margin
|
253
|
-
y = pdf_writer.absolute_bottom_margin
|
254
|
-
width = pdf_writer.absolute_right_margin - x
|
255
|
-
height = pdf_writer.absolute_top_margin - y
|
256
|
-
|
257
|
-
pdf_writer.open_object do |wm|
|
258
|
-
pdf_writer.save_state
|
259
|
-
center_image_in_box(imgpath, :x => x, :y => y,
|
260
|
-
:width => width, :height => height)
|
261
|
-
pdf_writer.restore_state
|
262
|
-
pdf_writer.close_object
|
263
|
-
pdf_writer.add_object(wm, :all_pages)
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
223
|
# Adds n to pdf_writer.y, moving the vertical drawing position in the
|
268
224
|
# document.
|
269
225
|
def move_cursor(n)
|
@@ -274,6 +230,15 @@ module Ruport
|
|
274
230
|
def move_cursor_to(n)
|
275
231
|
pdf_writer.y = n
|
276
232
|
end
|
233
|
+
|
234
|
+
# Moves the vertical drawing position in the document upwards by n.
|
235
|
+
def move_up(n)
|
236
|
+
pdf_writer.y += n
|
237
|
+
end
|
238
|
+
|
239
|
+
def move_down(n)
|
240
|
+
pdf_writer.y -= n
|
241
|
+
end
|
277
242
|
|
278
243
|
# Adds a specified amount of whitespace above and below the code
|
279
244
|
# in your block. For example, if you want to surround the top and
|
@@ -317,15 +282,15 @@ module Ruport
|
|
317
282
|
raise FormatterError, m if table_data.column_names.empty?
|
318
283
|
|
319
284
|
table_data.rename_columns { |c| c.to_s }
|
320
|
-
|
321
|
-
if table_format
|
322
|
-
format_opts =
|
323
|
-
|
285
|
+
|
286
|
+
if options.table_format
|
287
|
+
format_opts =
|
288
|
+
Marshal.load(Marshal.dump(options.table_format.merge(format_opts)))
|
289
|
+
end
|
324
290
|
|
325
291
|
old = pdf_writer.font_size
|
326
292
|
|
327
|
-
::PDF::SimpleTable.new do |table|
|
328
|
-
table.extend(PDFSimpleTableOrderingPatch)
|
293
|
+
::PDF::SimpleTable.new do |table|
|
329
294
|
table.maximum_width = 500
|
330
295
|
table.column_order = table_data.column_names
|
331
296
|
table.data = table_data
|
@@ -338,12 +303,7 @@ module Ruport
|
|
338
303
|
|
339
304
|
pdf_writer.font_size = old
|
340
305
|
end
|
341
|
-
|
342
|
-
# Save the output to a file.
|
343
|
-
def save_output(filename)
|
344
|
-
File.open(filename,"wb") {|f| f << output }
|
345
|
-
end
|
346
|
-
|
306
|
+
|
347
307
|
# This module provides tools to simplify some common drawing operations.
|
348
308
|
# It is included by default in the PDF formatter.
|
349
309
|
#
|
@@ -482,14 +442,14 @@ module Ruport
|
|
482
442
|
def render_justified_or_separated_grouping
|
483
443
|
table = table_with_grouped_by_column
|
484
444
|
data.each do |name,group|
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
table <<
|
490
|
-
|
445
|
+
group.each_with_index do |r,i|
|
446
|
+
if i == 0
|
447
|
+
table << { data.grouped_by => "<b>#{name}</b>" }.merge(r.to_hash)
|
448
|
+
else
|
449
|
+
table << r
|
450
|
+
end
|
491
451
|
end
|
492
|
-
table <<
|
452
|
+
table << [" "] if options.style == :separated
|
493
453
|
end
|
494
454
|
render_table table, options.to_hash.merge(:formatter => pdf_writer)
|
495
455
|
end
|
@@ -497,9 +457,8 @@ module Ruport
|
|
497
457
|
def render_offset_grouping
|
498
458
|
table = table_with_grouped_by_column
|
499
459
|
data.each do |name,group|
|
500
|
-
table << ["<b>#{name}</b
|
501
|
-
|
502
|
-
group.each {|r| table << r.to_a.unshift(nil) }
|
460
|
+
table << ["<b>#{name}</b>"]
|
461
|
+
group.each {|r| table << r }
|
503
462
|
end
|
504
463
|
render_table table, options.to_hash.merge(:formatter => pdf_writer)
|
505
464
|
end
|