paolo@bimodesign.com | +34 608 61 64 10

Framework

        

PhpExcel...la libreria definitiva

Prima di procedere, come anticipato nella premessa a questo articolo, Lo scopo di questo post e' solo ed esclusivamente quello di illustrarvi un esempio pratico, ma dovete fare riferimento al sito ufficiale sia per scaricare il codice che, sopratutto, per consultare la ricca ricca documentazione presente. http://phpexcel.codeplex.com/

Inoltre, preciso che queste istruzioni sono valide per creare un file per la versione Excel 2005, ma nel portale trovate anche quelle relative alla versione 2007.

Iniziamo...

Dopo aver scaricato i vari file delle librerie, iniziamo a scrivere il codice, cominciando dall'header

require_once(_PATH_COMMON.'WEB-INF/lib/PHPExcel.php');
require_once(_PATH_COMMON.'WEB-INF/lib/PHPExcel/Cell/AdvancedValueBinder.php');
La prima dichiarazione e' obbligatoria, mentre la seconda, opzionale, utilizzeremo per la formattazione delle celle.

Instanziamo la classe principale, ed ereditiamo quella per la formattazione.

$objPHPExcel = new PHPExcel();
PHPExcel_Cell::setValueBinder(new PHPExcel_Cell_AdvancedValueBinder());

Inseriamo le informazioni generali del documento, che sono comunque opzionali.

$objPHPExcel->getProperties()->setCreator("BiMo Design")
            ->setLastModifiedBy("BiMo Design")
            ->setTitle("Title".$sTitleExcel)
            ->setSubject("Subject".$sSubjectExcel)
            ->setDescription("Description".$sDescriptionExcel)
            ->setKeywords("Keyword".$sListKeywords);

$objPHPExcel->getActiveSheet()->setTitle($sTitleExcel);

Creaiamo quindi il foglio di lavoro, ovvero lo sheet "0". Se ne possono creare quanti se ne ritengano necessari.

$objPHPExcel->setActiveSheetIndex(0);
Ed ora passiamo ad inserire i dati nel documento. Trattero' solo alcuni aspetti della libreria, ma per tutte le innumerevoli opzioni, vi rimando alla guida ufficiale.

Inserire una immagine (Drawing)

Inseriamo il logo della nostra azienda, in alto a sinistra del documento.

$objDrawing = new PHPExcel_Worksheet_Drawing();
$objDrawing->setName('Logo Bi.Mo.Design');
$objDrawing->setDescription('Logo Bi.Mo.Design');

$objDrawing->setPath(_PATH_MAIN.'images/logo_bimodesign.png');
$objDrawing->setCoordinates('A1');
$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());	

Ho inserito come coordinate A1, perche' il logo voglio inserirlo nella posizione in alto a sinistra, ma chiaramente si puo' posizionarlo dove preferite. Consiglio di creare l'immagine gia' con la dimensione definitiva, ma in alternativa esistono comunque metodi che permettono il ridimensionamento.
Notate come si assegna l'immagine al foglio di lavoro attualmente attivo (activeSheet)

Il merge di una o piu' celle e formato del testo

Voglio inserire un testo centrato nel documento A4, che sia in bold, di 10 px ed Arial.

$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial');
$objPHPExcel->getDefaultStyle()->getFont()->setSize(10);

$objPHPExcel->getActiveSheet()->mergeCells('B6:G6');
$objPHPExcel->getActiveSheet()->getStyle('B6')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('B6')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getActiveSheet()->getStyle('B6')->getFont()->setSize(13);

$sLABVoiceDetailCallInvoice='Nome del Cliente';
$objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('B6', $sLABVoiceDetailCallInvoice);

Notare che il testo va inserito nella cella di inizio del merge.

Definizione delle colonne

Prima di illustrarvi il codice, ricordate che se volete che venga stampato su un formato A4, le dimensioni delle colonne non devono superare la larghezza definita. Di seguito un esempio, le cui dimensioni delle colonne vanno provate durante i test.

$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(18); //Fixed this column to enter the print margin
$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(15); //Fixed this column to enter the print margin
$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(9); //Fixed this column to enter the print margin
$objPHPExcel->getActiveSheet()->getColumnDimension('G')->setAutoSize(true);

Come potete notare, alcune colonne hanno la dimensione autodefinita (setAutoSize) mentre per altre la definisco fissa. Da notare che se una descrizione supera la dimensione fissata, il testo verra' parzialmente nascosto. La colonna potra' comunque essere successivamente ridimensionata dall'utente.

