JasperReports - Tableaux croisés

Les rapports de tableau croisé (tabulation croisée) sont les rapports contenant des tableaux qui organisent les données sur des lignes et des colonnes sous forme de tableau. L'objet de tableau croisé est utilisé pour insérer un rapport de tableau croisé dans le rapport principal. Les tableaux croisés peuvent être utilisés avec n'importe quel niveau de données (nominal, ordinal, intervalle ou rapport) et affichent généralement les données résumées, contenues dans les variables du rapport, sous la forme d'un tableau dynamique. Les variables sont utilisées pour afficher des données agrégées telles que des sommes, des nombres, des valeurs moyennes.

Propriétés du tableau croisé

Élément JRXML <crosstab> est utilisé pour insérer un tableau croisé dans un rapport.

Attribut

Voici une liste d'attributs d'un <crosstab> élément -

  • isRepeatColumnHeaders- Indique si les en-têtes de colonne doivent être réimprimés après un saut de page. La valeur par défaut est true .

  • isRepeatRowHeaders- Indique si les en-têtes de ligne doivent être réimprimés après un saut de colonne de tableau croisé. La valeur par défaut est true .

  • columnBreakOffset- Lorsqu'un saut de colonne se produit, indique la quantité d'espace vertical, mesurée en pixels, avant le morceau de tableau croisé suivant à placer sous le précédent sur la même page. La valeur par défaut est 10.

  • runDirection- Indique si les données du tableau croisé doivent être remplies de gauche à droite (LTR) ou de droite à gauche (RTL). La valeur par défaut est LTR.

  • ignoreWidth- Indique si le tableau croisé s'étendra au-delà de la limite de largeur initiale du tableau croisé et ne générera pas de sauts de colonne. Sinon, il arrêtera le rendu des colonnes dans la limite de largeur du tableau croisé et continuera avec les colonnes restantes seulement après que toutes les lignes aient commencé le rendu. La valeur par défaut est false .

Sous-éléments

Un élément <crosstab> a les sous-éléments suivants -

  • <reportElement>- Cet élément définit la position, la largeur et la hauteur du tableau croisé dans son cadre. Les attributs de cet élément incluent tous les attributs <reportElement> standard.

  • <crosstabParameter>- Cet élément est utilisé pour accéder aux variables et paramètres du rapport à partir du tableau croisé. Les attributs de cet élément incluent -

    • name - Ceci définit le nom du paramètre.

    • class - Ceci indique la classe de paramètre.

  • <parametersMapExpression>- Cet élément est utilisé pour transmettre une variable de rapport ou un paramètre contenant une instance de java.util.Map , en tant qu'ensemble de paramètres pour le tableau croisé. Cet élément ne contient aucun attribut.

  • <crosstabDataset>- Cet élément définit le jeu de données à utiliser pour peupler le tableau croisé (voir la section suivante pour une explication détaillée). Les attributs de cet élément incluent -

    • isDataPreSorted - Ceci indique si les données de l'ensemble de données sont pré-triées. La valeur par défaut est false .

  • <crosstabHeaderCell>- Cet élément définit le contenu de la région trouvée dans le coin supérieur gauche du tableau croisé où les en-têtes de colonne et les en-têtes de ligne se rencontrent. La taille de cette cellule est calculée automatiquement en fonction des largeurs et hauteurs de ligne et de colonne définies.

  • <rowGroup>- Cet élément définit un groupe utilisé pour diviser les données en lignes. Les attributs de cet élément incluent -

    • name - Ceci définit le nom du groupe de lignes.

    • width - Ceci définit la largeur du groupe de lignes.

    • headerPosition - Ceci définit la position du contenu de l'en-tête (Top, Middle, Bottom, Stretch).

    • totalPosition - Ceci définit la position de la colonne entière (Début, Fin, Aucun).

    Cet élément contient les sous-éléments suivants -

    • <bucket>

    • <crosstabRowHeader>

    • <crosstabTotalRowHeader>

  • <columnGroup>- Cet élément définit un groupe utilisé pour diviser les données en colonnes. Les attributs de cet élément incluent -

    • name - Ceci définit le nom du groupe de colonnes.

    • height - Ceci définit la hauteur de l'en-tête du groupe de colonnes.

    • headerPosition - Ceci définit la position du contenu de l'en-tête ( Droite, Gauche, Centre, Étiré ).

    • totalPosition - Ceci définit la position de la colonne entière ( Début, Fin, Aucun ).

    Cet élément contient les sous-éléments suivants -

    • <bucket>

    • <crosstabColumnHeader>

    • <crosstabTotalColumnHeader>

  • <measure>- Cet élément définit le calcul à effectuer sur les lignes et les colonnes. Les attributs de cet élément incluent -

    • name - Ceci définit le nom de la mesure.

    • class - Ceci indique la classe de mesure.

    • calcul - Ceci indique le calcul à effectuer entre les valeurs de cellule du tableau croisé. Ses valeurs peuvent être l'une de ces valeurs: Nothing, Count, DistinctCount, Sum, Average, Minimum, Maximum, StandardDeviation, Variance et First . La valeur par défaut estNothing.

  • <crosstabCell>- Cet élément définit la manière dont les données dans les cellules sans en-tête seront présentées. Les attributs de cet élément incluent -

    • columnTotalGroup - Ceci indique le groupe à utiliser pour calculer le total de la colonne.

    • height - Ceci définit la hauteur de la cellule.

    • rowTotalGroup - Ceci indique le groupe à utiliser pour calculer le total des lignes.

    • width - Ceci définit la largeur de la cellule.

  • <whenNoDataCell>- Cet élément définit ce qu'il faut afficher sur une cellule de tableau croisé vide. Cet élément ne contient aucun attribut.

