Creare PDF con PHP

Creare PDF con PHP in maniera efficace, veloce e funzionale.

In questo articolo esaminiamo come creare un PDF (Portable Document Format) di buona qualita’ utilizzando PHP con alcuni strumenti free quali dompdf e wkhtmltopdf che possono sostituire egregiamente strumenti commerciali ben piu’ blasonati e famosi per l’uso comune.

Iniziamo subito coll’escludere alcune delle soluzioni che troviamo in giro vuoi per la difficile implementazione, per gli scarsi o nulli risultati a causa di vecchie connessioni non piu’ valide o altre motivi, indi per cui eliminiamo rapidamente queste soluzioni qui:
1. Html2Pdf
2. R&OS (ezpdf)
3. fpdf

Almeno a nostro parere sono da escludere a priori per ovvi motivi di incompatibilita’ sia nella gestione che nella realizzazione del pdf (ove possibile…).

La soluzione che inizialmente abbiamo utilizzato visto i notevoli pareri positivi che si trovano sul web e’ dompdf che pero’ trova delle difficolta’ con le tabelle che hanno un tr che inizia in una pagina e si chiude nella successiva o con gli stili. Ecco due esempi di html con relativo link al pdf generato:

1. html semplice con tabella (clicca qui); pdf generato (clicca qui);

2. html di tr che si chiude nella pagina sucessiva con vari <p>&nbsp;</p> (clicca qui); relativo pdf generato con dompdf (clicca qui).

L’errore che si legge dal file di log e’:
[Fri Sep 11 15:56:33 2009] [error] [client xxx.xxx.xxx.xxx] PHP Warning:  file_put_contents(<path>/dompdf/lib/fonts/php_Times-Roman.afm) [<a href=’function.file-put-contents’>function.file-put-contents</a>]: failed to open stream: Permission denied in <pth>/dompdf/lib/class.pdf.php on line 2354
[Fri Sep 11 15:44:36 2009] [error] [client xxx.xxx.xxx.xxx] PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 256 bytes) in <path>/dompdf/include/style.cls.php on line 693

Il primo errore si risolve modificando la riga 2354 del file presente in lib/class.pdf.php da:
file_put_contents($dir . ‘php_’ . $name . ‘.afm’,  ‘$this->fonts[$font]=’ . var_export($data,  true)  . ‘;’);

in

file_put_contents($dir  . $name . ‘.afm’,  ‘$this->fonts[$font]=’ . var_export($data,  true)  . ‘;’);

perche’ in lib/fonts i fonts non hanno il prefisso php_

Il secondo errore invece non si risolve nemmeno aumentando il memory_limit dal php.ini. Il pdf non viene generato e la lentezza e’ immane.

3. html di tr che si chiude nella pagina sucessiva con vario testo generato da avvio — esegui — winword e scrivendo nel documento vuoto semplicemente =rand() (clicca qui); relativo pdf generato con dompdf (clicca qui).

4. html con div che crea una tabella (clicca qui); relativo pdf generato con dompdf (clicca qui).

Questo il codice sorgente del file che genera il pdf con dompdf:
<?php
require_once(“dompdf_config.inc.php”);

$filename = “tabella1.html”;
$handle = fopen($filename, “r”);
$txtOfferta = fread($handle,filesize($filename));

$dompdf = new DOMPDF();
$dompdf->load_html($txtOfferta);
$dompdf->render();
$dompdf->stream(“output.pdf”);

?>

La cosa che cambia e’ il la variabile $filename che diamo in pasto allo script che genera php, ossia (tabella.html, tabella1.html etc. etc.), il resto rimane inalterato.

Soltanto il primo link della generazione del pdf funziona e gli altri no. Il link della tabella fatta con i div non produce lo stesso risultato dell’html…ottimo risultato, no ?Insomma…

Passiamo alla soluzione efficace e veloce:

1. pdf con semplice tabella: clicca qui

2. pdf con tabella e tanti <p>&nbsp;</p>: clicca qui

3. pdf con tabella con tr inizia in una pagina e termina nell’altra: clicca qui

4. pdf con semplice tabella fatta con div: clicca qui

Ecco il codice del php utilizzato:
<?php
$filename = “tabella3.html”;
passthru(“./wkhtmltopdf ./”.$filename.” ./output.pdf”);

