Esse artigo faz parte da revista Java Magazine edição 09. Clique aqui para ler todos os artigos desta edição

Atenção: por essa edição ser muito antiga não há arquivo PDF para download.Os artigos dessa edição estão disponíveis somente através do formato HTML. 

 

Apache FOP

Impressão em Java com XML e XSL-FO

Fernando Lozano

Utilize o poder de XML e Java para gerar, visualizar e imprimir relatórios em aplicações Swing, ou para criar arquivos PDF a partir de aplicações web

O HTML, em suas diversas variações (HTML 2.0, HTML 4.01, XHTML, WML) é hoje absoluto nas empresas, pois a maioria dos sistemas de informações e dos documentos manipulados pelas organizações é visualizada por um navegador web.

Apesar disso, o HTML é um formato bastante limitado quando comparado com os formatos nativos da maioria das ferramentas de automação de escritório e, apesar da evolução que sofreu desde o surgimento da web, continua sendo adequado apenas para a tela, não fornecendo controle suficiente para a impressão de qualidade. Não é possível, em HTML, definir dimensões de página, margens, cabeçalhos e rodapés – mesmo que algumas dessas características possam ser definidas usando folhas de estilo CSS (Cascading Style Sheets), não há controles básicos para eliminar linhas órfãs/viúvas, manter parágrafos na mesma página (como um subtítulo e o parágrafo correspondente), ou forçar quebras de página antes de uma dada seção do documento (por exemplo, um novo capítulo em um livro ou um novo grupo de registros em um relatório).

O padrão na web, quando se deseja preservar as características do documento impresso, é o formato PDF (Portable Document Format) da Adobe, baseado na popular linguagem PostScript para impressoras topo de linha. É difícil encontrar quem não tenha o leitor de PDFs Acrobat Reader instalado em seu computador; além disso, softwares livres como o xpdf e o GhostView são capazes de exibir e manipular documentos PDF.

Apesar da popularidade e das vantagens do PDF em relação ao HTML, não são encontradas muitas aplicações que gerem diretamente documentos nesse formato. Isso se explica pelo fato do PDF ser, em vários aspectos, um formato de “baixo nível”, no qual o programador (ou a aplicação) tem que manipular primitivas gráficas e posicionar elementos na área do papel. Nem mesmo funções simples, orientadas a documentos, como “pular para a próxima linha”, são suportadas diretamente pelo PDF. Imagine desenhar um gráfico empresarial (de barras, de torta etc.) diretamente com primitivas gráficas de desenho de retas e polígonos! Na prática, são utilizados os recursos de um software de planilha eletrônica, ou um componente especializado para a geração de gráficos em uma aplicação visuais (GUI), como o JFreeChart.

É necessária uma ferramenta de nível mais alto para o desenvolvedor. O FOP da Apache Foundation fornece exatamente isso, baseando-se no padrão XSL-FO (XSL Formatting Objects).

Nota: Existem ainda alternativas ao FOP, tanto livres quanto proprietárias, mas que não seguem padrões para a descrição dos documentos impressos – o quadro “FOP x Geradores de relatórios” apresenta as situações em que elas podem ser mais adequadas.

XSL-FO: HTML para o papel

O W3C, órgão que define padrões independentes de fornecedor para a web, reconhecendo as limitações do HTML, não apenas para a impressão, mas também em outras áreas, definiu o XML. Hoje, grande parte do conteúdo da web já é gerada usando como base essa tecnologia.

É importante lembrar que o XML não define uma linguagem de marcação específica, como o HTML, mas sim uma “meta-linguagem”, sobre a qual podem ser definidos dialetos especializados. Um exemplo é o dialeto XHTML (Extensible HTML), uma reformulação do HTML em XML.

Uma série de tecnologias surgiu em torno do XML e isso é um dos fatores que o torna tão interessante para o desenvolvedor. Uma das primeiras criadas foi o XSL (Extensible Stylesheet Language), cujo propósito original foi definir folhas de estilo em XML para substituir o CSS, mas que evoluiu para o XSLT (XSL Transformations), uma tecnologia genérica para a transformação de documentos XML de um dialeto para outro. Utilizando XSLT, um site web pode, a partir de um único documento (representando, por exemplo, o cadastro de produtos de um site de comércio eletrônico), gerar versões HTML especializadas para navegadores com diferentes capacidades, além de páginas WML (Wireless Markup Language) para PDAs e celulares, entre vários outros formatos.

Para complementar as capacidades de transformação do XSLT, foi definido um dialeto XML para a formatação de documentos impressos, o já citado XSL-FO. Pense nele como um “HTML para o papel”. Em relação ao PDF, o XSL-FO possui várias vantagens; uma delas é ser um formato muito mais legível para humanos. (Hoje a questão da legibilidade pode parecer irrelevante, dado o foco do mercado em ferramentas visuais, mas lembre que a possibilidade de editar um documento HTML com qualquer editor de textos foi um dos fatores determinantes para o seu enorme sucesso). Além disso, como o XSL-FO é apenas uma linguagem de marcadores em arquivos texto, qualquer ferramenta ou tecnologia capaz de gerar páginas HTML dinâmicas também é capaz de gerar dinamicamente documentos XSL-FO.

Futuramente poderão existir navegadores ou plug-ins que “entendam” XSL-FO, como acontece hoje com o SVG (Scalable Vector Graphics), outro dialeto XML especializado. Mas, até lá, haverá a necessidade de uma aplicação capaz de processar um documento XSL-FO e transformá-lo em algum formato popular, como HTML ou PDF. Este é o papel do FOP.

O Apache FOP

O FOP é parte do projeto Apache XML, e visa fornecer tecnologias para o processamento de documentos XML. Desse mesmo projeto surgiram os populares Xerces (parser XML) e Xalan (transformador XSLT) – veja mais sobre o processamento de XML com Java na Edição 2.

O objetivo do FOP é fornecer um processador de documentos XSL-FO inteiramente escrito em Java. Apenas como uma comodidade, o FOP também pode ser utilizado para comandar transformações XSLT (na verdade realizadas pelo Xalan), de modo a formatar documentos XML com estilos em documentos XSL-FO. Estes, em seguida, são processados gerando a saída em PDF.

A Figura 1 ilustra vários cenários possíveis de uso do FOP. Outros projetos da Apache Foundation, como o Cocoon (veja artigo nesta edição), utilizam o FOP para a geração de documentos PDF.

O FOP não está restrito à geração de PDF. Também pode gerar arquivos PCL (linguagem de controle das impressoras laser e jato de tinta, criada pela HP), PostScript, SVG e até mesmo TXT. Além disso, fornece uma aplicação que pode exibir o documento formatado em uma janela AWT ou Swing, fornecendo assim um “print preview” que pode ser impresso diretamente.

Documento de exemplo

Não é o objetivo deste artigo ensinar a sintaxe do XSL-FO (para tal, visite os excelentes tutoriais do developerWorks da IBM, indicados nos links), mas precisamos de um documento simples para demonstrar o uso do FOP. A Listagem 1 apresenta um exemplo, com nome "teste.fo" (é comum o uso da extensão .fo para nomes de arquivos XSL-FO, embora não seja obrigatória).

Observe que o documento inicia pela definição de um layout mestre de página, com -master-set> (podem ser usados vários layouts diferentes no mesmo documento), seguido por uma seqüência de páginas (-sequence>) que referenciam o layout. Não é necessário delimitar explicitamente as páginas (como o seria em PDF), pois o FOP ou outro processador XSL-FO cuida desta tarefa – basta fornecer uma seqüência de fluxos (), que correspondem a capítulos, seções, parágrafos, itens ou quaisquer outros elementos estruturais do documento. Um fluxo pode conter blocos , tabelas e outros elementos. Dentro de qualquer elemento, caso seja necessário alterar parâmetros de formatação (como a família ou o tamanho da fonte), utiliza-se o elemento , que define atributos de formatação sem interferir no fluxo de formatação da página.

O exemplo teste.fo apresenta apenas os elementos de texto básicos do XSL-FO, o suficiente para que o leitor possa gerar documentos úteis e para exercitar as aplicações Java vistas mais adiante. O quadro “Gráficos e imagens em XSL-FO” fornece mais informações para o leitor interessado em inserir gráficos nos documentos.

Instalação

Para fazer a instalação do FOIP, baixe, do site oficial do projeto, a distribuição binária mais recente e descompacte-a em qualquer diretório (que será referenciado daqui para frente como FOP_HOME). Dentro de FOP_HOME/build/site se encontra a documentação do projeto, consistindo basicamente em uma cópia do site do FOP.

Na raiz da instalação do FOP encontram-se dois scripts, fop.sh e fop.bat, que fornecem uma maneira prática de executar o programa em Unix/Linux e Windows, respectivamente. Então, considerando que nosso documento de exemplo está no diretório corrente e o diretório FOP_HOME foi acrescentado ao path do sistema operacional, basta rodar o comando a seguir para visualizar o documento de testes gerado (veja a Figura 2).

 

fop.bat -fo teste.fo -awt

 

O script fop.bat fornecido na distribuição binária do FOP roda apenas no Windows NT ou superior (2000, XP etc.). Usuários do Windows 95/98 deverão editar o script para fornecer o valor da variável de ambiente LOCAL_FOP_HOME, que corresponde ao diretório de instalação do FOP. (Usuários Linux devem substituir fop.bat por fop.sh). Caso se deseje ver o resultado em formato PDF em vez de em uma janela Java, o comando seria:

 

fop.bat -fo teste.fo -pdf teste.pdf

 

Isso gera o arquivo teste.pdf no diretório corrente (veja a Figura 3). A aplicação de linha de comando do FOP fornece ainda outras opções, como impressão direta do documento ou transformação via XSLT, mas como nosso interesse é utilizar o FOP em aplicações Java customizadas, deixo a cargo do leitor a consulta de mais detalhes na documentação da ferramenta.

Desenvolvimento com FOP

A maneira mais fácil de utilizar o FOP em aplicações Java é instanciando um objeto da classe org.apache.fop.apps.Driver, cujo construtor recebe dois argumentos: um org.xml.sax.InputSource (da API JAXP) e um java.io.OutputStream, opcional, para gravação do resultado do processamento. Depois basta indicar o formato da saída com o método setRenderer, e “executar” o FOP com o método run.

A classe Driver é bastante flexível, oferecendo construtores alternativos e métodos get/set, no padrão JavaBean, de modo que existe suporte a vários cenários diferentes de aplicação, além da possibilidade de integração com IDEs. Infelizmente, a documentação desta e de outras classes do FOP não é fornecida na distribuição binária. Você deve consultá ...

Quer ler esse conteúdo completo? Tenha acesso completo