Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Static Defined Headers #160

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions lib/prawn/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ module Errors
# numbering (for styling and other row-specific options) always indexes
# based on your data array. Whether or not you have a header, row(n) always
# refers to the nth element (starting from 0) of the +data+ array.
# +headers+::
# If set to a multidimensional array of data, the defined header will be
# repeated on every page.
# +header+ must also be set to +true+ for this to function.
# +column_widths+::
# Sets widths for individual columns. Manually setting widths can give
# better results than letting Prawn guess at them, as Prawn's algorithm
Expand Down Expand Up @@ -142,10 +146,15 @@ def initialize(data, document, options={}, &block)
@pdf = document
@cells = make_cells(data, table_opts.delete(:cell_style) || {})
@header = false
@headers = nil
table_opts.each do |k, v|
send("#{k}=", v) if respond_to?("#{k}=")
end

unless @headers.nil?
@headers = make_cells(@headers, table_opts.delete(:cell_style) || {})
end

if block
block.arity < 1 ? instance_eval(&block) : block[self]
end
Expand Down Expand Up @@ -229,6 +238,12 @@ def height
#
attr_writer :header

# If set to a valid multidimensional array of data the data specified here
# will be used on each page as the header. +header+ must be set to +true+
# for this to function.
#
attr_accessor :headers

# Accepts an Array of alternating row colors to stripe the table.
#
attr_writer :row_colors
Expand Down Expand Up @@ -506,7 +521,11 @@ def fits_on_page?(needed_height, use_reference_bounds = false)
def header_rows
header_rows = Cells.new
number_of_header_rows.times do |r|
row(r).each { |cell| header_rows[cell.row, cell.column] = cell.dup }
if @headers.nil?
row(r).each { |cell| header_rows[cell.row, cell.column] = cell.dup }
else
headers.row(r).each { |cell| header_rows[cell.row, cell.column] = cell.dup }
end
end
header_rows
end
Expand Down Expand Up @@ -656,14 +675,18 @@ def natural_width
def set_column_widths
column_widths.each_with_index do |w, col_num|
column(col_num).width = w
headers.column(col_num).width = w if !headers.nil? && !headers.column(col_num).nil?
end
end

# Assigns the row heights to each cell. This ensures that every cell in a
# row is the same height.
#
def set_row_heights
row_heights.each_with_index { |h, row_num| row(row_num).height = h }
row_heights.each_with_index do |h, row_num|
row(row_num).height = h
headers.row(row_num).height = h if !headers.nil? && !headers.row(row_num).nil?
end
end

# Set each cell's position based on the widths and heights of cells
Expand All @@ -673,13 +696,19 @@ def position_cells
# Calculate x- and y-positions as running sums of widths / heights.
x_positions = column_widths.inject([0]) { |ary, x|
ary << (ary.last + x); ary }[0..-2]
x_positions.each_with_index { |x, i| column(i).x = x }
x_positions.each_with_index do |x, i|
column(i).x = x
headers.column(i).x = x unless headers.nil? || headers.column(i).nil?
end

# y-positions assume an infinitely long canvas starting at zero -- this
# is corrected for in Table#draw, and page breaks are properly inserted.
y_positions = row_heights.inject([0]) { |ary, y|
ary << (ary.last - y); ary}[0..-2]
y_positions.each_with_index { |y, i| row(i).y = y }
y_positions.each_with_index do |y, i|
row(i).y = y
headers.row(i).y = y unless headers.nil? || headers.row(i).nil?
end
end

# Sets up a bounding box to position the table according to the specified
Expand Down
1 change: 1 addition & 0 deletions prawn-table.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency('prawn-dev', '~> 0.3.0')
spec.add_development_dependency('prawn-manual_builder', ">= 0.2.0")
spec.add_development_dependency('pdf-reader', '~>1.2')
spec.add_development_dependency('matrix')

spec.homepage = "https://github.com/prawnpdf/prawn-table"
spec.description = <<END_DESC
Expand Down
12 changes: 12 additions & 0 deletions spec/table_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,18 @@
data.flatten[-2..-1]
end

it "should repeat defined headers across pages" do
data = [["foo","bar"]] * 30
first_page_headers = [["bazbar", "foobaz"]]
repeating_headers = [["baz","foobar"]]
@pdf = Prawn::Document.new
@pdf.table(first_page_headers + data, :header => true, :headers => repeating_headers)
output = PDF::Inspector::Text.analyze(@pdf.render)
expect(@pdf.page_count).to eq 2
expect(output.strings).to eq first_page_headers.flatten + data.flatten[0..-3] + repeating_headers.flatten +
data.flatten[-2..-1]
end

it "draws headers at the correct position" do
data = [["header"]] + [["foo"]] * 40

Expand Down