Code PHP pour convertir une requête MySQL en CSV [fermé]


128

Quel est le moyen le plus efficace de convertir une requête MySQL en CSV en PHP s'il vous plaît?

Il serait préférable d'éviter les fichiers temporaires car cela réduit la portabilité (chemins de répertoire et configuration des autorisations du système de fichiers requises).

Le CSV doit également inclure une ligne supérieure de noms de champ.


74
Pourquoi cette question a-t-elle été fermée comme non constructive? Celui-ci est beau et parfaitement clair.

14
@Alec Parce que certains modérateurs ici sont des super modérateurs, vous savez ... "Avec les superpuissances, il y a une grande responsabilité!" - Uncle Ben
finitenessofinfinity

18
Le pouvoir @finitenessofinfinity corrompt, le pouvoir absolu corrompt absolument. Stackoverflow en est un excellent exemple.

16
Je vote pour rouvrir cette question!
TN888

9
Six mois plus tard et j'utilise les réponses à cela dans mon site Web. Cela peut-il être rouvert?
Jon

Réponses:


138
SELECT * INTO OUTFILE "c:/mydata.csv"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n"
FROM my_table;

( la documentation à ce sujet est ici: http://dev.mysql.com/doc/refman/5.0/en/select.html )

ou:

$select = "SELECT * FROM table_name";

$export = mysql_query ( $select ) or die ( "Sql error : " . mysql_error( ) );

$fields = mysql_num_fields ( $export );

for ( $i = 0; $i < $fields; $i++ )
{
    $header .= mysql_field_name( $export , $i ) . "\t";
}

while( $row = mysql_fetch_row( $export ) )
{
    $line = '';
    foreach( $row as $value )
    {                                            
        if ( ( !isset( $value ) ) || ( $value == "" ) )
        {
            $value = "\t";
        }
        else
        {
            $value = str_replace( '"' , '""' , $value );
            $value = '"' . $value . '"' . "\t";
        }
        $line .= $value;
    }
    $data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );

if ( $data == "" )
{
    $data = "\n(0) Records Found!\n";                        
}

header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";

5
techniquement, c'est séparé par des tabulations;)
John Douthat

5
Notez l'utilisation de barres obliques avec SELECT INTO OUTFILEmême sur Windows.
Johan

1
Hii cela fonctionne bien pour le format xls mais si j'essaie d'enregistrer en tant que fichier CSV, tous les résultats s'affichent dans 1 colonne. Je veux l'enregistrer en tant que fichier csv.
vinod reddy

Parmi au-dessus de deux, lequel est le meilleur, le plus sûr et pourquoi?
Chella

1
J'aurais tendance à suggérer que la deuxième option est plus sûre car `SELECT INTO OUTFILE nécessite que l'utilisateur mysql ait accès au système de fichiers pour modifier les fichiers, ce qui représente un risque potentiellement important.
Jeepstone

91

Découvrez cette question / réponse . Il est plus concis que celui de @ Geoff et utilise également la fonction intégrée fputcsv.

$result = $db_con->query('SELECT * FROM `some_table`');
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++) {
    $headers[] = mysql_field_name($result , $i);
}
$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, $headers);
    while ($row = $result->fetch_array(MYSQLI_NUM)) {
        fputcsv($fp, array_values($row));
    }
    die;
}

1
Le vôtre n'a pas les en-têtes de colonne.
Paolo Bergantino

15
Au cas où quelqu'un d'autre serait aussi stupide que moi, ne le remplacez pas php://outputpar un nom de fichier réel ou n'essayez pas de le fermer par un fcloseà la fin: ce n'est pas un vrai fichier, juste un alias pour le flux de sortie. Quoi qu'il en soit, cette réponse a parfaitement fonctionné pour moi, merci Jrgns!
J.Steve

@ J.Steve Mon plaisir :)
Jrgns


1
mysql_num_fields () ne fonctionne pas pour moi et les en-têtes ne sont pas générés. Cette fonction est-elle obsolète ou quelque chose?
Doug

20

Consultez la documentation concernant la syntaxe SELECT ... INTO OUTFILE.

SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

18

Une mise à jour de la solution @jrgns (avec quelques légères différences de syntaxe).

