Java

Présentation vidéo

Architecture

Schéma de principe de Genero Report Writer pour Java

Évolutivité

Schéma illustrant la nature distribuée de Genero Report Writer pour Java

Points forts

Aperçu détaillé des fonctionnalités

  • Personnaliser la présentation
    • Édition basée sur un schéma et sûre du point de vue du type
    • Pas d’erreurs d’exécution liées aux conversions de chaînes,
    • Analyse de l’impact au moment de la compilation,
    • Affiche la liste des problèmes rencontrés dans la conception d’un rapport à la suite de modifications apportées au schéma. Cette fonction est particulièrement importante pour les utilisateurs finaux qui ont personnalisé ou créé leurs propres conceptions de rapports. Dès réception d’une mise à jour du logiciel, ils peuvent vérifier leurs rapports par rapport aux nouveaux schémas livrés avec la mise à jour afin de détecter et de résoudre les problèmes éventuels avant de rendre la mise à jour opérationnelle,
    • Mises à jour par lots et résolution des problèmes assistée par le logiciel dans le concepteur de rapports. Un outil en ligne de commande est disponible pour mettre à jour les fichiers de conception de rapports dans les cas où les schémas peuvent avoir changé (par exemple, lors d’une mise à jour de l’application et du site de l’utilisateur final). L’algorithme de mise à jour est optimal en ce sens qu’il trouve un correctif minimal de sorte que, dans le cas général, aucune intervention manuelle n’est nécessaire. Dans les rares cas où des parties d’un schéma ont été supprimées ou renommées, les utilisateurs sont aidés à résoudre les problèmes sous la forme d’une liste stockée en permanence avec le fichier de conception du rapport jusqu’à ce que tout ait été résolu.
  • Le flux de données et le formatage du document sont séparés,
  • Plusieurs présentations par source de données,
  • Définit une interface claire entre les fournisseurs d’applications qui sont chargés de fournir les sources de données et leurs schémas associés et les utilisateurs qui les personnalisent ou y ajoutent des présentations.
  • Interface au niveau du processus par opposition à l’accès direct à la base de données,
  • Moins sensible aux modifications de la base de données. Les messages au niveau du processus protègent les utilisateurs des détails de la base de données et permettent aux fournisseurs d’applications de modifier le schéma de la base de données sans interrompre les rapports personnalisés ou créés par l’utilisateur,
  • Empêche la réplication des règles de gestion dans la conception des rapports. En accédant à des données « cuites », les utilisateurs n’ont pas besoin de connaître les détails de la manière dont les données sont stockées dans la base de données. Cela évite la réplication de la logique commerciale centrale dans la conception des rapports (par exemple, les règles concernant l’adresse qui est réellement utilisée comme adresse de facturation d’une facture lorsqu’il y a plusieurs choix dans la base de données),
  • Prise en charge des données structurées, par opposition aux ensembles d’enregistrements plats renvoyés par les requêtes SQL. Les données qui sous-tendent les rapports sophistiqués tels que les factures ou les livraisons peuvent rarement être représentées sous la forme d’une liste plate d’enregistrements. La représentation naturelle est un message structuré permettant des listes imbriquées arbitraires de différents enregistrements. L’utilisation de « sous-rapports » comme dans de nombreux outils de reporting ad hoc n’est pas une solution adéquate car elle ajoute une complexité inutile et inverse généralement la communication réseau, ce qui entraîne des problèmes de performance dus à la latence du réseau,
  • Langage de correspondance et de transformation graphique, nouveau et sériel. Conceptuellement similaire à XSL-T, le langage de transformation RTL est limité dans le type de transformations qu’il peut effectuer (par exemple, pas de récursivité), mais il peut être représenté graphiquement. Il fonctionne pour des documents de taille arbitraire.
  • Traitement unidirectionnel à passage unique. La latence du réseau pouvant être considérée comme une ressource non évolutive, il est important d’éviter d’inverser le sens de la communication au cours d’un travail. Le moteur peut être utilisé dans un environnement distribué avec des temps d’aller-retour très élevés et une faible largeur de bande sans diminution notable des performances,
  • Traitement en série de documents de taille arbitraire.
  • Des milliers de pages, une mémoire faible et constante,
  • Traitement distribué et option de serveurs multiples. L’option multi-serveur permet de décharger le rendu du rapport sur une ou plusieurs machines séparées, en ne laissant au serveur que la création du message de la source de données.
  • Positionnement exact du pixel,
  • Positionnement relatif vertical et horizontal,
  • Propagation du contenu à la verticale et à l’horizontale,
  • Mise en page multi-colonnes,
  • Mise en page tabulaire,
  • Tableaux croisés dynamiques,
  • Sous-rapports,
  • En-têtes et pieds de page sophistiqués,
  • Sauts de page sophistiqués,
  • Impression d’étiquettes sur différents supports. La conception du rapport contient la description d’une seule étiquette, sans tenir compte de la mise en page réelle sur le support, ce qui évite de devoir modifier la conception du rapport pour différentes imprimantes d’étiquettes ou différentes feuilles d’étiquettes,
  • Totaux courants dans les en-têtes et les pieds de page,
  • Page n sur m dans les en-têtes et les pieds de page tout en conservant le traitement en série,
  • Graphiques commerciaux à mise en page automatique,
  • Grand nombre de codes à barres implémentés en mode natif,
  • Images bitmap et SVG. Les graphiques vectoriels extensibles (ainsi que ceux d’autres origines tels que les codes-barres et les graphiques commerciaux) sont préservés dans tous les formats qui prennent en charge le dessin vectoriel, tels que le PDF, le navigateur ou l’imprimante. Dans tous les autres formats, ils sont transformés en images bitmap.
  • • API pour la conception
    • API pour l’introspection des schémas,
    • API pour l’introspection et la génération de fichiers de conception de rapports,
    • API pour la génération de rapports basés sur des modèles,
    • API pour la configuration des tableaux croisés dynamiques.
  • API d’exécution
    • API au niveau des données
      • Sélection de la source,
      • Configuration de la localisation,
      • Recommandation de JAXB pour la génération de schémas et le marshalling,
    • API au niveau du document
      • Sélection de la conception,
      • Configuration des caractéristiques de la page,
      • Configuration de la présentation des étiquettes,
    • API au niveau du périphérique
      • Sélection de l’appareil (par exemple PDF, imprimante serveur, imprimante client, …),
      • Configuration spécifique à l’appareil (par exemple, sélection du bac à papier de l’imprimante).
  • Visualisation des rapports à partir d’un navigateur
    • Faible bande passante,
    • Rendu 100% exact au pixel près,
    • Utilise des polices WOFF et des graphiques vectoriels SVG pouvant être mis en cache,
    • Diffusion en continu pour un rendu immédiat des rapports volumineux,
    • Navigation rapide et aléatoire dans les documents volumineux,
    • Rapports pouvant être mis en signet et partagés
  • Visionneuse de rapports native
    • Traitement très rapide, faible consommation de mémoire, presque constante,
    • Rendu exact au pixel près à 100 % en utilisant des polices intégrées,
    • Possibilité de diffusion en continu pour un rendu immédiat des rapports volumineux,
    • Navigation rapide et aléatoire dans les documents volumineux,
    • Prise en charge de l’impression silencieuse
      • Visionneuse non visible,
      • Sélection de l’imprimante via l’API du serveur,
      • Configuration de l’imprimante via l’API du serveur (par exemple, sélection de la source de papier),
  • Impression côté serveur
    • Traitement en série si le système d’exploitation le permet,
    • Contrôle programmatique via les propriétés IPP
  • Génération de fichiers
    • PDF,
    • RTF (MS-Word),
    • XLS/XLSX (MS-Excel),
    • Postscript,
    • SVG
  • Une conception unique pour plusieurs langues. Des primitives sont fournies pour traduire les chaînes de caractères et formater les données en fonction des paramètres locaux, individuellement pour chaque document, au moment de l’exécution. Il est possible de définir des mises en page qui gèrent bien les différences de taille de texte qui en résultent.
  • Prise en charge des langues asiatiques et des modes d’écriture alternatifs.
  • Gestion efficace des polices asiatiques.
  • Prise en charge des modèles de documents créés,
  • Déroulement sécurisé des listes de champs et des espaces réservés,
  • Prise en charge des sources de données à structure complexe.
  • Formats de fichiers lisibles par l’homme et contrôlables par version,
  • Édition de la conception des rapports en toute sécurité,
  • Analyse de l’impact sur le temps de compilation après modification des sources de données,
  • Algorithme sophistiqué de mise à jour de la conception des rapports (similaire à diff/patch).
    • Tolérance à 100 % à l’ajout de champs et de structures,
    • Bonne tolérance à la suppression,
    • Signale les conflits et permet une correction manuelle.
  • Générateur graphique de sources de données,
  • Création du code pour la génération XML,
  • Création de schémas,
  • Déroulement sécurisé des listes de champs et des caractères génériques,
  • Prise en charge des sources de données à structure complexe.

