In Java, Programação

Gerando arquivos PDF a partir de sua aplicação Java

Posted June 23rd, 2008 by Rodrigo Lazoti.

Uma forma de se gerar aquivos PDF diretamente de sua aplicação Java é utilizando um projeto da Apache chamado FOP (Formatting Objects Processor), veja a seguir uma breve descriçao retirada do próprio site do projeto:

FOP (Formatting Objects Processor) is the world’s first print formatter driven by XSL formatting objects (XSL-FO) and the world’s first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. The primary output target is PDF but other output formats currently supported include:

  • PDF (Portable Document Format)
  • PS (Adobe Postscript)
  • PCL (Printer Control Language)
  • AFP (MO:DCA)
  • SVG (Scalable Vector Graphics)
  • XML (area tree representation)
  • Print
  • AWT/Java2D
  • MIF
  • RTF (Rich Text Format)
  • TXT (text)

Vou demonstrar com um pequeno exemplo, como utilizar a conversão de um documento XML em um documento PDF por uma aplicação Java.

Para iniciar o exemplo vou baixar o arquivo binário no endereço:

http://linorg.usp.br/apache/xmlgraphics/fop/binaries/fop-0.94-bin-jdk1.4.zip

Agora criarei um projeto java e irei incluir os seguintes jar’s necessários para o exemplo que encontram-se no download feito:

  • avalon-framework-4.2.0.jar
  • batik-all-1.6.jar
  • commons-io-1.3.1.jar
  • commons-logging-1.0.4.jar
  • fop.jar
  • serializer-2.7.0.jar
  • xalan-2.7.0.jar
  • xercesImpl-2.7.1.jar
  • xml-apis-1.3.02.jar
  • xmlgraphics-commons-1.2.jar

Na raiz do projeto irei criar uma pasta chamada documentos e irei colocar um arquivo chamado projeto.xml com o seguinte conteúdo:


< ?xml version="1.0" encoding="UTF-8"?>
<!-- $Id$ -->
<projeto>
<nomeprojeto>Teste de Aplicacao usando Apache FOP</nomeprojeto>
<membro>
<nome>Rodrigo</nome>
<funcao>Desenvolvedor</funcao>
<email>teste@teste.com</email>
</membro>
<membro>
<nome>Administrador</nome>
<funcao>Gerente</funcao>
<email>admin.teste@teste.com</email>
</membro>
<membro>
<nome>Usuario</nome>
<funcao>user</funcao>
<email>user.teste@teste.com</email>
</membro>
</projeto>

E também irei criar um estilo XSL para o documento XML chamado projeto.xsl dentro da pasta documentos com o seguinte conteúdo:

< ?xml version="1.0" encoding="UTF-8"?>
<!-- $Id$ -->
<xsl :stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">
<xsl :o utput method="xml" version="1.0" omit-xml-declaration="no" indent="yes"/>
<xsl :param name="versionParam" select="'1.0'"/>
<!-- ========================= -->
<!-- elemento principal: projeto           -->
<!-- ========================= -->
</xsl><xsl :template match="projeto">
<fo :root xmlns:fo="http://www.w3.org/1999/XSL/Format">
</fo><fo :layout-master-set>
</fo><fo :simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
<fo :region-body/>
</fo>

<fo :page-sequence master-reference="simpleA4">
</fo><fo :flow flow-name="xsl-region-body">
</fo><fo :block font-size="16pt" font-weight="bold" space-after="5mm">Projeto: <xsl :value-of select="nomeprojeto"/>
</fo>
<fo :block font-size="12pt" space-after="5mm">Versão <xsl :value-of select="$versionParam"/>
</fo>
<fo :block font-size="10pt">
</fo><fo :table table-layout="fixed" width="100%" border-collapse="separate">
<fo :table-column column-width="4cm"/>
<fo :table-column column-width="4cm"/>
<fo :table-column column-width="5cm"/>
</fo><fo :table-body>
<xsl :apply-templates select="membro"/>
</fo>

</xsl>
<!-- ========================= -->
<!-- elemento filho: membro               -->
<!-- ========================= -->
<xsl :template match="membro">
<fo :table-row>
<xsl :if test="function = 'lead'">
</xsl><xsl :attribute name="font-weight">bold</xsl>
</fo></xsl>
<fo :table-cell>
</fo><fo :block>
<xsl :value-of select="nome"/>
</fo>

<fo :table-cell>
</fo><fo :block>
<xsl :value-of select="funcao"/>
</fo>

<fo :table-cell>
</fo><fo :block>
<xsl :value-of select="email"/>
</fo>

Finalmente uma pequena aplicação Java que irá gerar um documento PDF chamado projeto.pdf em uma pasta chamada saida.


package br.com.rodrigolazoti;

import java.io.File;
import java.io.OutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;

public class ExportXMLtoPDF {

public static void main(String[] args) {
try {
File baseDir = new File(".");
File outDir = new File(baseDir, "saida");
outDir.mkdir();

File xmlfile = new File(baseDir, "documentos/projeto.xml");
File xsltfile = new File(baseDir, "documentos/projeto.xsl");
File pdffile = new File(outDir, "projeto.pdf");

FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);

try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
transformer.setParameter("versionParam", "2.0");

Source src = new StreamSource(xmlfile);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
}
finally {
out.close();
}
}
catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
}

}
}

Este exemplo foi baseado em um exemplo contido no download feito.

Related Posts

  1. Autenticação com Jboss Seam
  2. Testes unitários com TestNG
  3. Framework javascript Extjs em páginas jsp com tags tld

8 responses to Gerando arquivos PDF a partir de sua aplicação Java

  1. Rafael Salerno says:

    Por acaso alguem ja te apresentou o Jasper Report???????

  2. Rodrigo Lazoti says:

    Claro que sim Rafael, mas Jasper não é a unica forma de se fazer tudo. E se você ler um pouco mais sobre este projeto da Apache verá que sua finalidade é bem diferente do Jasper Reports que tem por finalidade ser um gerenciador de relatórios.

    []s

  3. Antonio Fernando Amorim says:

    É uma ótima ferramenta, tive a oportunidade a alguns anos atras de fazer meu projeto de monografia em cima dela voltada como uma solução para um grande jornal aqui de Salvador-Ba

    Uma vez que os documentos do jornal já estão sendo salvos em formato XML.
    Basta um XSL bem feito e você tem a saida do formato que deseja.

  4. Rafael de Camillis says:

    Caramba,

    Bem legal este recurso, estou procurando uma ferramenta mais leve para a geração de documentos PDF, porque em geral os geradores de PDF convencionais consomem muita memória e tempo de processamento. Será que existe algum exemplo consumindo esses componentes pelo Delphi?

    []‘s

    Camillis

  5. Rodrigo Lazoti says:

    Olá Rafael!

    Infelizmente não conheco algo similar para o Delphi, mas caso ache algo te aviso ok.

    []‘s.

  6. sidney says:

    Eu fiz o dowload e adicionei os jars mas esses imports:

    import org.apache.fop.apps.FOUserAgent;
    import org.apache.fop.apps.Fop;
    import org.apache.fop.apps.FopFactory;
    import org.apache.fop.apps.MimeConstants;

    não conseguem achar as classes , vc tem alguma idéia

  7. Evelize de Medeiros says:

    Este projeto FOP Apache transforma um arquivo PCL para um PDF?
    Se a resposta for sim, você tem algum exemplo?

  8. Ricardo says:

    Gostei deste recurso!

    Tem algum gerenciador para manipular essa biblioteca?

    Agradeço

Leave a response: