First8 staat voor vakmanschap. Al onze collega’s zijn een groot aanhanger van Open Source en in het bijzonder het Java-platform. Wij zijn gespecialiseerd in het pragmatisch ontwikkelen van bedrijfskritische Java toepassingen waarbij integratie van systemen, hoge eisen aan beveiliging en veel transacties een belangrijke rol spelen. Op deze pagina vind je onze blogs.

Paginating using Pojo BIRT Runtime

In a previous blog post I discussed how to use the Pojo BIRT Runtime to render an HTML report.

If you are embedding BIRT reports into a website and generating them on the fly you will probably want pagination as well. As discussed earlier, the BIRT Viewer can take care of this for you but if you need tighter control you can do it using the Pojo BIRT Runtime.

To have pagination I need to split the RunAndRenderTask we used before into a separate RunTask and a RenderTask. The RunTask gathers the data and the RenderTask renders it in the specified format.
First I will generate all the data for all pages and then render only the specific page. This allows me to know how many pages there are, so I can show a paginator and embed it (in for example a JSF Data table). Doing so is left for an upcoming blog post though ;). I can also use this to allow a user to download the full report in a different format after previewing it as HTML on screen.

Since the RunTask will gather the data which will later be consumed by the RenderTask, I need some place to store the data:
it is a waste of resources to rerun the RunTask for every page.
I could store the data in memory (see the reference below for an example of MemoryArchive), but since I expect multiple users to run reports concurrently and read through multiple pages, I expect it will take up too much memory. So, I’ll resort to temporary files which I’ll need to clean up later, though doing is is left out in this post.

Since I want to hide the actual implementation from the end user, I’ll use a ReportDataHandle class which represents the output of a RunTask:

We can now create the handle using something like this:

Then, we can use that handle to render a page. After a first time render, we know how many pages there are in total. To do that, we leave the page number empty (null). This will cause the render task to render the first page but also calculate how many pages there are. For successive pages, we simply give a page number.

If you want to use this in a webpage, you can for example make the ReportDataHandle serializable and store it in the HttpSession. I would advice to create some sort of cache where you use the report design and its parameters as a key and the handle as a value. This way, you can control the number of handles and create eviction strategies for them, or even share or distribute them on a cluster.

Some references: