De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.


Gerando PDF utilizando Java

Colaboração: Carlos Tosin

Data de Publicação: 01 de junho de 2010

O formato PDF é muito utilizado porque se trata de uma forma fácil de distribuir documentos, além de ser possível visualizá-los em qualquer plataforma.

Como documentos PDF são amplamente utilizados, existem diversas maneiras de gerá-los. E é claro que o Java não poderia ficar de fora! Através do uso da API iText, você pode criar seus próprios arquivos PDF através do Java.

O objetivo deste artigo é mostrar como gerar documentos PDF em Java, usando a API iText. Você aprenderá como configurar os elementos da página do documento, além de como inserir textos, imagens e tabelas.

A API iText

O iText é a API utilizada para gerar PDFs. Ela é gratuita e open source. Para utilizar o iText em sua aplicação Java, entre no site http://itextpdf.com e baixe o arquivo .JAR referente ao iText 5.0.2. Depois basta adicionar o iText ao classpath da sua aplicação e utilizar as funcionalidades desta API, que vai possibilitar que você gere os seus documentos PDF. O iText funciona com a versão 5 do Java ou superior.

Documento É hora de começarmos a aprendar a usar o iText! E a primeira classe que você deve conhecer é a classe Document. Ela representa o documento PDF, e para criar um documento PDF do tamanho A4 no modo retrato, o código fica assim:

  Document doc = new Document(PageSize.A4);

A classe PageSize possui diversas constantes para tamanhos comuns de páginas (LETTER, NOTE, A0, A1, A2, etc.). É possível também definir o tamanho manualmente, desta forma:

    Rectangle rect = new Rectangle(595, 841);
    Document doc = new Document(rect);

Neste caso, é usada a classe Rectangle, que representa as dimensões de um retângulo.

Sistema de medidas

É importante destacar como funcionam as medidas utilizadas pelo iText. Se você quiser especificar as medidas das páginas dos documentos ou das margens, você deve ter em mente que você deve utilizar pontos. Como estamos mais acostumados a trabalhar na escala métrica, você pode escrever um código que faça a conversão da escala métrica para pontos. A relação é: 2,54cm = 72 pontos.

No exemplo anterior, o uso de 595x841 pontos define as páginas do documento como tendo tamanho 21,0x29,7 cm, o que equivale ao tamanho A4.

Margens das Páginas

Para definir margens nas páginas do documento, basta que elas sejam especificadas no construtor da classe Document, como é feito a seguir:

  Document doc = new Document(PageSize.A4, 72, 72, 72, 72);

Lembre-se de especificar as margens em pontos, e não no sistema métrico! O código acima define que o tamanho das páginas será A4 com margens de 2,54cm na esquerda, direita, em cima e embaixo.

Preparando o documento para receber dados

Após a criação do objeto que representa o documento, é necessário seguir mais alguns passos antes de iniciarmos a inserção dos dados. O código que representa este passo é mostrado a seguir:

    OutputStream os = new FileOutputStream("out.pdf");
    PdfWriter.getInstance(doc, os);
    doc.open();

Vamos tentar entender o que é mostrado neste código. Primeiramente, devemos criar uma stream de saída, indicando o destino do documento PDF. Neste caso estamos interessados em gerar o documento em um arquivo, portanto criamos um FileOutputStream, indicando qual será o nome do arquivo de saída.

Na sequência, é necessário chamar o método getInstance() da classe PdfWriter, para que ele associe o documento à stream de saída.

O último passo antes de iniciarmos a criação do documento, é abri-lo. Isto é feito através da chamada ao método open(). É importante que, ao final da inserção dos dados no documento, o mesmo seja fechado através do método close(). E outro detalhe importante: todas as modificações no documento (como configuração de margens e tamanho de páginas) devem ser feitas antes da chamada ao método close().

Gerando seu primeiro PDF em Java

Agora você já sabe tudo o que precisa para começar a escrever o seu primeiro arquivo PDF usando o iText. O código abaixo mostra um exemplo completo da geração de um arquivo PDF simples, usando o que você viu nesta parte inicial:

    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import com.itextpdf.text.Document;
    import com.itextpdf.text.PageSize;
    import com.itextpdf.text.Paragraph;
    import com.itextpdf.text.pdf.PdfWriter;
  
    public class PrimeiroPDF {
        public static void main(String[] args) throws Exception {
            Document doc = null;
            OutputStream os = null;
  
            try {
                //cria o documento tamanho A4, margens de 2,54cm
                doc = new Document(PageSize.A4, 72, 72, 72, 72);
  
                //cria a stream de saída
                os = new FileOutputStream("out.pdf");
  
                //associa a stream de saída ao 
                PdfWriter.getInstance(doc, os);
  
                //abre o documento
                doc.open();
  
                //adiciona o texto ao PDF
                Paragraph p = new Paragraph("Meu primeiro arquivo PDF!");
                doc.add(p);
  
            } finally {
                if (doc != null) {
                    //fechamento do documento
                    doc.close();
                }
                if (os != null) {
                   //fechamento da stream de saída
                   os.close();
                }
            }
        }
    }
  