Toutes les principales bases de données de l’industrie sont supportées :

  • DB2
  • Informix
  • MS SQL Server
  • MySQL
  • Oracle
  • PostrgreSQL

Pour commencer

Dans cet exemple, nous utilisons un objet Java ordinaire (POJO) « Sales » comme source de données, comme le montre le code source ci-dessous :

//The XmlRootElement annotation causes a global element declaration to be produced in the schema.
@XmlRootElement
public class Sales {
//The XmlElement annotation maps a property to an XML element.
//The Genero Engine does not support optional variables so setting "required=true" is mandatory.
//If a variable needs to be optional then use "nillable=true" and set the variable to null when
//there is no value. If a primitive type needs to be optional then use the corresponding
//object wrapper instead (e.g java.lang.Integer for "int").
   @XmlElement(required = true, nillable = true)
   public String shopName;
   @XmlElement(required = true)
   public int zipCode;
   @XmlElement(required = true, nillable = true)
   public Date day;

Les rapports graphiques sont conçus sur la base d’un schéma XML qui correspond aux données à sérialiser.

L’outil en ligne de commande « schemagen » peut être utilisé pour générer le schéma :

schemagen Sales.java

Le schéma de l’exemple de programme est le suivant :

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

Concevez le rapport à l’aide de Report Designer. Choisissez votre modèle de rapport, associez les déclencheurs et remplissez le rapport avec les données extraites de la vue de données.

L’image ci-dessous montre le rapport « SalesList.4rp » créé dans le Report Designer :

saleslist.4rp

Sélectionner le modèle de rapport

if (args.length == 0) {
     designFile = "SalesList.4rp";
} else {
      designFile = args[0];
}

Configurer la sortie
Sélectioner la sortie PDF

PDFRenderer renderer = new PDFRenderer(handler);

Sérialiser le modèle
Utiliser le marshaller JAXB pour sérialiser les données.

report.runFromJAXBObject(data);

Voici le programme JAVA complet:

/*
 * FOURJS_START_COPYRIGHT(U,2003)
 * Property of Four Js*
 * (c) Copyright Four Js 2003, 2014. All Rights Reserved.
 * * Trademark of Four Js Development Tools Europe Ltd
 *   in the United States and elsewhere
 *
 * Four Js and its suppliers do not warrant or guarantee that these samples are
 * accurate and suitable for your purposes.
 * Their inclusion is purely for information purposes only.
 * FOURJS_END_COPYRIGHT
 */

import com.fourjs.pxml.standardpipe.runtimeapi.*;
import java.awt.Desktop;
import java.io.File;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.IOException;
import javax.xml.bind.JAXBException;
import org.xml.sax.SAXException;
import java.util.Vector;
import java.util.Date;
import java.io.Serializable;
 
//The XmlRootElement annotation causes an global element declaration to be produced in the schema.
@XmlRootElement
public class Sales {
//The XmlElement annotation maps a property to an XML element.
//The Genero Engine does not support optional variables so setting "required=true" is mandatory.
//If a variable needs to be optional then use "nillable=true" and set the variable to null when
//there is no value. If a primitive type needs to be optional then use the corresponding
//object wrapper instead (e.g java.lang.Integer for "int").
   @XmlElement(required = true, nillable = true)
   public String shopName;
   @XmlElement(required = true)
   public int zipCode;
   @XmlElement(required = true, nillable = true)
   public Date day;

//This and any other public collection will be serialized in the order they are declared descending //recursively into the classes contained in the collections.
    public Vector items=new Vector();
    public Sales(String shopName, int zipCode, Date day)
    {
        this.shopName=shopName;
        this.zipCode=zipCode;
        this.day=day;
        items.add(new SalesItem("Tablelamp",SalesItem.Category.Furniture,23.00,null));
        items.add(new SalesItem("Tablelamp",SalesItem.Category.Furniture,267.00, items.lastElement()));
        items.add(new SalesItem("Officechair",SalesItem.Category.Furniture,155.00, items.lastElement()));
        items.add(new SalesItem("Grandfather clock",SalesItem.Category.Furniture,329.00, items.lastElement()));
        items.add(new SalesItem("Scissors",SalesItem.Category.Supplies,19.00, items.lastElement()));
        items.add(new SalesItem("Measuring tape",SalesItem.Category.Supplies,23.00, items.lastElement()));
        items.add(new SalesItem("Sunglasses",SalesItem.Category.Travelling,15.95, items.lastElement()));
        items.add(new SalesItem("Penknife",SalesItem.Category.Travelling,6.25, items.lastElement()));
        items.add(new SalesItem("Ornateangel",SalesItem.Category.Art,1.95, items.lastElement()));
    }

/** Default Constructor that is required for JAXB deserialization.
    In this program this is never used.
*/
    public Sales() { assert false; }
/**
    Runs the report using the design file specified in args[0] or "SalesList.4rp" otherwise.
    The program creates the file "SalesList.pdf" and opens it using
Desktop.open() which will typically
    invoke the Acrobat Reader.
*/
    public static void main(String[] args) throws JAXBException, IOException, SAXException
    {
        String designFile;
        String outputFilename = "SalesList.pdf";
   
        if (args.length == 0) {
            designFile = "SalesList.4rp";
        } else {
            designFile = args[0];
        }
 
        FormatHandler handler = new FormatWriter(outputFilename);
        PDFRenderer renderer = new PDFRenderer(handler);
        FourRpLayouter report = new FourRpLayouter(designFile, renderer);
 
        report.setDebugLevel(9);
        Sales data = new Sales("Columbus Arts", 75038, new Date());
 
        report.runFromJAXBObject(data);
   
        // open the file
        File result = new File(outputFilename);
        Desktop desktop = Desktop.getDesktop();
        desktop.open(result);
 
  }
 
}
 
class SalesItem
{
    public enum Category {Furniture, Art, Supplies, Travelling };
   
    @XmlElement(required = true, nillable = true)
    public String articleName;
    @XmlElement(required = true, nillable = true)
    public Category category;
    @XmlElement(required = true)
    public double price;
    @XmlElement(required = true)
    public double runningTotal;
   
//The previous item is passed to allow computing the running total.
    public SalesItem(String articleName, Category category, double price, SalesItem previousItem)
    {
        this.articleName=articleName;
        this.category=category;
        this.price=price;
      
this.runningTotal=previousItem==null?price:previousItem.runningTotal+price;
    }
 
/** Default Constructor that is required for JAXB deserialization.
    In this program this is never used.
*/
    public SalesItem() { }
}