<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christophe Nowicki &#187; PDF</title>
	<atom:link href="http://www.csquad.org/tag/pdf/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.csquad.org</link>
	<description>Just for fun</description>
	<lastBuildDate>Thu, 29 Jul 2010 19:42:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Système d&#8217;impression PDF &#8220;RESTful&#8221;  pour le Web</title>
		<link>http://www.csquad.org/2009/02/10/systeme-dimpression-pdf-restful-pour-le-web/</link>
		<comments>http://www.csquad.org/2009/02/10/systeme-dimpression-pdf-restful-pour-le-web/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 21:43:13 +0000</pubDate>
		<dc:creator>cscm</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Cocoon]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[MAVISE]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.csquad.org/?p=78</guid>
		<description><![CDATA[Le monde du web et celui de l&#8217;impression, ont décidément du mal à se rencontrer.
La prise en charge de l&#8217;impression est bien souvent très problématique dans le cas d&#8217;un projet web. 
Dans la plupart des cas, il est possible de s&#8217;en sortir en utilisant les possiblités offertes par les feuilles de style CSS.
Mais le rendu [...]]]></description>
			<content:encoded><![CDATA[<p>Le monde du web et celui de l&#8217;impression, ont décidément du mal à se rencontrer.<br />
La prise en charge de l&#8217;impression est bien souvent très problématique dans le cas d&#8217;un projet web. </p>
<p>Dans la plupart des cas, il est possible de s&#8217;en sortir en utilisant les possiblités offertes par les feuilles de style CSS.<br />
Mais le rendu final du document n&#8217;est pas garanti, les différents navigateurs interprètent la feuille de style selon leur humeur<br />
et cela ne fonctionne pas dans le cas de documents complexes.</p>
<p>Dans ce cas, l&#8217;unique solution est de produire un document au format PDF, unique garantie pour une impression de qualité.<br />
Je vais donc décrire dans cet article, la solution que nous avons mis en place dans le cadre du projet MAVISE.</p>
<h3>Historique</h3>
<p>La base de données <a href="http://mavise.obs.coe.int/">MAVISE</a> fourni les données sur l’ensemble des chaînes de télévision accessibles dans l’Union européenne.</p>
<p>Elle a été développé par la société Easter-eggs en collaboration avec <a href="http://www.obs.coe.int/">l&#8217;Observatoire européen de l&#8217;audiovisuel</a> (OEA) pour le compte de la <a href="http://ec.europa.eu/dgs/communication/index_en.htm">DG Communication de la Commission Européenne</a>.</p>
<p>Dans la 1ère phase du projet nous avons développé un système d&#8217;impression avec des feuilles de style.<br />
Ce système ne donnait pas entièrement satisfaction au client. </p>
<p>En effet, les pages du projet étant très complexes, le résultat de l&#8217;impression produite par les différents navigateurs était très aléatoire (coupure en plein milieu d&#8217;un tableau, impression sur plusieurs pages et saut de pages inexpliqués).</p>
<p>Le résultat n&#8217;était pas professionnel et il était difficile pour le client d&#8217;alimenter un rapport avec les contenu de la base.<br />
Nous avons donc proposé de mettre en place un export PDF pour l&#8217;ensemble des éléments de l&#8217;application.</p>
<h3>Choix techniques</h3>
<p>Au fils du temps, je suis devenu un expert de la production de document PDF,<br />
en effet, j&#8217;ai été en charge de l&#8217;export PDF dans de nombreux projets. </p>
<p>J&#8217;ai eu le plaisir d&#8217;utiliser plusieurs API pour produire des documents au format PDF, comme par exemple :</p>
<ul>
<li><a href="http://www.reportlab.org/index.html">ReportLab</a> en Python ;</li>
<li><a href="http://www.fpdf.org/">FPDF</a> en PHP ;</li>
<li><a href="http://pdfapi2.sourceforge.net/">PDF::API2</a> en Perl.</li>
</ul>
<p>Le travail pour produire des documents PDF consiste dans la plupart des cas à dessiner avec l&#8217;aide de ces diffèrentes<br />
API, le contenu du document. (texte, tableaux, graphique et mise en page). </p>
<p>Il s&#8217;agit d&#8217;un travail long et fastidieux, qui consiste à fournir une suite d&#8217;instructions pour former le document.<br />
Cette technique montre vite ses limites :</p>
<ul>
<li>les demandes de modification de la mise en page du  document produit, sont lourdes et nécessitent beaucoup de temps ;</li>
<li>le code pour produire le document est difficilement rationalisable ;</li>
<li>elle ne convient pas à des documents de grande taille.</li>
</ul>
<p>Dans le modèle <a href="http://fr.wikipedia.org/wiki/Mod%C3%A8le-Vue-Contr%C3%B4leur">MVC</a>, qu&#8217;utilise la plupart des applications Web, nous utilisons un système de template pour l&#8217;affichage (la vue).  </p>
<p>Alors pourquoi bon &#8220;coder&#8221; la présentation des documents PDF?</p>
<p>Pour cette raison, j&#8217;ai proposé au client de bâtir le système d&#8217;impression des documents PDF sur un système de <em>template</em>.</p>
<p>Ce système repose sur le langage de programmation <a href="http://www.w3.org/TR/xsl/">XSL-FO</a>, les projets <a href="http://xmlgraphics.apache.org/fop/">Apache FOP</a> et  <a href="http://cocoon.apache.org/">Apache Cocoon</a>.</p>
<h3>Architecture du système d&#8217;impression</h3>
<p><img src='/wp-content/mavise_export_pdf_workflow.png' alt='' /></p>
<ol>
<li>Lorsque l&#8217;utilisateur clique sur le lien PDF,  il est redirigé vers Apache Cocoon ;</li>
<li>Cocoon, récupère l&#8217;ensemble des informations directement sur le site web, via l&#8217;API REST ;</li>
<li>Il agrége les informations dans un document XML ;</li>
<li>Ce document est transformé en FO à l&#8217;aide d&#8217;une feuille de style XSLT ;</li>
<li>Le document est produit par Apache FOP ;</li>
<li>L&#8217;utilisateur obtient le document final. </li>
</ol>
<h3>L&#8217;interface entre le Site Web et Apache Cocoon</h3>
<p>L&#8217;architecture du système d&#8217;impression repose sur le fait que l&#8217;ensemble des variables manipulées par notre application sont accessibles à l&#8217;aide d&#8217;URL <a href="http://fr.wikipedia.org/wiki/REST">REST</a>.</p>
<p>En effet, il est possible d&#8217;afficher le contenu des diffèrentes variables manipulées par l&#8217;application à l&#8217;aide d&#8217;adresses URL spécifiques.<br />
Voici un exemple de sortie :<br />
<code><br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;array&gt;<br />
&lt;is_admin /&gt;<br />
&lt;country&gt;<br />
&lt;id&gt;1&lt;/id&gt;<br />
&lt;iso3166&gt;FR&lt;/iso3166&gt;<br />
&lt;name&gt;France&lt;/name&gt;<br />
&lt;enabled&gt;t&lt;/enabled&gt;<br />
&lt;minimal_age_of_audience&gt;4+&lt;/minimal_age_of_audience&gt;<br />
&lt;/country&gt;&lt;/array&gt;<br />
...<br />
</code></p>
<p>Il est donc possible de récupèrer l&#8217;<strong>ensemble</strong> des informations du site à l&#8217;aide du protocol REST.</p>
<p>Nous avons aussi de très nombreux tableaux dans l&#8217;application, pour les récupérer, nous utilisons le format XML natif du contrôleur de tableaux <a href="http://dhtmlx.com/docs/products/dhtmlxGrid/">dhtmlxGrid</a>.<br />
Voici un exemple de sortie : <a href="http://mavise.obs.coe.int/company?id=1&#038;event=get_grid_xml_list_of_channels&#038;presenter=dhtmlXGrid_xml_loader">fichier XML pour dhtmlxGrid</a>.</p>
<h3>Agrégation des données dans un seul fichier</h3>
<p>Pour récupérer l&#8217;ensemble des données du site dans un fichier XML, j&#8217;utilise la directive <em>include</em>, offerte par Cocoon :<br />
<code><br />
$ cat /var/lib/tomcat5/webapps/cocoon/mavise/program/program.xml<br />
&lt;?xml version="1.0"?&gt;</p>
<p>&lt;page name='program' xmlns:i="http://apache.org/cocoon/include/1.0"&gt;<br />
      &lt;i:include src='cocoon:/webui_program'/&gt;<br />
...<br />
</code></p>
<p>Cette directive dit à Cocoon, d&#8217;inclure le contenu qui se trouve à l&#8217;url <em>cocoon:/webui_program</em>, défini dans le fichier<br />
<em>sitemap.xmap</em> :<br />
<code><br />
      &lt;!-- Webui --&gt;<br />
      &lt;map:match pattern="webui_*/*"&gt;<br />
        &lt;map:generate src='http://localhost/{1}?id={2}&amp;presenter=rest&amp;filter=webui'/&gt;<br />
        &lt;map:serialize type="exml"/&gt;<br />
      &lt;/map:match&gt;<br />
</code></p>
<h3>Transformation XSLT</h3>
<p>Pour transformer les données contenues dans ce fichier, nous avons créé notre propre feuille de style XSLT, pour produire un document FO.<br />
Cette feuille de style prend en compte la mise en forme des diffèrentes données du site.</p>
<p>Grâce à ce système, l&#8217;ensemble de la <strong>mise en forme est centralisé</strong> dans un seul fichier.<br />
Il est aussi possible d&#8217;ajouter du contenu statique dans le PDF à l&#8217;aide de balises dédiées.<br />
Comme par exemple, une balise <em>copyright</em>, qui sera transformées en un texte statique dans tous les documents PDF.</p>
<h3>Le pipeline pour les documents PDF</h3>
<p>Voici le <em>pipeline</em> final pour produire des documents PDF :<br />
<code><br />
      &lt;!-- PDF --&gt;<br />
      &lt;map:match pattern="*/*/*.pdf"&gt;<br />
        &lt;map:generate src='{1}/{3}.xml'/&gt;<br />
        &lt;map:transform src="mk_id.xsl" type="xslt"&gt;<br />
                &lt;map:parameter name="val" value="{2}" /&gt;<br />
        &lt;/map:transform&gt;<br />
        &lt;map:transform type="include"&gt;<br />
           &lt;map:parameter name="parallel" value="true"/&gt;<br />
           &lt;map:parameter name="support-caching" value="true"/&gt;<br />
           &lt;map:parameter name="expires" value="600"/&gt;<br />
        &lt;/map:transform&gt;<br />
</code></p>
<p>Le point intéressant à noter dans ce pipeline est l&#8217;encodage des arguments passés via l&#8217;URL pour le document PDF.<br />
En effet,  les URL pour produire les PDF sont formés de la manière suivante :</p>
<p>http://mavise.obs.coe.int/cocoon/mavise/channel/2157/channel.pdf</p>
<p>L&#8217;URL contient, le nom du module et l&#8217;identifiant de la chaîne.<br />
De cette manière, il est possible de passer d&#8217;autres arguments au système d&#8217;impression (comme par exemple, changer l&#8217;orientation du document).</p>
<h3>Performances</h3>
<p>Au niveau des performances du système d&#8217;impression, nous n&#8217;avons pas une charge très importante sur la génération des documents PDF.<br />
La production des documents est  une tâche complexe et nécessite donc de manière génèrale beaucoup de ressources.<br />
Néanmoins, il y a une chose intéressante à noter au niveau de la génération des documents PDF.<br />
Celle-ci est plus rapide que l&#8217;affichage dans un navigateur.<br />
En effet cela est lié au fait que les échanges de données se font en local sur le serveur, il y a donc moins de bande passante utilisée que dans le cas de l&#8217;affichage de cette même page par le navigateur.</p>
<h3>Les petits désagréments du format PDF</h3>
<p>Nous avons rencontré un petit problème, avec la gestion des polices UTF-8, en effet, comme la base contient des données sur des chaînes de télévision et des entreprises Turques, nous avons eu besoin d&#8217;embarquer une police UTF-8 à l&#8217;intérieur du document.<br />
Et visiblement cela pose des problèmes à certains lecteurs.</p>
<h3>Quelques liens utiles</h3>
<p>Voici quelques liens utiles qui nous ont aidé dans la réalisation de ce système d&#8217;impression :</p>
<ul>
<li><a href="http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-cocoon-2-1-x-et-fop-0-9x-sur-debian-4-0-etch">Le guide d&#8217;installation d&#8217;Apache Cocoon, FOP sur Debian GNU/Linux</a> ;</li>
<li><a href="http://cocoon.apache.org/2.1/introduction.html">Documentation de la version 2.1 d&#8217;Apache Cocoon</a> ;</li>
<li><a href="http://www.zvon.org/xxl/XPathTutorial/General/examples.html">XPath Tutorial</a> ; </li>
<li><a href="http://www.zvon.org/xxl/XSLTutorial/Output_fre/contents.html">XSLT Tutorial</a> ;</li>
<li><a href="http://www.ecrion.com/Support/Resources/XSL-FO-Tutorial-French/toc.xml.html">XSL-FO</a> ;</li>
</ul>
<h3>Conclusion</h3>
<p>En conclusion, j&#8217;aimerais remercié l&#8217;<a href="http://www.obs.coe.int/">Observatoire européen de l&#8217;audiovisuel</a> (OEA), pour nous avoir fait confiance pour la mise en place de cette solution.<br />
Au 1er abord, le schéma de l&#8217;architecture n&#8217;est pas très engageant <img src='http://www.csquad.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>J&#8217;espère que cette solution donnera des idées à d&#8217;autres personnes, pour leur système d&#8217;impression.<br />
L&#8217;objectif final est de faire des économies de papier par rapport à une impression faite via Internet Explorer <img src='http://www.csquad.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.csquad.org/2009/02/10/systeme-dimpression-pdf-restful-pour-le-web/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
