2010-11-22 135 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); 
}