Les développeurs de sites et d'applications mobiles doivent souvent contrôler la préparation des pages PDF pour l'impression ou leur envoi aux clients par courrier.
Les fichiers PDF ont un contrôle total sur l'affichage du texte et des graphiques sur la page. Malheureusement, les bibliothèques de génération de fichiers PDF à remplissage dynamique ne sont pas incluses dans les outils standard de PHP, JS (Web), Java ou Swift (Android et iOS, respectivement). Dans cet article, je veux vous parler de la solution open source pour générer des fichiers PDF.
JasperReports est une bibliothèque Java open source pour générer des fichiers remplis dynamiquement. Il dispose de nombreux outils pour créer des formulaires de rapport complexes, y compris au format PDF, mais d'autres formats sont également disponibles: RTF, DOCX, HTML, XLS, XLS, CSV et XML. En d'autres termes, il suffit de développer un formulaire, de faire une mise en page - et il sera possible de l'exporter dans l'un des formats ci-dessus.
Il existe également de bonnes bibliothèques, telles que PDFLib (version commerciale) pour PHP et sa version open source de PDFLib-Lite. Certes, la bibliothèque est assez chère et la version allégée est distribuée uniquement dans le code source, et lorsqu'elle est installée dans l'environnement de développement, cette limitation peut devenir un problème.
PDFbox est une autre bibliothèque Java open source pour travailler avec des documents PDF. Il vous permet de créer de nouveaux documents PDF, de gérer des documents existants avec la possibilité d'en extraire le contenu. Mais il n'a pas d'interface utilisateur (UI), contrairement à JasperReports.
Je pense que JasperReports est particulièrement utile dans les grands projets liés au reporting et pas seulement au format PDF. Il a tout ce dont vous avez besoin pour l'implémenter dans votre projet: création simple de formulaires de rapport complexes, interface utilisateur pour une mise en page pratique, application serveur et intégration simple avec le front.
Dans l'article, je couvrirai les sujets suivants:
- Installez l'environnement de développement et l'application serveur.
- Créez un fichier PDF automatiquement rempli à partir de la base de données.
- Intégration de l'application serveur avec le front-end pour obtenir le PDF créé.
Pour commencer à utiliser JasperReports dans votre projet, vous devez télécharger deux applications: JaspersoftStudio - ci-après nous l'appellerons l'
environnement de travail - et JasperServer - nous appellerons l'
application serveur .
JaspersoftStudio est un environnement de développement basé sur Eclipse avec la bibliothèque Java JasperReports intégrée où des fichiers PDF dynamiques ou statiques sont développés: par exemple, des tickets, des reçus, des contrats, des graphiques analytiques et autres.
JasperServer est une application serveur où les fichiers sont déployés et stockés à partir de JaspersoftStudio. Ils sont accessibles depuis une application mobile ou web. JasperServer a une interface utilisateur, avec laquelle vous pouvez afficher des rapports, créer des comptes pour différents utilisateurs et leur donner un accès approprié. Vous pouvez également configurer la liste de diffusion pour envoyer un e-mail (planificateur).
Configurer l'environnement de travail et l'application serveur
Vous pouvez télécharger et installer des applications en utilisant les liens ci-dessus. Après la configuration de deux applications, il est nécessaire d'établir une connexion entre l'environnement de travail et l'application serveur.
Serveurs → Créer une connexion au serveur JasperReports → Spécifiez le nom de serveur préféré, l'
URL , le nom d'utilisateur et le mot de passe. Cliquez sur
Tester la connexion pour vérifier que la connexion au serveur est établie. Si vous voyez
Réussi - allez plus loin.

Créez un PDF à remplissage dynamique et publiez-le
Nous avons installé l'environnement de développement, le serveur et établi une connexion entre eux. Créons maintenant un fichier PDF à remplissage dynamique primitif qui, lorsqu'il est lancé (généré), prendra les données de PostgreSQL et les installera sur une application serveur.
Tout d'abord, vous devez attacher la source de données (dans notre cas, PostgreSQL) à l'environnement de travail, d'où le PDF prendra les données. Commençons ensuite le développement de notre premier fichier PDF.
Adaptateurs de données → Créer un adaptateur de données → Connexion JDBS à la base de données et spécifiez les données de connexion:
- Pilote JDBC - PostgreSQL (org.postgresql.Driver). S'il n'y a pas de pilote pour votre SGBD, vous pouvez installer le pilote nécessaire dans l'onglet Chemin de classe du pilote.
- URL JDBC - elle se compose de leur nom d'hôte, de port et de base de données.
- Nom d'utilisateur et mot de passe - journal de connexion depuis votre compte SGBD.

