tutorial reportes jasperreports jasperreport generar español java jasper-reports jaspersoft-studio

java - reportes - jasperreports tutorial español



Trabajar con múltiples fuentes de datos en jaspersoft studio (1)

Después de poder agregar un origen de datos personalizado de Java Baba a un informe de acuerdo con Agregar un origen de datos personalizado a Jaspersoft Studio , llego al segundo punto de mi informe con jasper.

Tengo un informe principal que utiliza una base de datos como su fuente de datos. Luego agrego un origen de datos bean.xml al informe y agrego una tabla al informe principal que usa este origen de datos bean.xml para obtener los beans de Java.

Mi objetivo es obtener un valor de campo del informe principal y manipular su valor, luego llenar los beans con estos valores y, por último, llenar la tabla con los beans.

Para hacer esto, escribí 3 clases que uso como Scriptlet en el conjunto de datos de la tabla :

Esta es una ilustración de lo que necesito hacer:

El problema está en la clase FillTable, cuando I String kNFormelGG = (String) this.getParameterValue("gg"); el bean.xml creado falla la conexión de prueba con 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

Si asigno un valor fijo como String kNFormelGG ="Test me" la conexión del bean no encuentra ningún error y, después de asignar bean.xml como el valor del Adaptador de datos predeterminado en Dataset1, llena la tabla con valores estáticos. ¿Cómo se pueden obtener los datos de un parámetro o un valor dinámicamente del origen de datos principal del informe y usarlos en beans? Supongo que al momento de llamar a la clase de fábrica estática desde mi adaptador, los campos aún están vacíos. Tal vez me equivoque, pero no encuentro ninguna otra declaración para este problema.

Clase BeanFactory

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; } }

Clase de frijol

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 }

Clase para preparar y crear frijoles.

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>


Mi objetivo es obtener un valor de campo del informe principal y manipular su valor, luego llenar los beans con estos valores y, por último, llenar la tabla con los beans.

Ignoraré todos sus scriplets y otros códigos y le mostraré la forma más sencilla de crear una fuente de datos dinámica para otro componente utilizando un campo, variable o valor de parámetro actual.

Como ejemplo tendremos estos valores de cadena en el campo 1 (fila1, fila2)

Test1_1.23:Test2_4.32:Test3_1.08 Test1_2.12:Test2_5.12:Test3_2.13

Queremos dividir en : y crear filas (Lista de beans), luego dividir en _ para crear columnas (propiedades en bean) y mostrar esto en un componente jr:table .

código java (o Bean)

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; } }

Como se puede ver ya dentro de esta clase de bean, he agregado un método estático que devuelve un JRBeanCollectionDataSource función del valor pasado como parámetro.

Básicamente, usted pasa un fieldValue de fieldValue a este método, hace algo de lógica, crea el TableCellBean , los agrega a la lista y devuelve un JRBeanCollectionDataSource

Nota: el método no necesita ser estático ni dentro de esta clase, además, no se considera el manejo de excepciones.

Informe - el jrxml

En el ejemplo tendremos field1 contiene Test1_1.23:Test2_4.32:Test3_1.08 en la fila 1 y Test1_2.12:Test2_5.12:Test3_2.13 en la fila 2.

Definimos un subdataset que representa a 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>

como fuente de datos, llamamos a nuestro método estático que pasa el contenido de field1 en la fila actual.

<dataSourceExpression><![CDATA[my.package.TableCellsBean.getDatasource($F{field1})]]></dataSourceExpression>

Jrxml completo

<?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>


Prueba el ejemplo

Agregando el método principal para exportar a 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(); }

Salida

Conclusión

La forma más sencilla de proporcionar componentes con una fuente de datos personalizada según los valores de los informes en ejecución (campos, variables, parámetros), es crear un método que genere la dataSourceExpression datos y llamar a esto en dataSourceExpression