2010-11-22 137 views
114

比方说,我有一个数据库....有没有一种方法可以通过PHP将我从数据库中导出的数据导出到CSV文件(以及文本文件[如果可能])?通过PHP导出到CSV

+0

http://code.stephenmorley.org/php/created-downloadable-csv-files/ – 2016-01-27 05:14:56

回答

239

我个人使用此函数从任何数组创建CSV内容。

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

然后你就可以让你的用户使用类似下载文件:

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

用例:

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

它在本地服务器上工作,但在遥远的一个它显示一个新的页面,内容和没有下载窗口(对不起,我的英语) – 2012-12-28 08:27:15

25

您可以使用此命令导出日期。

<?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); 
?> 

首先,你必须加载从MySQL服务器的数据到一个数组

+9

或者,您可以在标准提取关联循环内执行fputcsv(),并将其直接从返回的结果中删除。 – DampeS8N 2010-11-22 19:38:01

+8

@ DampeS8N,+1在使用“直接倒掉”一句中。 – AnchovyLegend 2013-12-31 19:31:20

4

就像@ Dampes8N说:

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

希望这可以帮助。

12

只是为了记录在案,串联比fputcsv甚至implode waaaaaay更快(我的意思是);并且文件大小更小:

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

这是几个报告的优化结论,从10行到数千行。这三个例子在1000行下工作正常,但数据较大时失败。

3

与超过100行,如果您指定的文件的大小在头 简单调用get()方法在自己的类

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