Nous cliquons sur le bouton
Test qui nous est déjà familier et après une connexion réussie (réussie) avec la base de données -
Terminer .
A partir de cette base de données, le PDF sera renseigné dans l'environnement de production. Puisque nous prévoyons de déployer également notre premier fichier PDF sur le serveur, visons la même source de données à l'application serveur:
Sources de données → Ajouter une ressource → Source de données et répétez tout à partir du point ci-dessus.
Vous êtes maintenant prêt à créer le PDF. Les sources dans JasperReports sont stockées au format JRXML - il s'agit de XML avec des balises câblées et des attributs avec lesquels l'API JasperReports fonctionne.
Cliquez sur
Fichier → Nouveau → Rapport Jasper → A4 vierge → Spécifiez le nom du fichier JRXML → Terminer .

Après avoir créé un nouveau projet, vous verrez l'image suivante:

Sept blocs différents - chaque bloc a son propre comportement qui est différent des autres. Vous pouvez en savoir plus à ce sujet dans la
documentation . En cliquant sur Source, vous pouvez voir la structure de ces blocs:
<?xml version="1.0" encoding="UTF-8"?> <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="Example" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="ae9517f6-ff0b-41bb-a8dc-82196190e940"> <queryString> <![CDATA[]]> </queryString> <background> <band splitType="Stretch"/> </background> <title> <band height="79" splitType="Stretch"/> </title> <pageHeader> <band height="35" splitType="Stretch"/> </pageHeader> <columnHeader> <band height="61" splitType="Stretch"/> </columnHeader> <detail> <band height="125" splitType="Stretch"/> </detail> <columnFooter> <band height="45" splitType="Stretch"/> </columnFooter> <pageFooter> <band height="54" splitType="Stretch"/> </pageFooter> <summary> <band height="42" splitType="Stretch"/> </summary> </jasperReport>
Supprimons donc cinq blocs supplémentaires et n'en laisserons que deux: Titre et Détail. Le bouton
Supprimer (Windows) ou
Retour arrière (OS X) nous y aidera.
Ajoutez maintenant deux éléments. Vous pouvez ajouter un nouvel élément de deux manières: enregistrez le conteneur dans la structure XML (bouton
Source ) ou faites glisser l'élément souhaité depuis la fenêtre de
palette supérieure droite - Texte statique, où il y aura des noms de champ et un champ de texte, à l'intérieur duquel nous remplirons les champs variables extraits de la base de données:
<?xml version="1.0" encoding="UTF-8"?> <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="Example" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="ae9517f6-ff0b-41bb-a8dc-82196190e940"> <queryString> <![CDATA[]]> </queryString> <background> <band splitType="Stretch"/> </background> <title> <band height="30" splitType="Stretch"> <staticText> <reportElement x="0" y="0" width="100" height="30" uuid="7b697ed9-f52a-483c-965e-f0b2dc6130c1"/> <text> <![CDATA[Static Text]]> </text> </staticText> </band> </title> <detail> <band height="169" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="100" height="20" uuid="41002e0b-ddb2-4e4b-a049-10810ab51208"/> <textFieldExpression> <![CDATA["Text Field"]]> </textFieldExpression> </textField> </band> </detail> </jasperReport>
La requête dans la base de données peut être écrite dans la balise
queryString ou cliquer sur le bouton de
dialogue Editeur de DataSet et de requête . Après cela, une nouvelle fenêtre s'ouvrira où vous devrez sélectionner une source de données (1), écrire une requête (2) et déclarer des variables de champ. Le bouton
Lire les champs (3) lira automatiquement tous les champs sur demande
valide . Pour afficher les données, cliquez sur
Aperçu des données (4).

Super! Nous avons obtenu quatre champs de type String, maintenant nous pouvons effectuer presque n'importe quelle manipulation avec eux. Par exemple, nous les listons simplement et écrivons un peu de logique.
Nous imprimons les noms des champs obligatoires dans les éléments de texte statique et les plaçons dans le conteneur Titre. Nous indiquerons les champs variables dans les éléments de champ de texte du conteneur Détail, car ils se multiplieront. Notre PDF affichera le nom, la ville et l'adresse e-mail. Afin de ne pas s'ennuyer complètement, écrivons une logique simple dans l'élément Champ de texte, en utilisant le quatrième champ - le sexe du client, le sexe.
Nous faisons ce qui suit: si le client est une femme, alors Mme sera ajoutée devant le nom, si l'homme est M. Pour ce faire, utilisez l'opérateur ternaire Java:
<textFieldExpression> <![CDATA[$F{sex}.equals( "male" )?"Mr. "+$F{name}:"Mrs. "+$F{name}]]> </textFieldExpression>
En cliquant sur
Aperçu à côté du bouton
Source , vous pouvez voir le résultat:

Comme vous pouvez le voir sur la capture d'écran, le PDF a été assemblé avec succès: il a pris toutes les valeurs et appliqué la logique, en posant correctement Mme. et monsieur
Nous obtiendrons également le paramètre d'entrée City afin qu'il soit possible de filtrer les données par ville. Cela peut être fait en cliquant sur
Paramètres → Créer un paramètre dans la fenêtre Structure ou en ajoutant une nouvelle balise de
paramètre avec les attributs de
nom et de
classe :
<parameter name="City" class="java.lang.String"/>
Il ne reste plus qu'à ajouter le paramètre à la requête SQL:
SELECT Id, name, sex, city, email FROM users WHERE city = $P{City}
Nous transmettons la valeur San Francisco au paramètre City (je vais vous dire dans le paragraphe suivant comment procéder) et cliquez sur
Aperçu des données pour afficher le résultat.
Le PDF a été collecté en filtrant avec succès les données. Nous allons plus loinComme nous avons déjà un fichier PDF à remplissage dynamique, nous pouvons le télécharger sur le serveur pour une intégration plus poussée avec nos applications frontales. Pour ce faire, cliquez sur le bouton
Publier le rapport sur le serveur JasperReports → double-cliquez pour ouvrir le serveur → Sélectionnez le dossier du serveur où télécharger le PDF (dans notre cas, les
rapports ) →
Suivant → Source de données du référentiel → sélectionnez la source de données qui a été créée précédemment sur l'application serveur →
Terminer .
Intégration frontend
L'API JasperReports inclut sa propre implémentation RESTful pour l'interaction client-serveur -
REST v2 . Si cela ne vous convient pas, vous pouvez utiliser un protocole d'accès aux objets simple -
SOAP .
Nous considérerons REST v2.
Les quatre méthodes principales pour les actions CRUD (Create-Read-Update-Delete) sont disponibles: GET (get), POST (add, change, delete), PUT (add, replace), DELETE (delete). Toutes les informations détaillées sont disponibles dans la documentation des liens ci-dessus.
Nous considérerons la méthode GET la plus courante et la plus pertinente pour cet article.
http://<host>:<port>/jasperserver[pro]/rest_v2/reports/path/to/report.<format>?<arguments>
Ci-dessus est une demande
synchrone , avec laquelle vous pouvez obtenir la sortie du fichier (PDF terminé) en une seule demande-réponse (vous pouvez trouver l'appel asynchrone
ici ).
Je pense que tout est clair avec l'hĂ´te et le port, et
/ reports / path / to / report est l'URI du fichier qui est appelé. Puisque nous avons déployé la source du fichier PDF (Example.jrxml) dans le dossier du serveur de rapports, la version complète de l'URI sera: / reports / reports / Example.
format est un format (dans notre cas, PDF).
les arguments sont des paramètres.
Ci-dessus, nous avons ajouté le paramètre City, et nous le passerons dans la requête avec la valeur San Francisco pour filtrer les données de cette ville.
Si l'appel ne provient pas d'une zone autorisée, vous devez ajouter deux autres paramètres / attributs:
j_username et
j_password (passe de journal pour l'autorisation). Par défaut, le nom d'utilisateur et le mot de passe sur le serveur sont
jasperadmin .
Ainsi, nous obtenons l'URL suivante:
http://localhost:8080/jasperserver/rest_v2/reports/reports/Example.PDF?city=San Francisco&j_username=jasperadmin&j_password=jasperadmin
Nous obtenons donc un PDF déjà généré. Par exemple, lorsque vous appelez cette URL via la barre d'adresse du navigateur, le fichier doit être téléchargé automatiquement.
Vous devrez peut-être afficher une image PDF. Par exemple, si le client souhaite simplement visualiser le fichier, vous pouvez afficher le document au format PNG, si vous souhaitez le télécharger, puis en PDF.
En utilisant Java comme exemple à l'aide de la bibliothèque PDFbox, nous verrons comment vous pouvez générer et sélectionner un fichier PDF à partir d'une application externe, puis le convertir en PNG.
Ci-dessous se trouve la classe
PullPDF avec une méthode qui prend une URL comme argument.
import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; import java.util.Base64; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.tools.imageio.ImageIOUtil; public class PullPDF { public String ConvertPDF2PNG(String valuefromParam) throws IOException { BufferedInputStream input_file = new BufferedInputStream(new URL(valuefromParam).openStream()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { PDDocument document = PDDocument.load(input_file); PDFRenderer pdfRenderer = new PDFRenderer(document); for (int page = 0; page < document.getNumberOfPages(); ++page) { BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB); ImageIOUtil.writeImage(bim, "png", baos); baos.flush(); byte[] encodedBytes = Base64.getEncoder().encode(baos.toByteArray()); valuefromParam = new String(encodedBytes); } } catch (Exception e) { } return valuefromParam; } }
Vous pouvez obtenir le même résultat en utilisant, par exemple, le framework Spring. Mais j'ai essayé de montrer une manière universelle qui peut être appliquée à la fois sur Android et sur le Web lorsque je travaille avec Java.
Conclusion
Si vous souhaitez automatiser la génération d'une vérification simple pour une boutique en ligne et que vous avez un temps limité pour le créer, alors je vous recommande d'utiliser les outils natifs de votre projet ou le framework familier. Étant donné le temps consacré à l'installation de JasperReports, la familiarisation avec la documentation pour l'élaboration de formulaires de rapport plus complexes peut ne pas être justifiée. Dans d'autres cas, JasperReports est une bonne solution open source pour l'automatisation des rapports.