Come spiega la prima pagina del sito ufficiale, «FPDF è una classe PHP che permette di generare files PDF direttamente da PHP, senza utilizzare la liberia PDFlib.».
Trattandosi di una classe completamente libera (la prima F sta appunto per “free”), abbiamo la possibilità di studiarla per modificarla a nostro piacimento. Ecco perché in rete troviamo degli script già pronti che si adattano allo scopo: ne potete trovare alcuni esempi a questo indirizzo, tra l’altro accessibile direttamente dalla home page del sito.
Le sue prestazioni sono inferiori alla libreria PDFlib, ma la differenza non si risente per file poco pesanti. La sua personalizzazione, inoltre, lo rende un sostituto più che valido. Per esempio è possibile con facilità:
– modificare il font (colore, dimensioni, allineamento, ecc.)
– creare intestazioni e piè di pagina
– inserire link tra le pagine
– inserire e gestire immagini
– gestire gli elementi del file, come i margini, l’autore del documento, ecc.
– usare diverse unità di misura
I settaggi di base di FPDF
Iniziamo a passare in rassegna le basi per l’utilizzo di questa classe.
Dalla pagina di downloads scaricate la versione più recente. All’interno del file zip (o del tgz, a seconda se adoperiate come piattaforma Windows o Linux), una volta scompattato, troverete le FAQ, la cartella con i tutorial e la cartella contenente la guida ai metodi. Vi consiglio di consultarli già al primo utilizzo, seguendoli di pari passo. Le funzioni elencate nella cartella “doc” non sono molte e in gran parte non richiedono grossi sforzi per comprenderle in vista di uno script base.
Scompattate lo zip nella cartella voluta. Per i nostri scopi supponiamo che sia caricato nella root principale del sito, ma nulla vieta di metterlo in una sottocartella, modificando il riferimento della funzione require.
Perché il pdf possa generarsi, è necessario che in precedenza non sia stata inviata nessuna informazione, per esempio che non sia stato stampato niente a video con la classica funzione echo di php. Il nostro file php, quindi, inizierà in questo modo:
1 2 3 |
<?php require("fpdf/fpdf.php"); $pdf=new FPDF(); |
Possiamo poi settare le informazioni generali del file pdf che si andrà a creare e i margini validi per l’intero documento (per default i margini sono a 10 mm):
1 2 3 4 5 6 7 8 9 10 |
//setto l'autore, il creatore e il soggetto del pdf $pdf->SetAuthor("Nome Cognome", true); $pdf->SetCreator("Nome Cognome", true); $pdf->SetSubject("Oggetto del documento", true); //setto i margini sinistro, superiore e destro $margine_sx=20; $margine_top=15; $margine_dx=20; $pdf->SetMargins($margine_sx, $margine_top, $margine_dx); |
Inserimento di testi e di immagini
Per la produzione del corpo interno non avete che l’imbarazzo della scelta. Ogni elemento ha la sua posizione nella pagina, stabilita da due coordinate X e Y (rispettivamente indicano il punto di origine dell’elemento in orizzontale e in verticale). Queste coordinate possono essere settate con le funzioni setX() e setY(), qualora occorresse. E’ probabile che al principio avrete un bel po’ da smanettare prima di capirci qualcosa: con il tempo (e l’esperienza) queste due funzioni si riveleranno indispensabili.
Se per esempio dovete inserire un’immagine, avrete bisogno di fare qualche esperimento con la funzione image(), ovviamente da richiamare attraverso l’oggetto $pdf-> come abbiamo visto per le precedenti funzioni, dove abbiamo settato le informazioni della pagina e i margini. Vi renderete presto conto che le immagini sono “indipendenti” dal testo, nel senso che non settando dovutamente le coordinate X e Y correrete il rischio di sovrapporle al testo.
L’elenco delle funzioni contenute nella cartella scompattata vi aiuterà a capire quali usare all’occorrenza.
Le funzioni con cui avrete più a che fare saranno senz’altro cell() e multicell(). Entrambe creano un’area dove è possibile inserire del testo, con la sola differenza che nel secondo caso il testo andrà automaticamente a capo quando raggiunge la fine della riga oppure quando incontrerà il carattere di escape “\n” (senza virgolette). Un esempio:
1 2 |
$pdf->Cell(100, 5, "Questo è un testo di prova", 1, 0); $pdf->Multicell(100, 5, "Questo è un testo di prova\n in multicella"); |
Abbiamo creato due rettangoli, entrambi larghi 100 (millimetri, a meno che non si sia stabilita un’unità di misura diversa per il documento) e alti 5. Nella multicella il testo andrà a capo non appena incontrerà il \n.
Notiamo i parametri, nella funzione cell(), inseriti dopo il parametro della stringa:
– il primo parametro (impostato al valore 1), indica che il rettangolo sarà contornato da un bordo. Impostando il valore a 0 non apparirà il bordo. E’ altresì possibile scegliere di mostrare la cornice solo in uno o più bordi, combinando tra loro i valori L (sinistro), T (superiore), R (destro) e B (inferiore).
– il secondo parametro indica dove si posizionerà la successiva cella creata. Con il valore 0 significa che la successiva cella si creerà a fianco di questa; con 1 andrà a capo.
Senza entrare nei dettagli, altre funzioni con cui certamente vi troverete a lavorare saranno:
addPage(): forza il cambio pagina.
ln(): stabilisce uno spazio da un elemento e un altro, con altezza impostabile.
setFont(): applica dimensioni e stile ai font successivi.
setTextColor(): gestisce il colore dei font successivi.
Naturalmente è possibile integrare qualsiasi codice creato in php all’interno del file. Questo vi tornerà utile nel caso in cui i dati da mostrare debbano essere dinamici, per esempio estratti da un database.
L’output del file in formato pdf
Un’ultima notazione sulla funzione output(), che elabora effettivamente il file trasformandolo in pdf.
In gran parte dei casi basta evocare la funzione $pdf->Output(); alla fine del documento.
Può capitare però che questo metodo abbia problemi di funzionamento, spesso a causa di integrazione del pdf con il browser. In tal caso è utile usare il pdf dinamico: in pratica creiamo il file pdf in una cartella temporanea e lo estriamo in seguito. Lo script da usare è il seguente (i commenti dovrebbero essere sufficienti per capire il suo uso):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//crea il file temporaneo con permessi 0600, ovvero scrittura/lettura solo dal mio sito (gli utenti esterni non possono accedervi) $dir="pdf_tmp/"; $file = basename(tempnam($dir, 'tmp')); //percorso + file temporaneo $dir_file=$dir."".$file; //rinomino il file temporaneo con l'estensione .pdf rename($dir_file, $dir_file.'.pdf'); $file.= '.pdf'; //percorso + file rinominato in pdf $dir_file2=$dir."".$file; //salva il contenuto voluto nel file appena rinominato $pdf->Output($dir_file2, 'F'); //cambio i permessi del file creato chmod($dir_file2, 0755); //Reindirizzamento header('Location: '.$dir_file2); |
Ciao, molto interessante l’articolo.
Sto cercando di inserire una immagine dentro di una cella, ma l’immagine mi viene fuori.
Questo e il codigo.
$pdf->Cell(40,10,$pdf ->Image($fotografia, ‘jpg’),1, 0, ‘C’ , true);
Mi potresti aiutare
Grazie saluti
Ciao Mariano,
prima di inserire il tipo (jpg) devi mettere le coordinate della cella che deve contenere l’immagine. Cioè trasforma il tuo codice in questo (mettendo le opportune coordinate):
$pdf->Cell(40,10,$pdf ->Image($fotografia, $x, $y, $width, $hight, ‘jpg’),1, 0, ‘C’ , true);
Vedi la documentazione ufficiale per i dettagli:
http://www.fpdf.org/en/doc/image.htm
Ciao Manuel,
inanzi tutto ringraziarti per la tua pronta risposta.
Ho seguito il tuo consiglio e ho fatto lo seguente:
$y=”0″;
$pdf-> Ln(10);
$pdf->SetFont(‘Arial’,”,8);
$consulta = mysql_query(“SELECT * FROM articulo”);
while ($datos=mysql_fetch_array($consulta))
{
$fotografia = $datos[‘fotografia’];
$descripcion = $datos[‘descripcion’];
$nota = $datos[‘nota’];
$costo = $datos[‘costo’];
$pvp = $datos[‘pvp’];
if ($i == 0){
$color=”255, 255, 255″;
$i =”1″;
}else{
$color=”214, 235, 255″;
$i=”0″;
}
$width=13;
$hight=10;
$x=20;
if ($y == 0){
$y = 70;
}else {
$y=$y + 12;
}
$pdf -> SetFillColor($color);
$pdf->Cell(40,20,$pdf ->Image($fotografia, $x, $y, $width, $hight, ‘jpg’),1, 0, ‘C’ , true);
$pdf -> Cell(100,20, $nota, 1, 0, ‘C’ , true);
$pdf -> Cell(20,20, $costo, 1, 0, ‘C’ , true);
$pdf -> Cell(20,20, $pvp, 1, 0, ‘C’ , true);
$pdf -> Ln(20);
}
ok sono riuscito in parte a mettere le immagini ma non riesco a spostarli dove corrispondono quando aumento il valore di $y = 70; a 80 spariscono le immagini.
vedere immagine
https://www.dropbox.com/s/uyftsf5s3qzkfgf/imagen.jpg?dl=0
Ok, ho risolto questo ma adesso ho un’altro problema.
La prima pagina la fa bene, ma la seguente pagina non si vede il subtitulo e poi l’immagine salta alla fine della pagina.
Image($mimagen);
$this->SetFont(‘Arial’,’B’,10);
$this->Cell(180,12, ‘Fecha: ‘ .date(‘d/m/Y’), 0, 1, ‘R’);
$this->Ln(10);
$this->SetFont(‘Arial’,’B’,15);
$this->Cell(180,10, ‘LISTADO DE ARTICULOS’, 0, 1, ‘C’);
$this->Ln(8);
$this->SetFont(‘Arial’,’B’,10);
$this -> SetTextColor(66, 134, 247);
$this->Cell(40,10 , ‘Imagen’,1, 0, ‘C’);
$this->Cell(100,10 , ‘Descripcion’,1, 0, ‘C’);
$this->Cell(20,10 , ‘Costo’,1, 0, ‘C’);
$this->Cell(20,10 , ‘P.V.P’,1, 0, ‘C’);
}
}
// Imprime cuerpo
$pdf = new PDF();
$pdf -> addpage();
$i=”0″;
$y=”0″;
$pdf-> Ln(10);
$pdf->SetFont(‘Arial’,”,8);
$consulta = mysql_query(“SELECT * FROM articulo”);
while ($datos=mysql_fetch_array($consulta))
{
$fotografia = $datos[‘fotografia’];
$descripcion = $datos[‘descripcion’];
$nota = $datos[‘nota’];
$costo = $datos[‘costo’];
$pvp = $datos[‘pvp’];
if ($i == 0){
$color=”255, 255, 255″;
$i =”1″;
}else{
$color=”214, 235, 255″;
$i=”0″;
}
$width=13;
$hight=10;
$x=20;
if ($y == 0){
$y = 80;
}else {
$y=$y + 10;
}
$pdf -> SetFillColor($color);
$pdf->Cell(40,20,”,1,0,’C’,true);
$pdf -> Cell(100,20, $nota, 1, 0, ‘C’ , true);
$pdf -> Cell(20,20, $costo, 1, 0, ‘C’ , true);
$pdf -> Cell(20,20, $pvp, 1, 0, ‘C’ , true);
$pdf -> Ln(20);
$pdf->Image($fotografia,25,$y,10,10,’jpg’);
$y += 10;
}
$pdf->Output();
?>
allego il link di quello che mi fa.
https://www.dropbox.com/s/slpa9qppunax24x/listadoarticulos.pdf?dl=0
spero che mi puoi aiutare.
grazie e saluti
Visto così è un po’ difficile capire dov’è l’errore… Immagino comunque che sia dovuto al settaggio di $y, che manda l’immagine fuori posto.
Quando vai a nuova pagina (chiamiamola “pagina 2”) la $y dovrebbe ripartire da 80, invece da quello che vedo mantiene l’ultimo valore che aveva in “pagina 1”
Prova a modificare l’if in questo modo:
if ($y == 0 or $y > 1000){
$y = 80;
}else {
$y=$y + 10;
}
(al posto di “1000” mettici il valore opportuno, che sarebbe appunto l’ultimo valore possibile di y per una pagina)
Ok. ti ringrazio per la tua colaborazione, sto quasi vicino ma quello che mi manca e il sottotitolo ovvero
questo
$this->Cell(40,10 , ‘Imagen’,1, 0, ‘C’);
$this->Cell(100,10 , ‘Descripcion’,1, 0, ‘C’);
$this->Cell(20,10 , ‘Costo’,1, 0, ‘C’);
$this->Cell(20,10 , ‘P.V.P’,1, 0, ‘C’);
Come vedi nel link del pdf nella pagina 2 mette il titolo ma manca il sottotitolo
che non lo fa, e ho bisogno di questo per poter inserire bene l’immagine
Nell’attesa grazie e saluti
Devi aggiungere una condizione anche per questa parte di codice: quando $y raggiunge il valore per una nuova pagina, devi ristampare le celle del sottotitolo (altrimenti le stampa solo una volta e cioè a prima pagina)
Ciao Manuel,
Articolo molto interessante, ti chiedo una cosa: posso generare un file pdf tramite FPDF prelevando però i dati che dovrò inserire nel pdf da una TABLE ? Se si come si fa?
Nel senso posso prelevare i dati dalla TABLE e con quelli generare il pdf?
Grazie mille
Ciao Davide,
parli di una table html? Puoi farlo in due tempi separati: recuperi i dati delle varie celle e li immagazzini in variabili, quindi li stampi con il pdf.
Per recuperare i dati delle celle dipende come puoi accedervi: se sono creati da uno script pdf è semplice, ce li hai già pronti nella pagina dove crei la tabella. Se invece hai solo la pagina html, puoi usare questa funzione nativa del php che recupera appunto il contenuto html di una pagina:
http://php.net/manual/en/function.file-get-contents.php
Salve,
sapete se è possibile calcolare le dimensioni (larghezza e altezza) di un pdf e metterle in delle variabili in php con fpdf?
Grazie a tutti