After being able to add custom data source from java bean to a report according to Add custom data source to Jaspersoft Studio , I get to the second point of my reporting with jasper.
I have a main report which uses a data base as its data source. Then I add a bean.xml data source to the report and add a table to the main report which uses this bean.xml data source to get java beans.
My goal is to get a field value from the main report and manipulate its value, then fill the beans with these values and at last fill the table with the beans.
To do this I have written 3 classes which I use as Scriptlet in the table data set:
This is an illustration of what I need to do:
The problem is in FillTable class, when I us String kNFormelGG = (String) this.getParameterValue("gg");
the created bean.xml fails the test connection with java.lang.reflect.InvocationTargetException
Caused by: java.lang.NullPointerException
at net.sf.jasperreports.engine.JRAbstractScriptlet.getParameterValue(JRAbstractScriptlet.java:95)
at net.sf.jasperreports.engine.JRAbstractScriptlet.getParameterValue(JRAbstractScriptlet.java:86)
at org.iqtig.reporting.dataSource.bean.dataSourceXML.FillTable.fillTable(FillTable.java:45)
at org.iqtig.reporting.dataSource.bean.dataSourceXML.JRDataSourceFactory.createCollection(JRDataSourceFactory.java:27)
... 34 more
If I assign a fix value like String kNFormelGG ="Test me"
the bean connection encounters no error and after assigning bean.xml as the value for Default Data Adapter in Dataset1 it fills the table with static values.
How can get the data from a parameter or a value dynamically from the main report data source and use it in beans?
I have this assumption that at the time of calling the static factory class from my adapter, the fields are still empty. Maybe I am wrong but I do not find any other declaration for this problem.
BeanFactory Class
import java.util.Collection;
import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRScriptletException;
/**
* Factory for TableCellsBean Klasse
*
* @author iman.gharib
*/
public class JRDataSourceFactory extends JRDefaultScriptlet {
/**
* @return collection der TableCellsBean Objekten
* @throws JRScriptletException
*/
public static Collection<TableCellsBean> createCollection()
throws JRScriptletException {
FillTable ft = new FillTable();
Collection<TableCellsBean> reportRows = ft.fillTable();
return reportRows;
}
}
Bean Class
public class TableCellsBean {
private String fieldName;
private String keyFormel;
private String mK;
private String notation;
private String item;
/**
* Constructor.
*
* @param fieldName
* @param keyFormel
* @param mK
* @param notation
* @param item
*/
public TableCellsBean(final String fieldName, final String keyFormel, final String mK, final String notation, final String item) {
this.fieldName = fieldName;
this.keyFormel = keyFormel;
this.mK = mK;
this.notation = notation;
this.item = item;
}
/**
* Constructo Leer
*/
public TableCellsBean() {
}
public TableCellsBean getme() {
return this;
}
// getter and setters
}
Class for preparing and creating beans
public class FillTable extends JRDefaultScriptlet {
@Override
public void afterColumnInit()
throws JRScriptletException {
fillTable();
}
public ArrayList<String> splitGGArray(final String kNFormelGG) {
ArrayList<String> fieldNames = new ArrayList<>();
String[] array = (kNFormelGG.split(" "));
for (String sub : array) {
fieldNames.add(sub);
}
return fieldNames;
}
public Collection<TableCellsBean> fillTable()
throws JRScriptletException {
// gg is a parameter for table dataset. It is mapped to KN_FormelGG
// which comes from the main report data base
String kNFormelGG = (String) this.getParameterValue("gg");
List<TableCellsBean> listTableCells = new ArrayList<>();
// TableCellsBean tableCell = new TableCellsBean();
for (String fn : splitGGArray(kNFormelGG)) {
listTableCells.add(new TableCellsBean(fn, fn, fn, fn, fn));
// listTableCells.add(tableCell);
}
// JRBeanCollectionDataSource tableCellJRBean = new JRBeanCollectionDataSource(listTableCells);
// Map<String, Object> parameters = new HashMap<>();
// parameters.put("FieldDataSource", tableCellJRBean);
return listTableCells;
}
}
JRXML
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.3.0.final using JasperReports Library version 6.3.0 -->
<!-- 2016-08-08T14:30:03 -->
<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="main" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="4f1480cf-f8f9-420f-96b4-7fc1e41e791b">
<property name="com.jaspersoft.studio.data.sql.tables" value=""/>
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="QIDBReport"/>
<style name="Table_TH" mode="Opaque" backcolor="#F0F8FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="Table_CH" mode="Opaque" backcolor="#BFE1FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<subDataset name="Dataset1" uuid="5677929d-813b-4d39-828c-de966a9d7689">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="bean.xml"/>
<property name="net.sf.jasperreports.data.adapter" value="bean.xml"/>
<scriptlet name="Scriptlet_1" class="org.iqtig.reporting.dataSource.bean.mapBeanAsDatasource.JRDataSourceFactory"/>
<parameter name="gg" class="java.lang.String"/>
<field name="item" class="java.lang.String">
<fieldDescription><![CDATA[item]]></fieldDescription>
</field>
<field name="fieldName" class="java.lang.String">
<fieldDescription><![CDATA[fieldName]]></fieldDescription>
</field>
<field name="me" class="org.iqtig.reporting.dataSource.bean.dataSourceXML.TableCellsBean">
<fieldDescription><![CDATA[me]]></fieldDescription>
</field>
<field name="keyFormel" class="java.lang.String">
<fieldDescription><![CDATA[keyFormel]]></fieldDescription>
</field>
<field name="mK" class="java.lang.String">
<fieldDescription><![CDATA[mK]]></fieldDescription>
</field>
</subDataset>
<parameter name="LB_ID" class="java.lang.Integer">
<defaultValueExpression><![CDATA[62]]></defaultValueExpression>
</parameter>
<parameter name="KN_OffeziellGruppe" class="java.lang.Integer">
<defaultValueExpression><![CDATA[3]]></defaultValueExpression>
</parameter>
<parameter name="FieldDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource" isForPrompting="false"/>
<parameter name="KN_FormelGG" class="java.lang.String" isForPrompting="false"/>
<queryString>
<![CDATA[select * from "KennzahlReferenz2015_QIBericht", "Images"
where LB_ID = $P{LB_ID}
and KN_OffiziellGruppe = $P{KN_OffeziellGruppe}
and IMG_ID = 1]]>
</queryString>
<field name="QI_Praefix" class="java.lang.String"/>
<field name="KN_Id" class="java.lang.Integer"/>
<field name="bewertungsArtTypNameKurz" class="java.lang.String"/>
<field name="refbereich" class="java.lang.String"/>
<field name="refbereichVorjahres" class="java.lang.String"/>
<field name="KN_GGAlleinstehend" class="java.lang.String"/>
<field name="erlaueterungDerRechregeln" class="java.lang.String"/>
<field name="teildatensatzbezug" class="java.lang.String"/>
<field name="mindesanzahlZaeler" class="java.lang.Integer"/>
<field name="mindesanzahlNenner" class="java.lang.Integer"/>
<field name="KN_FormelZ" class="java.lang.String"/>
<field name="KN_FormelGG" class="java.lang.String"/>
<field name="verwendeteFunktionen" class="java.lang.String"/>
<field name="idLb" class="java.lang.String"/>
<field name="LB_LangBezeichnung" class="java.lang.String"/>
<field name="LB_ID" class="java.lang.Integer"/>
<field name="nameAlleinstehend" class="java.lang.String"/>
<field name="KN_BezeichnungAlleinstehendKurz" class="java.lang.String"/>
<field name="QI_ID" class="java.lang.Integer"/>
<field name="IMG_ID" class="java.lang.Integer"/>
<field name="Name" class="java.lang.String"/>
<field name="Image" class="java.lang.Object"/>
<group name="id" isStartNewPage="true">
<groupExpression><![CDATA[$F{KN_Id}]]></groupExpression>
<groupHeader>
<band height="44"/>
</groupHeader>
<groupFooter>
<band height="50"/>
</groupFooter>
</group>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="44" splitType="Stretch"/>
</title>
<pageHeader>
<band height="35" splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band height="34" splitType="Stretch"/>
</columnHeader>
<detail>
<band height="149" splitType="Stretch">
<componentElement>
<reportElement x="170" y="20" width="350" height="100" uuid="38d917fb-dfc2-4c08-890a-09cfe6e2214d">
<property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
<property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/>
<property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/>
<property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/>
<property name="net.sf.jasperreports.export.headertoolbar.table.name" value=""/>
<property name="com.jaspersoft.studio.components.autoresize.proportional" value="true"/>
</reportElement>
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" whenNoDataType="AllSectionsNoDetail">
<datasetRun subDataset="Dataset1" uuid="1b3548f6-7d6b-4070-bb8e-aaefbabdc7c9">
<datasetParameter name="gg">
<datasetParameterExpression><![CDATA[$F{KN_FormelGG}]]></datasetParameterExpression>
</datasetParameter>
</datasetRun>
<jr:column width="70" uuid="048812d7-0ed1-4db8-a09a-e6242f77c6ce">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/>
<jr:tableHeader style="Table_TH" height="30" rowSpan="1"/>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="70" height="30" uuid="c5aaea84-1367-41df-be8d-7f71e3ea5153"/>
<textFieldExpression><![CDATA[$F{item}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="70" uuid="11b85ada-c9fe-42b6-a646-8bd1697cdec2">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column2"/>
<jr:tableHeader style="Table_TH" height="30" rowSpan="1"/>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="70" height="30" uuid="728ff44d-1dbd-404c-b8b3-7cc0e1f07f60"/>
<textFieldExpression><![CDATA[$F{fieldName}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="70" uuid="892f30cb-fb41-444f-889b-1e005484c35e">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column3"/>
<jr:tableHeader style="Table_TH" height="30" rowSpan="1"/>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="70" height="30" uuid="e38ac951-71bc-45a6-8ed2-313805a77050"/>
<textFieldExpression><![CDATA[$F{keyFormel}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="70" uuid="7d0d700a-5a75-4c26-94c0-9ef7c53bd719">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column4"/>
<jr:tableHeader style="Table_TH" height="30" rowSpan="1">
<textField>
<reportElement x="0" y="0" width="70" height="30" uuid="68577007-0344-406c-8aa2-3127d1da1c65"/>
</textField>
</jr:tableHeader>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="70" height="30" uuid="873d63c1-1b91-4441-b7bd-f67db7729e7f"/>
<textFieldExpression><![CDATA[$F{mK}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="70" uuid="cf5a1a2f-594d-429f-8925-62d001e1dd00">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column5"/>
<jr:tableHeader style="Table_TH" height="30" rowSpan="1">
<textField>
<reportElement x="0" y="0" width="70" height="30" uuid="7fb46eb8-d0e1-44ab-89f9-ec31d49b8109"/>
<textFieldExpression><![CDATA[$P{gg}]]></textFieldExpression>
</textField>
</jr:tableHeader>
<jr:detailCell style="Table_TD" height="30"/>
</jr:column>
</jr:table>
</componentElement>
<textField>
<reportElement x="20" y="80" width="100" height="30" uuid="b89cd04c-2569-43ef-9730-445b874855dd"/>
<textFieldExpression><![CDATA[$F{KN_FormelGG}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="20" y="32" width="100" height="30" uuid="e91b4461-5e53-4f85-8992-14e69a1aa05f"/>
<text><![CDATA[KN_FormelGG]]></text>
</staticText>
</band>
</detail>
<columnFooter>
<band height="45" splitType="Stretch"/>
</columnFooter>
<pageFooter>
<band height="54" splitType="Stretch"/>
</pageFooter>
<summary>
<band height="42" splitType="Stretch"/>
</summary>
</jasperReport>
There are many ways to use multiple data sources in reports designed via Jaspersoft Studio or JasperReports Server: Multiple datasets, which is a standard feature in the product. You can associate a different dataset with each component added to a report, for example Tables, Crosstabs and Charts.
Creating a Cascading Input Control Then we publish the report on the server. Now define the input controls. Right-click the JasperReport node in the Repository Navigator and add the first input control by selecting Add > Input Control.
In Jaspersoft Studio, a data adapter is an XML file that contains the information about where your data is located. This information includes, URL, user, password, paths, etc. Data adapters also contain the logic to prepare all parameters for JasperReports to run the query and iterate data.
Launch Jaspersoft Studio, if you have not done so already. Click the Repository Explorer button on the main toolbar to open the Connections/Datasources dialog box. Right-click on Data Adapters and select Create Data Adapter. Select Database JDBC Connection and click Next to advance to the Database JDBC connection page.
My goal is to get a field value from the main report and manipulate its value, then fill the beans with these values and at last fill the table with the beans.
I will ignore all your scriplets and other code and show you the simplest way to create a dynamic datasource for another component using a current field, variable or parameter value.
As example we will have these String values in field1 (row1, row2)
Test1_1.23:Test2_4.32:Test3_1.08
Test1_2.12:Test2_5.12:Test3_2.13
We want to split on :
and create rows (List of beans), then split on _
to create columns (properties on bean) and display this in a jr:table
component.
public class TableCellsBean {
private String name;
private double value;
public TableCellsBean(String name,double value){
this.name = name;
this.value = value;
}
public static JRBeanCollectionDataSource getDatasource(String fieldValue){
List<TableCellsBean> retList = new ArrayList<>();
String[] values = fieldValue.split(":");
for (String v : values) {
String[] sp = v.split("_");
retList.add(new TableCellsBean(sp[0], Double.parseDouble(sp[1])));
}
return new JRBeanCollectionDataSource(retList);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
}
As you can see already inside this bean class I have added a static method that returns a JRBeanCollectionDataSource
depending on value passed as parameter.
Basically you pass a fieldValue
to this method, it does some logic, creates the TableCellBean
, adds them to list and return a JRBeanCollectionDataSource
Note: The method does not need to be static nor inside this class, furthermore exception handling is not considered.
In example we will have field1
containing Test1_1.23:Test2_4.32:Test3_1.08
on row 1 and Test1_2.12:Test2_5.12:Test3_2.13
on row 2.
We define a subdataset that represents out TableCellsBean
<subDataset name="table_dataset" uuid="4dc1b0fb-2588-4f98-8c8d-f0afefbb2fd1">
<field name="name" class="java.lang.String"/>
<field name="value" class="java.lang.Double"/>
</subDataset>
as datasource we call our static method passing the field1
content in current row.
<dataSourceExpression><![CDATA[my.package.TableCellsBean.getDatasource($F{field1})]]></dataSourceExpression>
Full jrxml
<?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="test" language="java" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="886a547e-11bd-434b-a330-d93ee5e4a280">
<style name="table">
<box>
<pen lineWidth="1.0" lineColor="#000000"/>
</box>
</style>
<style name="table_TH" mode="Opaque" backcolor="#F0F8FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="table_CH" mode="Opaque" backcolor="#BFE1FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="table_TD" mode="Opaque" backcolor="#FFFFFF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<subDataset name="table_dataset" uuid="4dc1b0fb-2588-4f98-8c8d-f0afefbb2fd1">
<field name="name" class="java.lang.String"/>
<field name="value" class="java.lang.Double"/>
</subDataset>
<field name="field1" class="java.lang.String">
<fieldDescription><![CDATA[_THIS]]></fieldDescription>
</field>
<detail>
<band height="40" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="555" height="20" uuid="a73343b1-ccb2-4a59-b882-381b98efd664"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{field1}]]></textFieldExpression>
</textField>
<componentElement>
<reportElement key="table" style="table" x="0" y="20" width="555" height="20" uuid="09a9a5b8-499b-40d2-b391-ece25772a31e"/>
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<datasetRun subDataset="table_dataset" uuid="05601bdb-5579-4253-90f7-6742739d9714">
<dataSourceExpression><![CDATA[bounty.TableCellsBean.getDatasource($F{field1})]]></dataSourceExpression>
</datasetRun>
<jr:column width="90" uuid="afbbb3d0-573a-495d-ab51-0ae4d601e6fb">
<jr:tableHeader style="table_TH" height="20" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="90" height="20" uuid="e476f026-bbec-4b19-9bd4-f4b21f3377ef"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Name]]></text>
</staticText>
</jr:tableHeader>
<jr:detailCell style="table_TD" height="20" rowSpan="1">
<textField>
<reportElement x="0" y="0" width="90" height="20" uuid="49cac181-b16b-4ab3-b600-78a56fb0f42b"/>
<box leftPadding="3" rightPadding="3"/>
<textElement verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="90" uuid="4a1b0759-c347-4294-82c5-3aed4762f0c4">
<jr:tableHeader style="table_TH" height="20" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="90" height="20" uuid="bfa965b5-b5a4-484d-bfbd-d8bc753718b1"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Value]]></text>
</staticText>
</jr:tableHeader>
<jr:detailCell style="table_TD" height="20" rowSpan="1">
<textField>
<reportElement x="0" y="0" width="90" height="20" uuid="925192bc-a761-48f5-bad5-097d15587198"/>
<box leftPadding="3" rightPadding="3"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{value}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
</componentElement>
</band>
</detail>
</jasperReport>
Adding main method to export to pdf
public static void main(String[] args) throws JRException {
//Compile report
JasperReport report = JasperCompileManager.compileReport("myJasperReport.jrxml");
//Setting up some arbitrary data to test the auto creation of datasource
List<String> someData = new ArrayList<>();
someData.add("Test1_1.23:Test2_4.32:Test3_1.08");
someData.add("Test1_2.12:Test2_5.12:Test3_2.13");
//Fill report
JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<>(),new JRBeanCollectionDataSource(someData));
//Export to pdf
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput("myJasperReport.pdf"));
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
exporter.setConfiguration(configuration);
exporter.exportReport();
}
The simplest way to provide components with custom datasource depending on running reports values (fields, variables, parameter), is to create a method that generates the datasource and call this in dataSourceExpression
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With