PHP : générer un fichier csv à partir d’une base de données MySQL

PHP : générer un fichier csv à partir d'une base de données MySQL

Nous allons voir dans ce tutoriel comment générer simplement un fichier CSV à partir d’une base de données MySQL. Commençons par créer notre table, celle qui va nous servir d’exemple dans ce tutoriel. Vous pouvez le créer visuellement si vous avez par exemple un gestionnaire de base de données comme PhpMyAdmin.

Nous allons considérer que notre base s’appelle tuto et contient une table eleves avec pour colonnes idnomprenommoyenne. Voilà un petit code sql pour créer cette table : 

CREATE TABLE eleves (
    id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
    nom VARCHAR(100),
    prenom VARCHAR(100),
    moyenne FLOAT
) ENGINE=INNODB;

Insérons ces enregistrements : 

NomPrénomMoyenne
BaloZiétin13.5
SossouGérard15
AgboAli14.75
TossaUrbain16

Le code sql pour créer ces enregistrements : 

INSERT INTO `eleves` (`id`, `nom`, `prenom`, `moyenne`) VALUES (NULL, 'Balo', 'Ziétin', '13.50'), (NULL, 'Sossou', 'Gérard', '15'), (NULL, 'Agbo', 'Ali', '14.75'), (NULL, 'Tossa', 'Urbain', '16');

Maintenant que nous avons ces enregistrements dans notre table, nous allons les extraire et avec ces informations, générer un fichier CSV.

Commençons par nous connecter à notre base de données. Utilisez vos propres identifiants le cas échéant :

<?php
    // connexion à la base de données. Renseignez vos propres identifiants
    $bd = new PDO("mysql:host=localhot;dbname=tuto", "root", "");
?>

Nous allons maintenant créer un tableau qui va recevoir la structure de notre fichier CSV : 

    $tabeleves = [];
    $tabeleves[] = ['NOM', 'PRENOMS', 'MOYENNE'];
    $tabeleves[] = ['', '', ''];

La deuxième ligne constitue les libellés des colonnes de notre fichier. La troisième ligne permet juste d’espacer les libellés des enregistrements.

Récupérons tous nos enregistrements : 

<?php
    $r = $bd->query('SELECT * FROM eleves');
?>

Parcourons ces enregistrements et insérons les dans notre tableau.

<?php
    while($rs = $r->fetch(PDO::FETCH_ASSOC)){
        $tabeleves[] = [$rs['nom'], $rs['prenom'], $rs['moyenne']];
    }
?>

On prépare notre fichier CSV pour la lecture et l’écriture : 

<?php
    $fichier_csv = fopen("eleves.csv", "w+");
?>

Le premier paramètre de fopen définit le chemin du fichier csv et le deuxième paramère définit le mode d’accès. Vous avez la documentation ici

Gérons le BOM du fichier ou en résumé disons l’encodage du fichier pour afficher correctement par exemple les caractères accentués :

<?php
    fprintf($fichier_csv, chr(0xEF).chr(0xBB).chr(0xBF));
?>

Parcourons notre tableau et écrivons dans le fichier CSV avec la fonction fputcsv

<?php
    foreach($tabeleves as $ligne){
        fputcsv($fichier_csv, $ligne, ";");
    }
?>

Le dernier paramètre de la fonction représente le délimiteur qui est généralament un « ; » pour les fichiers CSV.

Fermons maintenant notre fichier : 

<?php
    fclose($fichier_csv);
?>

Et voilà le code complet : 

<?php
    // connexion à la base de données. Renseignez vos propres identifiants
    $bd = new PDO("mysql:host=localhost;dbname=tuto", "root", "");
    $r = $bd->query('SELECT * FROM eleves');

    $tabeleves = [];
    $tabeleves[] = ['NOM', 'PRENOMS', 'MOYENNE'];
    $tabeleves[] = ['', '', ''];

    while($rs = $r->fetch(PDO::FETCH_ASSOC)){
        $tabeleves[] = [$rs['nom'], $rs['prenom'], $rs['moyenne']];
    }
    
    $fichier_csv = fopen("eleves.csv", "w+");

    fprintf($fichier_csv, chr(0xEF).chr(0xBB).chr(0xBF));

    foreach($tabeleves as $ligne){
        fputcsv($fichier_csv, $ligne, ";");
    }

    fclose($fichier_csv);
?>

Si les caractères accentués ne s’affichent pas toujours correctement, vous pouvez insérer cette ligne dans la boucle foreach:

$ligne = array_map("utf8_decode", $ligne);

Nous avons utilisé la fonction array_map pour agir sur chaque élément du tableau en renseignant une fonction qui est ici utf8_decode.

et le code devient :

<?php
    // connexion à la base de données. Renseignez vos propres identifiants
    $bd = new PDO("mysql:host=localhost;dbname=tuto", "root", "");
    $r = $bd->query('SELECT * FROM eleves');

    $tabeleves = [];
    $tabeleves[] = ['NOM', 'PRENOMS', 'MOYENNE'];
    $tabeleves[] = ['', '', ''];

    while($rs = $r->fetch(PDO::FETCH_ASSOC)){
        $tabeleves[] = [$rs['nom'], $rs['prenom'], $rs['moyenne']];
    }
    
    $fichier_csv = fopen("eleves.csv", "w+");

    fprintf($fichier_csv, chr(0xEF).chr(0xBB).chr(0xBF));

    foreach($tabeleves as $ligne){
        $ligne = array_map("utf8_decode", $ligne);
        fputcsv($fichier_csv, $ligne, ";");
    }

    fclose($fichier_csv);
?>

Pour une version PHP 5 >= 5.4.0, le code peut devenir ceci en utilisant la class SplFileObject et sa méthode fputcsv. Alors, le code peut devenir :

<?php
    // connexion à la base de données. Renseignez vos propres identifiants
    $bd = new PDO("mysql:host=localhost;dbname=tuto", "root", "");
    $r = $bd->query('SELECT * FROM eleves');

    $tabeleves = [];
    $tabeleves[] = ['NOM', 'PRENOMS', 'MOYENNE'];
    $tabeleves[] = ['', '', ''];

    while($rs = $r->fetch(PDO::FETCH_ASSOC)){
        $tabeleves[] = [$rs['nom'], $rs['prenom'], $rs['moyenne']];
    }
    
    $fichier_csv = new SplFileObject('eleves.csv', 'w');

    foreach($tabeleves as $ligne){
        $ligne = array_map("utf8_decode", $ligne);
        $fichier_csv->fputcsv($ligne, ';');
    }
?>

4 réactions sur “ PHP : générer un fichier csv à partir d’une base de données MySQL ”

  1. Eric

    Bonjour

    malgré le unicode_8 mon fichier n’a pas les caractères accentués
    mais si je le charge dans openoffice en mettant latin 3 là c’est bon
    comment puis je le coder directement ?

    Merci

    • lookman Auteur Article

      Re bonsoir,
      le fichier de sortie est déjà à l’emplacement voulu quand vous utilisez par exemple fopen(). Le premier paramètre définit le nom/emplacement du fichier.
      C’est le même cas pour SplFileObject()

      Maintenant si vous voulez faire télécharger le fichier par vos visiteurs, vous pouvez simplement utiliser un lien avec l’attribut download (Nom du lien)

Laisser un commentaire