« Back to Development

How to Use LiferayServiceBuilderClasses in JasperReports and IReport


As most of you will know, the standard way you retrieve your Data for JasperReports is to use a SQL Query to get the relevant data. In situations where Big loads of data are pulled out of the Database, in combination with subreports which do also have their own queries, this can result in 30+ seconds for ReportGeneration.

So wouldn't it be perfect, if we could utilize Liferay's Service and Model Classes for Report generation, which already use EHCahce?


the JRBeanCollectionDataSource

This class is Porvided by JasperReport engine has the purpose to "wrap collections or arrays of JavaBean objects".

How do we use this neat feature?

Let's start with creating a new Report.

Ok. So far so good. Nothing fancy here.

Now we need to tell IReport what additional jars it will need. So we choose:

Extras -> Options -> IReport -> Classpath

we click on Add JAR and add:



If you want to use Classes generated by ServiceBuilder from your own Portlet, you will also have to add the service-lib.jar of your Project.


Let's say, we want to Display some Users and their Roles within the portal in this Report

In Ireport in your new Report click on the SQLQuery Button (the one left to the "+" symbol):

In the window now opening, we swith to the JavaBean Datasource Tab and enter as Class name:


do NOT use

com.liferay.portal.model.User as it will not work as expected.

Now hit the Read Attributes button, choose which properties you need in your Report and mark them. Now hit the Add selected field(s) button and the selected Fields will show up in the List below.

Hit OK and we are ready to proceed.

Now add the output in the report:

Now we well add a SUBREPORT, which will output the Roles of that User within the current Group.

So, add a new Subreport via the Palette, and set Datasource to EmptyDataSource.

Now select the Subreport in the Master Report and add as DataSourceExpression the following:

new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource    (com.liferay.portal.service.RoleLocalServiceUtil.getUserRoles($F{userId}))

And as ConnectionType you set:

Use a Datasource expression.

Add some output to the Subreport.


Compile your two reports.

Now we need to add this stuff to our Controller. As I don't know which way of writing your portlets you prefer, I will just provide a sample in my favorite way, and that's Spring MVC.

In your ResourceRequest Method your code should look like this:

    public void handlePDF(ResourceRequest resourceRequest,
            ResourceResponse resourceResponse) throws SystemException {
        ThemeDisplay themeDisplay = (ThemeDisplay) resourceRequest
        ServletResponse servletResponse = PortalUtil
        try {
            List<User> users = UserLocalServiceUtil.getGroupUsers(themeDisplay
            ServletOutputStream sops = servletResponse.getOutputStream();
            String reportsDir = PropsUtil.get("reports.dir");
            String fileName = reportsDir + "LiferayObjectsAndServices.jasper";
            JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(
            Locale locale = themeDisplay.getLocale();
            HashMap<String, Object> parameters = new HashMap<String, Object>();
            parameters.put("SUBREPORT_DIR", reportsDir);
            parameters.put("REPORT_LOCALE", locale);
            JasperReport jasperReport = (JasperReport) JRLoader
                    .loadObject(new File(fileName));
            JasperPrint jasperPrint = JasperFillManager.fillReport(
                    jasperReport, parameters, dataSource);
            JasperExportManager.exportReportToPdfStream(jasperPrint, sops);

        } catch (Exception e) {



Well, this is it.

If you put your newly developed portlet on a page, and everything is correctly done, you will get a PDF like this:

The whole Project can be found at:



0 Attachments
Average (0 Votes)
The average rating is 0.0 stars out of 5.