picture picture
janvier 11, 2018 Excel, MySQL, PHP 5 Commentaires

Export d’une table MYSQL au format CSV… sans message d’erreur

La solution traditionnelle en PHP était de créer un tableau HTML : comment exporter une table MYSQL au format CSV sans message d'erreur ?Pour générer en PHP un fichier au format Excel (.xls ou .csv), la solution traditionnelle était de créer un tableau HTML, dont chaque ligne (<TD></TD>) correspondait à un tuple de la table MySQL exportée en boucle.

Oui, mais… si Excel sait lire le format HTML, les versions récentes affichent un désagréable message à l’ouverture du fichier pour signifier que le langage qu’on lui impose n’est pas le sien :
« Le format et l’extension du fichier « xxx.csv » ne correspondent pas. Le fichier peut présenter un risque ou avoir été endommagé. Ne l’ouvrez pas, à moins que la source soit fiable. Voulez-vous quand même l’ouvrir ? »

Comme quoi, le multiculturalisme ça ne marche pas pour les fichiers non plus… :lol:

 

L’appel du fichier CSV que l’on va créer via PHP est un simple lien vers le fichier de création du CSV, nommé ici csv_export.php :

<a href="csv_export.php"> Exporter la table MaTable au format CSV </a>
									

Pour éviter ce désagréable message à l’ouverture du fichier exporté par un simple clic sur ce lien :

…la solution est simple. Il faut préalablement créer dynamiquement un vrai fichier CSV, puis à le remplit en boucle en respectant ses codes de séparation (;) et de retour à la ligne.

Je vous propose ci-dessous 2 codes : l’un destiné aux versions PHP « anciennes » (bref, antérieures à PHP 7 !), et l’autre pour PHP7 (mais il est rétrocompatible à partir des versions PHP 5.xx) :

Versions PHP 4 et 5 :

<?php
// Nom de la table à exporter
$db_record = 'MaTable';

// En option : conditionnels de la requête d'export (WHERE, ORDER BY, LIMIT, etc.)
$where = '';

// Nom du fichier CSV à exporter
$csv_filename = $db_record.'_'.date('Y-m-d').'.csv';

// Variables de connexion à la base des données
$hostname = "localhost";
$user = "root";
$password = "MonMotDepasse";
$database = "MaBase";

// Connexion à la base
mysql_connect($hostname, $user, $password)
or die('Could not connect: ' . mysql_error());        
mysql_select_db($database)
or die ('Echec de la connexion : ' . mysql_error());

/* Si vous avez des erreurs d'accents dans les données extraites, selon l'encodage de la base :
@mysql_query("SET CHARACTER SET 'UTF8'");  */

// Création d'un fichier CSV vide
$csv_export = '';

// Extraction des données de la table
$query = mysql_query("SELECT * FROM ".$db_record." ".$where);
$field = mysql_num_fields($query);

// Création de la ligne des titres (noms des champs)
for($i = 0; $i < $field; $i++) {
  $csv_export.= mysql_field_name($query,$i).';';
}

// Nouvelle ligne (semble fonctionner avec Linux & Windows servers)
$csv_export.= '
';

// Boucle des tuples pour remplir le fichier
while($row = mysql_fetch_array($query)) {
  for($i = 0; $i < $field; $i++) {
    $csv_export.= '"'.$row[mysql_field_name($query,$i)].'";';
  }  
  $csv_export.= '
';  
}

// Export des données au format CSV et appel du fichier créé pour téléchargement
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=".$csv_filename."");
echo($csv_export);
?>
									

Version PHP  7

(les fonctions mysqli ont juste remplacé les fonctions mysql)

<?php
// Nom de la table à exporter
$db_record = 'MaTable';

// En option : conditionnels de la requête d'export (WHERE, ORDER BY, LIMIT, etc.)
$where = '';

// Nom du fichier CSV à exporter
$csv_filename = $db_record.'_'.date('Y-m-d').'.csv';

// Variables de connexion à la base des données
$hostname = "localhost";
$user = "root";
$password = "MonMotDepasse";
$database = "MaBase";
$port = 3306;

// Connexion à la base
$conn = mysqli_connect($hostname, $user, $password, $database, $port);
if (mysqli_connect_errno()) {
    die("Echec de la connexion : " . mysqli_connect_error());
}
/* si vous avez des erreurs d'accents dans les données extraites, selon l'encodage de la base :
// latin1 > UTF8
mysqli_set_charset($conn, "utf8");
// ou UTF8 > ISO-8859-1
mysqli_set_charset($conn, "latin1"); */

// Création d'un fichier CSV vide
$csv_export = '';

// Extraction des données de la table
$query = mysqli_query($conn, "SELECT * FROM ".$db_record." ".$where);
$field = mysqli_field_count($conn);

// Création de la ligne des titres (noms des champs)
for($i = 0; $i < $field; $i++) {
    $csv_export.= mysqli_fetch_field_direct($query, $i)->name.';';
}

// Nouvelle ligne (semble fonctionner avec Linux & Windows servers)
$csv_export.= '
';

// Boucle des tuples pour remplir le fichier
while($row = mysqli_fetch_array($query)) {
    for($i = 0; $i < $field; $i++) {
        $csv_export.= '"'.$row[mysqli_fetch_field_direct($query, $i)->name].'";';
    }
    $csv_export.= '
';
}

// Export des données au format CSV et appel du fichier créé pour téléchargement
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=".$csv_filename."");
echo($csv_export);
?>
									

Testé et approuvé !

Sources : Alsacréation et GitHubGist

 

5 Responses to “Export d’une table MYSQL au format CSV… sans message d’erreur”

5 Commentaires

  1. mikadou dit :

    Un grand merci

  2. webtolosa dit :

    Fais le sur ton Excel, il y a en pour 10 secondes !… Je ne pense pas qu’il y ait une fonction dans PHPMyadmin pour faire ça ?

  3. elitim dit :

    Merci webtolosa pour ce travail. Après avoir chercher et tester partout, j’ai pu faire mon export sans problème… et en français avé l’assen dit !

    Une petite question. COMMENT renommer mes champs de la base à la volée AVANT l’export ?

    Exemple renommer un champ appelé « date_dinter » par «Date» etc…
    Je peux le faire ensuite dans le tableau excell mais bon…

  4. webtolosa dit :

    Peut-être un pb de configuration de ton PHP ?

  5. chris dit :

    merci pour ce script, ca passe très bien, je viens de remarquer seulement lors de l’ouverture du fichier exporter s’affiche mais tourne en boucle;
    Merci encore une fois

Commentaire

Name

Mail (ne sera pas publié)

Website

Laisser ces deux champs tels quels :
:D :-) :( :o 8O :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: