IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Initiation à JasperReports - iReport / Présentation des concepts généraux

La sortie de documents imprimables, spécialement formatés est un problème récurrent dans les applications.
La production de documents PDF, l'export de données vers Excel, Word constituent des fonctionnalités souvent attendues par les utilisateurs.
Un produit gratuit et open source, JasperReports permet d'obtenir rapidement des résultats satisfaisants dans ce domaine…

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Objectif de ce document

L'objectif est ici de présenter les concepts généraux de JasperReports et l'éditeur iReport.
Nous ne traiterons par ici de l'intégration de JasperReports au sein d'un code existant ni de son interfaçage avec votre IDE favori.

II. Présentation - Prérequis

II-A. Brève présentation

JasperReports est outil 100 % open source de génération d'états/ rapports développé en Java, pour des applications Java.
Il se présente sous la forme de bibliothèques à intégrer aux applications.
Ces bibliothèques permettent la visualisation ou l'export de données vers de multiples formats.

II-B. Ce que peut ou ne peut pas faire l'outil

  • JapserReport est un outil de Business Intelligence, de reporting.

    Il peut :
  • produire des documents types : bons de commande, factures, rapports d'activités… bref des documents le plus souvent dynamiques, à partir de données existantes, et ce dans divers formats ;
  • permettre l'export de données à des formats divers pour une application existante (sortie imprimable, mailing…).
    Mais il ne peut pas :
  • permettre aux utilisateurs eux-mêmes de créer leurs rapports ou alors des utilisateurs qui connaissent SQL et un peu de Java ;
  • faire griller les toasts et faire le café.

II-C. Prérequis pour utiliser l'outil

Les prérequis ne sont pas bien méchants.

Matériels / logiciels

  • Rien à signaler niveau puissance machine… ce n'est pas un outil que l'on peut classer comme gourmand.
  • OS : Linux, MS Windows, Mac ou autres pas de souci, dès qu'il y a une machine virtuelle Java de disponible !
  • Un JDK (version 1.3 minimum) pour être tranquille.
  • Les drivers JDBC pour votre source de données (si base de données).

Connaissances

  • SQL : les rapports se basent sur des requêtes SQL le plus souvent : select, where, order, jointures et leurs amis seront de la partie.
  • Java niveau basique, utilisation des classes de base : String, Integer, BigDecimal…

III. Le rapport

III-A. Cycle de vie d'un rapport

Image non disponible

III-A-1. Fichier XML

