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 librairies à intégrer aux applications.
Ces librairies permettent la visualisation ou l'export de données vers de multiples formats.

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

  • JapserReport est un outils 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ême de créer leur rapport 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 / logciels
  • Rien à signaler niveau puissance machine ... ce n'est pas un outils que l'on peut classer comme gourmand
  • OS: Linux, MS Windows, Mac ou autre pas de soucis, dès qu'il y a une machine virtuelle Java de disponible !
  • Un JDK (version 1.3 minimum) pour être tranquile
  • 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 leur 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-A1. 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-A2. 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-A3. Sortie au format désiré

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

  • 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ée, du CSV ou encore des Beans Java ... (via des dataSources).
Toutefois, une 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. Eléments constituants un rapport

IV-A. Eléments visuels

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

  • Texte Statique
  • Texte dynamiques (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 textes peuvent être mis en forme selon le besoin et leur type de donnée. 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 utiliser des expressions conditionnelles courtes de type ternaires:

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 9 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 (en-tête de page)
  • ColumnHeader (en-tê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-C1. 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-C2. 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 première page

IV-C3. 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-C4. 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 ou 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-C5. Detail

Le coeur 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ée 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

Au final, 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.

En-têtes de colonnes

Image non disponible

Des beaux en-tê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 page 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. Et 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 "utilisateurs": Ceux là c'est nous qui les définissons (type, valeur par défaut ...). Un rapport peut ne pas avoir de paramètres utilisateurs.

    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 ... utilisateurs (bon ok, c'était pas trop dur ;))

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

Les variables utilisateurs 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 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ême 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 sont le moment ou 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.
A chaque fois que l'année changera, je veux que le rapport me fasse un nouveau tableau, en affichant de nouveau les en-tê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 nouvelles 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). Et 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 page 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 saisie 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 openSource 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.?).
A 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'élements vers la zone d'édition du rapport.

Image non disponible


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

Image non disponible

XI. Limitations

Même si il est bien, l'outil n'est pas parfait non plus et possèdent 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.