Convertir XML en PDF utilizando XSL-FO y FOP

En este artculo vamos a ver como podemos utilizar el FOP y el lenguaje de objetos de formateo XSL-FO para generar documentos en formato PDF a partir de nuestros documentos XML.

XSL

La XSL es una especificacin desarrollada dentro del W3c para aplicar formato a los documentos XML de forma estandarizada. La XSL es un lenguaje para escribir hojas de estilo que consta de dos partes:

  • XSLT, que es un lenguaje de transformacin, mediante el cual se puede transformar un documento XML en otro XML.
  • XSL-FO, un lenguaje de formateo, que no es ms que un vocabulario XML para especificar objetos de formateo (FO).

El lenguaje XSLT ya es ms que conocido (es una recomendacin del W3C desde el 16 Noviembre 1999) y en estas pginas de Programacin en castellano ya le hemos dedicado algunos artculos en los que hemos explicado como utilizarlo para por ejemplo generar HTML o SVG.

Por tanto en este artculo vamos a centrarnos en el lenguaje XSL-FO (candidato a recomendacin desde el 21 de Noviembre del 2000) y sobre todo en como utilizar una aplicacin denominada FOP mediante la cual podremos convertir nuestros documentos XML en formato PDF.

XSL-FO (Objetos de Formateo)

Mediante los objetos de formateo (Formatting Objects -FO-) y sus propiedades podemos describir cmo se van a visualizar los componentes de un documento. Con estos objetos definimos:

  • Las caractersticas de la pgina.
  • Los prrafos.
  • Las listas.
  • Las tablas.
  • Los enlaces.
  • etc.

La especificacin XSL indica el vocabulario XML que define estos objetos de formateo.

El siguiente cdigo hola.fo es un pequeo ejemplo de fichero XSL-FO:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!--  ================================================
      Hola.fo
      Joaquin Bravo Montero
      (c)Programacion en Castellano
         http://www.programacion.net
      ================================================ -->

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <fo:layout-master-set>
  
    <fo:simple-page-master master-name="simple"
                  page-height="29.7cm" 
                  page-width="21cm"
                  margin-top="1cm" 
                  margin-bottom="2cm" 
                  margin-left="2.5cm" 
                  margin-right="2.5cm">
      <fo:region-body margin-top="3cm"/>
      <fo:region-before extent="3cm"/>
      <fo:region-after extent="1.5cm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  
  <fo:page-sequence master-name="simple">

    <fo:flow flow-name="xsl-region-body">

      <fo:block font-size="18pt" 
            font-family="sans-serif" 
            line-height="24pt"
            space-after.optimum="15pt"
            text-align="center"
            padding-top="3pt">
        Mi primer XSL-FO
      </fo:block>


      <fo:block font-size="12pt" 
                font-family="sans-serif" 
                line-height="15pt"
                space-after.optimum="3pt"
                text-align="justify">
                Hola este es mi primer XSL-FO.
      </fo:block>


    </fo:flow>
  </fo:page-sequence>
</fo:root>

En el que podemos observar:

  • Que se trata de un vocabulario XML, en el que todos los elementos van precedidos del namespace 'fo', y que por tanto al escribir el elemento raiz del documento XML debemos declararlo de la siguiente manera:
  • <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  • Que esta formado por un conjunto de elementos: fo:simple-page-master, fo:flow, fo:block, etc. mediante los cuales y sus propiedades (definidas en los atributos): font-size, font-family, etc. describimos como se visualizan de forma genrica los componentes de un documento. La especificacin define por tanto todos estos elementos y sus propiedades y como deben expresarse mediante un vocabulario XML.

Procesadores XSL-FO

Un procesador XSL es la aplicacin que procesa un documento XML compuesto de XSL-FOS y lo presenta de manera que una persona lo pueda leer facilmente.

Flujo de proceso

En los ltimos meses han sido muchos los procesadores de XSL-FO que han aparecido. Estos son algunos de los ms significativos:

  • XEP, desarrollado por RenderX. Es sin duda alguna el ms avanzado. El nico inconveniente es que se trata de una aplicacin comercial aunque nos podemos bajar una versin demo evidentemente limitada en sus funcionalidades. Es recomendable darse una vuelta por su Web y visulizar los espectaculares ejemplos que han desarrollado. En Java.
  • PassiveTex. Es una librera de macros en Tex que pueden ser usadas para procesar documentos XML formados por XSL-FO. Ejecutando PassiveTex con pdfTex se pueden generar facilmente documentos PDF. Lo mejor de estas librerias es el buen soporte para MathML que poseen.
  • XSL Formatter, de Antenna House Inc. Consiste en un procesador de XSL-FO acompaado de un interfaz de usuario. Necesita la MSXML3.0 como procesador de XSLT y funciona sobre plataforma Windows.
  • Unicorn Formatting Objects (UFO), que es un procesador de XSL-FO implementado en C++. La salida de esta herramienta es TeX y a partir de este formato podemos generar PostScript, PDF, etc.
  • FOP, que es un procesador de XSL-FO desarrollado en Java por Apache XML Project. Es el primero que aparecio, es totalmente gratuito y aunque no es tan potente como el XEP es sin duda alguna el ms utilizado en la actualidad (es gratuito). Entre sus ventajas cabe destacar que permite trabajar con documentos SVG.

FOP

El FOP (Formatting Object to PDF) es el primer procesador de objetos de formateo XSL que aparecio. Empez a ser desarrollada en solitario por James Tauber pero posteriormente se incorporo al "Apace XML Project" lo que est acelerando su desarrollo.

En el momento de escribir estas lineas la versin actual del FOP es la 0.18.1 que es la que utilizaremos en nuestros ejemplos. Exactamente hemos utilizado la versin: Fop-0.18.1-DEV-src.zip que se puede obtener en la siguiente direccion: http://xml.apache.org/dist/fop/.

Prerequisitos

Como ya hemos dicho es una aplicacin en Java por lo que para poder utilizarla el nico requisito necesario es tener instalado la mquina virtual Java. Segn la documentacin basta con el Java 1.1.x o superior. Recomiendo tener como mnimo la versin 1.1.2 del JDK, ya que para las versiones 1.1.x hay algunos ejemplos que dan problemas.

No hace falta nada ms ya que esta distribucin viene con todos los archivos .jar que le hacen falta para poder funcionar. Fijaros que el fichero .zip ocupa 9.289 KB.

Instalacion

La instalacin es muy sencilla. Simplemente tenemos que descomprimir el fichero y veremos que nos crea una gran cantidad de directorios con todo lo necesario para empezar a trabajar y ver su funcionamiento: ejemplos, documentacin, ficheros bat, etc.

Funcionamiento

Para probar que todo nos funciona correctamente podemos realizar los siguientes pasos:

  • Dentro de la carpeta raiz del FOP nos situamos en el subdirectorio docs/examples/
  • Desde linea de comandos ejecutamos el fichero runtests.bat, el cual:
    • Crea un directorio tests.
    • Dentro del cual se generaran en formato PDF los ficheros XSL-FO que se encuentran en el directorio fo.

Si todo el proceso anterior ha funcionado correctamente significara que ya tenemos todo perfectamente instalado para trabajar con el FOP.

Y para convertir nuestro documento hola.fo, lo colocamos en el directorio raiz de la aplicacin y ejecutamos el fichero Fop.bat de la siguiente manera:

Fop hola.fo hola.pdf

Lo cual nos genera el siguiente fichero PDF:

Hola.fo en formato PDF

Pero con la anterior expresin slo hemos ejecutado la opcin ms sencilla que nos ofrece la aplicacin. Tambin podramos utilizar el FOP directamente como browser de ficheros XSL-FO. No tendramos ms que ejecutar el comando anterior de la siguiente manera:

Fop hola.fo -awt

Obteniendo el siguiente resultado:

Hola.fo visualizado en browser del FOP.

Tambin podriamos convertir al formato MIF, TXT, etc.

Para terminar esta seccin simplemente un comentario. Es importante que os fijis que el documento PDF lo hemos generado directamente desde el fichero hola.fo. Para el ejemplo lo he escrito directamente a mano. Pero como ya he dicho anteriormente se trata de un fichero XML que podramos haber generado desde otro fichero XML mediante una XSLT. Es decir, la conversin de nuestro XML original a PDF hubiese constado de dos partes:

  1. Conversin XML original a XSL-FO mediante XSLT y un procesador XSLT.
  2. Conversin de XSL-FO a PDF mediante el procesador FOP.

El FOP nos permite tambin realizar esta accin en un nico paso (el FOP lleva incorporado el procesador XSLT Xalan). Si suponemos que nuestro documento inicial se llama hola.xml, mediante la siguiente instruccin lo hubiesemos podido realizar:

Fop -xsl hola.xsl -xml hola.xml -pdf hola.pdf

Generando nuestro documento XML en formato PDF

A continuacin vamos a escribir un ejemplo completo en el que transformaremos a PDF el documento gastrono.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<direcciones>
 <tema>Mis direcciones de gastronoma</tema>
 <intro>Recopilacin de mis direcciones de gastronoma favoritas.</intro>

 <direccion>
  <titulo>A fuego lento</titulo>
  <url>http://www.bongust.com/</url>
  <descripcion>Portal sobre el mundo de la 
   gastronoma creado por Koldo Royo.</descripcion>
 </direccion>
 ....
 ....
</direcciones>

Que ya hemos utilizado en otros artculos.

Para ello, en primer lugar debemos escribir una XSLT que nos convierta dicho documento al vocabulario XSL-FO. A esta XSLT la llamaremos gastronofo.xsl.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!--  ================================================
      gastronofo.xsl
      Joaquin Bravo Montero
      (c)Programacion en Castellano
         http://www.programacion.net
      ================================================ -->

<xsl:stylesheet
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:fo="http://www.w3.org/1999/XSL/Format"
		 version="1.0">

<xsl:template match="direcciones">

	<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <fo:layout-master-set>
  
    <fo:simple-page-master master-name="simple"
                  page-height="29.7cm" 
                  page-width="21cm"
                  margin-top="1cm" 
                  margin-bottom="2cm" 
                  margin-left="2.5cm" 
                  margin-right="2.5cm">
      <fo:region-body margin-top="3cm"/>
      <fo:region-before extent="3cm"/>
      <fo:region-after extent="1.5cm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  
  <fo:page-sequence master-name="simple">

    <fo:flow flow-name="xsl-region-body">
     <xsl:apply-templates/>
    </fo:flow>
  </fo:page-sequence>
</fo:root>	

</xsl:template>

<xsl:template match="tema">

	<fo:block font-size="20pt" 
            font-family="sans-serif" 
            line-height="24pt"
            space-after.optimum="15pt"
            text-align="center"
            padding-top="3pt">
        <xsl:value-of select="."/>
  </fo:block>

</xsl:template>

<xsl:template match="intro">
	<fo:block font-size="12pt" 
            font-family="sans-serif" 
            line-height="15pt"
            space-after.optimum="3pt"
            text-align="justify">
      <xsl:value-of select="."/> 
  </fo:block>
</xsl:template>

<xsl:template match="direccion">
	<fo:block space-after.optimum="3pt"
            space-before.optimum="4pt">	
	    <xsl:apply-templates/>
	</fo:block>
</xsl:template>

<xsl:template match="titulo">
	<fo:block font-size="12pt" 
            font-weight="bold"
            font-family="sans-serif" 
            line-height="13pt"
            space-after.optimum="2pt"
            text-align="justify">
       <xsl:value-of select="."/>
  </fo:block>
</xsl:template>

<xsl:template match="url">
   <fo:block font-size="9pt">
     <fo:basic-link color="#0060A0" external-destination="{.}">
       <xsl:value-of select="."/>
     </fo:basic-link>
   </fo:block>	
</xsl:template>

<xsl:template match="descripcion">
	<fo:block font-size="9pt"
            start-indent="3pt"		 
            font-family="sans-serif" 
            line-height="12pt"
            space-after.optimum="3pt"
            text-align="justify">
         <xsl:value-of select="."/>
  </fo:block>
</xsl:template>

</xsl:stylesheet>

A partir de aqui tenemos dos posibilidades:

  • Generar el PDF en dos pasos:
    1. Transformar el fichero gastrono.xml el formato XSL-FO mediante la XSLT anterior y cualquier porcesador XSLT. Si por ejemplo utilizamos el XT
    2. xt gastrono.xml gastronofo.xsl gastrono.fo
    3. Transformar el resultado a PDF utilizando el FOP como ya sabemos:
    4. Fop gastrono.fo gastronopdf.pdf
  • O generarlo en un nico paso utilizando el FOP de la siguiente manera:
  • Fop -xsl gastronofo.xsl -xml gastrono.xml -pdf gastronopdf.pdf

En cualquiera de los dos casos el resultado es el siguiente documento PDF:

Documento gastrono.xml en formato PDF.

Direcciones

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.