A biblioteca OpenPDF é um fork da biblioteca iText 4 sob as licenças LGPL eMPL. Ela permite a criação de arquivos PDFs de maneira bastante fácil e simples. Para começar a criar um PDF, criamos um projeto maven adicionando a dependência da biblioteca.

<dependency>
    <groupId>com.github.librepdf</groupId>
    <artifactId>openpdf</artifactId>
    <version>1.1.0</version>
</dependency>

Após isso podemos criar o primeiro documento PDF através do seguinte código:

try {
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream("openpdf.pdf"));
    document.open();
                 
    Chunk c = new Chunk("Uma String" );
                 
    Font fontChunk = FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLDITALIC);
    c.setFont(fontChunk);
                 
    document.add(c);
 
    document.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (DocumentException e) {
    e.printStackTrace();
}

Na linha 2 começamos criando nosso objeto que representa o documento, na linha 3 criamos o writer que irá escutar o objeto document e irá direcionar a saída do para o objeto de stream passado como segundo parâmetro, no nosso exemplo estamos escrevendo o PDF em um arquivo, mas poderíamos enviar para o outputstream de um servlet no caso de uma aplicação web.

Na linha 4 abrimos o documento e na linha 6, criamos um objeto Chunk que é uma pequena parte de um texto, basicamente uma String que queremos colocar no PDF. Na linha 8 criamos um objeto Font através do método estático getFont da classe FontFactory, que aceita 3 parâmetros, o tipo da fonte, que informamos por uma das constantes da própria classe, o tamanho e o estilo da fonte, também informada por contantes, desta vez da classe Font. Na linha 9 configuramos a fonte criada atribuindo ao objeto chunk e na linha 11 adicionamos nosso objeto de texto ao documento através do método add. E na linha 13 fechamos o documento.

Do mesmo modo que adicionamos um pequeno texto podemos adicionar vários tipos de informações ao PDF através de vários tipos de objetos como, Paragraph, List, Image, Table, entre outros.

Vamos ver como adicionar parágrafos ao documento PDF:

try {
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream("openpdf.pdf"));
    document.open();
                 
    Font font = FontFactory.getFont(FontFactory.TIMES, 16, Font.NORMAL);
                 
    Paragraph p1 = new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris cursus velit ligula, eu pretium odio sodales nec. Nulla aliquam posuere leo ac sollicitudin. Vestibulum neque magna, auctor a ex et, gravida vestibulum sapien." , font   );
    p1.setSpacingAfter(10);
    p1.setFirstLineIndent(30);
    document.add( p1 );
                 
    Paragraph p2 = new Paragraph("Proin sed justo aliquam, ornare justo at, ultricies sapien. Vestibulum sit amet lorem vel velit bibendum elementum. Integer euismod in sapien a rutrum. Mauris viverra odio in efficitur semper. Nullam eu leo rhoncus, vehicula tellus nec, placerat enim." , font   );
    p2.setSpacingAfter(10);
    p2.setAlignment(ElementTags.ALIGN_CENTER);
    document.add( p2 );
                 
    Paragraph p3 = new Paragraph("Duis mattis fermentum nulla, sed egestas ante iaculis vel. Vestibulum ac felis ac ipsum euismod consectetur. Vivamus sit amet turpis eget magna tempus malesuada in at ex." , font   );
    p3.setSpacingAfter(10);
    document.add( p3 );
                 
    document.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (DocumentException e) {
    e.printStackTrace();
}

Seguimos o mesmo modelo que o exemplo anterior mas agora primeiro criamos um objeto Font(linha 6), para depois criamos o objeto Paragraph, passando para seu construtor o texto e a fonte desejada. Logo após basta adicionar o objeto Paragraph ao objeto Document através do método add, como visto na linha 11.

Podemos modificar várias propriedades do parágrafo através de diversos métodos como: setFirstLineIndent que permite definir o espaçamento da primeira linha do parágrafo, os métodos setSpacingAfter e setSpacingBefore para adicionar espaço antes e depois do parágrafo. Para alinhar o texto podemos chamar o método setAlignment que aceita os valores: ElementTags.ALIGN_CENTER, ElementTags.ALIGN_LEFT, ElementTags.ALIGN_RIGHT, ElementTags.ALIGN_JUSTIFIED.

Podemos adicionar lista:

try {
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream("openpdf.pdf"));
    document.open();
     
    //marcador normal
    List list = new List();
    list.add("Item 1");
    list.add("Item 2");
    list.add("Item 3");
    list.add("Item 4");
    document.add(list);
             
    document.add( Chunk.NEWLINE ); // nova linha
 
    //marcador numérico ordenado numero
    List listOrderedNumero = new List(List.ORDERED,List.NUMERICAL);
    listOrderedNumero.add("Item 1");
    listOrderedNumero.add("Item 2");
    listOrderedNumero.add("Item 3");
    listOrderedNumero.add("Item 4");
    document.add( listOrderedNumero );
             
    document.add( Chunk.NEWLINE ); // nova linha
             
    //marcador numérico ordenado letra
    List listOrderedLetra = new List(List.ORDERED,List.ALPHABETICAL);
    listOrderedLetra.add("Item 1");
    listOrderedLetra.add("Item 2");
    listOrderedLetra.add("Item 3");
    listOrderedLetra.add("Item 4");
    document.add( listOrderedLetra );
             
    document.add( Chunk.NEWLINE ); // nova linha
 
    //marcador com simbolo 
    List listItem = new List();
    listItem.setListSymbol("\u001A"); 
             
    listItem.add("Item 1");
    listItem.add("Item 2");
    listItem.add("Item 3");
    listItem.add("Item 4");
    document.add(listItem);
         
    document.add( Chunk.NEWLINE ); // nova linha
             
    document.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (DocumentException e) {
    e.printStackTrace();
}

Para criar uma lista podemos criando um objeto List, e utilizar seu método add para adicionar cada um dos item da lista, após todos os itens adicionado podemos adicionar o objeto List ao documento, como fizemos com o parágrafo.

Para definir que tipo de lista e consequentemente qual marcador será usado devemos passar parâmetros para o construtor do objeto. Para o primeiro parâmetro ele aceita um boolean, sendo o valor true ou List.ORDERED para uma lista ordenada e false ou List.UNORDERED para não ordenada, sendo este o padrão caso nenhum parâmetro for passado. Se o primeira valor for List.ORDERED, podemos escolher se desejamos que os marcadores sejam numéricos ou alfabético através do segundo parâmetro do construtor, sendo true ou List.ALPHABETICAL para alfabético e false ou List.NUMERICAL para numeral. Também podemos adicionar um marcador através de um código simbolo através do método setListSymbol como mostrado na linha 38.

Para inserir uma imagem no documento também é bem simples:

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("openpdf.pdf"));
document.open();
                          
document.add(new Paragraph("Uma imagem"));
Image png = Image.getInstance("coin.png");
png.setAlignment(Image.LEFT | Image.TEXTWRAP);  
document.add(png);
             
for(int i = 0 ; i < 100 ; i++) {
    document.add( new Phrase("Um texto qualquer. "));
}    

Basta criar um objeto Image através de seu método estático getInstance passando como parâmetro o caminho para o arquivo de imagem que pode ser png, jpg, gif ou bmp. Para alinhar a imagem podemos chamar o método setAlignment passando uma das constantes Image.LEFT, Image.MIDDLE ou Image.RIGHT. Para fazer o texto acompanhar a imagem utilizamos o operador bitwise “|” para combinar os valores de alinhamento e a opção de contornar o texto Image.TEXTWRAP, como visto na linha 7.

Também podemos posicionar a imagem em um ponto absoluto do documento através do método setAbsolutePosition(x,y), passando as coordenadas x e y onde queremos inserir a imagem.

Para redimensionar a imagem podemos utilizar o método scaleAbsolute(w, h), passando as novas dimensões, ou o método scalePercent(per), passando um parâmetro com a porcentagem de do tamanho que se deseja.

Agora vamos as tabelas:

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("openpdf.pdf"));
document.open();
             
PdfPTable table = new PdfPTable(4);
             
PdfPCell cellHeader = new PdfPCell(new Paragraph("Linha de cabeçaçho"));
cellHeader.setColspan(4);
table.addCell(cellHeader);
             
table.addCell("1 - 1");
table.addCell("1 - 2");
table.addCell("1 - 3");
table.addCell("1 - 4");
         
table.addCell("2 - 1");
table.addCell("2 - 2");
table.addCell("2 - 3");
table.addCell("2 - 4");
             
