Displaying page numbers

1,405 views
Skip to first unread message

Sriram Varahan

unread,
May 26, 2009, 5:39:58 AM5/26/09
to prawn...@googlegroups.com
Hello,

       I am generating a 5 page pdf from my application using prawn. I want to display the total pages at the bottom of every page.

For e.g. Page 1 of 5 and so on.

The command I found for generating page numbers displays only the present page.
#{pdf.page_count}

i.e. Page 1

Is there any way of doing this?

Thanks.

Sriram.

James Healy

unread,
May 26, 2009, 8:29:06 AM5/26/09
to prawn...@googlegroups.com

Unfortunately at this stage it's not possible to achieve this. Prawn
renders each page as you finish it so it's impossible to go back and add
page number once you've owrked out how many pages you have.

There's been several proposals to fix this, but not much code yet.

-- James Healy <jimmy-at-deefa-dot-com> Tue, 26 May 2009 22:24:48 +1000

Bryce Mecum

unread,
May 26, 2009, 8:59:17 AM5/26/09
to prawn...@googlegroups.com
I am getting total page count based upon the content I'm throwing at
Prawn. Fortunately, I know how many points my content takes up and I
know how much content I have. I would think you might be able to glean
a not-so-accurate-but-maybe-accurate-enough total page count by
looking at the data you want to put down by using font metrics. I hope
this might be of some use.

Gregory Brown

unread,
May 26, 2009, 9:18:32 AM5/26/09
to prawn...@googlegroups.com

It's bad for performance, but this can be done through a double render.

-greg

Benjamín Cárdenas Salamandra

unread,
May 26, 2009, 9:45:00 PM5/26/09
to prawn...@googlegroups.com
Hello,

i do this:

num_pag=0
pdf.footer [pdf.margin_box.left, pdf.margin_box.bottom + 25] do
pdf.font "Helvetica" do
pdf.stroke_horizontal_rule
pdf.move_down 5
pdf.text "PAGE FOOTER", :style => :bold, :size => 10
pdf.move_up 12
num_pag += 1
pdf.text @tip_det.other_text+" - "+p": Page "+num_pag.to_s+" of
"+pdf.page_count.to_s,
:align => :center, :size => 8, :align => :right
end
end

I expect this work for you,

Benjamín

Sriram Varahan escribió:

steveh

unread,
May 28, 2009, 8:43:15 PM5/28/09
to Prawn
I tried that once, but I always got page 1 of 1 on the first page ,
then page 2 of 2 on the second page...

My horrible hack of a solution was to do this in the page footer:

@pdf.footer [@pdf.margin_box.left, @pdf.margin_box.bottom + 25] do
@pdf.text "Page #{@pdf.page_count} of PPPPP"
end

and then search for PPPPP in the generated pdf document and replace it
with the total number of pages like this:

def render_to_file(file)
total_pages = @pdf.page_count
content = @pdf.render
search_string = "PPPPP".unpack("H*").first
sub_string = total_pages.to_s.unpack("H*").first
content.gsub!(search_string, sub_string)
File.open(file, "wb") { |f| f << content }
end

Here are few things to watch out for
- if you try to center or right align the page number it will be off a
little because the alignment will be done
with the "PPPPP" string instead of the number of pages (which is
likely narrower).
- "PPPPP" should never occur in your document or you will get the page
number instead.
- If you try a shorter string than "PPPPP" make sure that don't use
any characters that have kerning. Kerned
characters are not contiguous in the pdf file.

Also, be aware that prawn 0.41 will print your footer in whatever font/
style/size that is in effect when the page break occurs.

Gregory Brown

unread,
May 28, 2009, 8:46:57 PM5/28/09
to prawn...@googlegroups.com
On Thu, May 28, 2009 at 8:43 PM, steveh <steve....@gmail.com> wrote:

> Also, be aware that prawn 0.41 will print your footer in whatever font/
> style/size that is in effect when the page break occurs.

> --~--~---------~--~----~------------~-------~--~----~

Yep, you definitely want to use transactional font blocks with
explicit settings in your header / footer.
Our header and footer support sucks, I'm sorry. Leethal implemented
PDF::Wrapper's support, which is much better, but never prepared a
patch. If someone feels up for it, search the archives and submit a
patch.

-greg

Henrik N

unread,
Oct 9, 2009, 4:36:14 AM10/9/09
to steveh, prawn...@googlegroups.com

On May 29, 2:43 am, steveh <steve.hurl...@gmail.com> wrote:
> I tried that once, but I always got page 1 of 1 on the first page ,
> then page 2 of 2 on the second page...
>
> My horrible hack of a solution
> (...)

Thanks for that. How I ended up using it: http://gist.github.com/205863

On May 29, 2:46 am, Gregory Brown <gregory.t.br...@gmail.com> wrote:
> Our header and footer support sucks, I'm sorry. Leethal implemented
> PDF::Wrapper's support, which is much better, but never prepared a
> patch. If someone feels up for it, search the archives and submit a
> patch.
>

Couldn't find this. Also dug around a little in edge Prawn but didn't
see anything I could easily use for a total page count, so I'll settle
for this workaround for now.

Sorry for the "To: Steve, CC: list" thing btw. Google Groups is only
showing "Reply to author" links in this thread. Anyone know what's up
with that?

Gregory Brown

unread,
Oct 9, 2009, 8:10:50 AM10/9/09
to prawn...@googlegroups.com, steveh
On Fri, Oct 9, 2009 at 4:36 AM, Henrik N <hen...@nyh.se> wrote:
>
>
> On May 29, 2:43 am, steveh <steve.hurl...@gmail.com> wrote:
>> I tried that once, but I always got page 1 of 1 on the first page ,
>> then page 2 of 2 on the second page...
>>
>> My horrible hack of a solution
>> (...)
>
> Thanks for that. How I ended up using it: http://gist.github.com/205863
>
> On May 29, 2:46 am, Gregory Brown <gregory.t.br...@gmail.com> wrote:
>> Our header and footer support sucks, I'm sorry.   Leethal implemented
>> PDF::Wrapper's support, which is much better, but never prepared a
>> patch.   If someone feels up for it, search the archives and submit a
>> patch.
>>
>
> Couldn't find this. Also dug around a little in edge Prawn but didn't
> see anything I could easily use for a total page count, so I'll settle
> for this workaround for now.

You need to implement go_to_page, which is easy.

Then you do something like this:

page_count.times do |i|
go_to_page(i+1)
text "Page #{i + 1} of #{page_count}", :at => [x,y]
end

An easy helper for this will be in Prawn 0.6, but seeing as this is
just a few lines of code to implement, I'm sure someone here can fill
in the details for you.

Gregory Brown

unread,
Oct 9, 2009, 8:12:08 AM10/9/09
to prawn...@googlegroups.com
On Fri, Oct 9, 2009 at 8:10 AM, Gregory Brown <gregory...@gmail.com> wrote:
=

> You need to implement go_to_page, which is easy.
>
> Then you do something like this:
>
> page_count.times do |i|
>   go_to_page(i+1)
>   text "Page #{i + 1} of #{page_count}", :at => [x,y]
> end
>
> An easy helper for this will be in Prawn 0.6, but seeing as this is
> just a few lines of code to implement, I'm sure someone here can fill
> in the details for you.

BTW, for those interested, don't attempt this on the 0.5 codebase,
restructuring in 0.6 makes it much easier.

jouni

unread,
Oct 9, 2009, 8:41:17 AM10/9/09
to Prawn
I implemented this on 0.5 codebase as an extension so that you can
just "postpone" certain block of code to be executed later thus having
the page_count or other information available by then. I'm assuming
this go_to_page would need to be executed manually as second phase
instead of logically on the code where it would anyhow be rendered.

I would love to share the code, but I'm not certain about the
corporate policy regarding this. Technically my solution just does
second pass on @root.data[:Pages].data[:Kids] and restores the page,
bounding box and cursor before running the postponed block.
Compression has to be done during that phase instead of on the fly. Of
course pdf specs would allow a bit different solution too, but didn't
want to start working on the ref object versioning.
Reply all
Reply to author
Forward
0 new messages