PHP-Code zum Konvertieren einer MySQL-Abfrage in CSV [geschlossen]

128

Was ist der effizienteste Weg, um eine MySQL-Abfrage in PHV in PHP zu konvertieren?

Es ist am besten, temporäre Dateien zu vermeiden, da dies die Portabilität verringert (Verzeichnispfade und Festlegen von Dateisystemberechtigungen erforderlich).

Die CSV sollte auch eine oberste Zeile mit Feldnamen enthalten.

Reilly Beacom
quelle
73
Warum wurde diese Frage als nicht konstruktiv geschlossen? Dieser ist in Ordnung und vollkommen klar.
14
@Alec Weil einige Moderatoren hier Supermoderatoren sind, weißt du ... "Mit Supermächten geht große Verantwortung einher!" - Onkel Ben
Endlichkeit der
18
@ Endlichkeit der Unendlichkeit Macht korrumpiert, absolute Macht korrumpiert absolut. Stackoverflow ist ein hervorragendes Beispiel dafür.
16
Ich stimme dafür, diese Frage erneut zu eröffnen!
TN888
9
Sechs Monate später verwende ich die Antworten auf meine Website. Kann dies wieder geöffnet werden?
Jon

Antworten:

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

( Die Dokumentation hierzu finden Sie hier: http://dev.mysql.com/doc/refman/5.0/en/select.html )

oder:

$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";
Geoff
quelle
5
technisch ist dies tabulatorgetrennt;)
John Douthat
5
Beachten Sie die Verwendung von Schrägstrichen SELECT INTO OUTFILEauch unter Windows.
Johan
1
Hi, das funktioniert gut für das XLS-Format, aber wenn ich versuche, es als CSV-Datei zu speichern, werden alle Ergebnisse in einer Spalte angezeigt. Ich möchte dies als CSV-Datei speichern.
Vinod Reddy
Welches der beiden oben genannten ist besser, sicherer und warum?
Chella
1
Ich würde eher vorschlagen, dass die zweite Option sicherer ist, da `SELECT INTO OUTFILE erfordert, dass der MySQL-Benutzer Zugriff auf das Dateisystem hat, um Dateien zu ändern, was ein potenziell großes Risiko darstellt.
Jeepstone
91

Schauen Sie sich diese Frage / Antwort an . Es ist prägnanter als das von @ Geoff und verwendet auch die integrierte Funktion 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;
}
Jrgns
quelle
1
Ihre hat nicht die Spaltenüberschriften.
Paolo Bergantino
15
Falls jemand so dumm ist wie ich, ersetzen Sie ihn nicht durch php://outputeinen tatsächlichen Dateinamen oder versuchen Sie, ihn fcloseam Ende durch einen zu schließen : Es handelt sich nicht um eine echte Datei, sondern nur um einen Alias ​​für den Ausgabestream. Wie auch immer, diese Antwort hat perfekt für mich funktioniert, danke Jrgns!
J.Steve
@ J.Steve Es ist mir ein Vergnügen :)
Jrgns
10
Verwenden von mysqli: gist.github.com/jaredrummler/2bfcf48b48d3fefd50c2
Jared Rummler
1
mysql_num_fields () funktioniert bei mir nicht und Header werden nicht generiert. Ist diese Funktion veraltet oder so?
Doug
20

Lesen Sie die Dokumentation zur Syntax 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;
nickf
quelle
18

Ein Update auf die Lösung @jrgns (mit einigen geringfügigen Syntaxunterschieden).

$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; 
} 
John M.
quelle
Aus irgendeinem Grund gibt $ fp false an mich zurück.
Volatil3
Für modernes MySQL können Sie Folgendes verwenden: $ headers [] = mysqli_fetch_field_direct ($ result, $ i) -> name;
Ben in CA
Und ändern Sie die anderen mysql_-Funktionen in mysqli_-Funktionen.
Ben in CA
6

Wenn Sie möchten, dass der Download als Download angeboten wird, der direkt in Excel geöffnet werden kann, funktioniert dies möglicherweise für Sie: (kopiert von einem alten unveröffentlichten Projekt von mir)

Diese Funktionen richten die Header ein:

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;
}

Dieser sendet eine CSV mit einem MySQL-Ergebnis an einen Stream

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;
}

Dieser verwendet die obige Funktion, um eine CSV in eine Datei zu schreiben, die durch $ filename angegeben wird

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

Und hier passiert die Magie;)

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

Beispielsweise:

$result = mysql_query("SELECT foo, bar, shazbot FROM baz WHERE boo = 'foo'");
csvToExcelDownloadFromResult($result);
John Douthat
quelle
1
Danke John sehr nützlicher Code. Musste eine Zeile für die Funktion csvFromResult ändern. anstelle von while ($ row = mysql_fetch_row ($ result)) {fputcsv ($ stream, $ row); $ rows ++; }, ich musste while verwenden ($ row = mysql_fetch_row ($ result)) {$ data [] = $ row; // fputcsv ($ stream, $ row); // $ rows ++; } foreach ($ data als $ d) {fputcsv ($ stream, $ d); }. Nochmals vielen Dank für diesen wunderbaren Code.
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;
}
Wayne
quelle