Comment transmettre la source des données du rapport principal au sous-rapport (JasperReports)?

J'utilise JasperReports et je remplis le JRDataSource pour le rapport. Maintenant, je veux passer la principale REPORT_DATA_SOURCE au sous-rapport. Comment puis-je faire cela?

autant Que je sache, le REPORT_DATA_SOURCE est un objet consommable, donc il ne peut être utilisé qu'une seule fois, non?. Puis-je copier cette source de données et la transmettre?

BTW: j'utilise iReport pour créer la mise en page.

28
demandé sur ChrisWue 2011-12-13 18:08:20

5 réponses

Vous pouvez passer source de données via le REPORT_DATA_SOURCE paramètre.

exemple:

<subreport>
    <reportElement x="261" y="25" width="200" height="100"/>
    <dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
    <subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
</subreport>

Vous pouvez créer une nouvelle instance de source de données basé sur la variable, le paramètre ou le champ.

exemple:

<variable name="HeadingsCollection" class="java.util.Collection" calculation="System">
    <initialValueExpression><![CDATA[new java.util.ArrayList()]]></initialValueExpression>
</variable>
...
<subreport>
    <reportElement x="0" y="0" width="515" height="20"/>
    <subreportParameter name="ReportTitle">
        <subreportParameterExpression><![CDATA[$P{ReportTitle}]]></subreportParameterExpression>
    </subreportParameter>
    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($V{HeadingsCollection})]]></dataSourceExpression>
    <subreportExpression class="java.lang.String"><![CDATA["HeadingsReport.jasper"]]></subreportExpression>
</subreport>

un autre échantillon:

<field name="cast" class="java.util.Collection"/>
...
<subreport>
    <reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true" backcolor="#99CCFF"/>
    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{cast})]]></dataSourceExpression>
    <subreportExpression class="java.lang.String"><![CDATA["JRMDbCastSubreport.jasper"]]></subreportExpression>
</subreport>

ou vous pouvez passer le source de données par le paramètre:

<parameter name="SubreportDataSource" class="net.sf.jasperreports.engine.JRDataSource"/>
...
<subreport>
    <reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true"/>
    <dataSourceExpression>$P{SubreportDataSource}</dataSourceExpression>
    <subreportExpression class="java.lang.String"><![CDATA["Subreport.jasper"]]></subreportExpression>
</subreport>

Remarque: En utilisant le même (avec rapport maître) source de données sous-rapport peut causer l' effet de perdre la première ligne dans le sous-rapport. Vous pouvez lire pourquoi manque-t-il le premier document de mon sous-rapport? post pour comprendre la façon d'éviter ce problème.

32
répondu Alex K 2016-05-13 19:35:42

Oui, vous devez être prudent sur la façon de passer d'une source de données. Avec une connexion SQL, vous pouvez simplement passer une Expression de connexion comme $P{REPORT_CONNECTION}. Puis le sous-rapport a sa propre requête SQL.

Dans votre cas, vous souhaitez transmettre les données réelles. En fonction des détails, il peut être aussi simple que de définir une Expression de paramètre comme $P{REPORT_PARAMETERS_MAP}. C'est sur un onglet différent dans la même fenêtre où vous avez placé la connexion sous-rapport dans iReport. Souvent, cela est suffisant pour passer le source de données.

mais vous pourriez avoir besoin d'un petit code pour gérer les choses. Prenons l'exemple D'une source de données CSV réutilisée dans les sous-rapports. La raison pour laquelle vous ne pouvez pas juste utiliser le Jrparamètre.REPORT_DATA_SOURCE objet est parce que le pointeur de ligne d'index n'est jamais réinitialisé, donc passer cet objet original dans le sous-port va amener le recordset à sa fin prématurément. Nous avons résolu ce problème avec une classe d'aide minimale:

package com.jaspersoft.untested_unsupported; 

import java.io.File; 
import java.io.FileNotFoundException; 
import net.sf.jasperreports.engine.JRDataSource; 
import net.sf.jasperreports.engine.data.JRCsvDataSource; 

public class CsvDataSourceFactory { 
    public static JRDataSource getDataSource(String fileName, boolean firstRowHeaders) throws FileNotFoundException { 
        JRCsvDataSource csvDs = new JRCsvDataSource(new File(fileName)); 
        csvDs.setUseFirstRowAsHeader(firstRowHeaders); 
        return csvDs; 
    } 
}
1
répondu mdahlman 2011-12-13 18:11:22

nous supposons que le paramètre source de données est "dataSourceParam" et que la valeur source de données (liste) est "dataSourceList"" dans la classe java nous mettons :

final Map<String, Object> params = new HashMap<String, Object>();
JRDataSource dataSource = new ListOfArrayDataSource( dataSourceList, 
                          new String[] {"date", "age", "adress", "email"});
params.put("dataSourceParam",dataSourceList);**

dans le modèle de rapport principal nous avons mis dans la déclaration de paramètres :

<parameter name="dataSourceParam" class="net.sf.jasperreports.engine.JRDataSource"/>

puis dans la balise de sous-rapport nous mettons:

<subreport isUsingCache="true">
    <reportElement key="subreport-1" stretchType="RelativeToTallestObject" isPrintRepeatedValues="false" x="112" y="45" width="338" height="29"/>
    <subreportParameter name="otherParameter">
        <subreportParameterExpression><![CDATA[$P{sumM1}]]></subreportParameterExpression>
    </subreportParameter>
    <dataSourceExpression><![CDATA[$P{dataSourceParam}]]></dataSourceExpression>
    <subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{subReportFile}]]></subreportExpression>
</subreport>
0
répondu Shessuky 2013-10-29 09:41:57

"REPORT_DATA_SOURCE" est un objet consommable, vous pouvez utiliser autant de temps que vous voulez.

j'ai testé la source de données en tant que source de données de fichier xml, et ne sera pas apparu comme ALEX a dit.

"ce ne sera pas perdre de la première ligne du sous-rapport."

je pense que peut-être j'utilise xpath pour sélectionner, donc à chaque fois de ne pas être la perte de dossiers.

si vous utilisez la base de données JDBC comme source de données, pealse passe le paramètre sql comme sous-rapport.

Si vous utilisez le ResultSet comme paramètre, peut-être perdre un enregistrement comme vous définissez le sous-rapport dans les bandes de détail.

0
répondu zg_spring 2013-11-07 07:43:27

c'est une vieille question à laquelle on a déjà répondu, mais je dois passer l'étape suivante au sous-rapport, en évitant la perte du premier enregistrement ou en passant tous les enregistrements au sous-rapport. Cette solution a l'avantage que le sous-rapport peut être utilisé comme rapport principal et est "simplement" passer l'enregistrement réel comme source de données du sous-rapport (en utilisant groovy comme lang du rapport):

<subreport>
    <reportElement x="261" y="25" width="200" height="100"/>
    <dataSourceExpression><![CDATA[new JRBeanCollectionDataSource(
       $P{REPORT_DATA_SOURCE}.data.toList().subList($V{REPORT_COUNT}-1,$V{REPORT_COUNT})]]></dataSourceExpression>
    <subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
</subreport>
0
répondu jneira 2017-03-10 09:49:18