如何从 php 脚本创建和下载一个 csv 文件?

我是一个新手程序员,我搜索了很多关于我的问题,但找不到一个有用的解决方案或教程关于这一点。

我的目标是我有一个 PHP 数组和数组元素显示在一个列表中的页面。

我想添加一个选项,这样如果用户需要,他/她可以创建一个包含数组元素的 CSV 文件并下载它。

我不知道该怎么做。我也搜索了很多。但是还没有找到任何有用的资源。

请给我一些教程或解决方案或建议,以实现自己。由于我是一个新手,请提供易于实施的解决方案。

我的数组是这样的:

Array
(
[0] => Array
(
[fs_id] => 4c524d8abfc6ef3b201f489c
[name] => restaurant
[lat] => 40.702692
[lng] => -74.012869
[address] => new york
[postalCode] =>
[city] => NEW YORK
[state] => ny
[business_type] => BBQ Joint
[url] =>
)


)
333276 次浏览

您可以使用内置的 Fputcsv ()为您的数组生成正确的 csv 行从您的数组,所以您将不得不循环和收集行,像这样:

$f = fopen("tmp.csv", "w");
foreach ($array as $line) {
fputcsv($f, $line);
}

要让浏览器提供“另存为”对话框,您必须像下面这样发送 HTTP 头(请参阅 RFC中关于这个头的更多信息) :

header('Content-Disposition: attachment; filename="filename.csv";');

总而言之:

function array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
// open raw memory as file so no temp files needed, you might run out of memory though
$f = fopen('php://memory', 'w');
// loop over the input array
foreach ($array as $line) {
// generate csv lines from the inner arrays
fputcsv($f, $line, $delimiter);
}
// reset the file pointer to the start of the file
fseek($f, 0);
// tell the browser it's going to be a csv file
header('Content-Type: text/csv');
// tell the browser we want to save it instead of displaying it
header('Content-Disposition: attachment; filename="'.$filename.'";');
// make php send the generated csv lines to the browser
fpassthru($f);
}

你可以这样使用它:

array_to_csv_download(array(
array(1,2,3,4), // this array is going to be the first row
array(1,2,3,4)), // this array is going to be the second row
"numbers.csv"
);

更新:
取代 php://memory,你也可以使用 php://output作为文件描述符,去掉搜索和诸如此类的:

function array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="'.$filename.'";');


// open the "output" stream
// see http://www.php.net/manual/en/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-descriptioq
$f = fopen('php://output', 'w');


foreach ($array as $line) {
fputcsv($f, $line, $delimiter);
}
}

如果你的数组结构总是多维的,那么我们可以迭代这样的元素:

$fh = fopen('somefile.csv', 'w') or die('Cannot open the file');


for( $i=0; $i<count($arr); $i++ ){
$str = implode( ',', $arr[$i] );
fwrite( $fh, $str );
fwrite( $fh, "\n" );
}
fclose($fh);

这是一种方法... 你可以手动做,但这种方法更快,更容易理解和阅读。

Then you would manage your headers something what complex857 is doing to spit out the file. You could then delete the file using unlink() if you no longer needed it, or you could leave it on the server if you wished.

我没有足够的信誉来回复@Complex857解决方案。它工作得很好,但我必须添加; 在 Content-Disposition 标题的末尾。如果没有它,浏览器会在文件名的末尾添加两个破折号(例如,文件会被保存为“ export.csv ——”,而不是“ export.csv”)。也许它试图在标题行的末尾消毒 r n。

Correct line should look like this:

header('Content-Disposition: attachment;filename="'.$filename.'";');

In case when CSV has UTF-8 chars in it, you have to change the encoding to UTF-8 by changing the Content-Type line:

header('Content-Type: application/csv; charset=UTF-8');

另外,我发现使用 rewind ()而不是 ffind ()更为优雅:

rewind($f);

谢谢你的解答!

Try... Csv 下载。

<?php
mysql_connect('hostname', 'username', 'password');
mysql_select_db('dbname');
$qry = mysql_query("SELECT * FROM tablename");
$data = "";
while($row = mysql_fetch_array($qry)) {
$data .= $row['field1'].",".$row['field2'].",".$row['field3'].",".$row['field4']."\n";
}


header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="filename.csv"');
echo $data; exit();
?>

使用下面的代码将 php 数组转换为 CSV

<?php
$ROW=db_export_data();//Will return a php array
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
$fp = fopen('php://output', 'w');


foreach ($ROW as $row) {
fputcsv($fp, $row);
}
fclose($fp);

这是我在项目中使用的函数,它的工作原理与预期的一样。

function array_csv_download( $array, $filename = "export.csv", $delimiter=";" )
{
header( 'Content-Type: application/csv' );
header( 'Content-Disposition: attachment; filename="' . $filename . '";' );


// clean output buffer
ob_end_clean();
    

$handle = fopen( 'php://output', 'w' );


// use keys as column titles
fputcsv( $handle, array_keys( $array['0'] ), $delimiter );


foreach ( $array as $value ) {
fputcsv( $handle, $value, $delimiter );
}


fclose( $handle );


// flush buffer
ob_flush();
    

// use exit to get rid of unexpected output afterward
exit();
}

UTF-8编码更新

更新@plex 857的答案

function array_to_csv_download($array, $filename = "export.csv", $delimiter=",") {
header('Content-Disposition: attachment; filename="'.$filename.'";');
header('Content-Type: application/csv; charset=UTF-8');


// open the "output" stream
$f = fopen('php://output', 'w');
// Write utf-8 bom to the file
fputs($f, chr(0xEF) . chr(0xBB) . chr(0xBF));


foreach ($array as $line) {
fputcsv($f, $line, $delimiter);
}
}

May be a bit ugly code but it works!

这个函数可以生成一个可下载的 CSV 文件,可以设置名称和分隔符,不需要复杂的函数 (头部函数中的 UTF-8编码)。

/**
* Array2CSVDownload
*
*/
function Array2CSVDownload($array, $filename = "export.csv", $delimiter=";") {


// force object to be array, sorry i was working with object items
$keys = array_keys( (array) $array[0] );
// use keys as column titles
$data = [];
array_push($data, implode($delimiter, $keys));
// working with items
foreach ($array as $item) {
$values = array_values((array) $item);
array_push($data, implode($delimiter, $values));
}
// flush buffer
ob_flush();
// mixing items
$csvData = join("\n", $data);
//setup headers to download the file
header('Content-Disposition: attachment; filename="'.$filename.'";');
//setup utf8 encoding
header('Content-Type: application/csv; charset=UTF-8');
// showing the results
die($csvData);


}