Esto puede que sea algo viejo y muy visto. Pero la verdad es que mas tarde o más temprano es normal encontrarte con que necesitas generar un PDF dentro de un Servlet, Servicio o clase Java. Así que vamos a ver como hacerlo, y todo gracias a Apache FOP.
Vamos a ver varios ejemplos, para ver un poco por encima cuales son las distintas posibilidades que hay. Pero los pasos a seguir (con alguna diferencia según el ejemplo) serán los siguientes:
- Crear un objeto 'FopFactory', en base al que le podemos pasar un fichero de configuración. Usualmente le pasaremos 'new File(".").toURI()'.
- Crear un objeto 'Fop', que asociaremos a la salida (usualmente un OutputStream) y al que le indicaremos en que formato queremos dicha salida (pudiéndose un PDF, RFT, TXT, etc).
- Crear un objeto 'Transformer', que nos permitirá realizar la transformación de un objeto a otro y al que también podremos asociar un fichero XSLT para transformaciones de XML específicas.
- Preparar la entrada y salida de la transformada en base a los tipos de objetos predefinidos de la misma. Para la entrada usaremos un StreamSource y para la salida un Result proveniente del FOP.
- Realizar la transformada a través del método 'transform' del objeto 'Transformer'.
Llegados a este punto sería bueno aclarar ls siguientes cuestiones:
El ejemplo más básico lo tendremos cuando queremos generar un simple PDF sin pasarle ninguna fuente de datos. Para darle el formato deseado a ese PDF usaremos una simple plantilla 'XSL-FO'.
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); try (OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(outputFileRelPath)))) { Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); Source src = new StreamSource(new FileInputStream(new File(foRelativeFilePath))); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); }
Ahora veremos un ejemplo más cercano a la realidad. Donde pasaremos un XML de entrada, como un texto, y a través de la conjunción del XSLT y XSL podremos transformar y formatear dicho XML para sacar el PDF que queramos.
Como podeis ver son practicamente iguales, cambia que el segundo indicamos una fuente de entrada. La dificultad en el segundo ejemplo radica más en el manejo y la experiencia que tengas con XSLT y XSL.
Por último indicar que si lo que queremos es generar un PDF a través de una transformada XSLT 2.0 tendremos que utilizar otra librería, 'Saxon'. Con ella la única diferencia será la forma que generemos el objeto 'TransformerFactory', ya que deberemos usar el propio de esta nueva librería.
Podeis ver todo el código aquí.
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); try (OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(outputFileRelPath)))) { Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); Source template = new StreamSource(new FileInputStream(new File(xslRelativeFilePath))); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(template); StreamSource src = new StreamSource(IOUtils.toInputStream(xmlText)); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res);
}
Como podeis ver son practicamente iguales, cambia que el segundo indicamos una fuente de entrada. La dificultad en el segundo ejemplo radica más en el manejo y la experiencia que tengas con XSLT y XSL.
Por último indicar que si lo que queremos es generar un PDF a través de una transformada XSLT 2.0 tendremos que utilizar otra librería, 'Saxon'. Con ella la única diferencia será la forma que generemos el objeto 'TransformerFactory', ya que deberemos usar el propio de esta nueva librería.
TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl();
Podeis ver todo el código aquí.
No hay comentarios:
Publicar un comentario