NFop : Génération de fichier PDF avec.net Introduction FOP ( Formatting Objects Processor ) est un outil de formatage d impression piloté par XSL. C est une application qui lit un arbre d objets de formatage et qui génère les pages résultantes dans un format donné. Pour l instant les formats de rendus suivant sont supportés : PDF, PCL, PS, SVG, XML, Print, AWT, MIF et TXT. PDF étant le format de prédilection. NFop est le portage par Jason Pettys en Visual J# du projet Apache FOP sur la plateforme.net. NFop est disponible sur le site SourceForge à l adresse suivante : http://sourceforge.net/projects/nfop/ Afin de pouvoir utiliser NFop vous avez bien sûre besoin du Framework.NET et devez avoir au minimum le «Microsoft Visual J#.NET Redistributable Package» que vous pouvez télécharger ici : http:// Cette article va vous montrer comment créer à l aide de NFop un document PDF en partant de documents XML et XSL. Pour cette présentation j ai rédigé l article à l aide de Word et j ai utilisé un petit utilitaire crée en Java qui se nomme wh2fo (version 0.3.1) afin de générer très facilement le fichier XML et XSL permettant de générer le fichier FOP. Vous pouvez trouver cet utilitaire à l addresse web suivante : http:// Méthode Afin de pouvoir créer un fichier PDF à l aide de NFop il y a deux possibilités : 1. Création depuis un fichier FOP d un fichier PDF 2. Transformation d un fichier XML à l aide de XSLT en un fichier intermédiaire FOP puis génération du fichier PDF Dans les deux cas nous utilisons NFop pour générer le fichier PDF. Pour cela nous pouvons créer une méthode qui accepte en paramètre entrant une chaîne de caractères contenant les instructions FOP et une autre string représentant le chemin du fichier PDF à sauver. static protected void Transform ( string xmldocfo, string strfilename ) // Run the full FO doc through the engine to create a pdf Engine e = new Engine ();
try sbyte [] spdf = e.run ( xmldocfo ); int sz = spdf.length ; byte [] pdf = new byte [ sz ]; for ( int i=0; i< sz ; i++) pdf [i] = ( byte ) spdf [i]; // Write output file FileStream fs = new FileStream ( strfilename, FileMode.Create ); BinaryWriter sw = new BinaryWriter ( fs ); sw.write ( pdf ); sw.close (); fs.close (); catch ( org.apache.fop.apps.fopexception fope ) Console.WriteLine ( fope.getrootexception (). getmessage () ); Pour pouvoir utiliser ce code il faut : 1. Renommer Fop.Net.dll que vous avez téléchargé en ApacheFop.dll 2. Ajouter une référence à ApacheFop.dll 3. Ajouter une référence à vjslib.dll installé par le «Microsoft Visual J#.NET Redistributable Package» 4. Ajouter using ApacheFop ; On remarque que toutes la transformation est faite à l aide de deux lignes de code : Engine e = new Engine( ); sbyte [ ] spdf = e.run ( xmldocfo ); Implémentation Afin de créer un petit utilitaire qui va servir à la transformation dans les deux cas, créer un nouveau projet de type «Console Application». Ajouter les références comme expliquer un peu plus haut. Puis modifier votre projet pour obtenir : using System; using System.IO ;
using System.Xml ; using System.Xml.Xsl ; using ApacheFop ; namespace Fop class Transformer [ STAThread ] static void Main( string [] args ) if ( args.length == 3 ) XmlDocument datadoc = new XmlDocument (); datadoc.load ( args [0] ); // Transformation du XML en FOP à l'aide de XSLT XslTransform xslt = new XslTransform (); xslt.load ( args [1] ); StringWriter fullfodoc = new StringWriter (); xslt.transform ( datadoc.createnavigator (), null, fullfodoc ); //Transformation du FOP en PDF Transform ( fullfodoc.tostring (), args [2] ); else if ( args.length == 2 ) StreamReader sr = new StreamReader ( args [0] ); else //Transformation du FOP en PDF Transform ( sr.readtoend (), args [1] ); Console.WriteLine ("Usage: fop.exe file.xml file.xsl file.pdf "); Console.WriteLine (" or fop.exe file.fo file.pdf "); /// < summary > /// Transform a XmlFo document in a pdf and save the pdf to a file /// </ summary > /// < param name =" xmldocfo "> string containing the Fo document </ param >
</ param > /// < param name =" strfilename "> string representing the path to the output file static protected void Transform ( string xmldocfo, string strfilename ) // Run the full FO doc through the engine to create a pdf Engine e = new Engine (); try sbyte [] spdf = e.run ( xmldocfo ); int sz = spdf.length ; byte [] pdf = new byte [ sz ]; for ( int i=0; i< sz ; i++) pdf [i] = ( byte ) spdf [i]; ); // Write output file FileStream fs = new FileStream ( strfilename, FileMode.Create BinaryWriter sw = new BinaryWriter ( fs ); sw.write ( pdf ); sw.close (); fs.close (); catch ( org.apache.fop.apps.fopexception fope ) Console.WriteLine ( fope.getrootexception (). getmessage () ); Si l utilitaire est appelé avec trois paramètres, c'est-à-dire un fichier XML, un fichier XSL et le chemin de sauvegarde du fichier PDF, alors le fichiers XML est chargé en mémoire à l aide d un objet XmlDocument et est transformé en FOP à l aide du fichier XSL et d un objet XslTransform. Puis la méthode Transform qui transforme un fichier FOP en PDF est appelée à l aide du résultat de la transformation et du chemin de sauvegarde du fichier PDF. Dans le cas ou l utilitaire est appelé avec deux paramètres, le programme charge le fichier FOP représenté par le premier paramètre à l aide d un objet StreamReader et appelle la méthode Transform qui va transformer ce fichier FOP en PDF. Conclusion
L utilisation de XML et de NFop permet de créer un ensemble de document dans différent format. Pour ma part j utilise cette technique pour écrire les articles que je publie sur mon site web Tech Head. J écris un article dans un format XML et j ai un template XSL pour publier l article sur Tech Head, un autre pour le site Codeproject et un dernier pour générer un fichier PDF pour Tech Head. Cela me permet d écrire un article une seule fois et de le publier sur différent site sans avoir à retoucher chaque rendu. Bien que le portage ne soit pas encore complet cette version de NFop permet de faire pas mal de chose déjà et permet un gain de temps énorme.