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;

  1. Esecuzione della Query con MySQL
  2. Formattazione delle righe in formato CSV
  3. Invio dell’opportuno Mime-Type
  4. 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.

Se ti è stato utile potrebbero interessarti anche:

Commenti

  1. raf scrive:

    Articoli molto interessanti

  2. milejo scrive:

    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

    1. ikaro scrive:

      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?

  3. Marco scrive:

    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

    1. ikaro scrive:

      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 🙂

  4. enrico scrive:

    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…
    ???

    1. ikaro scrive:

      Che browser usi? Verifica nelle impostazioni del browser se può gestire il mime type “application/vnd.ms-excel”

  5. enrico scrive:

    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’?…

  6. Anonimo scrive:

    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*…

  7. Anonimo scrive:

    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

  8. Anonimo scrive:

    perchè non funziona se alla select aggiungo la condizione where

    grazie ciao

  9. Anonimo scrive:

    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

    1. ikaro scrive:

      Ciao Simon!

      Non ho afferrato bene, intendi l’allineamento nella cella di Excel?

      1. Anonimo scrive:

        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!

  10. Fabio scrive:

    Molti dei problemi sono dovuti a questa riga che è sbagliata:
    header(“Content-disposition: nomefile.xls”);

    quella corretta è:
    header(“Content-disposition: attachment;filename=nomefile.xls”);

  11. LINO scrive:

    Grazie!!!! E’ stato molto utile!!

  12. Iria scrive:

    Grazie! Funziona perfettamente con l’header corretto da Fabio 😀

  13. Lanfranco Giorgetti scrive:

    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

    1. ikaro scrive:

      Felice di essere stato utile 🙂

  14. Nicola scrive:

    Ho usato la sintassi indicata ma il server mi ritorna
    sempre un errore 500 di cui non riesco a trovare la causa…

  15. Lupogio scrive:

    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