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:

