I. Introduction▲
Parfois on a besoin d'illustrer nos rapports à l'aide de graphes. Cet article vous expliquera pas à pas comment générer un rapport contenant des graphes de différents formats via l'API JasperReports et JFreeChart.
II. Création du fichier JRXML▲
II-A. Présentation▲
Dans cet article je ne vais pas m'attarder sur les premières étapes pour la création d'un état jasper, vous pouvez toujours vous référez à cet article expliquant les différentes étapes pour créer et éditer un état jasper à partir d'une application web de type JSF.
Wikipédia définit JFreeChart comme étant une API Java permettant de créer des graphiques et des diagrammes de très bonne qualité. Cette API est open source et sous licence LGPL. En revanche, la documentation est payante.
L'API JFreeChart propose de nombreux types d'affichages de graphiques :
- Camemberts ;
- Courbes ;
- Histogrammes ;
- …
II-B. Téléchargement des bibliothèques nécessaires▲
Ici le site officiel officiel de l'API JFreeChart. Les différentes bibliothèques de l'API JFreeChart peuvent être téléchargées à partir de sourceforge.
II-C. Création de l'état sous iReport▲
La base de données utilisée dans cet article est de type ACCESS. Nous allons donc créer une base de données de type sur ACCESS en lui donnant pour nom TestJasperJFreeChart. Cette base de données contient une seule table Personne dont la définition des champs se présente comme suit :

Une fois cette table créée, nous devons l'alimenter par quelques enregistrements.
Sous iReport nous allons configurer la source de données pointant sur la base précédemment créée comme expliqué dans cet article.
Maintenant, nous allons créer un simple état à partir de la table Personne en listant tous ses enregistrements, en suivant toujours l'article précédemment mentionné.
Une fois notre état créé, nous y modifions la taille de la bande sommaire afin d'y mettre l'image qui contiendra le futur graphe. Pour ce faire, cliquez droit sur n'importe quelle bande (Header, footer, summary…) et choisissez Propriétés de bande.
Modifiez la taille de la bande sommaire, en y mettant 150 par exemple dans le champ Hauteur de bande comme le montre l'image suivante :
La partie sommaire, vide pour le moment, est bien visible sur notre rapport. Nous y plaçons un objet de type Image en sélectionnant l'objet Image en haut comme suit :
En plaçant cet objet sur le rapport, ce dernier ressemblera à ceci :
Créez un paramètre PersonneChart qui sera alimenté par la Classe Java et qui servira comme source de données pour le graphe sur l'état. Ce paramètre aura pour type java.awt.Image.
Double cliquer sur le graphe sous iReport, sélectionner l'onglet Image et mettre dans la propriété Expression de l'image l'expression $P{PersonneChart} comme suit :
Notre rapport est à présent prêt pour exécution. Nous pouvons le tester à partir de iReport, mais le graphe ne sera pas visible vu qu'on n'a pas encore alimenté le paramètre PersonneChart.
III. Exécution de l'état à partir d'une application Java▲
Pour tester notre état, nous allons créer une simple application Java qui y fera appel.
III-A. Configuration de l'environnement de travail▲
Nous allons créer une application Java testJasperJFreeChart. Créez un dossier lib pour y mettre les différentes bibliothèques y compris celles qu'on a téléchargées précédemment et mettez-les dans le CLASSPATH de l'application.
III-B. Création de la Classe appelant l'état▲
III-B-1. Exemple de graphe en Camembert▲
Créer une Classe MyTestCamembert et y insérer le code suivant :
package jaub;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.view.JasperViewer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
public class MyTestCamembert {
public MyTestCamembert() {
}
public static void main(String[] args) {
try {
Map parameters = new HashMap();
// on met dans le paramètre PersonneChart créé au niveau de iReport
// le résultat du chart créé avec les mêmes données issues
// de la table Personne
parameters.put("PersonneChart", createPersonneChartImage());
File file = new File("C:\\JASPER");
JasperPrint jasperPrint = JasperFillManager.fillReport(
new FileInputStream(new File(file, "personne.jasper")),
parameters, getConnection());
getConnection().close();
// on exporte l'état dans un fichier pdf
JasperExportManager.exportReportToPdfFile(jasperPrint,
"C:\\PersonnesCamembert.pdf");
// Affichage du rapport dans l'objet JasperViewer
JasperViewer.viewReport(jasperPrint);
} catch (Exception e) {
e.printStackTrace();
}
}
private static java.awt.Image createPersonneChartImage() throws SQLException {
// la variable infosPersonnes contient les noms
// des personnes (le champ Nom) comme clés
// et le nombre d'absences comme valeurs
java.util.Hashtable infosPersonnes = new Hashtable();
/**
* Alimentation de la variable infosPersonnes
*/
// On récupère l'objet Connection
PreparedStatement recherchePersonne = getConnection()
.prepareStatement("SELECT * FROM personne");
ResultSet resultats = null;
resultats = recherchePersonne.executeQuery();
boolean encore = resultats.next();
while (encore) {
infosPersonnes.put(resultats.getString(1), Double.parseDouble(resultats.getString(2)));
encore = resultats.next();
}
resultats.close();
// create a dataset...
DefaultPieDataset data = new DefaultPieDataset();
// fill dataset with infosPersonnes datas
for (java.util.Enumeration e = infosPersonnes.keys(); e
.hasMoreElements();) {
String employeeName = (String) e.nextElement();
data.setValue(employeeName, (Double) infosPersonnes
.get(employeeName));
}
// create a chart with the dataset
JFreeChart chart = ChartFactory.createPieChart("Personnes Chart", data,
true, true, true);
// create and return the image
return chart.createBufferedImage(500, 220);
}
// Retourne un objet de type Connection
// à partir d'un ODBC pointant vers
//la base de données ACCESS TestJasperJFreeChart
private static Connection getConnection() {
Connection conn = null;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (ClassNotFoundException e) {
}
// connexion à la base de données
try {
String DBurl = "jdbc:odbc:TestJasperJFreeChart";
conn = DriverManager.getConnection(DBurl);
} catch (SQLException e) {
}
return conn;
}
}À l'exécution de cette Classe, l'état est exporté sous format pdf sur C:\PersonnesCamembert.pdf et l'objet JasperViewer affiche l'ensemble des enregistrements de la table Personne ainsi qu'un graphe dans le sommaire comme suit :
III-B-2. Exemple de graphe en Histogramme en 3D▲
Créer une deuxième Classe MyTestHistogramme et y insérer le code suivant :
package jaub;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.view.JasperViewer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
public class MyTestHistogramme {
public MyTestHistogramme() {
}
public static void main(String[] args) {
try {
Map parameters = new HashMap();
// on met dans le paramètre PersonneChart créé au niveau de iReport
// le résultat du chart créé avec les mêmes données issues
// de la table Personne
parameters.put("PersonneChart", createPersonneChartImage());
File file = new File("C:\\JASPER");
JasperPrint jasperPrint = JasperFillManager.fillReport(
new FileInputStream(new File(file, "personne.jasper")),
parameters, getConnection());
getConnection().close();
JasperExportManager.exportReportToPdfFile(jasperPrint,
"C:\\PersonnesHistogramme.pdf");
// Affichage du rapport dans l'objet JasperViewer
JasperViewer.viewReport(jasperPrint);
} catch (Exception e) {
e.printStackTrace();
}
}
private static java.awt.Image createPersonneChartImage()
throws SQLException {
// la variable infosPersonnes contient les noms
// des personnes (le champ Nom) comme clés
// et le nombre d'absences comme valeurs
java.util.Hashtable infosPersonnes = new Hashtable();
/**
* Alimentation de la variable infosPersonnes
*/
PreparedStatement recherchePersonne = getConnection().prepareStatement(
"SELECT * FROM personne");
ResultSet resultats = null;
resultats = recherchePersonne.executeQuery();
boolean encore = resultats.next();
while (encore) {
// System.out.print(resultats.getString(1) + " " +
// resultats.getString(2));
System.out.println();
infosPersonnes.put(resultats.getString(1), Double
.parseDouble(resultats.getString(2)));
encore = resultats.next();
}
resultats.close();
// create a dataset
DefaultCategoryDataset defaultCategoryDataset = new DefaultCategoryDataset();
String s = "Personne";
// fill dataset with infosPersonnes
for (java.util.Enumeration e = infosPersonnes.keys(); e
.hasMoreElements();) {
String Personnename = (String) e.nextElement();
defaultCategoryDataset.addValue((Double) infosPersonnes
.get(Personnename), s, Personnename);
}
// create a chart with the dataset
JFreeChart chart = ChartFactory.createBarChart3D("Personne Chart", // Title
"Personne", // X-Axis label
"Nombre d'absences", // Y-Axis label
(CategoryDataset) defaultCategoryDataset, // Dataset
PlotOrientation.VERTICAL, true, // Show legend
true, true);
// create and return the image with the size specified in the XML design
return chart.createBufferedImage(500, 220);
}
private static Connection getConnection() {
Connection conn = null;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (ClassNotFoundException e) {
}
// connexion à la base de données
try {
String DBurl = "jdbc:odbc:TestJasperJFreeChart";
conn = DriverManager.getConnection(DBurl);
} catch (SQLException e) {
}
return conn;
}
}À l'exécution de cette Classe, l'état est exporté sous format pdf sur C:\PersonnesHistogramme.pdf et l'objet JasperViewer affiche l'ensemble des enregistrements de la table Personne ainsi qu'un graphe dans le sommaire comme suit :
IV. Téléchargement du code source▲
Le code source de l'application est disponible dans l'archive suivant :
Après décompression, vous aurez deux répertoires :
- JASPER : contient seulement le fichier Jasper, dans mon cas je l'ai mis dans C:\JASPER ;
- testJasperJFreeChart : contient le code source de l'application, ainsi que les différents fichiers JAR nécessaires.
V. Conclusion▲
Cet article a pour objectif de donner une des façons pour coupler les deux API JasperReports et JFreeChart pour illustrer un rapport avec différents types de graphes. L'application pourra être optimisée afin de n'exécuter la même requête qu'une seule fois, chose qui pourra faire l'objet d'une mise à jour de cet article à l'avenir.
VI. Remerciements▲
Mes remerciements vont à Baptiste Wicht pour ses remarques et à Fleur-Anne.Blain pour ses remarques et sa relecture précieuse.












