2 column report layout

891 views
Skip to first unread message

Dave Kruse

unread,
Mar 3, 2010, 6:06:55 PM3/3/10
to Prawn
I am trying to achieve a fairly simple layout, but have been unable to
do so with prawn/prawnto. After a few days of fighting with it, I
suspect I am using the wrong tool for the job.

I want to generate a report where each row has two columns. The
columns contain various lines of text, and their height will vary.

I now realize this does not work due to the current design of a
bounding box, but it shows what I am attempting:

20.times do

#row
pdf.bounding_box [0,pdf.cursor], :width => 500 do

# draw left column box
pdf.bounding_box pdf.bounds.top_left, :width => 200 do
2.times do
pdf.text "Attribute"
pdf.text "Value"
pdf.move_down 12
end
pdf.stroke_bounds
end

# draw right column box
pdf.bounding_box [pdf.bounds.left + 200, pdf.bounds.top], :width
=> 300 do
4.times do
pdf.text "Attribute"
pdf.text "Value"
pdf.move_down 12
end
pdf.stroke_bounds
end

end # row

end # loop

Lessons learned: When a bounding box flows onto a new page, it does so
at the bottom of the new page. And if a page break occurs in one
column the cursor doesn't go back to the previous page to draw the
second column where it would ideally appear. This example renders a
182 page document for 2 pages of content.

Is there a way to make this layout flow with prawn?

Thanks for your help!

Gregory Brown

unread,
Mar 3, 2010, 6:27:36 PM3/3/10
to Prawn
I think you probably thought that bounding box was a much more high
level tool than what it actually is, but the good news is, we do have
the tools to do the job you want.

On Mar 3, 6:06 pm, Dave Kruse <kruse.enterpri...@gmail.com> wrote:

> Lessons learned: When a bounding box flows onto a new page, it does so
> at the bottom of the new page.

That's not correct. It resumes at wherever you anchored it on the
previous page. Whatever point you pass to bounding_box() is the point
it resumes at.

>And if a page break occurs in one
> column the cursor doesn't go back to the previous page to draw the
> second column where it would ideally appear. This example renders a
> 182 page document for 2 pages of content.

How would you expect this to work? If you expect the pointer to move
into the second column and *then* to the next page, use column_box().
If you expect to render a column across as many pages as it takes, and
then return back to the page that column started on to form a second
one, use something like this:

starting_page = page_number
span(...) {} # column 1
go_to_page(starting_page)
span() {} # column 2

Spans are drawn from the current cursor position but return to the top
of the page when you overflow them.

I understand the frustration you have, because there is too much early
documentation (even in our API docs) about bounding_box() as if it's a
general layout tool. What we really use BoundingBox for is
translating coordinate spaces, to build the underpinnings (including
things like margins). Most user code that relies on bounding_box is
probably doing something wrong, or probably should have a higher level
analogous feature in Prawn if it doesn't already.

Dave Kruse

unread,
Mar 4, 2010, 3:03:57 PM3/4/10
to Prawn
Ok, that makes sense about bounding boxes. I am trying to achieve a
layout like that of a 2 column table where rows spill over multiple
pages.

Using spans, I have a similar issue. A span which spills onto a new
page seems to expand to fill the entire second page. What is the
quality of span that I am missing?

-----------------------

20.times do |i|

starting_y = pdf.y
starting_page = pdf.page_number

# draw left column box

pdf.span 200, :position => :left do
2.times do
pdf.text "Left #{i.to_s}"
pdf.text "Page #{starting_page}"
pdf.move_down 12
end
end

# align with left column
pdf.go_to_page starting_page
pdf.y = starting_y

# draw right column box

pdf.span 300, :position => :right do
4.times do
pdf.text "Right #{i.to_s}"
pdf.text "Page #{starting_page}"


pdf.move_down 12
end
pdf.stroke_bounds
end

end # loop

--------------------------

Thanks,
Dave

zerothabhishek

unread,
Mar 18, 2010, 1:08:58 AM3/18/10
to Prawn
I too am facing similar problems, and I guess the only way out for a 2-
column layout is to use just two spans. For positioning the content in
the columns, we may have to use look-ahead height calculations.

eg, assuming the first column contains headings, and the second one
contains the corresponding content

---------------------------
# column 1


pdf.span 200, :position => :left do

pdf.text "heading 1"

# get the height of the corresponding content
text1 = content_1 # same as that to be rendered in column2
box1 = Prawn::Text::Box.new(text1, {:document => pdf, :width => 400})
box1.render(:dry_run => true)
h = box1.height
pdf.move_down h # leave as much space

pdf.text "heading 2"
.
. # same for content2

end

# column 2
pdf.span 400, :position => :right do

# content 1
pdf.text content_1

# content 2
.
.
end
---------------------------


I don't find this method very good, so please let me know if there
could be a better one.


On Mar 5, 1:03 am, Dave Kruse <kruse.enterpri...@gmail.com> wrote:
> Ok, that makes sense about bounding boxes.  I am trying to achieve alayoutlike that of a 2 column table where rows spill over multiple

Reply all
Reply to author
Forward
0 new messages