iText é uma biblioteca java para manipulação de documentos em PDF, que é um formato de arquivo aberto (ISO-32000-1), originalmente criado pela Adobe. Este documento é independente de sistemas de software ou hardware e atualmente é uma parte essencial da web. O visualizador de PDF mais utilizado hoje é o Adobe Reader, porém existem muitos outros que são tanto grátis como pagos.

O iText é livre e de código-fonte aberto sob a licença Affero General Public License (AGPL). Atualmente existem duas versões do iText: uma versão para Java e outra versão para C#, esta última chamada de iTextSharp. Essa poderosa ferramenta pode ser usada para criar relatórios em pdf, além de uma variedade de outras coisas, como ingressos digitais para companhias aéreas ou shows, boletos, e muito mais. iText também pode ser integrado com uma aplicação para gerar documentos PDF como um alternativa à papéis impressos para adicionar assinaturas digitais aos documentos. Além disso, podemos concatenar ou separar diferentes documentos.

No restante do artigo veremos mais sobre o iText e faremos exemplos práticos para testarmos algumas das suas características.

Utilizando iText

Para utilizar o iText nosso projeto, você deve possuir um dos seguintes requisitos:

  • O conteúdo não está disponível imediatamente. O conteúdo é disponibilizado baseado na entrada do usuário ou informações de uma base de dados.
  • O arquivo PDF não pode ser produzido de forma manual devido o grande número de conteúdo.
  • O documento precisa ser criado após execução de um processo batch.
  • O conteúdo precisa ser customizado.

Os documentos PDF gerados pelo iText também são muito úteis na web. Ao invés de gerarmos um conteúdo HTML, algumas vezes precisamos gerar o conteúdo no formato PDF, por ser mais preferido ao HTML, por razões de segurança ou até mesmo para reduzir o tamanho total do arquivo.

Portanto, o iText ajuda os desenvolvedores das seguintes formas:

  • Gerar documentos e relatórios através de arquivos XML ou Banco de Dados
  • Criar mapas e livros
  • Adicionar marcadores, números de páginas e muito mais.
  • Separar ou concatenar páginas de arquivos PDF existentes.
  • Gerar ou manipular documentos PDF para um browser.

Adquirindo iText

Para adquirir o iText (iText.jar) basta visitar o SourceForge ou o site www.itextpdf.com. O iText versão 5 funciona com Java Development Kit 5 ou superior.

Exemplo de Uso

Para compilar o exemplo utilize uma IDE (Integrated Development Environment) como o Eclipse ou então utilize a linha de comando não esquecendo de referenciar onde está o jar do iText (-cp) e o caminho do código fonte, como por exemplo:

javac -d bin -cp lib/iText.jar src/pacoteexemplo/HelloWorld.java

Para começar devemos abrir o eclipse e adicionar no build path do projeto o iText.jar. Para isso clique com o botão direito do mouse em cima do nome do projeto e selecione Properties, conforme ilustra a Figura 1.

Figura 1. Selecionando as propriedades do projeto.

Após isso selecione Java Build Path no menu esquerdo, conforme ilustra a Figura 2.

Figura 2. Selecionado a opção “Java Build Path” no menu esquerdo.

Selecione a aba Libraries, conforme ilustra a Figura 3.

Figura 3. Selecionando “Libraries” no menu superior.

Por fim, clique em “Add External JARs” e selecione o arquivo “itextpdf-5.4.5.jar” que foi descompactado do itext baixado do site oficial.

Agora que adicionamos o .jar no projeto vamos partir para a codificação. Crie uma classe com o nome HelloWorld e adicione o método da Listagem 1 dentro da classe.

Listagem 1. Primeiro exemplo com itext.


  import java.io.FileOutputStream;
  import java.io.IOException;
   
  import com.itextpdf.text.Document;
  import com.itextpdf.text.DocumentException;
  import com.itextpdf.text.Paragraph;
  import com.itextpdf.text.pdf.PdfWriter;
   
  public static final String RESULT = " C:\\Users\\higor\\Desktop\\proj_iText\\arqPDFexemplo.pdf";
   
  public static void main(String[] args) throws DocumentException, IOException {
           Document document = new Document();
           PdfWriter.getInstance(document, new FileOutputStream(RESULT));
           document.open();
           document.add(new Paragraph("Primeiro Exemplo com iText!"));
           document.close();
  }
  