Regroupement de données dans le tableau croisé

Le moteur de calcul de tableau croisé agrège les données en effectuant une itération dans les enregistrements de l'ensemble de données associés. Afin d'agréger les données, il faut d'abord les regrouper. Dans un tableau croisé, les lignes et les colonnes sont basées sur des éléments de groupe spécifiques, appelésbuckets. Une définition de compartiment doit contenir -

  • bucketExpression - Expression à évaluer pour obtenir des éléments de groupe de données.

  • comparatorExpression - Nécessaire dans le cas où l'ordre naturel des valeurs n'est pas le meilleur choix.

  • orderByExpression - Indique la valeur utilisée pour trier les données.

Les groupes de lignes et de colonnes (définis ci-dessus) dans un tableau croisé reposent sur buckets.

Variables totales du tableau croisé intégré

Vous trouverez ci-dessous une liste de la valeur actuelle de la mesure et des totaux des différents niveaux correspondant à la cellule accessibles via des variables nommées selon le schéma suivant -

  • La valeur actuelle d'un calcul de mesure est stockée dans une variable portant le même nom que la mesure.

  • <Mesure> _ <Groupe de colonnes> _ALL - Cela donne le total de toutes les entrées du groupe de colonnes de la même ligne.

  • <Mesure> _ <Groupe de lignes> _ALL - Cela donne le total de toutes les entrées du groupe de lignes de la même colonne.

  • <Mesure> _ <Groupe de lignes> _ <Groupe de colonnes> _ALL - Cela donne le total combiné correspondant à toutes les entrées dans les groupes de lignes et de colonnes.

Exemple

Pour illustrer les tableaux croisés, écrivons un nouveau modèle de rapport (jasper_report_template.jrxml). Ici, nous allons ajouter le tableau croisé à la section récapitulative. Enregistrez-le dans le répertoireC:\tools\jasperreports-5.0.1\test. Le contenu du fichier est indiqué ci-dessous -

<?xml version = "1.0" encoding = "UTF-8"?>

<!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN"
   "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
	
<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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>
   
   <field name = "name" class = "java.lang.String"/>
   <field name = "country" class = "java.lang.String"/>
   
   <title>
      <band height = "70">
         
         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>
         
         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>
            
            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>
            
            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>
         
         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>
            
            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>
         </textField>
      
      </band>
   </title>
   
   <summary>
      <band height = "60">
      
      <crosstab>
         <reportElement width = "782" y = "0" x = "0" height = "60"/>
          
         <rowGroup name = "nameGroup" width = "100">
         
            <bucket>
               <bucketExpression class = "java.lang.String">
                  <![CDATA[$F{name}]]>
               </bucketExpression>
            </bucket>
            
            <crosstabRowHeader>
            
               <cellContents>
                  <box border = "Thin" borderColor = "black"/>
                  
                  <textField>
                     <reportElement width = "100" y = "0" x = "0" height = "20"/>
                     <textElement textAlignment = "Right" 
                        verticalAlignment = "Middle"/>
                     
                     <textFieldExpression>
                        <![CDATA[$V{nameGroup}]]>
                     </textFieldExpression>
                  </textField>
            
               </cellContents>
         
            </crosstabRowHeader>

         </rowGroup>
         
         <columnGroup name = "countryGroup" height = "20">
            <bucket>
               
               <bucketExpression class = "java.lang.String">
                  $F{country}
               </bucketExpression>
            </bucket>
            
            <crosstabColumnHeader>
               <cellContents>
                  <box border = "Thin" borderColor = "black"/>
                  <textField isStretchWithOverflow = "true">
                     <reportElement width = "60" y = "0" x = "0" height = "20"/>
                     <textElement verticalAlignment = "Bottom"/>
                     <textFieldExpression>
                        <![CDATA[$V{countryGroup}]]>
                     </textFieldExpression>
                  </textField>
               </cellContents>
            </crosstabColumnHeader>

         </columnGroup>
         
         <measure name = "tailNumCount" class = "java.lang.Integer"  
            calculation = "Count">
            <measureExpression>$F{country}</measureExpression>
         </measure>
         
         <crosstabCell height = "20" width = "60">
            <cellContents backcolor = "#FFFFFF">
               <box borderColor = "black" border = "Thin"/>
               <textField>
                  <reportElement x = "5" y = "0" width = "55" height = "20"/>
                  <textElement textAlignment = "Left" 
                     verticalAlignment = "Bottom"/>
                  <textFieldExpression class = "java.lang.Integer">
                      $V{tailNumCount}
                  </textFieldExpression>
               </textField>
            </cellContents>
         </crosstabCell>
      
      </crosstab>
      
      </band>
   </summary>
	
</jasperReport>

Les détails du fichier ci-dessus sont les suivants -

  • Le tableau croisé est défini par l'élément <crosstab>.

  • L'élément <rowGroup> définit un groupe pour diviser les données en lignes. Ici, chaque ligne affichera des données pour un nom différent.

  • Les éléments <bucket> et <bucketExpression> définissent l'expression de rapport à utiliser comme délimiteur de groupe pour <rowGroup>. Ici, nous avons utilisé le champ de nom comme délimiteur, afin de diviser les lignes par nom.

  • L'élément <crosstabRowHeader> définit l'expression à utiliser comme en-tête de ligne. Il contient un seul sous-élément, à savoir <cellContents>, qui agit comme une bande interne dans le tableau croisé. Au lieu de définir le nom de la variable pour le champ de texte à l'intérieur de <crosstabRowHeader>, nous avons attribué le nom à <rowGroup> (via son attribut name), d'où il crée une variable implicite. L'élément <crosstabRowHeader> définit le contenu de la cellule d'en-tête pour la ligne entière. Il prend un seul élément <cellContents> comme seul sous-élément.

  • L'élément <columnGroup> ainsi que ses sous-éléments sont analogues à l'élément <rowGroup>, sauf qu'il influence les colonnes au lieu des lignes.

  • L'élément <measure> définit le calcul à effectuer sur les lignes et les colonnes. L' attribut de calcul est défini sur Count .

  • L'élément <crosstabCell> définit la manière dont les données dans les cellules sans en-tête seront disposées. Cet élément contient également un seul élément <crosstabCell> comme seul sous-élément.

Les codes java pour le remplissage des rapports restent inchangés. Le contenu du fichierC:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java sont comme indiqué ci-dessous -

package com.tutorialspoint;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName = 
         "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource =
      new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

Le contenu du fichier POJO C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java sont comme suit -

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

Le contenu du fichier C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java sont comme suit -

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);
      
      return dataBean;
   }
}

Génération de rapports

Ensuite, compilons et exécutons les fichiers ci-dessus en utilisant notre processus de construction ANT normal. Le contenu du fichier build.xml (enregistré sous le répertoire C: \ tools \ jasperreports-5.0.1 \ test) est indiqué ci-dessous.

Le fichier d'importation - baseBuild.xml est extrait du chapitre Configuration de l'environnement et doit être placé dans le même répertoire que le build.xml.

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />
   
   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the 
      report stored in the .JRprint file.">
      
      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>
   
   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">
      
      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>
      
      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>
		
   </target>
	
</project>

Ensuite, ouvrons la fenêtre de ligne de commande et allons dans le répertoire où build.xml est placé. Enfin, exécutez la commandeant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport est la cible par défaut) comme suit -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting to
   [javac] Compiling 3 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig 
      for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger (
   net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 20 minutes 53 seconds

À la suite de la compilation ci-dessus, une fenêtre JasperViewer s'ouvre comme indiqué dans l'écran ci-dessous -

Ici, nous voyons que chaque pays et nom sont tabulés.