La creazione di report è un’attività molto comune per tutti i programmatori, non solo per coloro che si occupano a tempo pieno di applicazioni gestionali e simili. La gestione di siti web o e-commerce, cataloghi on-line, community e qualsiasi attività che coinvolga dei dati prima o poi avrà bisogno di analizzarli, ecco dunque che la necessità di creare dei report si manifesta.
In questo articolo vedremo come creare dei semplici report utilizzando PHP e la libreria FPDF, che ha diversi pregi: è molto leggera, è completamente free anche per usi commerciali e modifiche, è ben documentata.
Un semplice report tabulare
Per familiarizzare con la libreria consigliamo di installare lo stack XAMPP adatto al proprio sistema (Win o Linux), perché di base ha già installato FPDF come modulo PEAR.
In questo primo script vediamo come sia possibile creare un report in forma tabulare:
<?php include ('fpdf/fpdf.php'); define('EURO', chr(128)); // dati di test $data = array( array( 'product_code' => 'S284056', 'product_name' => 'Ferrary F1234', 'customer_code' => 'CUST1234', 'customer_name' => 'Gino Ginetti', 'amount' => 250000), array('product_code' => 'S284056', 'product_name' => 'Ferrary F1234', 'customer_code' => 'CUST1100', 'customer_name' => 'Gongolo Nannolo', 'amount' => 270000 ), array('product_code' => 'S292383', 'product_name' => 'Lardonghini Mucila', 'customer_code' => 'CUST0120', 'customer_name' => 'Pasquale Pasqualini', 'amount' => 352000 ), array('product_code' => 'S292383', 'product_name' => 'Lardonghini Mucila', 'customer_code' => 'CUST1234', 'customer_name' => 'Gino Ginetti', 'amount' => 352000 ), array('product_code' => 'S898964', 'product_name' => 'Porsck Paprika', 'customer_code' => 'CUST0120', 'customer_name' => 'Pasquale Pasqualini', 'amount' => 352000 ), array('product_code' => 'S898964', 'product_name' => 'Porsck Paprika', 'customer_code' => 'CUST0054', 'customer_name' => 'Pino Pinerati', 'amount' => 175000 ) ); // crea PDF $pdf = new FPDF(); $pdf->AddPage(); $pdf->SetFont('Arial', 'B', 16); $pdf->Cell(40, 10, 'Report vendite'); $pdf->Ln(); $pdf->Ln(5); $pdf->SetFont('Helvetica', 'B', 10); $pdf->Cell(30, 7, 'Cod. prodotto', 1); $pdf->Cell(40, 7, 'Nome prodotto', 1); $pdf->Cell(30, 7, 'Cod. cliente', 1); $pdf->Cell(40, 7, 'Nome cliente', 1); $pdf->Cell(40, 7, 'Prezzo pagato', 1); $pdf->Ln(); $pdf->SetFont('Helvetica', '', 10); foreach($data as $row) { $pdf->Cell(30, 7, $row['product_code'], 1); $pdf->Cell(40, 7, $row['product_name'], 1); $pdf->Cell(30, 7, $row['customer_code'], 1); $pdf->Cell(40, 7, $row['customer_name'], 1); // formattazione italiana $pdf->Cell(40, 7, EURO . ' ' . number_format($row['amount'], 2, ',', '.'), 1, 0, 'R'); $pdf->Ln(); } $pdf->Output();
In questo breve script ci sono molti elementi da notare:
- l’istruzione include (‘fpdf/fpdf.php’); funziona con XAMPP, in un’applicazione reale potrebbe essere necessario utilizzare un path differente. Verificare la documentazione o l’amministratore di sistema per chiarire eventuali dubbi;
- L’istruzione define(‘EURO’, chr(128)); definisce il carattere “euro”, in modo da non doversi ricordare il codice carattere (128);
- l’array $data contiene i dati prelevati dal (ipotetico) database;
- per creare il PDF viene istanziato un oggetto di tipo FPDF;
- per creare i vari elementi del report abbiamo fatto uso praticamente di soli tre metodi: SetFont(), Cell() e Ln();
- l’istruzione $pdf->Output(), infine, invia al browser i byte del PDF prodotto.
Il risultato è un semplice file PDF, aperto direttamente nella finestra del browser:
Da notare come la colonna degli importi sia stata allineata a destra grazie al parametro ‘R’ nel metodo Cell(). Sul sito ufficiale c’è la documentazione completa della libreria (anche in italiano!) alla quale vi rimandiamo per scoprire i dettagli di utilizzo dei vari metodi.
Raggruppamenti
Una delle funzionalità più utili dei report sono sicuramente i raggruppamenti, perché consentono di estrarre degli indicatori sintetici da una lunga fila di dati. Affinché si possano raggruppare i dati, è necessario che questi siano ordinati per la caratteristica che si vuole raggruppare. Nell’esempio sopra possiamo notare che i rapporti di vendita sono già ordinati per prodotto: non ci resta che creare un report che sfrutti questo raggruppamento:
<?php include ('fpdf/fpdf.php'); define('EURO', chr(128)); function report_table_header($pdf) { $pdf->SetFont('Helvetica', 'B', 10); $pdf->Cell(30, 7, 'Cod. prodotto', 1); $pdf->Cell(40, 7, 'Nome prodotto', 1); $pdf->Cell(30, 7, 'Cod. cliente', 1); $pdf->Cell(40, 7, 'Nome cliente', 1); $pdf->Cell(40, 7, 'Prezzo pagato', 1); $pdf->Ln(); } function report_product_total($pdf, $productTotal) { if (isset($productTotal)) { $pdf->SetFont('Helvetica', 'B', 10); $pdf->Cell(100, 7, '', 3); $pdf->Cell(40, 7, 'Totale', 0, 0, 'R'); $pdf->Cell(40, 7, EURO . ' ' . number_format($productTotal, 2, ',', '.'), 1, 0, 'R'); $pdf->Ln(); } } // dati di test NB: COPIARE LA SEZIONE DI DATI DALL'ESEMPIO N. 1 // crea PDF $pdf = new FPDF(); $pdf->AddPage(); $pdf->SetFont('Arial', 'B', 16); $pdf->Cell(40, 10, 'Report vendite - per modello'); $pdf->Ln(); $pdf->Ln(5); $pdf->SetFont('Helvetica', '', 10); $lastProductCode = null; $breakProduct = true; $productTotal = null; foreach($data as $row) { $breakProduct = $row['product_code'] != $lastProductCode; if ($breakProduct) { // mostra totali del prodotto precedente (se c'è) report_product_total($pdf, $productTotal); // mostra titolo prodotto $pdf->SetFont('Helvetica', 'B', 10); $pdf->Cell(40, 10, $row['product_code'] . ' - ' . $row['product_name']); $pdf->Ln(); // mostra header tabella report_table_header($pdf); } $pdf->SetFont('Helvetica', '', 10); $pdf->Cell(30, 7, $row['product_code'], 1); $pdf->Cell(40, 7, $row['product_name'], 1); $pdf->Cell(30, 7, $row['customer_code'], 1); $pdf->Cell(40, 7, $row['customer_name'], 1); // formattazione italiana $pdf->Cell(40, 7, EURO . ' ' . number_format($row['amount'], 2, ',', '.'), 1, 0, 'R'); $pdf->Ln(); $lastProductCode = $row['product_code']; $productTotal += $row['amount']; } // totale dell'ultimo prodotto report_product_total($pdf, $productTotal); $pdf->Output();
NB: Per limitare la lunghezza del sorgente abbiamo omesso la dichiarazione dell’array $data, che può essere copiata dall’esempio n. 1. Da notare:
- abbiamo spostato il codice che crea l’intestazione della tabella nella funzione report_table_header(), poiché questa intestazione andrà ripetuta per ogni prodotto;
- la funzione report_product_total() mostra l’ammontare totale; da notare in questo caso l’uso di una cella che occupa tre spazi (l’quivalente del colspan in HTML);
- le variabili $lastProductCode , $breakProduct e $productTotal sono utilizzate per capire se mostrare una nuova tabella e il riassunto della precedente, oppure no.
L’output di questo report è il seguente: