I have been digging around for days and havent seen anything on the
problem im encountering, so was wondering if someone else had
encountered it.
I am trying to place a page header on multiple pages using the
all_pages extension in ruport
However I cant seem to get anything to respect the top_margin.
I am using the example directly from the ruportbook (ruportbook.com/
printable_documents.html) under the section for generating page
headers. Below is the code, if someone could give me a push in the
right direction that would be great.
The error I get with the below code is being told that top_margin is
not a valid method.
class ReportPDF < Ruport::Formatter::PDF
renders :pdf, :for => [ MemberTableController,
MemberPrintViewController]
build :member_report do
pdf_writer.top_margin = 30
build_member_report_header
> I am trying to place a page header on multiple pages using the > all_pages extension in ruport
I've never heard of all_pages before, it seems you're using a gem called pdf-helpers but we don't even have the source on the GitHub account! I will have a look at that and get it uploaded if it looks useful.
> However I cant seem to get anything to respect the top_margin.
> I am using the example directly from the ruportbook (ruportbook.com/ > printable_documents.html) under the section for generating page > headers. Below is the code, if someone could give me a push in the > right direction that would be great.
> The error I get with the below code is being told that top_margin is > not a valid method.
A quick search of the API docs shows neither PDF::Writer or the Ruport PDF formatter implement a top_margin method so I guess the book is out of date. You can use PDF::Writer's own margins_pt method or if I don't see why move_down wouldn't work.
I only came across pdf-helpers because it was in the book. Would never have known it otherwise
> A quick search of the API docs shows neither PDF::Writer or the Ruport PDF > formatter implement a top_margin method so I guess the book is out of date. > You can use PDF::Writer's own margins_pt method or if I don't see why > move_down wouldn't work.
I have also tried margins_pt but it does not actually have any effect on the resulting PDF. move_down also gives me a 'undefined method' error. These things point me to that im probably calling them wrong, but im not sure what...
inside PDF::simpleTable there is also a :header_gap attribute, which claims to leave header space with each new page, however even when forcing its value straight in initialize, did it ever seem to have any effect whatsoever.
>> A quick search of the API docs shows neither PDF::Writer or the Ruport PDF >> formatter implement a top_margin method so I guess the book is out of date. >> You can use PDF::Writer's own margins_pt method or if I don't see why >> move_down wouldn't work.
> I have also tried margins_pt but it does not actually have any effect > on the resulting PDF. move_down also gives me a 'undefined method' > error. These things point me to that im probably calling them wrong, > but im not sure what...
margins_pt only works before any content is written (maybe per-page, not sure).
move_down is implemented in the formatter so don't prepend pdf_writer, it's simply: def move_down(n) pdf_writer.y -= n end
> inside PDF::simpleTable there is also a :header_gap attribute, which > claims to leave header space with each new page, however even when > forcing its value straight in initialize, did it ever seem to have any > effect whatsoever.
At a guess that value is probably only ready by SimpleTable.
> margins_pt only works before any content is written (maybe per-page, not > sure).
I can understand the margins only working before being written, but im not really sure how what im doing is not happening then. Here is some more depth to maybe help. I dont know if im missing something basic in either ruby or ruport...
So when the user clicks to download a member report, the function generates the data for basic_member_report to be passed as below. (in the app controller)
Which my understanding passes control to the helper code below (because this class extends the ruport controller for that call ?)
class MemberTableController < Ruport::Controller
stage :member_report required_option :post_num, :count end
This is where my understanding is a bit murky, and a bit of guesswork is whats driving this, but control is then passed (by the stage command? cant find references to it) to the code before, listed as follows:
I figured the control passing here mainly by inference (when I add silly phrases here, they add on my pdf) but figure im in the right direction :)
the first build command (build :member_report) i dont understand, but assume its a control block piece.
so in all the above, im not really clear on when PDF::Writer.new gets called in teh control scheme, so I can figure out how to set the margins there.
Maybe im missing something else basic?
By the way, thank you very much for your quick and helpful response. I have banged my head on the wall for days digging into things trying to learn rather than come in to a email group with a 'how do I do this basic thing, because i cant be bothered to dig through the documentation' and i appreciate trying to help me understand whats going on here.
> So when the user clicks to download a member report, the function > generates the data for basic_member_report to be passed as below. (in > the app controller)
> Which my understanding passes control to the helper code below > (because this class extends the ruport controller for that call ?)
Yes render_pdf is a dynamic method on Ruport::Controller that your controller inherits.
> class MemberTableController< Ruport::Controller
> stage :member_report > required_option :post_num, :count > end
> This is where my understanding is a bit murky, and a bit of guesswork > is whats driving this, but control is then passed (by the stage > command? cant find references to it) to the code before, listed as > follows:
When you call render the controller runs each build method in the formatter with the same name as the stage in the order the stages are listed. Formatters don't have to implement all the stages though.
> end > the first build command (build :member_report) i dont understand, but > assume its a control block piece.
build :member_report creates a method called build_member_report, which is then called by the controller because of the stage of the same name. It's just a syntactical nicety. Ideally you would do: stage :header, :body, :footer, :finalize Where :header = build_member_report_header, :body = :member_report etc: build :header do ... end build :body do ... end ...
> so in all the above, im not really clear on when PDF::Writer.new gets > called in teh control scheme, so I can figure out how to set the > margins there.
The instantiation of PDF::Writer is fixed in the formatter, but it only takes size and orientation options anyway according to API doc (http://ruby-pdf.rubyforge.org/pdf-writer/doc/index.html). I looked at the margins_pt docs and it goes to some length to update the cursor position when you change them.
The draw_table command uses PDF::Writer's SimpleTable, maybe it is ignoring margins. Try temporarily replacing the table with text and see if that obeys the margins. You can also set pdf_writer.absolute_top_boundary, or set pdf_writer.y explicitly.
After a long delay of dealing with other things, I have gotten client approval on my project that it worked to their satisfaction, so I wanted to make sure that I listed how I fixed things here, so that others might find some workarounds a bit easier.
First the all_pages function from pdf-helpers-0.1.0 was a great help. It was located at http://gems.rubyreports.org/gems/ (which kind of amused me when I went back to find it and you had mentioned you hadnt heard of it andrew :) )
It does have the limitation however of doing it on Every page. Which means that you will not be able to put two different 'headers' on seperate pages of the report. For the PDF that had two reports in it, I simply forced the titles to match and moved on.
The second limitation is that the all_pages function is not directly aware of what page you are on when it is going in and generating the headers. so I used pdf_writer.start_page_numbering to manually number all the pages. An interesting quirk about start page numbering, is you can stop and start it multiple times, so your page numbering can potentially match multiple reports in the same output PDF.
There is a slight issue with draw_table (not in the ruport side, but rather in the pdf writer side) that will cause it to ignore the header gap on the first page of the table, so you must manually add a margin to that page before you begin the table, otherwise it will overlap your header.
I think that covers all the problems I ran into, and how I solved them. Hope it helps others in the future!
<andrew-li...@odaeus.co.uk> wrote: > On 23/09/10 23:08, Fafnir Crow wrote:
>> So when the user clicks to download a member report, the function >> generates the data for basic_member_report to be passed as below. (in >> the app controller)
>> Which my understanding passes control to the helper code below >> (because this class extends the ruport controller for that call ?)
> Yes render_pdf is a dynamic method on Ruport::Controller that your > controller inherits.
>> class MemberTableController< Ruport::Controller
>> stage :member_report >> required_option :post_num, :count >> end
>> This is where my understanding is a bit murky, and a bit of guesswork >> is whats driving this, but control is then passed (by the stage >> command? cant find references to it) to the code before, listed as >> follows:
> When you call render the controller runs each build method in the formatter > with the same name as the stage in the order the stages are listed. > Formatters don't have to implement all the stages though.
>> the first build command (build :member_report) i dont understand, but >> assume its a control block piece.
> build :member_report creates a method called build_member_report, which is > then called by the controller because of the stage of the same name. It's > just a syntactical nicety. > Ideally you would do: > stage :header, :body, :footer, :finalize > Where :header = build_member_report_header, :body = :member_report etc: > build :header do ... end > build :body do ... end ...
>> so in all the above, im not really clear on when PDF::Writer.new gets >> called in teh control scheme, so I can figure out how to set the >> margins there.
> The instantiation of PDF::Writer is fixed in the formatter, but it only > takes size and orientation options anyway according to API doc > (http://ruby-pdf.rubyforge.org/pdf-writer/doc/index.html). I looked at the > margins_pt docs and it goes to some length to update the cursor position > when you change them.
> The draw_table command uses PDF::Writer's SimpleTable, maybe it is ignoring > margins. Try temporarily replacing the table with text and see if that obeys > the margins. You can also set pdf_writer.absolute_top_boundary, or set > pdf_writer.y explicitly.
> Hope that helps! > Andrew
> -- > You received this message because you are subscribed to the Google Groups > "Ruby Reports" group. > To post to this group, send email to ruby-reports@googlegroups.com. > To unsubscribe from this group, send email to > ruby-reports+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/ruby-reports?hl=en.