web-dev-qa-db-fra.com

Interrogez mysql et exportez les données au format CSV dans PHP

J'ai myssql db avec différentes tables. Les données entre les tables sont liées et je les récupère et les affiche en utilisant l'ID utilisateur. J'ai utilisé la référence de PHP MYSQLi Afficher toutes les tables d'une base de données

Mais comment exporter ces informations sous forme de fichier csv? J'ai essayé au lieu de l'écho changé en une chaîne et imprimer la chaîne dans un fichier CSV mais cela ne fonctionne pas.

J'ai aussi essayé l'exemple de: http://sudobash.net/php-export-mysql-query-to-csv-file/

Mais je peux voir les données, mais en haut, il y a aussi de la malbouffe (comme "<font size='1'><table class='xdebug-error xe-notice' dir='ltr' border='1' cellspacing='0' cellpadding='1'>"
etc) à l'intérieur du fichier csv.

Y a-t-il une autre façon de faire cela?

7
aandroidtest

Si vous voulez écrire chaque ligne MySQL dans un fichier CSV, vous pouvez utiliser la fonction PHP5 intégrée dans fputcsv

$result = mysqli_query($con, 'SELECT * FROM table');
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);

$fp = fopen('file.csv', 'w');

foreach ($row as $val) {
    fputcsv($fp, $val);
}

fclose($fp);

Ce qui devrait retourner une chaîne séparée par des virgules pour chaque ligne écrite dans file.csv

row1 val1, row1 val2
row2 val1, row2 val2 
etc..

Veillez également à vérifier les autorisations pour le répertoire dans lequel vous écrivez.

13
dcd0181

C'est une solution qui incorpore les en-têtes ou les noms de champs en utilisant La fonctionfetch_fields de MySQLi - 

$query = "SELECT * FROM table";
$result = $db->query($query);
if (!$result) die('Couldn\'t fetch records');
$headers = $result->fetch_fields();
foreach($headers as $header) {
    $head[] = $header->name;
}
$fp = fopen('php://output', 'w');

if ($fp && $result) {
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename="export.csv"');
    header('Pragma: no-cache');
    header('Expires: 0');
    fputcsv($fp, array_values($head)); 
    while ($row = $result->fetch_array(MYSQLI_NUM)) {
        fputcsv($fp, array_values($row));
    }
    die;
}

C’est aussi une modification d’une réponse différente où une solution similaire a été suggérée mais que la partie en-tête ne m’a pas fonctionné, j’ai donc changé la méthode de récupération. Le crédit est dû à @Jrgns 

12
RCNeil

Vous pouvez essayer d'utiliser MySql INTO OUTFILE clause:

SELECT *
  INTO OUTFILE '/tmp/tablename.csv'
       FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
       LINES TERMINATED BY '\n'
   FROM tablename
  WHERE userid = 1
4
peterm

pour créer et télécharger un fichier csv à partir d'une requête mysqli (en utilisant un objet orienté), je pense que cela aiderait.

C'est une classe qui se connecte à la base de données et les fonctions feront tout ce que vous voulez en utilisant mysqli et PHP. Dans ce cas, en appelant cette classe (require ou include), utilisez simplement la fonction "downloadCsv ()".

A titre d'exemple, ce serait le fichier "class.php":

<?php
class DB{

private $con;

//this constructor connects with the database
public function __construct(){
$this->con = new mysqli("Your_Host","Your_User","Your_Pass","Your_DatabaseName");

if($this->con->connect_errno > 0){
    die('There was a problem [' . $con->connect_error . ']');
    }
}

//create the function that will download a csv file from a mysqli query

public function downloadCsv(){

$count = 0;
$header = "";
$data = "";
//query
$result = $this->con->query("SELECT * FROM Your_TableName");
//count fields
$count = $result->field_count;
//columns names
$names = $result->fetch_fields();
//put column names into header
foreach($names as $value) {
    $header .= $value->name.";";
    }
}
//put rows from your query
while($row = $result->fetch_row())  {
    $line = '';
    foreach($row as $value)       {
        if(!isset($value) || $value == "")  {
            $value = ";"; //in this case, ";" separates columns
    } else {
            $value = str_replace('"', '""', $value);
            $value = '"' . $value . '"' . ";"; //if you change the separator before, change this ";" too
        }
        $line .= $value;
    } //end foreach
    $data .= trim($line)."\n";
} //end while
//avoiding problems with data that includes "\r"
$data = str_replace("\r", "", $data);
//if empty query
if ($data == "") {
    $data = "\nno matching records found\n";
}
$count = $result->field_count;

//Download csv file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=FILENAME.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $header."\n".$data."\n";

}
?>

Après avoir créé le fichier "class.php", dans cet exemple, utilisez cette fonction sur le fichier "download.php":

<?php
//call the "class.php" file
require_once 'class.php';
//instantiate DB class
$export = new DB();
//call function
$export->downloadCsv();
?>

Après le téléchargement, ouvrez le fichier avec MS Excel.

J'espère que cela vous aidera, je pense que je l'ai bien écrit, je ne me sentais pas à l'aise avec le champ texte et code.

1
manuelmatas

Essayez ceci.

function addRowToCsv(& $csvString, $cols) {
    $csvString .= implode(',', $cols) . PHP_EOL; //Edits must be 6 characters - all I added was a "." before the =. :-)
}

$csvString = '';
$first = true;

while ($row = mysqli_fetch_assoc($query)) {
    if ($first === true) {
        $first = false;
        addRowToCsv($csvString, array_keys($row));
    }
    addRowToCsv($csvString, $row);
}

header('Content-type: text/csv');
header('Content-disposition: attachment;filename=MyCsvFile.csv');

echo $csvString;

Notez que le premier argument de addRowToCsv est passé par référence. Ce n'est pas obligatoire et vous pouvez facilement utiliser une valeur de retour, mais c'est exactement ce que je ferais.

Si vous souhaitez enregistrer le résultat dans un fichier plutôt que de le télécharger, utilisez ce qui précède, mais remplacez-le.

header('Content-type: text/csv');
header('Content-disposition: attachment;filename=MyCsvFile.csv');

echo $csvString;

Avec..

file_put_contents('MyCsvFile.csv', $csvString);
1
Tom Wright