Nov 7, 2009

Some Tips – Jasper Reports

JasperReports

JasperReports is an engine that takes an XML file and forms a report out of that file using the data source specified in the XML file. This file defines exactly what appears where in the report. Writing this file by hand is not practical. This is where iReport comes into play.

iReport

iReport is a visual tool to obtain XML files for JasperReports. It provides a WYSIWYG environment to design reports. Anything that can be placed in a report (static text, geometric shapes, images, subreports, groups, texts and images coming from a data source)can be put together in drag’n’drop fashion.

Overview of General Report Template

clip_image002

Figure 1: General Report Template

title - appears only once at the very beginning of the report. Title of the report is written in this part.

eg. “Employee Performance Report”

pageHeader - appears at the top of each page. This part may contain date and time information and/or organization name.

columnHeader - lists names of those specific fields which you want to display. eg. “Employee Name”, “Starting Hour”, “Finishing Hour”, “Hours Worked”, “Date”

detail - is the part where those fields of the entries are shown. eg. “John Doe”, “09:00”, “18:00”, “9”, “16.07.2004”

columnFooter - may display summation of any of the fields. eg. “Total Hours Worked: 150”

pageFooter - appears at the bottom of each page. This part may contain page count information like Page Numbers.

Summary - is the part where information inferred from the data in the “detail” part is displayed. For example, after listing the worked hours for each employee in “detail” part, total hours worked for each employee can be put in a pie to enable a better visual comparison between the employees.

TIPS AND TRICKS

Dynamic Element Formatting

Some reports may require that the same kind of data be displayed differently, depending on its significance.

For example, someone would want to highlight on an orders list, all the orders that have a total value greater than 100$, like in the following table:

OrderId

City

Date

Value

198760

Paris

01/15/2009

45.34

198234

Caracas

02/20/2009

178.23

198511

Buenos Aires

05/12/2009

87.45

198422

Humble

05/14/2009

76.05

How to do that, since the format of a text field can not change dynamically? The solution is within reach. We can put in the same place two text fields, one on top of the other, both displaying the same value, but having different formats: one black and the other bold and red.

In addition, we should make use of the <printWhenExpression> element that is available for every report element and switch between those two texts fields.

The red text field should be displayed only when its value is greater than 100 and the black one in the rest of the cases.

“Page i of n”

Quite often we might need to put at the beginning of our reports, values that are calculated only after the entire document is generated.

The most common situation of this kind would be the display of the total number of pages on the page footer or header of each page.

How to do that, since the report is filled page by page and the total number of pages is known only when we reach the end of our document? Well, that's easy.

JasperReports allows us to specify the exact moment at which an expression for a text field is evaluated. To display the total number of pages, we only need to put on our page footer (or any other report section) a text field that will use the PAGE_NUMBER report variable in its expression. For this field we will specify that the evaluation time should be "Report", because only when the end of the report is reached, this system variable will contain the total number of pages on our report.

The text field declaration in the XML report design file for the total number of pages in a document will look like this:

<textField evaluationTime="Report">  
<reportElement x="280" y="10" width="275" height="20"/>
<textElement textAlignment="Left">
<font fontName="Helvetica" size="14"/>
</textElement>
<textFieldExpression class="java.lang.Integer">
$V{PAGE_NUMBER}
</textFieldExpression>
</textField>



If we remove the attribute evaluationTime from the <textField> element, the text field expression will be evaluated when the section is filled (default behavior) so we will obtain the current page number on the document.



To display the current page number and the total number of pages simultaneously, like in



"Page 3 of 5" phrases, we need two text fields with the same expression (PAGE_NUMBER variable value), but with different evaluationTime attributes:



evaluationTime="Now" for the current page number (default)



evaluationTime="Report" for the total number of pages.



There are 5 possible values for the attribute evaluationTime: Now, Report, Page, Column and Group.




Hide Unhide Fields


Generally the static JasperReports are used when we are clear as to where exactly the content has to be placed. But at times we are forced to insert some dynamic content into the report. To explain with, let’s take an example of displaying a person’s address in the report. Let’s say we have to display the fields in the following format:



Rachel Ross \\ Name



#15, Hogswille \\ Address Line1



Park Lane \\ Address Line2



Texas. \\ State



For this we need to create four <textField> elements as follows:




<textField isStretchWithOverflow="true" isBlankWhenNull="true" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement x="50" y="46" width="277" height="14"
key="textField-16"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>

<textElement>
<font fontName="Arial" pdfFontName="Arial" size="9"
isPdfEmbedded ="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]>
</textFieldExpression>
</textField>
<textField isStretchWithOverflow="true" isBlankWhenNull="true" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement x="50" y="46" width="277" height="14"
key="textField-16"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>

<textElement>
<font fontName="Arial" pdfFontName="Arial" size="9"
IsPdfEmbedded ="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{addressLine1}]]>
</textFieldExpression>
</textField>
<textField isStretchWithOverflow="true" isBlankWhenNull="true" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement x="50" y="46" width="277" height="14"
key="textField-16"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>

<textElement>
<font fontName="Arial" pdfFontName="Arial" size="9"
isPdfEmbedded ="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{addressLine2}]]>
</textFieldExpression>
</textField>
<textField isStretchWithOverflow="true" isBlankWhenNull="true" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement x="50" y="46" width="277" height="14"
key="textField-16"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>

<textElement>
<font fontName="Arial" pdfFontName="Arial" size="9"
isPdfEmbedded ="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{state}]]>
</textFieldExpression>
</textField>


Now what if a person does not have an Address Line 2? In that case the Address Line 2 text field will be left empty resulting in a distorted display,



Rachel Ross \\ Name



#15, Hogswille \\ Address Line1



\\ Address Line2



Texas. \\ State



Such a problem can be avoided by a simple and interesting approach. We know that Address Line 2 is a non-mandatory field and hence it has to be set when there is a data for that text field.



For this use the <printWhenExpression> of the Address Line 2 text field to show it only when the data is not NULL. Then set the ‘Position Type’ to “float”. Finally, set the ‘Remove line when blank’ property to “yes”.



Now to make the State field to move up when there is no Address Line 2 set the ‘Position Type’ to “float”. Thus, according to the data availability the fields will be aligned.



Combining Dynamic and Static JasperReports





The need to combine a static jrxml template in a dynamic report is very rare, but is again a useful approach. Let’s consider one such kind of scenario which will explain this.



Let’s say we need to generate a report that has a layout of a letter-head, which has a heavy text filled header and footer, which is pretty difficult in Dynamic Jasper.



In such situations where some type of static content is always required amidst dynamic contents, we can embed a pre-designed jrxml template. The following code snippet shows how and where the jrxml template can be added.



DynamicReportBuilder drb = util.getDynamicLetterBuilder(“Report”,
logoPath, false);
drb.addColumn(orderId);
drb.addColumn(city);
drb.addColumn(date);
drb.addColumn(value);
drb.setSubtitle("Report Title");
drb.setTemplateFile("Sample.jrxml");
drb.setSubtitleStyle(subtitleStyle);
drb.setUseFullPageWidth(true)


References



1 http://jasperreports.sourceforge.net



2 http://ireport.sourceforge.net



3 http://www.jfree.org/jfreechart/



Useful Links




3 comments:

Nimish Inamdar said...

Hi,

I appreciate your posting.
I am already following the way you mentioned. But the problem with this is that the footer that should remain fixed below also moves up. I tried with the tag "Position Type" as "Fix Relative to Bottom" but the text and the image always moves up when the address line 2 is blank. Can you help me at this?

Thanks in advance.

Sergio said...

Thank you for the information, I got solve an issue with the total quantity of pages. Regards from Argentina.

Anonymous said...

Hi,

Thanks for clear explanation.

I have followed your steps and setted all properties. Still my below element is NOT moving up when above elemnt is empty.

Please use below link to view my jrxml file. Any help would be appreciated.

http://stackoverflow.com/questions/15780542/how-to-set-x-y-for-a-textelement-in-jasperreports-depending-on-if-above-textele

-Monika

Text Widget

Copyright © Vinay's Blog | Powered by Blogger

Design by | Blogger Theme by