2008-09-24 12 views
105

Jaki jest najbardziej efektywny sposób konwersji zapytania MySQL na CSV w PHP?Kod PHP do konwersji zapytania MySQL do CSV

Najlepiej byłoby unikać plików tymczasowych, ponieważ zmniejsza to przenośność (wymagane są ścieżki katalogów i wymagane ustawienia systemu plików).

Plik CSV powinien również zawierać jeden górny wiersz nazw pól.

+56

Dlaczego to pytanie zostało zamknięte jako nie konstruktywne? Ten jest w porządku i idealnie czysty. – Mario

+12

@Alec Ponieważ niektórzy moderatorzy są tutaj supermoderatorami, wiesz ... "Z supermoce przychodzi wielka odpowiedzialność!" - Wujek Ben – finitenessofinfinity

+16

@ Kompletność energii nieskończoności korumpuje, władza absolutna psuje absolutnie. Stackoverflow jest doskonałym tego przykładem. – Mario

Odpowiedz

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

(dokumentacja tego jest tutaj: http://dev.mysql.com/doc/refman/5.0/en/select.html)

czyli

$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

technicznie, jest to oddzielone tabulatorami;) –

+5

Zwróć uwagę na użycie ukośników w przód z "SELECT INTO OUTFILE" nawet w systemie Windows. – Johan

+1

Hii działa to dobrze dla formatu xls, ale jeśli próbuję zapisać jako plik CSV, pokazuje wszystkie wyniki w 1 kolumnie. Chcę zapisać to jako plik csv. –

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

Spójrz na documentation dotyczące składni 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; 
81

Sprawdź tę question/answer. Jest bardziej zwięzły niż @ Geoff, a także wykorzystuje wbudowaną funkcję 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; 
} 
+0

Twój nie ma nagłówków kolumn. –

+0

Dodałem nagłówki kolumn – Jrgns

+13

Jeśli ktoś jest tak głupi jak ja, nie zamieniaj 'php: // output' na rzeczywistą nazwę pliku lub spróbuj zamknąć na końcu' fclose': to nie jest prawdziwe plik, po prostu alias dla strumienia wyjściowego. Tak czy inaczej ta odpowiedź zadziałała idealnie, dzięki Jrgns! –

4

Jeśli chcesz pobieranie być oferowane do pobrania, które mogą być otwierane bezpośrednio w programie Excel, to może pracować dla Ciebie: (skopiowane ze starego niepublikowane projekt kopalni)

Te funkcje konfiguracja nagłówki:

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

Ten wysyła CSV do strumienia za pomocą rezultat 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; 
} 

Ten wykorzystuje powyższą funkcję napisać CSV do pliku, podane przez $ filename

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

I to gdzie magia dzieje;)

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

Na przykład:

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

Dzięki bardzo przydatny kod john. Musiał zmodyfikować linię dla funkcji csvFromResult. zamiast while ($ row = mysql_fetch_row ($ result)) { fputcsv ($ stream, $ row); $ rows ++; } , Musiałem użyć podczas ($ row = mysql_fetch_row ($ result)) { $ data [] = $ rząd; // fputcsv ($ stream, $ row); // $ rows ++; } foreach (dane: $ d) { fputcsv ($ stream, $ d); } . jeszcze raz dziękuję za tak wspaniały kod. – noobcode

15

Aktualizacja rozwiązania @jrgns (z niewielkimi różnicami w składni).

$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; 
} 
+0

Z jakiegoś powodu $ fp zwraca mi wartość false. – Volatil3