A Figura 4 abaixo mostra como ficou o nosso documento:

Figura 4. Arquivo PDF criado com o iText.

O arquivo está disponível no caminho colocado na variável “RESULT”.

Com poucas linhas de código já temos nosso primeiro documento PDF pronto para ser executado. No exemplo acima temos a linha "Document document = new Document()" onde criamos um documento. Após isso, recebemos uma instância do tipo PdfWriter e na terceira linha abrimos um documento com o comando "document.open()". Sempre que um objeto documento é aberto, tem-se que diversas inicializações são realizadas, além do cabeçalho do arquivo ser escrito para o OutputStream. Se abrirmos um PDF com notepad podemos visualizar o cabeçalho na primeira linha, algo como o nome do arquivo (PDF) e a sua versão (Figura 5).

Figura 5. Versão do documento PDF criado.

A versão do PDF pode ser alterada com o comando "PdfWriter.setPdfVersion(PdfWriter.VERSION_1_7)". Na quarta linha adicionamos o conteúdo "Primeiro Exemplo com iText!" com um parágrafo. Além de Paragraph poderíamos também ter utilizado Chunk, Phrase, Anchor ou List. Por fim, o comando "document.close()" fecha o documento e libera todos os recursos alocados. O iText mantém alguns objetos na memória principalmente para reutilizá-los. É interessante notarmos que OutputStream em nenhum momento foi fechado, isto porque o iText se encarrega de fecha-lo.

Podemos fazer diversas modificações nesse simples PDF. Primeiramente vamos adicionar margens e aumentar o tamanho do documento explicitamente com com.itextpdf.text.Rectangle. Para isso altere o código anterior para o código da Listagem 2.

Listagem 2. Alterando o PDF anterior com novas funcionalidades.


  import java.io.FileOutputStream;
  import java.io.IOException;
   
  import com.itextpdf.text.Document;
  import com.itextpdf.text.DocumentException;
  import com.itextpdf.text.Paragraph;
  import com.itextpdf.text.Rectangle;
  import com.itextpdf.text.pdf.PdfWriter;
   
   
  public class HelloWorld {
           
    public static final String RESULT = 
     "C:\\Users\\higor\\Desktop\\proj_iText\\arqPDFexemplo2.pdf";
   
    public static void main(String[] args) 
       throws DocumentException, IOException {
          Rectangle pagesize = new Rectangle(216f, 720f);
          Document document = new Document(pagesize, 36f, 72f, 108f, 180f);
           PdfWriter.getInstance(document, new FileOutputStream(RESULT));
           document.open();
           document.add(new Paragraph("Primeiro Exemplo com iText!"));
           document.close();
    }
           
  }

A Figura 6 mostra agora como ficou o nosso documento com as modificações realizadas.

Figura 6. Alterações no PDF anterior.

Neste exemplo criamos um retângulo medindo 216 x 720. Este retângulo é o tamanho do documento que ainda possui 36 unidades de margem esquerda, 72 unidades de margem direita, 108 unidades de margem no topo e 180 unidades na margem abaixo. Essas medidas são definidas no documento ISO-32000-1. O documento diz que uma unidade num espaço de 1/72 polegada é aproximadamente um ponto, uma unidade muito utilizada na indústria de impressão. Dessa forma, temos que acima o iText criou uma margem esquerda de 0.5 inch (36/72), uma margem direita de 1 inch (72/72), uma margem no topo de 1.5 inch (108/72), e uma margem abaixo de 2.5 inch (180/72).

Como essa medida pode parecer um tanto complicada e fora da utilização prática do nosso dia a dia o iText providenciou sete métodos utilitários que ajudam a fazer a conversão dessas medidas, são eles:

  • millimetersToPoints()
  • millimetersToInches()
  • pointsToMillimeters()
  • pointsToInches()
  • inchesToMillimeters()
  • inchesToPoints()

Todos os métodos acima esperam um float em seus valores.

O iText também permite aos desenvolvedores criarem páginas de qualquer tamanho. Porém, a especificação do PDF impõem certos limites dependendo da versão do documento do PDF. Versões posteriores à 1.3 possuem um tamanho mínimo de 72 x 72 unidades ou 1 inch x 1 inch e tamanho máximo de 3240 x 3240 unidades ou 45 inch x 45 inch, ao passo que versões 1.4 ou superiores possuem tamanho mínimo de 3 x 3 units e 0.04 inch x 0.04 inch e tamanho máximo de 14,400 x 14,400 unidades ou 200 inch x 200 inch.

O valor da unidade pode ser modificado a partir da versão 1.6 do PDF. O valor mínimo de uma unidade é 1 (default) ou 1/72 inch, e o valor máximo é de 75.000 pontos (1 unidade = 1042 inch).

Vale ressaltar que o valor default de uma página no iText é A4 (210 mm x 297 mm, ou 8.3 inch × 11.7 inch, ou 595 pontos x 842 pontos), podendo ser alterado através de parâmetros. Para alterar o formato padrão utilizamos a classe PageSize que possui diversos objetos Rectangle com padrões de tamanhos de páginas incluindo A0 até A10, B0 até B10 e diversos outros. Para alterar o padrão A4 para Carta poderíamos utilizar o código abaixo:

Document document = new Document(PageSize.LETTER);

Outros dois métodos muito utilizados são setPageSize() e setMargins() que podem ser usados a qualquer momento, mas a alteração nunca será efetivada na página atual e sim apenas na próxima página. Segue abaixo um exemplo de utilização desses métodos:


  document.setPageSize(PageSize.A5);
  document.setMargins(36, 72, 108, 180);
  document.setMarginMirroring(true);

Duas exceções utilizadas nos exemplos são DocumentException e IOException. A exceção DocumentException é a mais geral no iText e podem ocorrer na segunda linha "PdfWriter.getInstance(document, new FileOutputStream(RESULT));" ou na quarta linha "document.add(new Paragraph("Primeiro Exemplo com iText!"));". Uma exceção IOException pode ocorrer se o caminho determinado não for encontrado.

Quando estamos adicionando conteúdo ao Document, o PdfWriter escreve gradualmente um arquivo PDF para o OutputStream. Este arquivo PDF será escrito para um arquivo no disco se escolhermos um FileOutputStream. Em aplicações Web, geralmente iremos preferir enviar o arquivo PDF para um browser da web sem salvá-lo no servidor, portando podemos escrever esse arquivo diretamente para o ServletOutputStream, usando response.getOutputStream().

Segue na Listagem 3 um exemplo de como escrever um arquivo para memória usando um ByteArrayOutputStream.

Listagem 3. Escrevendo um arquivo para memória com iText.


  Document document = new Document();
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  PdfWriter.getInstance(document, baos);
  document.open();
  document.add(new Paragraph("Teste iText!"));
  document.close();
  FileOutputStream fos = new FileOutputStream(RESULT);
  fos.write(baos.toByteArray());
  fos.close();
  

Podemos notar que o PDF é criado na memória na primeira parte deste código. Nas últimas três linhas deste código os bytes são escritos para um arquivo, provando que o que foi gerado na memória representa um arquivo PDF válido.

Neste artigo vimos uma breve introdução ao PDF e ao iText. Também vimos o que é possível de ser feito com o iText e fizemos diversos exemplos para introduzir essa importante ferramenta muito utilizada na indústria de software.

Bibliografia

[1] Eclipse Foundation Tutorial, disponível em http://www.eclipse.org/tutorial

[2] LOWAGIE, B. iText in Action, Second Edition. Manning, 2011.

[3] iText PDF Library. Disponível em http://sourceforge.net/projects/itext/