header(‘Cache-Control: public’);    // per ie.
header(‘Content-type: application/pdf’);
header(‘Content-Disposition: attachment; filename=”output.pdf”‘);
readfile(“http://www.listahosting.net//utility/dompdf/output.pdf”);

?>

Anche in questo caso $filename presenta il nome della varibiale che varia a seconda dell’html da convertire (tabella.html, tabella1.html etc. etc.).

In questo esempio e ‘stato utilizzato l’eseguibile wkhtmltopdf che dopo essere stato messo in root (ma puo’ avere qualsiasi altra locazione) e’ stato utilizzato con la funzione passthru per prendere l’html sorgente e generare il pdf, dopodiche’ e’ stato cambiato l’header della pagina (compatibilmente con Internet Explrer) e mostrato a video il PDF generato.

E’ plausibile che alcuni host condivisi abbiano la funzione passthru tra le funzioni proibite ma e’ piuttosto semplice per l’amministratore del server permettere l’esecuzione dello script senza alterare la sicurezza dell’host.

Il problema di sicurezza che abbiamo utilizzando passthru sul server e’ stato spiegato qui ma il funzionamento di wkhtmltopdf e’ decisamente ottimo e la velocita’ di esecuzione perfetta con notevole alleggerimento del carico nel server. Inoltre  con dompdf anche quando genere il pdf genera un sacco di warning nei file di log che rendono piu’ pesante la generazione.

Soluzioni piu’ complesse con l’uso di CSS all’interno del template in HTML con dei segnaposto che vengono sostituiti a runtime prima della generazione del pdf hanno sempre dato esito positivo.

Vi invito a fare i vostri commenti sulla base della vostra  esperienza personale.

9 pensieri riguardo “Creare PDF con PHP”

  1. Ho già inviato un E-mail in precedenza, in inglese, per chiedere informazioni circa la fattibilità di creare automaticamente un file PDF dopo aver creato in precedenza un file php che prevede il collegamento con il database di MYSQL e che quindi preleva dei dati in base a quanto richiesto.
    In pratica il file php viene creato e necessiterebbe la sua traformazione in un file PDF da stampare.
    Questo un esempio (anche se il file è in formato htm) vedere questro link :

    http://www.pedigreedatabase.eu/vedomoduli/pedigreedoc.htm

    Sono a conoscenza delle librerie come fpdf.php, ma cercavo di capire se c’è dell’altro in automatico che puó fare un PDF prima di presentare le attuali pagina WEB nel mio sito.

    In attesa di una Vostra risposta,
    distinti saluti
    Bruno DA TOS

  2. Ci scusi ma la mail non ci e’ arrivata d e’ stata filtrata dal sistema antispam.

    Il sistema indicato nel POST permette la creazione del file PDF prelevando anche dati dal Database Mysql che puo’ essere successivamente mostrato a video. Puo’ anche creare il PDF dal documento in HTML generato con le funzioni file_get_contents di PHP.
    Per ulteriori informazioni non esiti a contattarci direttamente cosi’ da capire piu’ in dettaglio il problema.

  3. Ho già inviato un E-mail in precedenza, in inglese, per chiedere informazioni circa la fattibilità di creare automaticamente un file PDF dopo aver creato in precedenza un file php che prevede il collegamento con il database di MYSQL e che quindi preleva dei dati in base a quanto richiesto.In pratica il file php viene creato e necessiterebbe la sua traformazione in un file PDF da stampare.Questo un esempio (anche se il file è in formato htm) vedere questro link :
    +1

  4. Salve, il sistema funziona esattamente come da lei indicato: lo script in PHP si interfaccia con il Database MySql ed una volta estratti i dati necessari prepara il PDF che puo’ essere comodamente stampato.
    Per maggiori informazioni non esiti a contattarci via mail: info@freescriptphp.com

    Buona giornata.

  5. This is my very first time i visit here. I found so numerous interesting stuff in your weblog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good function.

  6. Salve, vorrei sapere se è a risolvere un problema che mi sta assillando da diversi giorni.
    Cercherò di descrivere il problema.

    Grazie a FPDF.PHP ho generato un file PDF per la stampa del registro del professore. Esso stampa le lezioni svolte durante il quadrimestre. Se un insegnante svolge poche lezioni durante tale periodo, la pagina creata dal file PDF riesce bene a contenerle, e vengono correttamente visualizzate.
    Il problema si verifica quando in una materia sono previste diverse ore d’insegnamento per mese e nella pagina creata dal file PDF vengono visualizzate solo in parte, cioè solo le lezioni di settembre e una parte del mese di ottobre e le lezioni svolte fino a gennaio non vengono stampate, come mostrato nel esempio :
    http://registroonweb.it/registro/stampaRegistro.php?a=1&b=C300&c=1

    Vorrei, che una volta stampate le prime 15 lezioni, il programma automaticamente creasse una nuova pagina con l’elenco degli alunni e le successive 15 lezioni e così via per tutte le lezioni svolte durante il quadrimestre.

    Qualcuno può aiutarmi a risolvere questo problema?

    Grazie in anticipo.

    Tegatti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.