JasperReport Components - java

New to JasperReports and attempting to either: (a) manually write a JRXML or (b) manually program a JasperDesign myself (not using a template). My understanding is that both the XML and the Java object represent the same concept: an empty "shell" of a report without any data in it.
I'm trying to figure out what JR components would be suit my needs, and the reference, the samples as well as many online searches haven't turned back anything that is clear-cut. Most JR documentation seems, at least to a newbie, to be written from an "assumed knowledge" standpoint.
What is the difference between, and appropriate usages for, the following "components" (not really sure what else to call them):
Text
TextField
TextElement
StaticText
This images example here shows most of these elements being used, seemingly willy-nilly in a not-so-obvious format.
The root of my question is that I wish to display two types of text-based information; one I am referring to as "fields" (not to be confused with JR fields) and the other I am calling "text blocks" consisting of a header and a body. I would like these fields/text blocks rendered as follows:
"Field":
Name: John Smith
Age: 42
Summary: This is an example of a field
And a "text block":
Name:
John Smith
Age:
42
Summary:
This is an example of a text block. "Summary:" is the head, and this is the body.
Same information, just presented differently. I believe that one/several of the JR components listed above are the one's I need to use, but I can't seem to find any documentation that confirms/rejects that.
Anybody have any ideas on this? Thanks in advance!

You're right in that the .jrxml and the JasperDesign object are analogous and represent an empty report design. This design can then be compiled into a .jasper file or JasperReport object, which is then filled with data to produce an actual report.
Out of the four "components" you listed, only TextField and StaticText are really report components. The others simply hold properties of a parent element.
StaticText holds text that never changes. It is set in the design and that's it.
A TextField has an expression that is executed when the report is filled. These are the elements you will you to put data into your report.
Text is a tag that holds the actual text content of a StaticText element. This is the only place it will appear.
TextElement declares properties that are specific to how the report should render text. Every TextField or StaticText can include this tag. Properties include text alignment, rotation, typeface, font size, etc.
To solve your problem, you will need to use StaticText components for the name, age and summary labels, as they will always be the same; and TextField components for the actual report data.
As others have suggested, I would recommend iReport. I would do most of the design using it, then make and changes to the JRXML by hand (The xml it produces is a bit bloated). The designer will hide Text and TextElement from you and it will appear as though the properties are being set on the text components themselves. This isn't a problem, but if you're going to change the JRXML by hand you should be aware of it so you don't add attributes to the wrong tags. Looking at the output of iReport is also a good way to learn valid JRXML, as the error messages you get for an incorrect .jrxml file are not always helpful.
Hope that helps!

If you don't want to use iReport you can try to build reports dynamically with help of DynamicJasper Java API or JasperReports Java API.
My advice to you: do not try to reinvent the wheel. Try to use iReport designer, it is a really helpful tool for building both easy and complex reports.
Just one cross of using iReport: the JasperServer application (ready for use web application for deploying, building reports and exporting data to different formats) works with jrxml templates.
The iReport Ultimate Guide and JasperReports Ultimate Guide are very valuable books. You can find some manuals here.
This is the snippet of jrxml template relevant to your question (I hope). It was written with iReport.
<detail>
<band height="60" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="63" height="20"/>
<box leftPadding="10">
<topPen lineWidth="1.0"/>
<leftPen lineWidth="1.0"/>
</box>
<textElement/>
<text><![CDATA[Name:]]></text>
</staticText>
<staticText>
<reportElement x="0" y="20" width="63" height="20"/>
<box leftPadding="10">
<leftPen lineWidth="1.0"/>
</box>
<textElement/>
<text><![CDATA[Age:]]></text>
</staticText>
<staticText>
<reportElement x="0" y="40" width="63" height="20"/>
<box leftPadding="10">
<leftPen lineWidth="1.0"/>
<bottomPen lineWidth="1.0"/>
</box>
<textElement/>
<text><![CDATA[Summary:]]></text>
</staticText>
<textField>
<reportElement x="63" y="0" width="290" height="20"/>
<box leftPadding="10">
<topPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement/>
<textFieldExpression><![CDATA[$F{Name}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="63" y="20" width="290" height="20"/>
<box leftPadding="10">
<pen lineWidth="1.0"/>
<topPen lineWidth="0.0"/>
<leftPen lineWidth="0.0"/>
<bottomPen lineWidth="0.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement/>
<textFieldExpression><![CDATA[$F{Age}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="63" y="40" width="290" height="20"/>
<box leftPadding="10">
<bottomPen lineWidth="1.0"/>
<rightPen lineWidth="1.0"/>
</box>
<textElement/>
<textFieldExpression><![CDATA[$F{Summary}]]></textFieldExpression>
</textField>
</band>
</detail>
The result will be:
It takes me just 5 minutes.

Related

Exporting to Excel with JasperReports: How to add AutoFilter for columns

I am using this code for create report in MS Excel format:
JRXlsExporter exporter = new JRXlsExporter();
From there I don't know if it's possible to tell JasperReports to apply an auto filter on each column.
I was facing the same issue i.e in my spreadsheet(.xls) I wanted to add auto filter to all the columns(15), so I have added one property(Properties expression )name = net.sf.jasperreports.export.xls.auto.filter and value as 'Start' at first column header and same property with value as End at last column header and it worked.
Go to the 'Exporter Parameters' pane and make sure none of the 'Start' or 'Stop' options are set for Auto Filter. Choose the empty space in the related list box (see the attached image). Then run the report again. This time you should see the filters in the right places.
http://community.jaspersoft.com/jaspersoft-studio/issues/6876
JasperReports engine can is able to apply autofilters for columns for MS Excel output format. For applying autofilters we have to use net.sf.jasperreports.export.xls.auto.filter property. We should apply this property for header cells. It is possible to set filter for only one column or for the several columns.
Working example
Datasource
I used the csv datasource in this sample:
language,framework
Java,Guava
Java,Lombok
Java,JasperReports
Java,Spring
Java,Vaadin
C#,ASP.NET MVC
C#,NancyFX
C#,Automapper
JavaScript,AngularJS
JavaScript,React
JavaScript,jQuery
The name of data adapter for this datasource in the example below is frameworks.csv
The report's template
I used Jaspersoft Studio (JSS) for designing a report template.
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="excel_filter" pageWidth="595" pageHeight="842" columnWidth="595" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="b521f87a-96ed-43bd-80bd-c7b81ef2e8aa">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="frameworks.csv"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="language" class="java.lang.String"/>
<field name="framework" class="java.lang.String"/>
<columnHeader>
<band height="30" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="278" height="30" uuid="6b8ba60b-3df3-4c78-a780-79ee493ca5f8">
<property name="net.sf.jasperreports.export.xls.auto.filter" value="Start"/>
</reportElement>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Language]]></text>
</staticText>
<staticText>
<reportElement x="278" y="0" width="277" height="30" uuid="731ba580-2168-49f6-b844-d02549d3d83c">
<property name="net.sf.jasperreports.export.xls.auto.filter" value="End"/>
</reportElement>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Framework]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="30" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="278" height="30" uuid="7bf9acec-b13a-4261-91c1-0bf6f2c9c784"/>
<textFieldExpression><![CDATA[$F{language}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="278" y="0" width="277" height="30" uuid="d15bd48e-77ee-43df-b11f-4ec1a65811c0"/>
<textFieldExpression><![CDATA[$F{framework}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
I've used the Detail band for showing data. For the first column I set the Start value to the net.sf.jasperreports.export.xls.auto.filter property for staticText in Column Header band (will be the column header in Excel file) and the End value for the second (last) column.
In case using of setting property for only one column the only one filter will be created.
We can easy set property with help of context menu "XLS Tags -> Autofilter -> Start (End)" in JSS.
Output result
The generated output file in MS Excel format contains autofilters for both columns. The file was generated with help of JSS.
Notes:
More information about applying different features for exported Excel files can be found on vendor site

generating jasper reports using ireport designer tool

I generated PDF report using ireport designer tool. Upto here it is fine.
My question is :
If there is no data in the database then it is showing blank pdf page. At this time how can i show "No data found for this request" in pdf?
There is a property of the template WhenNoDataType.
Just set it to WhenNoDataType: AllSectionsNoDetail.
This will have the template(static fields) but no dynamic data from database.
If you just want to print some message than you will have to change the design up a bit. You would need to place a condition at the beginning of your report to check if data is coming from database, and act accordingly.
If you want to show none of the content of your report when there is no data (no title, headers, footers, etc.) then you should add a noData band to your report and put the message there. Then change the whenNoDataType report parameter to NoDataSection.
From the JasperReports Ultimate Guide:
If the <noData> section is defined in the report template, and if the data source is empty, then the <noData> section will be the only one taken into account at fill time
Example:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
name="report1"
whenNoDataType="NoDataSection">
<pageHeader>
<band height="20">
<staticText>
<reportElement x="0" y="0" width="100" height="20"/>
<text><![CDATA[Page Header]]></text>
</staticText>
</band>
</pageHeader>
<detail>
<band height="20">
<staticText>
<reportElement x="0" y="0" width="100" height="20"/>
<text><![CDATA[Detail]]></text>
</staticText>
</band>
</detail>
<pageFooter>
<band height="20">
<staticText>
<reportElement x="0" y="0" width="100" height="20"/>
<text><![CDATA[Page Footer]]></text>
</staticText>
</band>
</pageFooter>
<noData>
<band height="20">
<staticText>
<reportElement x="0" y="0" width="555" height="20"/>
<text><![CDATA[No data found for this request]]></text>
</staticText>
</band>
</noData>
</jasperReport>

Calling Java API in the iReport expression

I'm trying to attach a call to a Java library into the iReport expression.
I tried this with a very simple library returning a hello world string.
package utils;
public class Hello {
public static String hello()
{
return "Hello";
}
}
Within iReport, i want to use this API. I compiled the above library into a jar file. Added the location in Tools -> Options -> Classpath.
then tried the following:
Editing the expression in a a text field new utils.Hello().hello()
Creating a new field and setting its type to utils.Hello. Then using the field.hello() in the expression
In both cases, it complains that it cannot resolve hello. However its in the classpath. I've also tried to right click on the report root and add utils.Hello/utils to the Java import directive. Neither of which seemed to pick up the class.
Any advice is greatly appreciated.
Your right expression might be like this:
<textFieldExpression><![CDATA[utils.Hello.hello()]]></textFieldExpression>
The working sample:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport ..>
<queryString>
<![CDATA[SELECT DISTINCT city FROM address ORDER BY city]]>
</queryString>
<field name="CITY" class="java.lang.String"/>
<detail>
<band height="20" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{CITY}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="100" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[utils.Hello.hello()]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
You can also add import instruction to the report. In this case the expression will be:
<textFieldExpression><![CDATA[Hello.hello()]]></textFieldExpression>
The working sample:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport ... whenNoDataType="AllSectionsNoDetail">
<import value="utils.Hello"/>
<title>
<band height="41">
<textField>
<reportElement x="188" y="11" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[Hello.hello()]]></textFieldExpression>
</textField>
</band>
</title>
</jasperReport>
Note: For both samples the jar file (with utils.Hello class) must be in classpath.
More info about using srciptlets you can find here.
You field type should be String , not utils.Hello

Abort Jasper report generation on NullPointerException

I'm creating reports with Jasper Reports (4.0.0) for our project (JRE 1.6.x).
I'm getting bothered with NullPointerExceptions in my scriptlets, as they do not cause the report to abort, they just make the field be silently evaluated to null. As far as I tested, it happens only to NPE's.
The generated reports are quite important and should not have any errors. So, if an exception occurs (like NPE's for some missing data), it should stop the generation, and the database and/or report should be fixed. Such behavior may hide some report coding errors, unless someone spots the missing field.
What is the reason for this behavior with NPE's? Is there any compilation option or execution flag I can switch to make NPE's bubble up as other exceptions do?
I really wish I won't have to wrap every scriptlet method in a try..catch block and throw another exception on NPE's.
Thanks!
Ok, a sample report. It does not uses scriptlets, but generate the NPE directly on a field evaluation (the result is the same), and can be executed directly on iReport preview without parameters:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="NPE_Report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<variable name="NullVariable" class="java.lang.Integer" calculation="System">
<initialValueExpression><![CDATA[null]]></initialValueExpression>
</variable>
<variable name="NotNullVariable" class="java.lang.Integer" calculation="System">
<initialValueExpression><![CDATA[200]]></initialValueExpression>
</variable>
<title>
<band height="72" splitType="Stretch">
<staticText>
<reportElement x="11" y="10" width="179" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<text><![CDATA[Successful field evaluation:]]></text>
</staticText>
<textField>
<reportElement x="190" y="10" width="296" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["0x"+Integer.toHexString($V{NotNullVariable}.intValue()+55)]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="11" y="32" width="179" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<text><![CDATA[NPE on field evaluation:]]></text>
</staticText>
<textField>
<reportElement x="190" y="32" width="296" height="22"/>
<textElement>
<font size="14"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA["0x"+Integer.toHexString($V{NullVariable}.intValue()+55)]]></textFieldExpression>
</textField>
</band>
</title>
<detail>
<band height="24" splitType="Stretch"/>
</detail>
</jasperReport>
It doesn't sound like a null pointer expression problem. It sounds like your data source allows null fields. JasperReports is robust enough to handle a report where some information is missing. There is a property you can set so that when information is missing the field prints "null" or is left blank. If you don't want the report to generate at all if the data field is null, modify your data source so the fields are "not null".
Alternatively, drop on a conditional statement so that your scriptlet only runs if th fields are not null and break if they are. Then when the report hits a null field it will stop.

stretch a row to fit the data in jasper reports using iReport

I use iReport 2.0.5 to generate jrxml file and use the same in my java web propject, I have used all the flags to stretch to fit the data, but it doesn't work
The example:
<textField isStretchWithOverflow="true" isBlankWhenNull="true" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement style="dNew" mode="Opaque" x="55" y="0" width="55" height="19" key="value-1" stretchType="RelativeToTallestObject" positionType="Float" isPrintWhenDetailOverflows="true"/>
<box></box>
<textElement>
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{value1}]]></textFieldExpression>
</textField>
It should be able to stretch down based on the band.
If it is a TextField you can set the option "Stretch with Overflow" AFAIK straight StaticTexts will not overflow.
Add the following two properties in your reportElement tag.
name="net.sf.jasperreports.print.keep.full.text" value="true"
name="net.sf.jasperreports.export.xls.wrap.text" value="false"

Categories

Resources