2008-09-24 18 views
105

¿Cuál es la forma más eficiente de convertir una consulta MySQL a CSV en PHP, por favor?Código PHP para convertir una consulta MySQL a CSV

Sería mejor evitar los archivos temporales ya que esto reduce la portabilidad (rutas de directorios y configuración de permisos del sistema de archivos necesarios).

El CSV también debe incluir una línea superior de nombres de campo.

+56

¿Por qué esta pregunta se cerró como no constructiva? Este está bien y perfectamente claro. – Mario

+12

@Alec Porque algunos moderadores aquí son supermoderadores, ya sabes ... "¡Con las superpotencias viene una gran responsabilidad!" - El tío Ben – finitenessofinfinity

+16

@finitenessofinfinity power corrompe, el poder absoluto corrompe absolutamente. Stackoverflow es un excelente ejemplo de eso. – Mario

Respuesta

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

(la documentación para esto está aquí: http://dev.mysql.com/doc/refman/5.0/en/select.html)

o:

$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

técnicamente, esto está separado por tabulaciones;) –

+5

Tenga en cuenta el uso de barras diagonales con 'SELECT INTO OUTFILE' incluso en Windows. – Johan

+1

Hii esto funciona bien para el formato xls, pero si intento guardar como archivo CSV, muestra todos los resultados en 1 columna. Quiero guardar esto como un archivo 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

Mira el documentation con respecto a la sintaxis 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

Control hacia fuera este question/answer. Es más conciso que @ Geoff, y también usa la función incorporada 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

El suyo no tiene los encabezados de columna. –

+0

Agregué los encabezados de columna – Jrgns

+13

En caso de que alguien más sea tan estúpido como yo, no reemplace 'php: // output' con un nombre de archivo real o intente cerrarlo con un' fclose' al final: no es un verdadero archivo, solo un alias para la secuencia de salida. De todos modos, esta respuesta funcionó perfectamente para mí, gracias Jrgns! –

4

Si desea la descarga que se ofrece como una descarga que se pueden abrir directamente en Excel, esto puede funcionar para usted: (copiado de un viejo proyecto inédito mío)

Estas funciones configuración de las cabeceras:

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

Ésta envía un archivo CSV a una corriente usando un resultado 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; 
} 

Éste utiliza la función anterior para escribir un archivo CSV a un archivo, dada por $ archivo

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

Y aquí es donde sucede la magia;)

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

Por ejemplo:

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

Gracias a John un código muy útil. Tuvo que modificar una línea para la función csvFromResult. en lugar de while ($ row = mysql_fetch_row ($ result)) { fputcsv ($ stream, $ row); $ rows ++; } , tuve que usar while ($ row = mysql_fetch_row ($ result)) { $ data [] = $ row; // fputcsv ($ stream, $ fila); // $ rows ++; } foreach ($ data as $ d) { fputcsv ($ stream, $ d); } . gracias de nuevo por un código tan maravilloso. – noobcode

15

Una actualización de la solución @jrgns (con algunas diferencias de sintaxis leves).

$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

Por alguna razón $ fp me devuelve falso. – Volatil3