INTRODUCCIÓN:
En Java, a la hora de crear documentos PDF, existen múltiples librerias que nos ayudan a generarlos, en este articulo vamos a hablar sobre la librería ITEXT.
ITEXT a parte de ser una buena librería para generar PDFs tiene la ventaja de que se integra facilmente con SPRING a la hora de desarrollar aplicaciones Web.
Los datos pueden ser escritos a un fichero o, por ejemplo, desde un servlet a un navegador web.
CARACTERÍSTICAS PRINCIPALES:
- Generación de documentos PDF (parrafos, tablas, imágenes, encabezados y pies de pagina…)
- Generar documentos dinámicos a partir de archivos XML o bases de datos
- Agregar marcadores de libros, números de página, marcas de agua, etc
- Split, concatenar, y manipular las páginas PDF
- Automatizar el llenado de formularios PDF
- Agregar firma digital a un archivo PDF
INSTALACIÓN:
Para empezar veamos donde descargarnos la librería
Esta es la web de la librería, aquí se puede ver la API, ejemplos y tutoriales:
Una vez que seleccionamos descargrnos la version para Java nos redirecciona a esta otra página:
http://sourceforge.net/projects/itext/files/
Actualmente la versión más reciente es la 5.0.2
Una vez nos hemos descargado la librería, la añadimos al CLASSPATH de nuestro proyecto Java para poder utilizarla
EJEMPLO:
Este ejemplo abarca la creación de un documento PDF simple, para ver ejemplos mas complejos nos podemos descargar de la propia página muchos ejemplos que abarcan toda la funcionalidad de esta libreria:
http://www.itextpdf.com/examples/index.php
CÓDIGO:
import java.io.FileOutputStream;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;public class Test {
//Nombre del fichero PDF Resultante de la ejecucion
public static final String RESULT = “Ejemplo1.pdf”;
//Titulos
public static final String CHUNK = “CHUNK”;
public static final String PHRASE = “PHRASE”;
public static final String PARAGRAPH = “PARAGRAPH”;
public static final String TABLE = “TABLE”;
public static final String IMAGE = “IMAGE”;
//Textos
public static final String SEPARADOR = “———————————————————————————————————————-”;
public static final String CHUNK1 = “This is the smallest significant part of text that can be added to a document.”;
public static final String CHUNK2 = “Most elements can be divided in one or more Chunks. A chunk is a String with a certain Font. All other layout parameters should be defined in the object to which this chunk of text is added.”;
public static final String PHRASE1 = “A Phrase is a series of Chunks.”;
public static final String CHUNKPHRASE21 = “A Phrase has a main Font,”;
public static final String CHUNKPHRASE22 = ” but some chunks within the phrase can have a Font that differs from the main Font.”;
public static final String CHUNKPHRASE23 = ” All the Chunks in a Phrase have the same leading.”;
public static final String PARAGRAPH1 = “A Paragraph is a series of Chunks and/or Phrases.”;
public static final String PARAGRAPH2 = “A Paragraph has the same qualities of a Phrase, but also some additional layout-parameters: The indentation AND The alignment of the text”;public static void main (String[] args) {
try
{
//Creacion del documento con un tamaño y unos margenes predeterminados
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
//Al documento se le puede añadir cierta metaInformacion
document.addAuthor(“FJHO”);
document.addTitle(“EJEMPLO1″);//A DocWriter class for PDF.
//When this PdfWriter is added to a certain PdfDocument,
//the PDF representation of every Element added to this Document will be written to the outputstream.
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
//LEADING = separacion entre lineas del documento
writer.setInitialLeading(16);
Rectangle rct = new Rectangle(36, 54, 559, 788);
//Definimos un nombre y un tamaño para el PageBox los nombres posibles son: “crop”, “trim”, “art” and “bleed”.
writer.setBoxSize(“art”, rct);
//Se crea una instancia de la clase que pinta la cabecera y el pie de pagina y se le asignan los eventos que ocurran en el PDF
//La en la clase HeaderFooter se capturarar el evento onEndPage para pintarlos
HeaderFooter event = new HeaderFooter();
writer.setPageEvent(event);
//Opens the document.
//You have to open the document before you can begin to add content to the body of the document.
document.open();
//Ejemplos de CHUNKS
//Creamos el CHUNK definiendo su tipo de letra, tamaño…
Chunk titulo = new Chunk(CHUNK, FontFactory.getFont(FontFactory.COURIER, 20, Font.UNDERLINE, BaseColor.BLACK));
//Lo añadimos al documento
document.add(titulo);
//CHUNK predefinido, es un salto de linea
document.add(Chunk.NEWLINE);
Chunk chunkSeparador = new Chunk(SEPARADOR);
Chunk chunkNormal = new Chunk(CHUNK1);
document.add(chunkNormal);
document.add(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
Chunk chunkTunning = new Chunk(CHUNK2,FontFactory.getFont(FontFactory.COURIER, 20, Font.ITALIC, BaseColor.GREEN));
document.add(chunkTunning);
document.add(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
Chunk chunkTunning2 = new Chunk(CHUNK2,new Font(FontFamily.HELVETICA, 6, Font.BOLD, BaseColor.WHITE));
chunkTunning2.setBackground(BaseColor.BLACK, 10f, 10f, 10f, 10f);
document.add(chunkTunning2);
document.add(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
document.add(chunkSeparador);
//FIN Ejemplos de CHUNKS
//**************************************************************
//Ejemplos de PHRASES
titulo = new Chunk(PHRASE, FontFactory.getFont(FontFactory.COURIER, 20, Font.UNDERLINE, BaseColor.BLACK));
document.add(titulo);
document.add(Chunk.NEWLINE);
Phrase phraseNormal = new Phrase(PHRASE1);
document.add(phraseNormal);
document.add(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
Phrase phraseTunning = new Phrase(new Chunk(CHUNKPHRASE21));
phraseTunning.add(new Chunk(CHUNKPHRASE22, FontFactory.getFont(FontFactory.COURIER, 5, Font.ITALIC, BaseColor.GREEN)));
phraseTunning.add(new Chunk(CHUNKPHRASE23, FontFactory.getFont(FontFactory.TIMES_ROMAN, 15, Font.BOLD, BaseColor.ORANGE)));
document.add(phraseTunning);
document.add(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
Phrase phraseConLeading = new Phrase(30, “Todo es la misma frase LEADING de esta PHRASE=100, Todo es la misma frase LEADING de esta PHRASE=100, Todo es la misma frase LEADING de esta PHRASE=100″);
document.add(phraseConLeading);
document.add(Chunk.NEWLINE);
document.add(chunkSeparador);
//FIN Ejemplos de PHRASES
//**************************************************************
//Ejemplos de PARAGRAPH
titulo = new Chunk(PARAGRAPH, FontFactory.getFont(FontFactory.COURIER, 20, Font.UNDERLINE, BaseColor.BLACK));
document.add(titulo);
document.add(Chunk.NEWLINE);
// Añadir parrafo sin formato
document.add(new Paragraph(PARAGRAPH1));
Paragraph par = new Paragraph(PARAGRAPH2);
par.setIndentationLeft(200);
document.add(par);
par = new Paragraph(PARAGRAPH2);
par.setIndentationRight(300);
document.add(par);
// Añadir parrafo en Negrita
par = new Paragraph(PARAGRAPH2);
par.getFont().setStyle(Font.BOLD);
par.setAlignment(Element.ALIGN_CENTER);
document.add(par);
// Añadir parrafo en Cursiva
par = new Paragraph(PARAGRAPH2);
par.getFont().setStyle(Font.ITALIC);
par.setAlignment(Element.ALIGN_RIGHT);
document.add(par);
// Añadir parrafo tunning
par = new Paragraph(PARAGRAPH2,
FontFactory.getFont(“arial”, // fuente
16, // tamaño
Font.ITALIC, // estilo
BaseColor.RED)); // color
document.add(par);
par.setAlignment(Element.ALIGN_LEFT);
document.add(chunkSeparador);
document.add(Chunk.NEWLINE);
document.add(Chunk.NEWLINE);
//FIN Ejemplos de PARAGRAPH
//**************************************************************
//Ejemplos de TABLE
titulo = new Chunk(TABLE, FontFactory.getFont(FontFactory.COURIER, 20, Font.UNDERLINE, BaseColor.BLACK));
document.add(titulo);
//Añadir tabla 5 columnas
PdfPTable table = new PdfPTable(5);
//Añadir CABECERA
PdfPCell cell = new PdfPCell(new Phrase(“CABECERA”));
cell.setColspan(5);
cell.setBackgroundColor(BaseColor.GREEN);
table.addCell(cell);
//Añadir dos filas de celdas sin formato
table.addCell(“1.1″);
table.addCell(“1.2″);
table.addCell(“1.3″);
table.addCell(“1.4″);
table.addCell(“1.5″);
table.addCell(“2.1″);
table.addCell(“2.2″);
table.addCell(“2.3″);
table.addCell(“2.4″);
table.addCell(“2.5″);
//tunning de Celdas
cell = new PdfPCell(new Phrase(“Alto 3 celdas”));
cell.setRowspan(2);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell);
table.addCell(“3.1″);
table.addCell(“3.2″);
table.addCell(“3.3″);
table.addCell(“3.4″);
table.addCell(“4.1″);
table.addCell(“4.2″);
table.addCell(“4.3″);
table.addCell(“4.4″);
table.addCell(“5.1″);
cell = new PdfPCell(new Phrase(“Ancho 4 celdas”));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setColspan(4);
table.addCell(cell);
document.add(table);
document.add(chunkSeparador);
//FIN Ejemplos de TABLE
//**************************************************************
//Ejemplos de IMAGE
titulo = new Chunk(IMAGE, FontFactory.getFont(FontFactory.COURIER, 20, Font.UNDERLINE, BaseColor.BLACK));
document.add(titulo);
Image foto = Image.getInstance(“resources/ferrari.jpg”);
foto.scaleToFit(100, 100);
foto.setAlignment(Chunk.ALIGN_MIDDLE);
document.add(foto);
//FIN Ejemplos de IMAGE
//**************************************************************
// Cierre del documento
document.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
static class HeaderFooter extends PdfPageEventHelper {public void onEndPage (PdfWriter writer, Document document) {
Rectangle rect = writer.getBoxSize(“art”);
//CABECERA
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_RIGHT, new Phrase(“LaMandarinaMecanica”),
rect.getRight(), rect.getTop(), 0);
//PIE
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_CENTER, new Phrase(String.format(“page %d”, writer.getPageNumber())),
(rect.getLeft() + rect.getRight()) / 2, rect.getBottom() – 18, 0);
}
}
}
WEB:
Si lo que necesitamos es generar documentos PDF dinamicamente que se le abran al usuario directamente al interactuar con una página web (pinchar botones, links…), podemos crear un servlet que reciba las peticiones de creacion de ficheros PDF
CÓDIGO:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;public class Demo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
/*GENERACION AL VUELO DE PDF*/
try {
// Texto que va a ser añadido al PDF
String text = “Generacion al Vuelo de un PDF”;
// Paso 1: Creamos el documento
Document document = new Document();
// Paso 2: Creamos un ByteArrayOutputStream
// todo lo que se escriba en el documento
// se escribe tambien en el ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// Abrimos el documento
document.open();
// Escribimos
document.add(new Paragraph(text));
// Cerramos
document.close();
// Hay que configurar las cabeceras para que
//el navegador detecte que es un PDF
response.setHeader(“Expires”, “0″);
response.setHeader(“Cache-Control”,
“must-revalidate, post-check=0, pre-check=0″);
response.setHeader(“Pragma”, “public”);
// Configuramos el content type
response.setContentType(“application/pdf”);
// Tamaño
response.setContentLength(baos.size());
// Esccribir el ByteArrayOutputStream a el ServletOutputStream
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
}
catch(com.itextpdf.text.DocumentException e) {
throw new IOException(e.getMessage());
}
}
}