2010-11-22 21 views
114

Digamos que tengo una base de datos ... ¿hay alguna manera de exportar lo que tengo de la base de datos a un archivo CSV (y archivo de texto [si es posible]) a través de PHP?Exportar a CSV a través de PHP

+0

http://code.stephenmorley.org/php/creating-downloadable-csv-files/ –

Respuesta

239

Personalmente uso esta función para crear contenido CSV desde cualquier matriz.

function array2csv(array &$array) 
{ 
    if (count($array) == 0) { 
    return null; 
    } 
    ob_start(); 
    $df = fopen("php://output", 'w'); 
    fputcsv($df, array_keys(reset($array))); 
    foreach ($array as $row) { 
     fputcsv($df, $row); 
    } 
    fclose($df); 
    return ob_get_clean(); 
} 

A continuación, puede hacer que su usuario descargar ese archivo usando algo como: ejemplo

function download_send_headers($filename) { 
    // disable caching 
    $now = gmdate("D, d M Y H:i:s"); 
    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT"); 
    header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate"); 
    header("Last-Modified: {$now} GMT"); 

    // force download 
    header("Content-Type: application/force-download"); 
    header("Content-Type: application/octet-stream"); 
    header("Content-Type: application/download"); 

    // disposition/encoding on response body 
    header("Content-Disposition: attachment;filename={$filename}"); 
    header("Content-Transfer-Encoding: binary"); 
} 

Uso:

download_send_headers("data_export_" . date("Y-m-d") . ".csv"); 
echo array2csv($array); 
die(); 
+1

en el servidor local funciona, pero en el distante muestra una nueva página con contenido y sin ventana de descarga (perdón por mi inglés) –

+1

Puede haber varios motivos para los errores, la forma más sencilla de encontrarlos es ver el error de apache .archivo de registro. –

+0

Estoy intentando usar este ejemplo y lo que obtengo en el archivo CSV es mi fuente HTML de página completa en lugar de los resultados de la función array2csv()? –

25

Puede exportar la fecha usando este comando.

<?php 

$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd'), 
    array('123', '456', '789'), 
    array('"aaa"', '"bbb"') 
); 

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

foreach ($list as $fields) { 
    fputcsv($fp, $fields); 
} 

fclose($fp); 
?> 

En primer lugar debe cargar los datos desde el servidor MySQL en una matriz de

+9

O bien, puede hacer el fputcsv() dentro de un lazo assoc de búsqueda estándar y desplegarlo directamente desde los resultados devueltos. – DampeS8N

+8

@ DampeS8N, +1 para el uso de "plop down straight out" en una oración. – AnchovyLegend

9

recomiendo parsecsv-for-php de moverse por varios problemas con saltos de línea anidados y citas.

4

Al igual que @ Dampes8N dijo:

$result = mysql_query($sql,$conecction); 
$fp = fopen('file.csv', 'w'); 
while($row = mysql_fetch_assoc($result)){ 
    fputcsv($fp, $row); 
} 
fclose($fp); 

Espero que esto ayude.

+1

"fp = fopen ('archivo.csv', 'w'); " debería comenzar con $ fp, pero no se permiten 1 edición de carbonilla. – jay

12

Sólo para que conste, la concatenación es waaaaaay más rápido (lo digo en serio) que fputcsv o incluso implode; Y el tamaño del archivo es más pequeño:

// The data from Eternal Oblivion is an object, always 
$values = (array) fetchDataFromEternalOblivion($userId, $limit = 1000); 

// ----- fputcsv (slow) 
// The code of @Alain Tiemblo is the best implementation 
ob_start(); 
$csv = fopen("php://output", 'w'); 
fputcsv($csv, array_keys(reset($values))); 
foreach ($values as $row) { 
    fputcsv($csv, $row); 
} 
fclose($csv); 
return ob_get_clean(); 

// ----- implode (slow, but file size is smaller) 
$csv = implode(",", array_keys(reset($values))) . PHP_EOL; 
foreach ($values as $row) { 
    $csv .= '"' . implode('","', $row) . '"' . PHP_EOL; 
} 
return $csv; 
// ----- concatenation (fast, file size is smaller) 
// We can use one implode for the headers =D 
$csv = implode(",", array_keys(reset($values))) . PHP_EOL; 
$i = 1; 
// This is less flexible, but we have more control over the formatting 
foreach ($values as $row) { 
    $csv .= '"' . $row['id'] . '",'; 
    $csv .= '"' . $row['name'] . '",'; 
    $csv .= '"' . date('d-m-Y', strtotime($row['date'])) . '",'; 
    $csv .= '"' . ($row['pet_name'] ?: '-') . '",'; 
    $csv .= PHP_EOL; 
} 
return $csv; 

Esta es la conclusión de la optimización de varios informes, de diez a miles filas. Los tres ejemplos funcionaron bien bajo 1000 filas, pero falla cuando los datos eran más grandes.

3

trabaja con más de 100 líneas, si se especifica el tamaño del archivo en las cabeceras simple llamada al método get() en su propia clase

function setHeader($filename, $filesize) 
{ 
    // disable caching 
    $now = gmdate("D, d M Y H:i:s"); 
    header("Expires: Tue, 01 Jan 2001 00:00:01 GMT"); 
    header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate"); 
    header("Last-Modified: {$now} GMT"); 

    // force download 
    header("Content-Type: application/force-download"); 
    header("Content-Type: application/octet-stream"); 
    header("Content-Type: application/download"); 
    header('Content-Type: text/x-csv'); 

    // disposition/encoding on response body 
    if (isset($filename) && strlen($filename) > 0) 
     header("Content-Disposition: attachment;filename={$filename}"); 
    if (isset($filesize)) 
     header("Content-Length: ".$filesize); 
    header("Content-Transfer-Encoding: binary"); 
    header("Connection: close"); 
} 

function getSql() 
{ 
    // return you own sql 
    $sql = "SELECT id, date, params, value FROM sometable ORDER BY date;"; 
    return $sql; 
} 

function getExportData() 
{ 
    $values = array(); 

    $sql = $this->getSql(); 
    if (strlen($sql) > 0) 
    { 
     $result = dbquery($sql); // opens the database and executes the sql ... make your own ;-) 
     $fromDb = mysql_fetch_assoc($result); 
     if ($fromDb !== false) 
     { 
      while ($fromDb) 
      { 
       $values[] = $fromDb; 
       $fromDb = mysql_fetch_assoc($result); 
      } 
     } 
    } 
    return $values; 
} 

function get() 
{ 
    $values = $this->getExportData(); // values as array 
    $csv = tmpfile(); 

    $bFirstRowHeader = true; 
    foreach ($values as $row) 
    { 
     if ($bFirstRowHeader) 
     { 
      fputcsv($csv, array_keys($row)); 
      $bFirstRowHeader = false; 
     } 

     fputcsv($csv, array_values($row)); 
    } 

    rewind($csv); 

    $filename = "export_".date("Y-m-d").".csv"; 

    $fstat = fstat($csv); 
    $this->setHeader($filename, $fstat['size']); 

    fpassthru($csv); 
    fclose($csv); 
}