Nella documentazione del framework PHP P4A della Crealabs, non ci sono informazioni troppo dettagliate su come
produrre report in formato pdf. Cercando nei thread del forum, ci sono diversi frammenti ed indizi, che
aiutano parecchio, ma si perde un po’ di tempo a metterli insieme per produrre il codice necessario a
generare il report come si desidera. In questo articolo mostrerò la soluzione che ho scelto mettendo insieme i vari indizi, e applicandola alla base application “Products Catalogue” distribuita sul sito della Crealabs come applicazione di esempio.
Step 1: scelta ed installazione delle librerie pdf
In questo thread del forum, viene suggerito di usare le librerie FPDF o R&OS.
Ho scelto R&OS semplicemente perché in passato avevo avuto qualche difficoltà con FPDF, probabilmente per mia colpa. Credo che siano in sostanza equvalenti.
Una volta scaricato il pacchetto, è necessario creare nella root della applicazione (nel nostro caso: localhost/p4a/applications/products_catalogue/) una cartella che si deve chiamare
libraries. All’interno di questa cartella vengono decompresse le librerie (nel nostro caso i due files: class.pdf.php e class.ezpdf.php) e la cartella fonts contenente i file per la generazione dei font.
Step 2: Aggiunta di un pulsante nella toolbar
A questo punto bisogna creare un pulsante per la generazione del report in pdf. Personalmente ho scelto di crearlo nella toolbar, ma evidentemente si può crearlo dove si vuole.
All’interno del file products.php sarà sufficiente aggiungere questo codice PHP:
1
2
3
4
5
6
7
8
9
10
| // Toolbar
$toolbar = & $this->build("p4a_standard_toolbar",
"toolbar");
$toolbar->setMask($this);
$toolbar->addSeparator($position = "left");
// Aggiungo un pulsante alla toolbar per la stampa su pdf
$toolbar->addButton('stampapdf','pdf');
// Intercetto onClick per eseguire stampa_documento()
$this->intercept($toolbar->buttons->stampapdf,
'onClick','stampa_documento'); |
// Toolbar
$toolbar = & $this->build("p4a_standard_toolbar",
"toolbar");
$toolbar->setMask($this);
$toolbar->addSeparator($position = "left");
// Aggiungo un pulsante alla toolbar per la stampa su pdf
$toolbar->addButton('stampapdf','pdf');
// Intercetto onClick per eseguire stampa_documento()
$this->intercept($toolbar->buttons->stampapdf,
'onClick','stampa_documento');
Notate che, per comodità, ho creato una variabile $toolbar
contenente l’oggetto toolbar.
Il secondo parametro 'pdf'
passato al metodo addButton
crea automaticamente un img link all’icona pdf.png.
Questa icona deve essere presente nella cartella di default per il set di icone di P4A: localhost/p4a/icons/default/32/
In alternativa, si può impostare a NULL
questo parametro per lasciare solo la scritta impostata ('stampapdf'
).
L’ultima riga di codice intercetta l’evento onClick
sul pulsante ed esegue il metodo stampa_documento
Step 3: Aggiunta del metodo stampa_documento
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| function stampa_documento()
// funzione per la stampa su pdf
{
require('class.ezpdf.php');
$pdf =& new Cezpdf('a4','portrait');
$pdf->selectFont($_SERVER['DOCUMENT_ROOT'].
P4A_APPLICATION_PATH.
'/libraries/fonts/Helvetica');
$db =& p4a_db::singleton();
$res = $db->getAll("SELECT model,
brands.description AS brand,
categories.description AS category, selling_price
FROM products
LEFT JOIN brands
ON brands.brand_id = products.brand_id
LEFT JOIN categories
ON categories.category_id = products.category_id");
$pdf->ezTable($res,'','Products',array('fontSize'=>12));
$type = 'application/pdf';
$filename = 'report.pdf';
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0,
pre-check=0");
header("Cache-Control: private", false);
header("Content-type: $type");
header("Content-Disposition: attachment;
filename=\"$filename\"");
$pdfcode = $pdf->output(1); // flusso dati senza header
header("Content-Length: " . strlen($pdfcode));
echo $pdfcode;
die();
} |
function stampa_documento()
// funzione per la stampa su pdf
{
require('class.ezpdf.php');
$pdf =& new Cezpdf('a4','portrait');
$pdf->selectFont($_SERVER['DOCUMENT_ROOT'].
P4A_APPLICATION_PATH.
'/libraries/fonts/Helvetica');
$db =& p4a_db::singleton();
$res = $db->getAll("SELECT model,
brands.description AS brand,
categories.description AS category, selling_price
FROM products
LEFT JOIN brands
ON brands.brand_id = products.brand_id
LEFT JOIN categories
ON categories.category_id = products.category_id");
$pdf->ezTable($res,'','Products',array('fontSize'=>12));
$type = 'application/pdf';
$filename = 'report.pdf';
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0,
pre-check=0");
header("Cache-Control: private", false);
header("Content-type: $type");
header("Content-Disposition: attachment;
filename=\"$filename\"");
$pdfcode = $pdf->output(1); // flusso dati senza header
header("Content-Length: " . strlen($pdfcode));
echo $pdfcode;
die();
}
Note: nella variabile $res
viene memorizzato un’array multidimensionale associativo che è il risultato della query. Come esempio ho preparato una query di tipo JOIN
perché nella maggior parte dei casi, è proprio questo il tipo utilizzato.
Il path per la scelta dei font deve essere assoluto, per averlo in termini relativi è possibile utilizzare la variabile $_SERVER['DOCUMENT_ROOT']
propria del PHP e la costatnte P4A_APPLICATION_PATH
propria del framework P4A.
Per forzare il browser ad aprire il report pdf in una nuova finestra, ho cambiato l’header del documento generato, specificando che il contenuto è un attachment. Altrimenti, il contenuto viene riconosciuto come mime-type 'application/pdf'
e (a seconda dei browser utilizzati) viene aperto nella stessa finestra.
Infine il nuovo processo viene terminato attraverso l’istruzione die();
Download:
Il sorgente comprende anche le librerie R&OS e l’SQL per creare il database con alcuni record d’esempio per il report in pdf. Il report generato è visualizzabile qui.
Conclusioni:
Il framework P4A è uno strumento davvero ben fatto, gli autori hanno fatto un gran lavoro, adesso sta a noi utilizzatori, attraverso l’interscambio di informazioni, generare la documentazione necessaria al suo sviluppo.
A tal proposito è mia intenzione produrre altra documentazione su altri aspetti di comune interesse agli utilizzatori di questo ottimo framework.
Riferimenti ed approfondimenti:
Valerio Maglietta ha scritto:
Definire ottima questa imbeccata di Mario Spada e’ il minimo…
L’unica aggiunta che mi sento di consigliare è quello di preprocessare il contenuto della stringa da stampare tramite iconv.
Ovvero per noi Italiani:
$res = iconv(‘UTF-8’, ‘CP1252’, $res);
prima dare in pasto $res a ezTable come nell’esempio precedente
In questa maniera caratteri accentati, simbolo euro e simili, non ci daranno problemi.
Nel mio caso (so linux Ubuntu 7.10) la codifica iniziale è UTF-8 ma potrebbe essere differente (ISO-8859-1, ISO-8859-16).
CP1252 è la codifica Windows Western European (sembra che R&OS sia stato sviluppato proprio sotto win…).
Grazie 1k Mario!