ruport 1.2.3 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|