PdfPCell cell = new PdfPCell(new Paragraph("Celula 1"));
cell.setBorderColor(new Color(255, 0, 0));
table.addCell(cell);
         
cell = new PdfPCell(new Paragraph("Celula 2"));
cell.setColspan(3);
cell.setBackgroundColor(new Color(192, 192, 192));
cell.setHorizontalAlignment( PdfPCell.ALIGN_CENTER);
table.addCell(cell);
             
document.add(table);
          
document.close();

Para criar uma tabela devemos instanciar um objeto PdfPTable, que recebe como parâmetro do seu construtor o número de colunas que a tabela deverá ter. Após adicionamos célula por célula, utilizando o método addCell, que aceita como parâmetros uma String, ou um objeto PdfPCell que permite configurar o alinhamento, fundo, espaço ocupado, etc. As células irão ser colocadas lado a lado até até atingirem o número de coluna configurado, passando assim para a próxima linha, não existido a configuração de qual linha a célula está.

Para que uma célula ocupe o espaço de mais de uma coluna, devemos criar um objeto PdfPCell e chamar o método setColspan, passando quantas colunas esta célula deverá ocupar, como visto na linha 8.

Podemos também configurar as cores de fundo e borda de uma célula através dos métodos setBackgroundColor, setBorderColor que recebem como parâmetro um objeto Color, como mostrado nas linhas 22 e 27.

Voltando um pouco para o objeto document, na instanciação deste podemos definir o tamanho das páginas do PDF e suas margens.

Document document = new Document( PageSize.A4, 10,10,10,10 ); // tamanho da página A4 e 10 de margem
PdfWriter.getInstance(document, new FileOutputStream("openpdf.pdf"));
document.open();
             
document.add( new Paragraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean non nibh bibendum, blandit lacus condimentum, gravida erat. Vestibulum tincidunt cursus lacus, interdum sodales risus fringilla et. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ante sem, ornare sed dolor vel, condimentum congue orci. Curabitur libero sapien, pharetra id sem at, interdum mollis nibh. Donec nec ante tristique orci pellentesque rutrum. Nam quis leo ligula.") );
 
document.add( new Paragraph("Nulla pharetra ligula vel dolor hendrerit, eu egestas velit iaculis. Nullam faucibus mauris facilisis lobortis aliquam. Nam quis augue nec turpis lobortis convallis quis in ante. Integer luctus, tellus id pharetra vehicula, sem libero finibus nisi, eu pharetra turpis mauris ac dolor. Cras convallis, dolor a tincidunt ornare, libero quam dapibus tortor, vitae ultrices lacus ligula et erat. Aliquam tellus lectus, tempus vitae volutpat a, lobortis non erat. Pellentesque molestie, purus dignissim malesuada mollis, purus eros accumsan libero, eget pretium mi augue a nibh. Pellentesque molestie eu sem vel accumsan. Suspendisse in dapibus nisl. Proin tristique mi sit amet rutrum blandit. Vestibulum feugiat massa et purus eleifend, eu faucibus felis semper. Donec pharetra et quam et consectetur. Proin blandit sit amet leo non ultricies."));
 
document.add( new Paragraph("Praesent quis posuere dolor. Integer dui sapien, imperdiet nec elementum non, faucibus in sem. Praesent sed tempus justo, et ullamcorper sem. Suspendisse risus urna, ullamcorper volutpat cursus in, dapibus vitae augue. Donec ornare, metus sit amet eleifend congue, ante justo mattis nisl, eu mattis felis enim at nisl. Duis egestas felis a purus gravida, ut luctus augue lobortis. Aliquam quis risus nunc. Fusce et neque nec purus gravida ullamcorper nec nec lacus. Proin viverra placerat nulla, at commodo diam posuere et.") );
             
document.close();

Para definir o tamanho da página do documento PDF é necessário criar um objeto Rectangle, passando para seu construtor as dimensões desejada da página e passar este objeto para o construtor do objeto Document. Caso se deseje um formato de página padrão como o A4, A3, LETTER podemos utilizar as constantes da classe PageSize, como visto na linha 1.

Através do objeto Rectangle, também podemos mudar a cor da página através de seu método setBackground(Color) como no exemplo abaixo.

Rectangle r = new Rectangle(200, 200);
r.setBackgroundColor( Color.blue);
     
Document document = new Document(r); 

Para mais exemplos de uso temos os exemplos disponíveis no repositório Git do projeto.