Dans un premier temps, le développeur crée le rapport au format XML, via l'éditeur graphique iReport ou encore n'importe quel éditeur de texte (c'est du xml après tout :)).
Ce fichier porte généralement l'extension .jrxml (Jasper Report XML).

III-A-2. Fichier jasper

Le fichier JRXML est ensuite compilé pour pouvoir être utilisé. Cette compilation peut se faire dans iReport comme dans le code d'une application. Dans le cas d'une application, ce sera souvent le fichier compilé qui sera appelé, car il est généralement inutile et coûteux de recompiler le XML à chaque appel du rapport

III-A-3. Sortie au format désiré

À partir du même fichier japser, JasperReport peut ensuite produire plusieurs types de fichiers :

  • PDF ;
  • XLS (Excel) ;
  • ODF (OpenOffice) ;
  • RTF (Word en autres) ;
  • CSV ;
  • Texte ;

Pour cela, on transmet les paramètres voulus (si besoin), on spécifie le type de sortie désiré et voilà, un beau fichier !

III-B. Sources de données

JapserReports accepte plusieurs types de sources de données. Que ce soit classiquement une base de données, du CSV ou encore des Beans Java… (via des dataSources).
Toutefois, un rapport ne peut avoir qu'une seule source de données et ne peut faire qu'une seule requête SQL ! Heureusement un rapport peut être composé de sous-rapports qui auront chacun leur requête (ouf, sauvés !)…

Image non disponible

IV. Éléments constituant un rapport

IV-A. Éléments visuels

Un rapport peut être constitué de multiples éléments visuels :

  • Texte statique
  • Texte dynamique (extraites de données en bases, retraitées ou non)
  • Graphiques (histogrammes, camemberts….)
  • Formes géométriques plus ou moins complexes
  • Images
  • Liens hypertextes

Les champs texte peuvent être mis en forme selon le besoin et leur type de données. La concaténation statique / dynamique est bien évidemment possible.

IV-B. Tiens, du Java ! (ou groovy)

  • Chaque paramètre, variable, champ est typé. Les types utilisés sont les classes enveloppes de Java (String,Integer, BigDecimal…), et non les types primitifs.
  • Pour les paramètres et les variables, les types sont définis quand on les déclare (iReport).
  • Pour les champs provenant de la base de données, les types sont automatiquement identifiés et éventuellement modifiables.

Ce typage permet d'appliquer des méthodes Java sur chaque objet. Par exemple un toLowerCase() sur un String. On peut ainsi facilement appeler les méthodes statiques des classes de base Java (ex. : Float.parseFloat()).

Il est également fréquent d'utiliser des expressions conditionnelles courtes de type ternaire :

ex. : nom!=null:nom?« toto » => Si le nom n'est pas null, tu le prends sinon tu prends « toto ».

IV-C. Les différentes parties d'un rapport

La composition du rapport ressemble à ce qui se fait dans d'autres produits de reporting. Nous allons ici détailler ces parties pour les personnes qui ne sont pas familières avec les outils de génération de rapports, c'est une manière de penser qu'il faut acquérir, mais qui vient rapidement.

Le rapport est composé de neuf parties jusque iReport 2.0.1, 10 au-delà, que nous allons détailler. Ces parties sont :

  • Background : l'arrière-plan du rapport (logo, etc.) ;
  • Title (Titre) ;
  • PageHeader (entête de page) ;
  • ColumnHeader (entête de colonne) ;
  • Detail (corps du rapport) ;
  • ColumnFooter (pied de colonne) ;
  • PageFooter (pied de page) ;
  • LastPageFooter (pied de la dernière page) ;
  • Summary ;
  • No-Data (depuis 2.02) : ce qui sera affiché sur demande quand la requête SQL (par exemple) ne renvoie rien.

Chaque partie s'affiche à un moment précis dans le rapport, elles sont ici classées dans l'ordre.

IV-C-1. Background

Une partie très simple, il s'agit de l'arrière-plan de la page, si vous voulez y mettre un logo ou autre… on peut évidemment y mettre des éléments dynamiques.

IV-C-2. Title - LastPageFooter

Le contenu de Title n'est affiché qu'une seule fois en haut de la première page.

Si vous voulez mettre un logo ou un titre à votre rapport de 10 pages et désirez que celui-ci n'apparaisse que dans la première page. C'est dans cette zone qu'il faudra le mettre.

De la même manière, LastPageFooter n'est affiché qu'une seule fois en bas de la dernière page.

IV-C-3. PageHeader - PageFooter

Contrairement au title, le contenu de PageHeader est affiché en haut de toutes les pages du rapport.

Si vous voulez mettre un logo ou un titre à votre rapport de 10 pages et désirez que celui-ci apparaisse en haut de chaque page. C'est dans cette zone qu'il faudra le mettre.

Question : si je mets à la fois title et pageHeader que se passe-t-il sur la première page ?
Réponse : vous aurez les deux.

IV-C-4. ColumnHeader - ColumnFooter

C'est dans ColumnHeader qu'on définira les entêtes des colonnes d'un tableau, elles seront répétées sur chaque page du rapport où le tableau est présent.

Vous commencez à y être habitué, ColumnFooter est son pendant en bas de chaque colonne, répété sur chaque page si nécessaire.

IV-C-5. Detail

Le cœur du rapport… La plupart du temps, c'est la zone qui contient les données que l'on affiche, issues de la requête SQL après retraitement ou non… Cette zone est reproduite pour chaque ligne de résultat renvoyée par la requête SQL.
Si vous collez un rond tout seul dans cette zone et que la requête SQL ramène 10 résultats, vous obtiendrez 10 ronds l'un en dessous de l'autre !

IMPORTANT : l'ordre d'affichage des éléments sera celui ramené par la requête ou la source de données le cas échéant !

V. Euh, et concrètement ? Un exemple !

V-A. Objectif : Rapport voulu

Considérons que l'on veut afficher une liste d'entreprises.
La requête SQL est de la forme « SELECT * FROM ENTREPRISES WHERE… ORDER BY… »

Le logo / titre du rapport doit exister sur la première page uniquement et chaque page devra avoir un numéro de page et un pied.

Finalement, l'objectif est d'avoir quelque chose dans le genre :

Image non disponible

V-B. Le fichier JRXML dans iReport

Le titre   :

Image non disponible

Le grand carré avec un dessin dedans c'est le logo :)
Le titre est statique dans une bande grisée.

Entêtes de colonnes

Image non disponible

Des beaux entêtes de colonnes statiques (c'est souvent le cas…), grisés pour un peu plus d'esthétique.

Le détail

Image non disponible

Là c'est 100 % dynamique, on utilise les champs ramenés par la requête (vous pouvez voir la syntaxe au passage : $F{NOMDUCHAMP}).
Ces éléments seront répétés autant de fois que la requête SQL a ramené d'enregistrements.

Pied de page

Image non disponible

Ici on insère le numéro de page grâce à des variables (on y revient plus tard…) ainsi que le nombre total de pages et un texte statique à la fin.

VI. Paramètres, Variables, Champs…

VI-A. Paramètres

Cas concret : je possède un rapport qui donne le détail sur les informations de l'entreprise X.
Il va donc falloir pouvoir influer sur le rapport en lui disant de quelle entreprise on parle. Les paramètres sont là pour ça.

Il existe deux types de paramètres :

  • les paramètres dits « intégrés » : ils sont peu nombreux, mais obligatoires pour le bon fonctionnement du rapport.
    Ils possèdent souvent une valeur par défaut, ce qui permet donc de ne pas s'en préoccuper.
    Citons toutefois parmi eux la connexion à la base de données. Eh oui, c'est un paramètre (et intégré !), il faudra le transmettre en général si on veut avoir des résultats… Depuis un IDE ou une application, on transmettra assez souvent une connexion déjà existante ;
  • les paramètres « utilisateur » : ceux-là c'est nous qui les définissons (type, valeur par défaut…). Un rapport peut ne pas avoir de paramètres utilisateur.

    Exemple : on veut l'entreprise avec l'identifiant ID='X', on insérera donc le paramètre dans la requête SQL. On créera donc le paramètre 'ENTREPRISE_ID', de type String et la requête SQL ressemblera à ça : SELECT * from entreprises WHERE ID=$P{ENTREPRISE_ID}


Syntaxe : $V{NOMDELAVARIABLE}

VI-B. Variables

Les variables sont des valeurs qui n'existent qu'au sein du rapport. Là encore, deux types de variables, intégrées et… utilisateur (bon OK, c'était pas trop dur ;))

Les variables intégrées sont par exemple le numéro de la page, le nombre d'enregistrements traités par page…

Les variables utilisateur peuvent être simples ou encore définies comme des sommes de valeurs d'un ou plusieurs champs… bref pas mal de possibilités et iReport permet de faire rapidement beaucoup de choses.

Syntaxe : $P{NOMDUPARAMETRE}

VI-C. Champs (Fields)

Ce sont les résultats de la requête SQL ou des sources de données. Elles changent au fur et à mesure que jasperReports lit les enregistrements dans la zone détail.

Syntaxeš: $F{NOMDUCHAMP}

VII. Les sous-rapports

On ne peut avoir qu'une source de données et une requête SQL par rapport, ceci aurait pu être gênant, mais c'est là qu'interviennent les sous-rapports !

Les sous-rapports sont des rapports dans les rapports. Pour créer un sous-rapport, rien de plus simple, on crée un rapport normal, que l'on appellera dans un autre rapport qui deviendra donc le rapport « père ».

Un rapport peut contenir plein de sous-rapports qui peuvent eux-mêmes en contenir ! Attention à ne pas trop compliquer.

Enfin, on peut transmettre les informations que l'on veut depuis le rapport père vers le rapport fils. On se servira ainsi des paramètres du rapport fils.

Exemple
Dans le cas de notre entreprise, si on désire avoir tous les résultats financiers de l'entreprise dont on connaît l'identifiant, on créera alors un sous-rapport dont la requête sera de la forme
select * from resultats WHERE identifiant_entreprise=$P{MONIDENTIFIANT}
Et on s'assurera dans le rapport père de passer le paramètre $P{MONIDENTIFIANT} au rapport fils en lui donnant la valeur voulue.

VIII. Les groupes

Voilà une fonction un peu plus compliquée de l'outil, mais souvent très pratique.

Qu'est-ce qu'un groupe ?
Title, pageHeader, detail… sont des groupes !
La seule chose qui change entre ces éléments est le moment où ils sont « évalués », où ils interviennent, l'un à la fin une seule fois, l'autre au début de chaque page.

Les groupes permettent une grande souplesse, par exemple on peut définir le groupe « année ».
Ce que l'on mettra dans ce groupe pourra ainsi être affiché à chaque changement d'année dans les données… explication.

Un peu de concret ?

Je souhaite détailler la production de l'entreprise pour chaque année.
À chaque fois que l'année changera, je veux que le rapport me fasse un nouveau tableau, en affichant de nouveau les entêtes de colonnes.
Pour cela je vais créer un groupe que j'appellerai par exemple « grp_annee » et qui aura pour « valeur associée » l'année.
Grâce à cela, quand l'année changera, jasper créera un nouveau tableau, avec de nouveaux entêtes de colonnes :).

Image non disponible

Un groupe aura un groupeHeader et un groupeFooter qui apparaîtront à chaque fois qu'on aura un changement dans la valeur associée.
Sur l'exemple ci-dessus, les entêtes du tableau étaient dans le groupe grp_anneeHeader, ils ont été répétés à chaque changement de valeur.

IX. Le temps ou moment d'évaluation

Allez, encore une notion un peu compliquée et ce sera fini (pour ce tuto…).

Qu'est-ce que c'est que ce truc ?
Pour illustrer cette explication, je vais prendre un cas concret. Imaginons que vous vouliez mettre en pied de page le numéro de page au format Page X/Y ou X est la page courante et Y le nombre de pages total (Page 3/5 par exemple). Eh ben là ce n'est pas si trivial que ça : iReport propose bien parmi les variables intégrées une variable $V{PAGE_NUMBER} et qui a pour valeur la page actuelle. La question qui vient donc naturellement est « mais, et pour le nombre de pages total ??? ». La réponse encore brumeuse est « c'est la même variable, mais pas au même moment, c'est toujours $V{PAGE_NUMBER}, mais avec la valeur qu'elle a quand le rapport est fini ».

Et c'est là qu'on touche du doigt une notion, le « temps d'évaluation »: il faut qu'on mette à cet endroit la valeur de la variable « quand le rapport est fini ». La bonne nouvelle c'est que ce n'est pas compliqué du tout de le faire :)

Exemple : nous allons donc saisir deux zones de texte dynamiques

Image non disponible

dont les valeurs vaudront :

  • « Page » + String.valueOf($V{PAGE_NUMBER}) + « / » Pour la première ;
  • «   » + String.valueOf($V{PAGE_NUMBER}) Pour la seconde.

Ce qui est censé nous donner un affichage du type « Page X/Y ».
La différence entre ces deux valeurs c'est que nous allons dire à japserReports de les évaluer à des moments différents, en réglant le temps d'évaluation à « Maintenant » (valeur par défaut) pour le premier, et « Rapport » pour le deuxième. La zone de texte n° 2 aura donc la valeur de la variable en fin de rapport ! Allez deux petites copies pour le coup :

Image non disponible
Image non disponible

X. iReport

Image non disponible


Un bon outil de reporting c'est bien, mais avec un bon Designer c'est beaucoup mieux. Et quand ce Designer est lui aussi open source et gratuit, on aime. iReport n'est peut être pas la Rolls dans son domaine, mais il fonctionne bien et vous permettra bien des choses. Chaque version de iReport est associée à une version de JasperReports (attention les numéros peuvent être trompeurs, iReport 2.0 fonctionnait avec JasperReports 1.3.?).
À ce jour le dernier en date est iReport 2.0.2, fonctionnant avec JasperReports 2.0.

Image non disponible



Fenêtre principale
C'est là qu'on va travailler, on y voit toutes les zones par défaut.

Image non disponible


Barre de menus
Euh que dire, plein de boutons, je ne vais pas les détailler ici… Compilation, exécution, alignement…

Image non disponible


Fenêtre structure
La fenêtre « structure » permet de déclarer, modifier paramètres, variables et champs.
Il permet également du drag'and'drop d'éléments vers la zone d'édition du rapport.

Image non disponible


Fenêtre Propriétés
Chaque élément a ses propriétés, c'est ici qu'on sait lesquelles et qu'on peut les modifier.

Image non disponible

XI. Limitations

Même s’il est bien, l'outil n'est pas parfait non plus et possède comme tous des limites. En voici quelques-unes…

  • Objets bas niveaux, la notion de tableau n'existe pas par exemple.
  • Une seule source / requête par rapport.
  • Formats de sortie : les graphiques sont toujours des images, la sortie en RTF se fait via des zones de texte.

XII. Quelques exemples de rapports en sortie

Image non disponible
Image non disponible

XIII. Liens

XIV. Remerciements

Merci à RideKick pour sa relecture et la correction orthographique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2013 Jean-Philippe Guilloux. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.