$result = mysql_query('SELECT * FROM `some_table`'); 
if (!$result) die('Couldn\'t fetch records'); 
$num_fields = mysql_num_fields($result); 
$headers = array(); 
for ($i = 0; $i < $num_fields; $i++) 
{     
       $headers[] = mysql_field_name($result , $i); 
} 
$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, $headers); 
       while ($row = mysql_fetch_row($result)) 
       {
          fputcsv($fp, array_values($row)); 
       }
die; 
} 

Pour une raison quelconque, $ fp me renvoie false.
Volatil3

Pour MySQL moderne, vous pouvez utiliser: $ headers [] = mysqli_fetch_field_direct ($ result, $ i) -> nom;
Ben en Californie

Et changez les autres fonctions mysql_ en fonctions mysqli_.
Ben en Californie

6

Si vous souhaitez que le téléchargement soit proposé sous forme de téléchargement pouvant être ouvert directement dans Excel, cela peut fonctionner pour vous: (copié à partir d'un ancien projet inédit)

Ces fonctions configurent les en-têtes:

function setExcelContentType() {
    if(headers_sent())
        return false;

    header('Content-type: application/vnd.ms-excel');
    return true;
}

function setDownloadAsHeader($filename) {
    if(headers_sent())
        return false;

    header('Content-disposition: attachment; filename=' . $filename);
    return true;
}

Celui-ci envoie un CSV à un flux en utilisant un résultat mysql

function csvFromResult($stream, $result, $showColumnHeaders = true) {
    if($showColumnHeaders) {
        $columnHeaders = array();
        $nfields = mysql_num_fields($result);
        for($i = 0; $i < $nfields; $i++) {
            $field = mysql_fetch_field($result, $i);
            $columnHeaders[] = $field->name;
        }
        fputcsv($stream, $columnHeaders);
    }

    $nrows = 0;
    while($row = mysql_fetch_row($result)) {
        fputcsv($stream, $row);
        $nrows++;
    }

    return $nrows;
}

Celui-ci utilise la fonction ci-dessus pour écrire un CSV dans un fichier, donné par $ filename

function csvFileFromResult($filename, $result, $showColumnHeaders = true) {
    $fp = fopen($filename, 'w');
    $rc = csvFromResult($fp, $result, $showColumnHeaders);
    fclose($fp);
    return $rc;
}

Et c'est là que la magie opère;)

function csvToExcelDownloadFromResult($result, $showColumnHeaders = true, $asFilename = 'data.csv') {
    setExcelContentType();
    setDownloadAsHeader($asFilename);
    return csvFileFromResult('php://output', $result, $showColumnHeaders);
}

Par exemple:

$result = mysql_query("SELECT foo, bar, shazbot FROM baz WHERE boo = 'foo'");
csvToExcelDownloadFromResult($result);

1
Merci john code très utile. J'ai dû modifier une ligne pour la fonction csvFromResult. au lieu de while ($ row = mysql_fetch_row ($ result)) {fputcsv ($ stream, $ row); $ lignes ++; }, j'ai dû utiliser while ($ row = mysql_fetch_row ($ result)) {$ data [] = $ row; // fputcsv ($ stream, $ row); // $ lignes ++; } foreach ($ data as $ d) {fputcsv ($ stream, $ d); }. merci encore pour un code si merveilleux.
codingbbq

3
// Export to CSV
if($_GET['action'] == 'export') {

  $rsSearchResults = mysql_query($sql, $db) or die(mysql_error());

  $out = '';
  $fields = mysql_list_fields('database','table',$db);
  $columns = mysql_num_fields($fields);

  // Put the name of all fields
  for ($i = 0; $i < $columns; $i++) {
    $l=mysql_field_name($fields, $i);
    $out .= '"'.$l.'",';
  }
  $out .="\n";

  // Add all values in the table
  while ($l = mysql_fetch_array($rsSearchResults)) {
    for ($i = 0; $i < $columns; $i++) {
      $out .='"'.$l["$i"].'",';
    }
    $out .="\n";
  }
  // Output to browser with appropriate mime type, you choose ;)
  header("Content-type: text/x-csv");
  //header("Content-type: text/csv");
  //header("Content-type: application/csv");
  header("Content-Disposition: attachment; filename=search_results.csv");
  echo $out;
  exit;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.