Creare PDF con Java
Negli ultimi anni il formato PDF è divenuto di fatto lo standard per lo scambio dei documenti, per questa ragione in questo articolo descriveremo in che modo è possibile creare documenti in questo formato utilizzando Java®. Sin da ora premettiamo che questo non vuole essere un tutorial, né tanto meno si vuole cerca di essere esaustivi nella trattazione, ciò che infatti ci proponiamo è di fornire una serie di input che poi il lettore interessato può decidere di approfondire. Detto questo la libreria a cui faremo riferimento di qui in avanti è iText, la quale è scaricabile al seguente indirizzo (iText). Tenuto conto del numero molto elevato di funzionalità offerte da questa libreria la nostra trattazione, non si pone come obiettivo quello di essere esaustiva, al contrario ciò cui si mira, è fornire una serie di spunti, per mezzo di una serie di esempi, che il lettore interessato può decidere di approfondire in un secondo momento.
Premettiamo sin da ora che le fonti, con cui possiamo popolare i file da noi generati sono arbitrarie, quindi nulla ci vieta di utilizzare come fonte una tabella salvata in un db oppure un foglio Excel® (per questa seconda possibilità si rimanda il lettore interessato all’articolo intitolato “JExcel API” presentato in precedenza) .
Come primo esempio di utilizzo della libreria iText cominciamo con il realizzare un pdf il cui contenuto è l’ormai arcinoto messaggio “Hello World!”, nonostante la sua semplicità questo esempio utilizza sono tutti gli elementi di base necessari alla definizione di un documento pdf.
package hellopdf;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Primo esempio di utilizzo della
* libreria iText: HelloPDF.
*/
public class Hellopdf {
/** Path to the resulting PDF file. */
public static final String filePDF = “./hello.pdf”;
/**
* Creazione di un semplice file PDF chiamato: hello.pdf
* @param args non si ha bisogno di parametri particolari
*/
public static void main(String[] args) throws DocumentException, IOException {
new Hellopdf().createPdf(filePDF);
}
/**
* Metodo demandata alla creazione di un documento in formato PDF.
* @param filePDF il path del file pdf
* @throws DocumentException
* @throws IOException
*/
public void createPdf(String filename) throws DocumentException, IOException {
// step 1 Creazione del container (un oggetto della classe Document)
Document document = new Document();
// step 2 Creazione del writer come al solito di tratta di un stream nello specifico uno stream di output
// associato all’oggetto document questo in particolare significa che ogni modifica effettuata su questo oggetto
// si ripercuoterà anche sul file di output
PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3 apertura del documento
document.open();
// step 4 scrittura del testo
document.add(new Paragraph(“Hello World!\n Questo è il mio primo file pdf realizzato con iText”));
// step 5 chiusra e salvataggio delle infomrazioni sul file pdf
document.close();
}
}
L’elemento principale nella definizione di un documento è il paragrafo, all’interno del quale l’utente ha la facoltà di inserire il contenuto che meglio si adatta alle proprie esigenze (testo, immagini, tabelle ecc.)
Chiaramente un documento è spesso organizzato in una serie di sezioni e/o capitoli, con il prossimo esempio cercheremo quindi di descrivere come ciò possa essere realizzato ricorrendo all’uso delle classi Chapter e Section.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package hellopdf;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* First iText example: Hello World.
*/
public class Hellopdf {
/** Path to the resulting PDF file. */
public static final String filePDF = “./hello.pdf”;
/**
* Creazione di un semplice file PDF chiamato: hello.pdf
* @param args non si ha bisogno di parametri particolari
*/
public static void main(String[] args) throws DocumentException, IOException {
new Hellopdf().createPdf(filePDF);
}
/**
* Creates a PDF document.
* @param filePDF il path del file pdf
* @throws DocumentException
* @throws IOException
*/
public void createPdf(String filename) throws DocumentException, IOException {
// step 1 Creazione del container (un oggetto della classe Document)
Document document = new Document();
// step 2 Creazione del writer come al solito di tratta di un stream nello specifico uno stream di output
// associato all’oggetto document questo in particolare significa che ogni modifica effettuata su questo oggetto
// si ripercuoterà anche sul file di output
PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3 apertura del documento
document.open();
// step 4 scrittura del testo
// step 4.a creazione di un capitolo
Chapter capitolo = new Chapter(new Paragraph(“Capitolo 1: Un Grande Benvenuto”),1);
// step 4.b creazione delle sezioni allinterno del capitolo
Section sezione = capitolo.addSection(new Paragraph(“Sezione saluto in inglese”));
sezione.add(new Paragraph(“Hello World!”));
sezione = capitolo.addSection(new Paragraph(“Sezione saluto tradotto”));
sezione.add(new Paragraph(“Ciao Mondo!”));
// step 4.c inserimento del nuovo capitolo all’interno del documento
document.add(capitolo);
// step 4.d creazione di un secondo capitolo con relativa sezione
capitolo = new Chapter(new Paragraph(“Capitolo 2: Una prima spiegazione”),2);
sezione = capitolo.addSection(new Paragraph(“Sezione spiegazione”));
sezione.add(new Paragraph(“\n Questo è il mio primo file pdf realizzato con iText”));
// step 4.e inserimento del secondo capito, questo implica la creazione
// di una seconda pagina all’interno del documento pdf
document.add(capitolo);
// step 5 chiusura e salvataggio delle informazioni sul file pdf
document.close();
}
}
Così come indicato in precedenza, notiamo come la classe Paragraph abbia un ruolo centrale nella definizione del documento finale.
Nel realizzare un documento sorge spesso la necessità di inserire una serie di metadati utilizzabili ad esempio per identificare l’autore, il giorno in cui il documento è stato realizzato, i tags associati al documento, ecc., affinché questi dati possano essere acclusi al documento nell’ambito della classe Document sono stati implementati una serie di metodi di cui facciamo uso nel metodo seguente:
// iText consente di inserire una serie di metadati in quali possono essere visualizzati nel reader
// sotto la voce File -> Properties
private static void addMetaData(Document document) {
document.addTitle(“My first PDF”);
document.addSubject(“Using iText”);
document.addKeywords(“Java, PDF, iText”);
document.addAuthor(“Alessandro Grande”);
document.addCreator(“Alessandro Grande”);
document.addCreationDate();
}
Nell’ambito della costruzione di un paragrafo si può avere la necessità di definire una serie di sezioni tra loro indipendenti, una sorta di caselle di testo formattabili liberamente e che non influenzano in alcun modo gli altri elementi del paragrafo, in questi casi per realizzare questo tipo di risultato si ricorre ai Chunk, questa può essere pensata la parte più piccola di un documento.
package hellopdf;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
/**
* First iText example: Hello World.
*/
public class Hellopdf {
/** Path to the resulting PDF file. */
public static final String filePDF = “./hello.pdf”;
public static void main(String arg[])throws Exception{
Document document=new Document();
PdfWriter.getInstance(document,new FileOutputStream(filePDF));
document.open();
Chunk chunk=new Chunk(“Hello World!”);
chunk.setUnderline(+1f,-2f);
Chunk chunk1=new Chunk(“AGAIN!!!”,FontFactory.getFont(FontFactory.COURIER_BOLDOBLIQUE,28));
// il primo parametro intero indica lo spessore
// il secondo parametro indica quanto dove deve essere posizionata la sottolineatura rispetto ad un’ipotetica baseline
// valori negativi fanno si che la linea sia posizionata al di sotto del testo, mentre valori positivi consentono di creare
// un effetto barrato
chunk1.setUnderline(+1f,+3f);
// impostato uno sfondo rosso da applicare al solo chunk corrente
chunk1.setBackground(BaseColor.RED);
document.add(chunk);
document.add(chunk1);
document.close();
}
}
Nell’esempio precedente oltre all’introduzione dei chunk si sono utilizzate anche le funzionalità di gestione dei font, nel nostro caso si è deciso di utilizzare uno dei font per i quali è stata definita una costante all’interno della libreria nulla comunque ci vieta di utilizzare un font differente in questo caso è sufficiente specificarne il path quindi ad esempio “C:\windows\Fonts\calibri.ttf”, valido per windows7.
Un’altra feature utilizzabile nella costruzione di un documento pdf è lagata alla possibilità di inserire degli i elenchi, in questo caso per realizzare questo tipo di strutture si ricorre alla classe List la quale nel suo costruttore prevede un parametro di tipo boolean, il quale se impostato su vero ci permetterà di definire un elenco numerato in caso contrario sarà possibile costruire il classico elenco non numerato, inoltre per mezzo dei chuck è possibile definire degli elenchi non numerati che utilizzano dei simboli personalizzati.
Vediamo ora come questo si realizza mediante un semplice esempio:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package listpdf;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
/**
* List iText Example.
*/
public class Listpdf {
/** Path to the resulting PDF file. */
public static final String filePDF = “./listDemo.pdf”;
public static final String imagePath =”./img/fruits.png”;
public static final String[] fruits = {“Orange”,”Apple”,”Cherry”,”Banana”,”Grapes”};
public static void main(String arg[])throws Exception{
Document doc=new Document();
PdfWriter.getInstance(doc,new FileOutputStream(filePDF));
doc.open();
//Create a numbered List with 30-point field for the numbers.
List list=new List(true,30);
list.add(new ListItem(“First List”));
list.add(new ListItem(“Second List”));
list.add(new ListItem(“Third List”));
doc.add(list);
//Add a separator.
doc.add(Chunk.NEWLINE);
//Create a symboled List with a 30-point field for the symbols.
list=new List(false,30);
list.setListSymbol(Chunk.NEWLINE);
for(String fruit:fruits) {
list.add(new ListItem(fruit));
}
// Add the list to the document.
doc.add (list);
list=new List(false,40);
Image bullet = Image.getInstance(imagePath);
ListItem item;
list.setListSymbol(new Chunk(bullet, 0, -10));
for(String fruit:fruits) {
item = new ListItem(new Chunk (fruit));
item.setExtraParagraphSpace(10f);
item.setSpacingAfter(18f);
//item.setSpacingBefore(20f);
list.add (item);
}
doc.add (list);
doc.close ();
}
}
Con questo esempio concludiamo il nostro primo articolo sull’uso della libreria itext, nel prossimo saranno descritti un’ulteriore serie di elementi inseribili all’interno di un documento pdf (immagini, tabelle, ecc)
Commenti