Anatomy of a Template II - Headers and Filler


Continuing on from yesterday, today we'll add in the repeating header and a filler for the invoice lines. Imagine you have pre-printed stationary, yesterday we tacled how to get X number of lines on each page, now assume that on the last page of the document you need a summary at the bottom of the page. If that last page only has 5 rows of data and we were printing 20 rows on the previous pages then once the 5 rows are rendered the summary will then render directly under the five rows i.e. not at the bottom of the last page ... still with me? With 5.6.2 we introduced the concept of a last page only command; we could use that here but I want to continue with the idea of filler rows and we'll tackle the last page only option later.

Taking a batch invoices as our example we can add the header and the filler rows.

Reset your Head

For the header we want to have say an invoice header with page numbering, etc. As we hit a new invoice we want the header information to change and the page numbering to reset. To do this we can use the '@section' option for the for-each command. We create the header layout in the MSWord header.


Notice we can not put formfields in to the MSWord header section so we either need to type in the commands or use a header template and reference it.
The only extra fields added are:a
FE G_INVOICE - this starts the looping over each invoice using the @section to reset the header information as each new invoice is reached.
EFE - this closes out the loop above

Running this template (Inv_Header.rtf) gives us two invoices with a repeating header on each page with page numbering per invoice.

Spaced Out

Now lets add the logic for the filler rows, you can see the new fields and empty table just below the lines table in the Inv_Header_Spacer.rtf template. There are two new fields
Filling Out Space - this contains the logic to check if the number of rows rendered above equals the lines per page variable. If not then insert the table row until it does.
<?if:not(count($invLines) mod $lpp=0) and ($start+$lpp>count($invLines))?>
     <?if:position()<$lpp - (count($invLines) mod $lpp)?>

then we have the blank table row, then 
End Filling - this just closes out the for-each and the if statements. 

I just added a static string 'End of padded lines' to check that we are actually padding. Complete samples available here.

Next, page totals and last page only ...


Hi Tim - just spotted a problem with this code. If the number of lines is less than the lines per page, then the filler will add the same number of lines as there on the invoice. Unfortunately I don't know XML well enough to suggest any alternatives. Sorry! Mike

Posted by Mike Parr on July 14, 2008 at 02:26 AM MDT #

Hi Tim After several hours thinking and experimentation, I just worked out what the fundamental flaw is here - the filler process will only work if the number of invoices lines to be printed is > half the lines per page. This is because the filling loop is based on looping through the invoice lines. I will keep thinking of possible solutions to this - needs some means of constructing a loop not based on data elements.

Posted by Mike Parr on July 14, 2008 at 06:52 PM MDT #

Mike, I hit this issue and have a workaround using a recursive XSL template to display the filler lines. Let us know if you need further info or check out the following website which is where I got the idea: Cheers, Jon. mail 'at' jaybe 'dot' net

Posted by Jon Bartlett on July 30, 2008 at 03:16 PM MDT #

Hi Tim, What happens when the Invoice Description length is greater than one row width? 99% of the eBS Invoices I have written all require that the description is able to wrap. This solution does not cater for this as it throws out the number of rows per page calculation. Think that this needs to be pointed out before developers spend a lot of time implementing this solution only to find it doesn't work in the real world. Been there, done that. Comments? Cheers, Jon.

Posted by Jon Bartlett on August 21, 2008 at 05:38 PM MDT #

@Jon Fair point - but why not just reduce the number of rows? I know you can not always predict the rows that will wrap. When this article was written we did not have our last page only support - this will remove the need for row counting. I'll try and write that up. Tim

Posted by Tim on August 22, 2008 at 02:43 AM MDT #