Definizione dei titoli delle colonne

Dopo aver definito le colonne occorre definirne i titoli. Definiremo anche un colore di sfondo e un bordo solo per questa riga.

$objPHPExcel->setActiveSheetIndex(0)
			->setCellValue('A' . $iIndexDetailCalls, 'Numero')
			->setCellValue('B' . $iIndexDetailCalls, 'Data')
			->setCellValue('C' . $iIndexDetailCalls, 'Durata')
			->setCellValue('D' . $iIndexDetailCalls, 'Tipo')
			->setCellValue('E' . $iIndexDetailCalls, 'Prefisso')
			->setCellValue('F' . $iIndexDetailCalls, 'Prezzo ('._MONEDA.')')
			->setCellValue('G' . $iIndexDetailCalls, 'Destino');

$styleThinBlackBorderOutline = array(
	'borders' => array(
		'outline' => array(
			'style' => PHPExcel_Style_Border::BORDER_THICK,
			'color' => array('argb' => 'FF6B7C6B'),
		),
	),
);

$objPHPExcel->getActiveSheet()->getStyle('A' . $iIndexDetailCalls.':'.'G' . $iIndexDetailCalls)->getFill()
                              ->setFillType(PHPExcel_Style_Fill::FILL_SOLID)
			      ->getStartColor()->setARGB('FFC0C0C0');

Non c'e' bisogno di alcuna spiegazione ;), se non che al momento ancora non ho capito come si genera la tabella dei colori in excel (ARGB)...

Formattiamo un campo numerico (0,0000)

Per fare questo, occorre usare le definizioni presenti nel file ./PHPExcel/Style/NumberFormat.php o, come in questo caso, crearne una nuova nel file stesso. Cosi'.

class PHPExcel_Style_NumberFormat implements PHPExcel_IComparable
{
	/* Pre-defined formats */
	const FORMAT_GENERAL					= 'General';

	const FORMAT_TEXT					= '@';

	const FORMAT_NUMBER					= '0';
	const FORMAT_NUMBER_00					= '0.00';
        const FORMAT_NUMBER_0000				= '0.0000';
...
...

per richiamare la formattazione, scrivere questa istruzione.

$objPHPExcel->getActiveSheet()->getStyle('F' . $iIndexDetailCalls)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_0000);			

Inserire i dati nelle colonne

Ma come inserire i dati, prelevati ad esempio da una tabella, nelle relativi colonne. Premesso che la formattazione di ogni colonna va fatta prima di inserire i dati e per ogni riga creata, questo potrebbe essere il codice da inserire nel vostro ciclo che legge ad esempio un array.

$objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A' . $iIndexDetailCalls, $rowCalss['cli_a'])
            ->setCellValue('B' . $iIndexDetailCalls, ' '.$rowCalss['call_date_ini'].'') //The format yyyy-mm-dd hh:mi:ss is ok only if put one space before
            ->setCellValue('C' . $iIndexDetailCalls, ' '.$sPartialDurationFormat.'') //The format hh:mi:ss is ok only if put one space before
            ->setCellValue('D' . $iIndexDetailCalls, $rowCalss['area_type_description'])
            ->setCellValue('E' . $iIndexDetailCalls, $rowCalss['area_description'])
            ->setCellValue('F' . $iIndexDetailCalls, $rowCalss['call_price'])
            ->setCellValue('G' . $iIndexDetailCalls, $rowCalss['cli_b']);

Notate che la variabile $iIndexDetailCalls e' l'indice di ogni riga.

Salvare il file su disco

Per salvare il file in una directory occorrono poche righe. Queste

$objWriter->save(_PATH_SHARED."dir_file_excel/".$nomeFileExcel_codicliente.".xls");
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

visualizzare il file su disco (senza salvarlo)

Per questioni di privacy, puo' essere necessario visualizzare al cliente il file excel (che poi scarichera' in locale), senza salvarli sul server. In questo caso la procedura e' leggermente diversa e occorre fare attenzione a queste impostazioni dell'header.

header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$nome_file_codi_cliente.'.xls"');
header("Pragma: public");
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

$objWriter = new PHPExcel_Writer_Excel5($objPHPExcel);
$objWriter->save('php://output');
In particolare le ultime tre istruzioni dell'header, sono necessarie per permettere che questo funzioni anche su Internet Explorer!!!.