Este é o esqueleto básico de código que você irá utilizar ao criar seus arquivos PDF, mudando apenas o conteúdo. Na sequência você verá mais detalhes sobre a classe Paragraph.

Textos

A forma mais fácil de adicionar textos ao PDF é utilizar a classe Paragraph. Esta classe permite que você adicione blocos de texto ao documento. O texto é inserido na página como se você estivesse utilizando um editor de textos. O iText respeita as margens que você especificou para o documento e também gerencia automaticamente as quebras de linha. Observe o código abaixo, que gera dois blocos de texto como saída:

    Paragraph p1 = new Paragraph("Meu primeiro arquivo PDF!");
    doc.add(p1);
  
    Paragraph p2 = new Paragraph("Estou utilizando a classe Paragraph para criar um bloco de texto na geração do meu primeiro arquivo PDF.");
    doc.add(p2);
  

O construtor da classe Paragraph recebe o texto como parâmetro. Depois basta chamar o método add() para adicionar o texto ao PDF.

Alterando a fonte Nem sempre a fonte utilizada por padrão pelo iText é a fonte que você deseja nos seus documentos. Logo, é possível que você altere a fonte dos textos que você adiciona ao PDF.

A fonte é representada pela classe com.itextpdf.text.Font. Basta criar um objeto desta classe com a fonte desejada e associá-lo ao texto. Observe o exemplo:

  Font f = new Font(FontFamily.COURIER, 20, Font.BOLD);

O código acima cria uma fonte da família Courier, tamanho 20, itálica. O enum FontFamily e a classe Font possuem também outras constantes para você explorar.

A associação entre a fonte e o texto é feita no construtor da classe Paragraph, desta forma:

  Paragraph p1 = new Paragraph("Meu primeiro arquivo PDF!", f);

Pronto! Você já tem um título para o seu PDF! Observe como ficou o resultado:

[http://www.dicas-l.com.br/imagens/itext_01.jpg]

Alinhamento Muitas vezes o alinhamento à esquerda não é o suficiente. O iText proporciona outras formas de alinhamento do texto. Observe:

  p1.setAlignment(Element.ALIGN_CENTER);

O método setAlignment() permite especificar um alinhamento para o bloco. Neste caso, p1 será alinhado no centro da linha. Observe:

[http://www.dicas-l.com.br/imagens/itext_02.jpg]

Espaçamento Caso você deseje ter um controle maior sobre o espaçamento utilizado antes e depois de um bloco de texto, você pode utilizar os métodos setSpacingBefore() e setSpacingAfter(). Observe:

  p1.setSpacingAfter(20);

Neste exemplo, após p1 ser adicionado ao documento, será deixado um espaço em branco extra de 20 pontos. Observe:

[http://www.dicas-l.com.br/imagens/itext_03.jpg]

Imagens

Da mesma forma que textos, imagens também podem ser inseridas no documento PDF. A maneira mais fácil de fazer isto é através da classe com.itextpdf.text.Image. Ela é utilizada desta forma:

    Image img = Image.getInstance("softblue.jpg");
    img.setAlignment(Element.ALIGN_CENTER);
    doc.add(img);

Basta chamar o método getInstance() da classe, passando o caminho da imagem que deve ser carregada, e depois adicionar a imagem ao documento através do método add(). Os métodos setAlignment(), setSpacingBefore() e setSpacingAfter() já vistos anteriormente também podem ser aplicados às imagens. Observe como fica o resultado:

[http://www.softblue.com.br/public/blog/7/itext_04.jpg]

Tabelas

O iText possui também suporte à criação de tabelas. Observe uma tabela simples abaixo que contém algumas palavras reservadas do Java:

[http://www.softblue.com.br/public/blog/7/itext_05.jpg]

O código que gera a tabela acima é o seguinte:

    PdfPTable table = new PdfPTable(3);
    PdfPCell header = new PdfPCell(new Paragraph("Algumas Palavaras Reservadas do Java"));
    header.setColspan(3);
    table.addCell(header);	
    table.addCell("abstract");
    table.addCell("extends");
    table.addCell("import");
    table.addCell("while");
    table.addCell("if");
    table.addCell("switch");
    doc.add(table);

Vamos tentar entender o que significa este código. Ao trabalhar com tabelas no iText, você basicamente vai usar duas classes: PdfPTable e PdfPCell. A primeira representa a tabela, enquanto a última representa uma célula da tabela.

A chamada new PdfPTable(3) cria uma tabela com 3 colunas, de forma que a largura das colunas é a mesma. Veremos na sequência como especificar larguras diferentes para cada coluna.

Depois criamos um objeto da classe PdfPCell, que irá representar o cabeçalho da nossa tabela. No construtor do PdfPCell você pode passar um objeto Paragraph contendo o texto que será colocado na célula. Uma característica importante do cabeçalho é que ele deve ocupar as 3 colunas da tabela. Por este motivo nós usamos o método setColspan(3).

Toda vez que desejamos adicionar uma célula à tabela, chamamos o método addCell(). Neste método podemos passar tanto objetos PdfPCell como os textos de cada célula diretamente (neste caso o próprio iText gera o objeto PdfPCell internamente). Perceba que em nenhum momento você diz em qual linha ou coluna da tabela a célula será inserida. O iText vai inserindo as células de cima para baixo e da esquerda para a direita. O gerenciamento da criação de novas linhas é feito de forma automática.

Depois de preparar a tabela, basta adicioná-la ao documento através da chamada doc.add(table).

Definindo a Largura das Colunas Como vimos anteriormente, ao construirmos uma tabela informando apenas o número de colunas, o iText deixa todas as colunas com o mesmo tamanho, o que nem sempre é o ideal.

A melhor forma de especificar a largura das colunas da tabela é usar a forma relativa. Ela funciona assim: você indica qual o tamanho da coluna com relação à largura total da tabela. Observe:

  PdfPTable table = new PdfPTable(new float[] { 0.2f, 0.2f, 0.6f });

Ao passar um array de números no construtor da PdfPTable, você está indicando um tamanho relativo para cada coluna. Como o array tem 3 elementos, a tabela terá três colunas. Agora você deve pensar da seguinte forma: todas as colunas da tabela juntas representam 100%. E, neste caso, a primeira coluna representa 20%, a segunda 20% e a terceira 60%. Perceba que as duas primeiras colunas terão o mesmo tamanho, e a terceira coluna será três vezes maior que cada coluna anterior. O resultado final fica assim:

[http://www.softblue.com.br/public/blog/7/itext_06.jpg]

Mudando o tamanho e alinhamento da tabela O iText permite também que você especifique qual o tamanho e o alinhamento da tabela com relação do documento. Isto é feito através dos métodos setWidthPercentage() e setHorizontalAlignment(). Observe:

    table.setWidthPercentage(60.0f);
    table.setHorizontalAlignment(Element.ALIGN_RIGHT);

No exemplo acima, estamos definindo que a tabela deve ocupar apenas 60% da largura do documento. Também estamos definindo que ela deve ser alinhada à direita. Observe o resultado:

[http://www.softblue.com.br/public/blog/7/itext_07.jpg]

Customizando as bordas e cores É possível também customizarmos as bordas das células e as cores das bordas e das células. Observe o código abaixo:

    header.setBackgroundColor(BaseColor.YELLOW);
    header.setBorderWidthBottom(2.0f);
    header.setBorderColorBottom(BaseColor.BLUE);
    header.setBorder(Rectangle.BOTTOM);

Ele gera como resultado:

[http://www.softblue.com.br/public/blog/7/itext_08.jpg]

O método setBackgroundColor() define a cor de fundo da célula. O método setBorderWitdhBottom() define a largura da linha da borda inferior. O método setBorderColorBottom() define a cor da borda inferior. E o método setBorder() define em que parte das célula a borda deve existir. Usando Rectangle.BOTTOM, estamos definindo que existe apenas uma borda inferior na célula.

É importante que você saiba que existem variantes dos métodos que definem a largura e cor da linha da borda. Utilizamos neste exemplo os método setBorderWidthBottom() e setBorderColorBottom(), para a borda inferior, mas é possível também usar os métodos equivalentes top, left e right (para borda superior, esquerda e direita, respectivamente.

Conclusão

Este artigo introduziu a API iText, usada para gerar documentos PDF em Java. O que está descrito aqui é apenas uma visão inicial de algumas funcionalidades importantes do iText. Mas muita coisa além do que está descrito aqui pode ser feita. Consulte a página oficial da API para ter maiores informações.

Carlos Tosin é instrutor oficial dos Cursos On-Line de Java (assista uma vídeo-aula grátis) da Softblue, formado em Ciência da Computação pela PUC-PR, pós-graduado em Desenvolvimento de Jogos para Computador pela Universidade Positivo e Mestre em Informática na área de Sistemas Distribuídos, também pela PUC-PR. Trabalha profissionalmente com Java há 7 anos e possui 4 anos de experiência no desenvolvimento de sistemas para a IBM dos Estados Unidos, utilizados a nível mundial. Atua há mais de 2 anos com cursos e treinamentos de profissionais em grandes empresas. Possui as certificações da Sun SCJP, SCJD, SCWCD, SCBCD, SCEA, IBM SOA e ITIL Foundation.
Error: No site found with the domain 's2.dicas-l.com.br' (Learn more)