Come creare un file Excel con PHP e MySQL
Apro una nuova sezione del portale dedicata allo sviluppo PHP che presto avrà una sezione dedicata. Creare un file Excel al volo con php è molto semplice e tremendamente utile nel caso di sviluppo applicazioni orientate al business come piattaforme di BI o gestionali di vario tipo.
La soluzione si articola in 4 semplici passi;
- Esecuzione della Query con MySQL
- Formattazione delle righe in formato CSV
- Invio dell’opportuno Mime-Type
- Output
Esecuzione della Query con MySQL
Supponiamo di voler esportare in Excel un elenco clienti da un applicativo php/MySQl la prima cosa da fare sarà ovviamente la query sul db per l’estrazione dati, che sarà qualcosa di simile;
<?php
$hostname = "<host_db>";
$database = "<nome_db>";
$username = "<admin>";
$password= "<password>";
$conn= mysql_pconnect($hostname, $username, $password) or die(mysql_error());
mysql_select_db($database, $conn);
$query = "SELECT nome, cognome, citta FROM clienti";
$clienti = mysql_query($query, $conn) or die(mysql_error());
$row_clienti = mysql_fetch_assoc($clienti);
?>
Formattazione record CSV
A questo punto andiamo a formattare ogni riga separando i campi con la tabulazione ed includendo i campi di testo con i doppi apici. Il carattere speciale di tabulazione in php è "\t" e per includere i doppi apici useremo sempre lo slash;
<?php
do {
$righe.= "\"".$row_clienti[‘nome’]."\"\t\"".$row_clienti[‘cognome’]."\"\t\"".$row_clienti[‘citta’]."\"\n";
} while ($row_clienti= mysql_fetch_assoc($clienti));
?>
L’invio del Mime-Type
Questa è la parte fondamentale di tutto il codice, l’invio del’header con il Mime-Type adatto per Excel. Attenzione a non inviare nulla in output prima dell’header, pena il mancato funzionamento;
<?php
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: nomefile.xls");
?>
e per finire, inviamo i dati e usciamo;
<?php
print $righe;
exit;
?>
Se è tutto impostato a dovere, quando si chiama il file non si apre nessuna nuova finestra, ma il browser invia un file CSV ed il sistema apre la classica maschera di salvataggio, quindi apre il foglio Excel con i dati. Ho provato anche ad inviare dati numerici con differenti formati e vengono letti benissimo. Basta utilizzare le funzioni di formattazione del php e non includere il dato nei doppi apici. Testato sia con Explore che con Firefox.
Articoli molto interessanti
complimenti l’articolo è molto interessante e spiegato…. Ho un problemino però, non mi visualizza bene le date, nella casella della date appaiono tanti #####. Però se mi sposto con il mouse sopra riesco effettivamente a vedere il contenuto delle celle. Come potrei fare a visualizzarlo?
Inoltre appena mi apre il foglio di excel mi dice che il file non è di un estensione corrette e mi chiede conferma per aprirlo comunuqe, ma in realta il file ha estensione corretta xls. Ti ringrazio anticipatamente
Per quanto riguarda le date è una caratteristica di Excel: se la cella non è sufficientemente larga per mostrarle regolarment usa quel tipo di visulizzazione per indicare che è necessario allargare le celle.
Riguardo l’estensione forse dipende dalla versione di Excel. Hai la 2007?
Ciao, io ho utilizzato questa funzione in un modulo del mio sito, questa sezione mi deve esportare i dati inseriti in precedenza in un file xls, ma mi restituisce questo
“Warning: Cannot modify header information – headers already sent by (output started at c:programmieasyphp1-8wwwprontoviaggiindex.php:20) in c:programmieasyphp1-8wwwprontoviaggiincesporta.inc.php on line 35
Warning: Cannot modify header information – headers already sent by (output started at c:programmieasyphp1-8wwwprontoviaggiindex.php:20) in c:programmieasyphp1-8wwwprontoviaggiincesporta.inc.php on line 36
35 e 36 sono gli header
Mi aiuti grazie
Vuol dire che prima ancora di inviare in output l’header
hai mandato inavvertitamente in output qualcos’altro. E’ un errore molto comune ed in genere è causato da spazi “ballerini” nel codice php. Apri il tuo file, e tutte le librerie incluse prima di quelle due righe, e verifica che non venga inviato nulla in output.
Stai attento anche a situazioni del genere;
———————–
———————-
Lo spazio tra le due righe di codice va in output e causa l’errore “headers already sent”
Daniele
ps. mi hai ricordato i tempi delle docenze in php 🙂
A me, invece, al posto di un file .xls crea un file .php, e con una sola riga di dati:
“Mr” “Stefano” “Quitadamo” “qube” “Architecture” “Architect” “Viale Gramsci” “” “Napoli” “” “” “info@studios.it” “999999” “Y” “Y” “” “”
Gli spazi (diversi) tra un campo e l’altro sono quelli generati dal php…
???
Che browser usi? Verifica nelle impostazioni del browser se può gestire il mime type “application/vnd.ms-excel”
Uso Mozilla Firefox, versione 3.0.10
In effetti, tra le tipologie di file che gestisce non c’è xls, ma non vedo come si possa aggiungere…
E poi, se dipende da queste impostazioni, probabilmente il problema lo risolvo io ma rimane… non c’è un sistema ‘universale’?…
Ciao e complimenti per la chiarezza.
Non riesco però a fare in modo che un numero, se inferiore ad un certo numero di caratteri, venga preceduto dagli zeri.
Es.: se nella tabella mysql c’è 000123, esportando in excel riporta solo *123*…
Salve. Complimenti per l’articolo… breve, facile e chiaro. 😉
Vorrei segnalare un problema.. quando salvo il file devo salvarlo per forza in xls e quando vado ad aprirlo con Excel noto che i nomi dei campi dei records non vengono messi in orizzontale ma sono in verticale.
Prima di aprire questo file mi esce un avviso e dice che il file è diverso da quello specificato nell’estensione del file, e chiede se voglio comunque aprirlo.
Premetto che uso Excel 2007.
Come mai?
Grazie
Max
perchè non funziona se alla select aggiungo la condizione where
grazie ciao
Ciao! complimenti per la spiegazione…è molto chiara!
Avrei una domanda: nel caso in cui volessi settare anche l’allineamento del testo nel file .xls che tipo di codice dovrei mettere nel php?
Grazie Simon
Ciao Simon!
Non ho afferrato bene, intendi l’allineamento nella cella di Excel?
Ciao,
si esattamente questo intendevo….fare in modo che quando un utente apra il file .xls lo visualizzi già con il testo centrato nelle caselle.
Grazie!
Molti dei problemi sono dovuti a questa riga che è sbagliata:
header(“Content-disposition: nomefile.xls”);
quella corretta è:
header(“Content-disposition: attachment;filename=nomefile.xls”);
Grazie!!!! E’ stato molto utile!!
Grazie! Funziona perfettamente con l’header corretto da Fabio 😀
Fantastico, grazie mille… modificando un file php fatto in versione 3, non riuscivo più a generare un file xls con PEAR in versione 5, con i tuoi consigli ho raggiunto l’obiettivo anche nella nuova versione.
grazie
Lanfra
Felice di essere stato utile 🙂
Ho usato la sintassi indicata ma il server mi ritorna
sempre un errore 500 di cui non riesco a trovare la causa…
Mi sono permesso di modificare il codice come segue:
1) Ho messo i due header in testa.
2) Ho aggiunto filename:”utenti.xls” per usare il nome del file.
3) Il file apertura_sql.php effettua il collegamento con il DB.
4) Ho aggiunto le intestazioni delle colonne.
5) La costruzione della $righe non era corretta, e deve essere questa.
6) Ho usato la tabella user del DB MySql.
Grazie comunque per l’idea, semplice e perciò brillante.
Saluti da lupogio