@Tim I tried reducing the number of rows per page but the client I am working for had data that varied from very small descriptions, to very long descriptions. You just cannot predict what is going to come out. When the number of rows per page are reduced, you often end up with a lot of white space at the end of the 'data' section. I don't think that this is the solution. With regards to last page only functionality, I presume you are refering the ability to put the total section on the last page. This works great and is what I ended up doing on my Invoice. However, the reason for wanting the filler rows was not so that the totals section would align. It was so that the transaction section 'box' would be rendered to the bottom of the page rather than simply around the transaction rows. Without using filler rows, I could not find any other way of doing this. A lot of clients want to mirror their existing reports which are themselves based upon reports produced from the days of pre-printed stationary. Consequently, you end up needing to render static boxes around sections of the report. This is my biggest problem with BIP. I can only find a way to render these boxes around the data. This results in the boxes being dynamic as they are only as big as the data reported. Sounds trivial but try telling the client that it can't be done! Any ideas? Cheers, Jon.

Posted by Jon on September 09, 2008 at 06:15 PM MDT #

Hi Tim, I have a requirement where on the last page I need to get my table Vertical lines of the table flow to the bottom of the page if there is less amount of lines data. I tried your filler logic and it doesnt flow to the bottom. Can you please help me out. I can send you my template and xml file and desired output. Awaiting your reply. Thanks.

Posted by Rajesh on October 21, 2008 at 02:53 AM MDT #

Hi, I am using the template builder in MS word to view the output of your sample above. The PDF output does not display the header from the RTF template. Can you help me with this?

Posted by Fred on February 10, 2009 at 07:23 PM MST #

@Jon In order to have fixed size boxes on a page, you must use PDF templates. Despite how great everyone says the RTF templates are, they cannot reproduce the pre-printed stationary effect. You must either use PDF templates, or purchase a more advanced thrid-party product. Ryan

Posted by Ryan on June 27, 2009 at 02:29 PM MDT #

informative for me, like that injectable filler

Posted by niccisweden on August 18, 2009 at 01:26 AM MDT #

There is an extra space between the header and the start of the lines if you compare the first page and the second page of the same invoice. How to make the space to be exactly the same between P1 and P2? Rgds Dany

Posted by Dany on April 01, 2010 at 12:03 AM MDT #

Hi Tim Excellent article it solved a lot of my problems,but i still need a small help. The filling space row is invoked based on a for loop of $invlines. my problem is i need 5 rows per page and there may be chances that i will have a single row of line data,with current logic which depends on count of line data element in XML,the filler logic will fail. Any idea's on probable workarounds for this? Thanks Rohit

Posted by Alternative for during filling out space on July 30, 2010 at 02:27 AM MDT #

so informative, thanks to tell us.

Posted by Usabloogs on September 25, 2010 at 02:01 PM MDT #


I am new to BI Publisher. I am working on the pre-printed check. I have taken the Oracle seeded template for check printing.After making some adjustment, it appears that the printing is working fine for the 1st check. Once I have multiple checks to print, I have realized that the line information such as "Two Hundred dollars" goes upward a little bit starting from the 2nd page.

Please suggest me how I can fix the alignment problem. Basically, in oracle report, I can put a dummy frame, which prints for all the pages, between the lines to keep the alignment same all the time. The same thing I would like to acheive the same functionality.



Posted by Bidhan on August 23, 2011 at 03:27 PM MDT #

I Tried @section in my Template and its creating a blank page after every Order.

Posted by Giri on September 09, 2011 at 11:08 AM MDT #


I also tried @section and its creating a blank page after each order. Is there any solution to avoid this.


Posted by Keerthi on November 01, 2014 at 12:21 AM MDT #

Hi,i am having a similar problem,report throws to a new page even though there are no more data lines.



did anyone get a solution to this?

Posted by guest on February 09, 2015 at 11:09 AM MST #

Post a Comment:
  • HTML Syntax: NOT allowed

Follow bipublisher on Twitter Find Us on Facebook BI Publisher Youtube ChannelDiscussion Forum

Join our BI Publisher community to get the most and keep updated with the latest news, How-to, Solutions! Share your feedback and let us hear your voice @bipublisher on Twitter, on our official Facebook page, and Youtube!


« March 2015