An Oracle blog about BI Publisher

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 ...

Join the discussion

Comments ( 17 )
  • Mike Parr Monday, July 14, 2008
    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.
  • Mike Parr Tuesday, July 15, 2008
    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.
  • Jon Bartlett Wednesday, July 30, 2008
    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:
    mail 'at' jaybe 'dot' net
  • Jon Bartlett Thursday, August 21, 2008
    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.
  • Tim Friday, August 22, 2008
    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.
  • Jon Wednesday, September 10, 2008
    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?
  • Rajesh Tuesday, October 21, 2008
    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.
  • Fred Wednesday, February 11, 2009
    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?
  • Ryan Saturday, June 27, 2009
    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.
  • niccisweden Tuesday, August 18, 2009
    informative for me, like that
    injectable filler
  • Dany Thursday, April 1, 2010
    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?
  • Alternative for during filling out space Friday, July 30, 2010
    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?
  • Usabloogs Saturday, September 25, 2010
    so informative, thanks to tell us.
  • Bidhan Tuesday, August 23, 2011


    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.



  • Giri Friday, September 9, 2011


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

  • Keerthi Saturday, November 1, 2014


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



  • guest Monday, February 9, 2015

    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?

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.