Pour désigner votre modèle RTF, vous pouvez utiliser les élements RTF suivant :
Un champs de fusion peut être aussi utilisé pour insérer une image (qui pourrait être généré dynamiquement) dans votre modèle.
Le nom du champs de fusion doit respecter le nom de votre objet JAVA et de ses getters (votre contexte).
Le design de votre modèle RTF peut s'effectuer à l'aide de MS Word. Concernant OpenOffice, il n'est pas possible de l'utiliser aujourd'hui, cliquer ici pour plus d'informations.
Les sections suivantes décrivent les règles à utiliser pour modéliser votre modèle RTF en fonction de votre contexte JAVA. Elles expliquent :
Vous pouvez trouver des exemples de modèles RTF dans la distribution rtftemplate-usecases-<version> dans le répertoire usecases/model. Le modèle RTF qui répertorie la plupart des cas d'utilisation de RTFTemplate est jakarta-velocity-model.rtf
Les exemples décrits ci dessous s'appuieront sur le contexte d'une liste de deux développeurs. Un développeur a un nom. Voici le code utilisé lorsque cette liste sera posé dans le contexte :
List developers = new ArrayList(); Developer developer = new Developer(); developer.setName("Developer 1"); developers.add(developer); developer = new Developer(); developer.setName("Developer 2"); developers.add(developer); context.put("developers", developers );
Les valeurs simples sont désignées par les champs de fusions (MERGEFIELD) et les champs liens hyper textes (HYPERLINK). Vous pouvez appliquer sur ces élements RTF un style (Gras, Couleur, Police,...) en utilisant les fonctionnalités standards de votre outil de modélisation (MS Word,...).
ATTENTION lorsque vous appliquez un style sur un de vos champs, faites attention à sélectionner le champs en entier, sinon vous risquez de rencontrer des problèmes lors de la fusion.
Lorsque vous créer un champs, utilisez ABSOLUMENT les fonctionnalités de création d'un champs fourni par MS Word ou par la macro RTFTemplate.dot. Ne vous amusez pas à modifier le nom dans le modèle RTF!!! Je me permets d'insister sur ce point car j'ai eu plusieurs personnes qui m'ont contacté et qui ont eu des soucis avec RTFTemplate. Leur problème venait de là.
Le nom de votre champs doit respecter une certaine syntaxe. Par exemple, pour afficher la valeur de l'objet JAVA Project :
public class Project { private String name; public Project(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
mis dans le contexte avec la clé project :
context.put("project", new Project("Jakarta Velocity"));
le nom du champs doit être nommé ainsi dans votre modèle RTF :
$project.Name
Il est aussi possible d'utiliser une java.util.Map si vous ne voulez pas créer d'objets POJO (fonctionne uniquement avec Velocity). La clé de la Map correspond au nom du getter, et la valeur de la Map à la valeur du getter. L'exemple ci-dessus peut être effectué à l'aide d'une Map comme ceci :
// Prepare le context Project Map projectMap = new HashMap(); projectMap.put("Name", "Jakarta Velocity"); // Met la Map dans le contexte context.put("project", projectMap);
ATTENTION, il est important de respecter la casse dans la clé de la Map et dans le nom du champs utilisé dans votre modèle RTF.
Vous pouvez trouver des examples ici.
L'affichage d'une valeur simple d'un objet s'effectue lorsque l'objet JAVA a un getter de type :
Il est possible de formatter la valeur retournée par un de ces types de getters à l'aide d'une classe formateur qui implémente l'interface java.text.Format. Un formatteur est associé à un type de classe.
Par exemple pour formatter tous les getters de type java.util.Date dans le pattern spécifique dd/MM/yyyy, vous devez enregistrer dans l'instance rtftemplate à l'aide de la méthode setDefaultFormat, le formatteur pour le type java.util.Date comme ceci :
Format format = new SimpleDateFormat("dd/MM/yyyy"); rtfTemplate.setDefaultFormat(java.util.Date.class, format);
Par défaut RTFtemplate enregistre les formatteurs :
L'interface IRTFCode est un type d'objet particulier de RTFTemplate. Voici sa signature :
public interface IRTFCode { /** * Return true if content must be escaped * (replace '{' character with "\{" and '}' with "\}") * @return */ public boolean isEscaped(); /** * Return RTF content. * @return */ public String getContent(); }
IRTFcode se distingue aussi des autres types (non primitifs) par son utilisation dans le modèle RTF. Elle se comporte comme un type primitif, autrement dit si vous posez votre objet de type IRTFCode dans le contexte avec la clé myRTFCode, vous devez nommez votre champs de fusion comme ceci :
$myRTFCode
et pas comme on pourrait le croire
$myRTFCode.content
RTFTemplate fournit par défaut net.sourceforge.rtf.format.rtfcode.RTFCodeString, une implémentation de IRTFcode, qui est associée au formatteur net.sourceforge.rtf.format.DefaultRTFCodeStringFormat. Voici le code du formatteur :
package net.sourceforge.rtf.format; import java.text.FieldPosition; import java.text.Format; import java.text.ParsePosition; import net.sourceforge.rtf.format.rtfcode.IRTFCode; import net.sourceforge.rtf.util.StringUtils; public class DefaultRTFCodeStringFormat extends Format { public StringBuffer format(Object obj, StringBuffer stringbuffer, FieldPosition fieldposition) { if (obj == null) return null; String content = null; if (obj instanceof IRTFCode) content = ((IRTFCode) obj).getContent(); else if (obj instanceof String) content = (String) obj; if (content == null) return null; // Replace \n\r with \\par String formattedContent = StringUtils.sub(content, "\n\r", "\\par "); // Replace \n with \\par formattedContent = StringUtils.sub(formattedContent, "\n", "\\par "); // Replace \t with \\tab formattedContent = StringUtils.sub(formattedContent, "\t", "\\tab "); return new StringBuffer(formattedContent); } public Object parseObject(String s, ParsePosition parseposition) { // Do nothing return null; } }
Si votre getter est susceptible de contenir des retour à la ligne, des tabulations, RTFCodeString vous permettra de les interpréter dans votre modèle RTF, autrement dit :
Si vous enregistrez dans le contexte RTFtemplate, une instance RTFCodeString comme ceci :
context.put("myRTFCode", new RTFCodeString("\n\n\t\r\nvalue\n\n"));
ceci génerera le code RTF suivant :
\par \par \tab \par value \par\par
pour afficher les retours à la lignes et les tabulations correctement dans votre modèle RTF.
Si vous êtes susceptibles d'avoir des caractères '{' ou '}' vous pouvez les échaper comme ceci :
context.put("myRTFCode", new RTFCodeString("\n\n\t\r\nvalue\n\n{", true);
Lorsque vous avez une liste de données, il est possible de les afficher dans votre modèle RTF. Parfois vous voulez afficher votre liste dans un tableau RTF (qui générera plusieurs lignes), parfois vous voulez afficher votre liste d'items séparés par des ,.
En règle générale, les boucles sont gérés par les signets (BOOKMARK). Il existe certaines exception concernant les tableaux RTF.
La règle utilisé par RTFTemplate est d'itérer sur le premier champs de type list, détecté après un début de boucle. Un champs est de type list, si son objet JAVA associé est stocké dans une liste JAVA (java.util.Collection, java.util.List,...).
Si vous utilisez la macro RTFTemplate.dot fourni par RTFTemplate, lorsque vous sélectionner un champs, une indication type list s'affiche. Si le champs est de type list, il doit OBLIGATOIREMENT être inséré entre un début/fin de boucle.
Pour indiquer un début/fin de boucle, vous devez créer (sauf exception) les signets suivants :
Par exemple si on souhaite afficher la liste des développeurs séparés par le caractère , :
Developer 1, Developer 2,
le modèle RTF doit être désigné de la façon suivante :
START_LOOP_1 $developers.Name , END_LOOP_1
Depuis la version 1.0.1-b10 la règle est de ne plus utiliser de signets début/fin boucle pour itérer sur les lignes d'un tableau. RTFTemplate est capable de detecter les lignes RTF et d'itérer sur le premier champs de type liste trouvé dans la ligne du tableau.
Vous pouvez trouver des examples ici.
Si vous utilisez une version antérieur à 1.0.1-b10, vous devez distinguer les cas suivants.
Les tableaux RTF sont un cas à part. En effet selon le tableau que vous désigner, les signets début/fin boucle doivent ou ne doivent pas être utilisés.
------------------------------------------------ |$developers.Name | | | ------------------------------------------------
Après fusion, on obtient :
------------------------------------------------ |Developer 1 | | | ------------------------------------------------ |Developer 2 | | | ------------------------------------------------
------------------------------------------------ |Ligne Header QUI A UN STYLE | | | ------------------------------------------------ |$developers.Name | | | ------------------------------------------------
Après fusion, on obtient :
------------------------------------------------ |Ligne Header QUI A UN STYLE | | | ------------------------------------------------ |Developer 1 | | | ------------------------------------------------ |Developer 2 | | | ------------------------------------------------
Depuis la version 1.0.1-b10, vous pouvez faire abstraction de cas.
Celui-ci est un cas d'exception. Il ressemble tres fortement au dernier cas. Le tableau est constitué d'une ligne header QUI N'A PAS DE STYLE et d'une ligne qui contient le champs de type liste :
------------------------------------------------ |Ligne Header QUI N'A PAS DE STYLE | | | START_LO0P_1 ------------------------------------------------ |$developers.Name | | | END_LO0P_1 ------------------------------------------------
Après fusion, on obtient :
------------------------------------------------ |Ligne Header QUI N'A PAS DE STYLE | | | ------------------------------------------------ |Developer 1 | | | ------------------------------------------------ |Developer 2 | | | ------------------------------------------------
Les autres cas décrits ci dessous, sont à titre d'exemples de ce que l'on peut faire avec RTFTemplate.
MyTitle ------------------------------------------------ |Developer 1 | | | ------------------------------------------------ MyTitle ------------------------------------------------ |Developer 2 | | | ------------------------------------------------
Vous devez désigner votre modèle RTF de la façon suivante :
START_LOOP_1 MyTitle ------------------------------------------------ |$developers.Name | | | ------------------------------------------------ END_LOOP_1
---------------------------------------------------------- |Developer 1, Developer 2 | | | ----------------------------------------------------------
Vous devez désigner votre modèle RTF de la façon suivante :
---------------------------------------------------------- | START_LOOP_1 $developers.Name , END_LOOP_1 | | | ----------------------------------------------------------
RTFTemplate permet d'insérer des images (qui pourraient être générées dynamiquement) dans votre modèle RTF. Pour placer l'image dans votre modèle, utilisez un champs de fusion comme si vous voulez afficher une valeur simple. Il suffit que l'objet JAVA associé à ce champs de fusion retourne un InpuStream qui contient le flux de l'image à insérer.
Les formats d'images supportés par RTFTemplate sont PNG, JPG, EMF et BPM.
Vous pouvez trouver des exemple de modèles RTF qui gère les images dans la distribution rtftemplate-usecases-<version> dans le répertoire usecases/model/image. Les classes JAVA associées à ce modèles se trouvent dans le package net.sourceforge.rtf.usecases.image.
Avec RTFTemplate il est possible d'itérer sur une liste d'items et d'ajouter un saut de page après chaque item. RTFTemplate ne génera pas de saut de page après le dernier item (pour éviter d'avoir une page blanche).
Pour gérer les sauts de pages, vous devez modéliser votre modèle RTF comme ceci :
START_LOOP_1 (placé au début du modèle RTF) .... $developers.Name .... Saut de page END_LOOP_1
Il est aussi possible de grouper les items de la liste et de générer un saut de page après chaque groupe. Ceci s'effectue programmatiquement. Pour plus d'information cliquez ici.
Vous pouvez trouver des exemple de modèles RTF qui gère les sauts de pages dans la distribution rtftemplate-usecases-<version> dans le répertoire usecases/model/page. Les classes JAVA associées à ce modèles se trouvent dans le package net.sourceforge.rtf.usecases.page.
Avec MS Word, il est possible de créer des propriétés utilisateurs. Pour effectuer ceci, accédez au menu Fichier/Propriétés. Dans l'onglet Personnalisation, vous pouvez créer vos propriétés utilisateurs (nom, type et valeur).
Vous pouvez gérer ces propriétés avec RTFtemplate comme si vous gérer un champs de fusion :
Vous pouvez trouver des exemple de modèles RTF qui gère les sauts de pages dans la distribution rtftemplate-usecases-<version> dans le répertoire usecases/model/jakartavelocityproject. Les classes JAVA associées à ce modèles se trouvent dans le package net.sourceforge.rtf.usecases.userproperties.