Saturday, October 20, 2007

BIRT: Parameterized Page Break Interval

A useful trick to know with BIRT is how to control the pagination for report output. It would be nice if you could present the user with a parameter to control the number of rows displayed per page and let them decide. While there is the page_break_interval property in a table, it is not easily exposable. Thanks to Jason Weathersbys of BirtWorlds help, I have a simply answer on how to create a parameter and assign the page_break_interval the value I need.

What I did was create a user parameter called NewParameter. I know, clever name, but this was just at test scenario. I have a table called counTable that will output the results of a dataset. Then, I used the following script in the tables onPrepare event handler (although this could be done in the reports Initialize event handler also):

tableContext = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("countTable");

tableContext.setPageBreakInterval(params["NewParameter"]);


That’s it. Now, when the report is displayed, a parameter will prompt the user to enter the number of rows to break each page on. This is useful when used with the Progressive Viewing feature to allow the user to really control pagination when embedding BIRT into an application. The completed report is below in XML.

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.14" id="1">
<property name="author">John Ward</property>
<property name="createdBy">Eclipse BIRT Designer Version 2.2.0.v20070620 Build &lt;2.2.0.v20070626-1003></property>
<property name="units">in</property>
<text-property name="title">Page Break Interval</text-property>
<property name="comments">Copyright (c) 2007 &lt;&lt;Your Company Name here>></property>
<html-property name="description">A test report that will generate a data set with 6000 numbers, then assign the tables page break interval using a parameter.</html-property>
<text-property name="displayName">Blank Report</text-property>
<property name="iconFile">/templates/blank_report.gif</property>
<parameters>
<scalar-parameter name="NewParameter" id="6">
<property name="valueType">static</property>
<property name="dataType">string</property>
<text-property name="promptText">Page Break Interval</text-property>
<property name="controlType">text-box</property>
<property name="defaultValue">5</property>
<structure name="format">
<property name="category">Unformatted</property>
</structure>
</scalar-parameter>
</parameters>
<data-sources>
<script-data-source name="Data Source" id="23"/>
</data-sources>
<data-sets>
<script-data-set name="Data Set" id="24">
<list-property name="resultSetHints">
<structure>
<property name="position">0</property>
<property name="name">count</property>
<property name="dataType">any</property>
</structure>
</list-property>
<list-property name="columnHints">
<structure>
<property name="columnName">count</property>
</structure>
</list-property>
<structure name="cachedMetaData">
<list-property name="resultSet">
<structure>
<property name="position">1</property>
<property name="name">count</property>
<property name="dataType">any</property>
</structure>
</list-property>
</structure>
<property name="dataSource">Data Source</property>
<method name="open"><![CDATA[x = 0;]]></method>
<method name="fetch"><![CDATA[if (x < 6000)
{
x++;
row["count"] = x;

for (y = 0; y < 6000; y++);

return true;
}

return false;]]></method>
</script-data-set>
</data-sets>
<page-setup>
<simple-master-page name="Simple MasterPage" id="2">
<page-footer>
<text id="3">
<property name="contentType">html</property>
<text-property name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-property>
</text>
</page-footer>
</simple-master-page>
</page-setup>
<body>
<table name="countTable" id="27">
<property name="width">100%</property>
<property name="dataSet">Data Set</property>
<list-property name="boundDataColumns">
<structure>
<property name="name">count</property>
<expression name="expression">dataSetRow["count"]</expression>
<property name="dataType">any</property>
</structure>
</list-property>
<method name="onPrepare"><![CDATA[tableContext = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("countTable");

tableContext.setPageBreakInterval(params["NewParameter"]);]]></method>
<column id="36"/>
<header>
<row id="28">
<cell id="29">
<label id="30">
<text-property name="text">count</text-property>
</label>
</cell>
</row>
</header>
<detail>
<row id="31">
<cell id="32">
<data id="33">
<property name="resultSetColumn">count</property>
</data>
</cell>
</row>
</detail>
<footer>
<row id="34">
<cell id="35"/>
</row>
</footer>
</table>
</body>
</report>

7 comments:

Anonymous said...

Hi, I am not able to get the pagination using your rptdesign code. Please advise. Thanks in advance.

Jagadeesh.

John Ward said...

How are you viewing the report? What version of BIRT?

shaker Reddy said...

yeh.. setPageBreakIntervel(as u given above ) is not working in birt 3.0,can u please tell me how should i use in birt 3.0

John Ward said...

Sure enough, something changed in the latest versions of BIRT (2.3 and 2.3.1). If you move the script to the reports initialize method, that will fix the issue and this will work. For some reason, the execution order for the onPrepare event changed.

Shadow said...

not working on BIRT 2.3.2...I'd need to have one row per page, but can't... maybe it's better if I explain...I have to send 5 identical mails to 5 different people so, I'd need a 5 pages report with only one person on it as address:

PAGE 1 ------
person 1
mail
-------------
PAGE 2 ------
person 2
mail
-------------

and so on...any idea on how about I can do it?

sTupIdCuPiD said...

Hello, I wonder can we do the script of page break by hardcode?
example:
If table detail's is 39 row, then force pagebreak~?

as when I test this example, it will page break when user enter number of count.

So, how if when the engine detect there is 39 row in a page(regardless of the number of table) where the 39 rows including table header, details, footer etc...
then force page break~? how to do this~?

sTupIdCuPiD said...

Forgot to mention... The BIRT engine I use is version 2.5.1. ^_^ Hope to hear from you soon...
Have a nice day~

regards,
Lydia