如果你需要直接将 CSV 文件发送到浏览器,而无需写入外部文件,你可以打开输出并对它使用 fputcsv。
<?php
$out = fopen('php://output', 'w');
fputcsv($out, array('this','is some', 'csv "stuff", you know.'));
fclose($out);
?>
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
fputcsv — 将行格式化为 CSV 并写入文件指针
$stream
,$fields
,$separator
= ",",$enclosure
= "\"",$escape
= "\\",$eol
= "\n"
fputcsv() 将一行(作为 fields
数组传递)格式化为 CSV,并将其(以换行符结尾)写入指定的文件 stream
。
stream
文件指针必须有效,并且必须指向由 fopen() 或 fsockopen() 成功打开(尚未由 fclose() 关闭)的文件。
fields
一个 字符串 数组。
separator
可选的 separator
参数设置字段分隔符(只能是一个单字节字符)。
enclosure
可选的 enclosure
参数设置字段围封符(只能是一个单字节字符)。
escape
可选的 escape
参数设置转义字符(最多一个单字节字符)。空字符串 (""
) 将禁用专有的转义机制。
eol
可选的 eol
参数设置自定义换行符序列。
注意:
如果一个字段中包含
enclosure
字符,它将被双重转义,除非它紧接在escape
之后。
如果成功,则返回写入的字符串长度,否则返回 false
。
版本 | 描述 |
---|---|
8.1.0 | 添加了可选的 eol 参数。 |
7.4.0 | escape 参数现在也接受空字符串来禁用专有的转义机制。 |
示例 #1 fputcsv() 示例
<?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);
?>
上面的示例将以下内容写入 file.csv
aaa,bbb,ccc,dddd 123,456,789 """aaa""","""bbb"""
注意: 如果 PHP 在读取文件时无法正确识别换行符,无论是 Mac 上的文件还是 Mac 上创建的文件,启用 auto_detect_line_endings 运行时配置选项可能有助于解决问题。
如果你需要直接将 CSV 文件发送到浏览器,而无需写入外部文件,你可以打开输出并对它使用 fputcsv。
<?php
$out = fopen('php://output', 'w');
fputcsv($out, array('this','is some', 'csv "stuff", you know.'));
fclose($out);
?>
如果你需要将输出保存到变量中(例如,用于框架内),你可以写入临时内存包装器并检索其内容
<?php
// 最多 5MB 的输出将保留在内存中,如果超过此大小,它将自动写入临时文件
$csv = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
fputcsv($csv, array('blah','blah'));
rewind($csv);
// 将所有内容放入变量中
$output = stream_get_contents($csv);
?>
有时将 CSV 行作为字符串获取很有用。例如,将其存储在某个位置,而不是文件系统中。
<?php
function csvstr(array $fields) : string
{
$f = fopen('php://memory', 'r+');
if (fputcsv($f, $fields) === false) {
return false;
}
rewind($f);
$csv_line = stream_get_contents($f);
return rtrim($csv_line);
}
?>
如果你想为 Excel 创建 UTF-8 文件,请使用以下代码
$fp = fopen($filename, 'w');
// 添加 BOM 来修复 Excel 中的 UTF-8
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
请注意,fputcsv 并不总是使用围封符将字符串围起来。
<?php
$fh = fopen('file.csv', 'w');
$a = [ 'One 1', 'Two', 'Three 3' ];
fputcsv($fh, $a, "\t");
fclose($fh);
?>
结果是在文件中包含以下行
"One 1" Two "Three 3"
似乎只有包含以下至少一个字符的字符串才会被围起来
- 分隔符
- 围封符
- 转义字符
- \n (换行)
- \r (回车)
- \t (制表符)
- 空白
我希望这能为你节省我花了一个小时才找到这种行为根源的时间。
在所有这些情况下,你需要一个没有 bug 的 csv 写入器,它具有自定义记录分隔功能。
<?php
/**
* 自定义 fputcsv
* @param int $handle 文件句柄
* @param mixed[] $fields 要写入的值数组
* @param string $delimiter 字段分隔符
* @param string $enclosure 字段包围符
* @param string $escape_char 转义包围符在字段中的字符
* @param string $record_seperator
* @return int 写入的字符数
*/
function _fputcsv($handle, $fields, $delimiter = ",", $enclosure = '"', $escape_char = "\\", $record_seperator = "\r\n")
{
$result = [];
foreach ($fields as $field) {
$result[] = $enclosure . str_replace($enclosure, $escape_char . $enclosure, $field) . $enclosure;
}
return fwrite($handle, implode($delimiter, $result) . $record_seperator);
}
?>
制表符分隔。
使用 fputcsv 输出带有制表符分隔符的 CSV 有点棘手,因为分隔符字段只能接受一个字符。
答案是使用 chr() 函数。制表符的 ASCII 代码是 9,所以 chr(9) 返回一个制表符字符。
<?php
fputcsv($fp, $foo, '\t'); // 不起作用
fputcsv($fp, $foo, ' '); // 不起作用
fputcsv($fp, $foo, chr(9)); // 起作用
?>
==================
它应该是
<?php
fputcsv($fp, $foo, "\t");
?>
你只是忘记了单引号是文字...这意味着你在那里放什么就会输出什么,所以 '\t' 就和 't' 一样,因为在这种情况下 \ 仅用于转义,但如果你使用双引号,那就会起作用。
以下是如何解决将数组转换为 csv 文件时的编码问题的解决方案。
$fp = fopen('php://memory', 'w');
// 添加 BOM 来修复 Excel 中的 UTF-8
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
// 输出列标题
//fputcsv($fp, array('Topic', 'Title', 'URL', 'Keywords', 'Score', 'FB_count', 'TW_count', '|'));
if(isset($trend)){
foreach ( $trend as $myField ){
fputcsv($fp, $myField, '|');
}
}
实用程序函数,用于将 mysql 查询输出到 csv,并可以选择写入文件或以 csv 附件的形式发送回浏览器。
<?php
function query_to_csv($db_conn, $query, $filename, $attachment = false, $headers = true) {
if($attachment) {
// 向浏览器发送响应头
header( 'Content-Type: text/csv' );
header( 'Content-Disposition: attachment;filename='.$filename);
$fp = fopen('php://output', 'w');
} else {
$fp = fopen($filename, 'w');
}
$result = mysql_query($query, $db_conn) or die( mysql_error( $db_conn ) );
if($headers) {
// 输出标题行(如果至少存在一行)
$row = mysql_fetch_assoc($result);
if($row) {
fputcsv($fp, array_keys($row));
// 将指针重置回开头
mysql_data_seek($result, 0);
}
}
while($row = mysql_fetch_assoc($result)) {
fputcsv($fp, $row);
}
fclose($fp);
}
// 使用该函数
$sql = "SELECT * FROM table";
// $db_conn 应该是一个有效的数据库句柄
// 以附件形式输出
query_to_csv($db_conn, $sql, "test.csv", true);
// 输出到文件系统
query_to_csv($db_conn, $sql, "test.csv", false);
?>
我已经创建了一个函数,可以快速生成与 Microsoft 应用程序一起使用的 CSV 文件。在这个领域,我学到了一些关于生成 CSV 的不那么显而易见的事情。首先,由于 PHP 通常是基于 *nix 的,所以行尾总是 \n 而不是 \r\n 这是有道理的。但是,某些 Microsoft 程序(我指的是你,Access 97)除非每行以 \r\n 结尾,否则无法正确识别 CSV。因此,此函数会相应地更改行尾。其次,如果 CSV 文件的第一列标题/值以大写 ID 开头,某些 Microsoft 程序(咳咳,Excel 2007)会将该文件解释为 SYLK 格式而不是 CSV,如这里所述:http://support.microsoft.com/kb/323626
此函数也为此提供支持,通过强制将第一个值包含在引号中(当这种情况不会自动发生时)。修改此函数以使用其他分隔符将非常简单,我把它留作读者的练习。简而言之,此函数用于以对 Windows 应用程序安全的方式将 CSV 数据输出到 CSV 文件。它接受两个参数 + 一个可选参数:文件保存位置、数据行数组和可选的列标题数组。(从技术上讲,你可以省略标题数组,只需将其包含为数据的第一行,但在实践中,将这些数据存储在不同的数组中通常很有用。)
<?php
function mssafe_csv($filepath, $data, $header = array())
{
if ( $fp = fopen($filepath, 'w') ) {
$show_header = true;
if ( empty($header) ) {
$show_header = false;
reset($data);
$line = current($data);
if ( !empty($line) ) {
reset($line);
$first = current($line);
if ( substr($first, 0, 2) == 'ID' && !preg_match('/["\\s,]/', $first) ) {
array_shift($data);
array_shift($line);
if ( empty($line) ) {
fwrite($fp, "\"{$first}\"\r\n");
} else {
fwrite($fp, "\"{$first}\",");
fputcsv($fp, $line);
fseek($fp, -1, SEEK_CUR);
fwrite($fp, "\r\n");
}
}
}
} else {
reset($header);
$first = current($header);
if ( substr($first, 0, 2) == 'ID' && !preg_match('/["\\s,]/', $first) ) {
array_shift($header);
if ( empty($header) ) {
$show_header = false;
fwrite($fp, "\"{$first}\"\r\n");
} else {
fwrite($fp, "\"{$first}\",");
}
}
}
if ( $show_header ) {
fputcsv($fp, $header);
fseek($fp, -1, SEEK_CUR);
fwrite($fp, "\r\n");
}
foreach ( $data as $line ) {
fputcsv($fp, $line);
fseek($fp, -1, SEEK_CUR);
fwrite($fp, "\r\n");
}
fclose($fp);
} else {
return false;
}
return true;
}
?>
好的,玩了一段时间后,我相信以下替换函数在所有情况下都能正常工作,包括原生 fputcsv 函数无法处理的情况。 如果 fputcsv 无法正常工作(尤其是在 mysql csv 导入中),请尝试使用此函数作为替代,它可以无缝替代。
传入的参数与 fputcsv 完全相同,不过我增加了一个额外的 $mysql_null 布尔值,允许将 php 的 null 值转换为 mysql 可插入的 null 值(默认情况下,此附加功能被禁用,因此与 fputcsv 工作原理相同[除了这个工作!])。
<?php
function fputcsv2 ($fh, array $fields, $delimiter = ',', $enclosure = '"', $mysql_null = false) {
$delimiter_esc = preg_quote($delimiter, '/');
$enclosure_esc = preg_quote($enclosure, '/');
$output = array();
foreach ($fields as $field) {
if ($field === null && $mysql_null) {
$output[] = 'NULL';
continue;
}
$output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field) ? (
$enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure
) : $field;
}
fwrite($fh, join($delimiter, $output) . "\n");
}
// 要使用的_完全_LOAD DATA INFILE 命令
// (如果您在上面的 $delimiter 和/或 $enclosure 中传入不同的内容,请在此处也更改它们;
// 但_保留 ESCAPED BY EMPTY!_).
/*
LOAD DATA INFILE
'/path/to/file.csv'
INTO TABLE
my_table
FIELDS TERMINATED BY
','
OPTIONALLY ENCLOSED BY
'"'
ESCAPED BY
''
LINES TERMINATED BY
'\n'
*/
?>
我从 PHP 源代码中转换了这个。 这完全复制了 PHP5 的功能,而这里其他例子没有。
<?php
if (!function_exists('fputcsv')) {
function fputcsv(&$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {
$str = '';
$escape_char = '\\';
foreach ($fields as $value) {
if (strpos($value, $delimiter) !== false ||
strpos($value, $enclosure) !== false ||
strpos($value, "\n") !== false ||
strpos($value, "\r") !== false ||
strpos($value, "\t") !== false ||
strpos($value, ' ') !== false) {
$str2 = $enclosure;
$escaped = 0;
$len = strlen($value);
for ($i=0;$i<$len;$i++) {
if ($value[$i] == $escape_char) {
$escaped = 1;
} else if (!$escaped && $value[$i] == $enclosure) {
$str2 .= $enclosure;
} else {
$escaped = 0;
}
$str2 .= $value[$i];
}
$str2 .= $enclosure;
$str .= $str2.$delimiter;
} else {
$str .= $value.$delimiter;
}
}
$str = substr($str,0,-1);
$str .= "\n";
return fwrite($handle, $str);
}
}
?>
为了生成符合 RFC 4180 标准的输出,不要使用 fputcsv,而是手动编码,例如:
function rfccsv($arr){
foreach($arr as &$a){
$a=strval($a);
if(strcspn($a,",\"\r\n")<strlen($a))$a='"'.strtr($a,array('"'=>'""')).'"';
}
return implode(',',$arr);
}
echo rfccsv(array(.....))."\n";
[由 danbrown AT php DOT net 编辑:这是作者改进和修复了一些错误后的修改后的函数。原始函数示例由 arthur AT mclean DOT ws 编写,并由 arthur AT korn DOT ch 在之间重写。]
- 当调用 str_replace() 时,必须将返回值赋予 $cell,否则不会保存任何内容
- 当使用 strchr() 时,应显式检查 !== FALSE,否则它会将返回值 0(在字符串位置 0 处找到字符)视为 FALSE
- Excel 似乎不仅引用包含逗号的字段,还引用包含引号的字段,因此我为引号添加了另一个 strchr();我不是说微软一定知道正确的方法,但对我来说这似乎是合理的
- 原始函数在每个逗号后添加了一个空格;这可能是合法的,我不知道,但我从未见过它(我认为不是,因为如何指示你想让一个字段以空格开头,而不是通过引用它?)
- 原始函数没有正确返回输出数据的长度
以下是修改后的函数
<?php
function fputcsv($handle, $row, $fd=',', $quot='"')
{
$str='';
foreach ($row as $cell) {
$cell=str_replace(Array($quot, "\n"),
Array($quot.$quot, ''),
$cell);
if (strchr($cell, $fd)!==FALSE || strchr($cell, $quot)!==FALSE) {
$str.=$quot.$cell.$quot.$fd;
} else {
$str.=$cell.$fd;
}
}
fputs($handle, substr($str, 0, -1)."\n");
return strlen($str);
}
?>
Drew
总的来说,我发现自己想将结果作为字符串而不是写入文件,特别是我想使用与我生成它的服务器不同的 EOL 生成 CSV。这是我在不重写 fputcsv 的情况下解决问题的方法。
<?php
function sputcsv($row, $delimiter = ',', $enclosure = '"', $eol = "\n")
{
static $fp = false;
if ($fp === false)
{
$fp = fopen('php://temp', 'r+'); // 参阅 https://php.net/manual/en/wrappers.php.php - 注意结尾有两个 '.php'
// 备注:任何读写到/从 'php://temp' 的内容都特定于此文件句柄
}
else
{
rewind($fp);
}
if (fputcsv($fp, $row, $delimiter, $enclosure) === false)
{
return false;
}
rewind($fp);
$csv = fgets($fp);
if ($eol != PHP_EOL)
{
$csv = substr($csv, 0, (0 - strlen(PHP_EOL))) . $eol;
}
return $csv;
}
// 测试
$rows = array
(
array('blue, sky', 'green, lime', 'red', 'black'),
array('white', 'gold', 'purple, imperial', 'grey, slate'),
array('orange, burnt', 'pink, hot', 'violet', 'indigo'),
);
if (PHP_EOL == "\r\n")
{
$eol = "\n";
}
else
{
$eol = "\r\n";
}
foreach($rows as $row)
{
echo nl2br(sputcsv($row, ',', '"', $eol));
}
?>
测试应该产生类似下面的结果
"blue, sky","green, lime",red,black
white,gold,"purple, imperial","grey, slate"
"orange, burnt","pink, hot",violet,indigo
我们有一个函数可以写入单行 CSV。我注意到,在启用 auto_detect_line_endings 后,fputcsv 不会在文件末尾写入换行符。
启用 auto_detect_line_endings 会改变 fputcsv 的行为,使其包含换行符。
为了与标准 (RFC-4180) CSV 文件最大程度兼容,请记住应禁用专有转义机制。即,将可选的第五个参数设置为 ""(空字符串)。
关于 Excel 和 UTF-16LE 编码
为了与 Excel 完全兼容(变音符、西里尔字母、汉语字母等),需要将 .csv 编码为 UTF-16LE,使用制表符 (\t) 作为分隔符,并在文件开头包含 UTF-16LE BOM。
但是,这不能通过简单地对 putcsv 的输入进行编码来完成,因为分隔符和包围符仍将以默认编码写入,并且 fputcsv 不会接受 utf-16 编码的分隔符/包围符。
简单的解决方案是使用自己的 fputcsv 实现(包括转义等),或者可能在事后对生成的 .csv 文件进行编码。
我发现 PHP 4 中的 fputcsv 示例缺少了一点,那就是在 $enclosure 值为引号时进行正确的处理(如果在字段中传递了引号,并且它由斜杠分隔,则这些函数将无法正确处理)。
我的修改后的函数是使用 fputcsv 的实际 PHP5 源代码构建的,并添加了对正在处理的字段中是否存在分隔符引号的正确反应。
<?php
if (!function_exists('fputcsv')) {
function fputcsv(&$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {
// 安全性检查
if (!is_resource($handle)) {
trigger_error('fputcsv() expects parameter 1 to be resource, ' .
gettype($handle) . ' given', E_USER_WARNING);
return false;
}
if ($delimiter!=NULL) {
if( strlen($delimiter) < 1 ) {
trigger_error('delimiter must be a character', E_USER_WARNING);
return false;
}elseif( strlen($delimiter) > 1 ) {
trigger_error('delimiter must be a single character', E_USER_NOTICE);
}
/* 使用字符串的第一个字符 */
$delimiter = $delimiter[0];
}
if( $enclosure!=NULL ) {
if( strlen($enclosure) < 1 ) {
trigger_error('enclosure must be a character', E_USER_WARNING);
return false;
}elseif( strlen($enclosure) > 1 ) {
trigger_error('enclosure must be a single character', E_USER_NOTICE);
}
/* 使用字符串的第一个字符 */
$enclosure = $enclosure[0];
}
$i = 0;
$csvline = '';
$escape_char = '\\';
$field_cnt = count($fields);
$enc_is_quote = in_array($enclosure, array('"',"'"));
reset($fields);
foreach( $fields AS $field ) {
/* 将包含分隔符、引号字符或换行的字段包含起来 */
if( is_string($field) && (
strpos($field, $delimiter)!==false ||
strpos($field, $enclosure)!==false ||
strpos($field, $escape_char)!==false ||
strpos($field, "\n")!==false ||
strpos($field, "\r")!==false ||
strpos($field, "\t")!==false ||
strpos($field, ' ')!==false ) ) {
$field_len = strlen($field);
$escaped = 0;
$csvline .= $enclosure;
for( $ch = 0; $ch < $field_len; $ch++ ) {
if( $field[$ch] == $escape_char && $field[$ch+1] == $enclosure && $enc_is_quote ) {
continue;
}elseif( $field[$ch] == $escape_char ) {
$escaped = 1;
}elseif( !$escaped && $field[$ch] == $enclosure ) {
$csvline .= $enclosure;
}else{
$escaped = 0;
}
$csvline .= $field[$ch];
}
$csvline .= $enclosure;
} else {
$csvline .= $field;
}
if( $i++ != $field_cnt ) {
$csvline .= $delimiter;
}
}
$csvline .= "\n";
return fwrite($handle, $csvline);
}
}
?>
如果你不想对字符串进行包含(因为你正在自己管理,或者你的内容已经包含了?),请注意,你不能将空的包含传递给 fputcsv。该函数需要一个字符作为该参数。chr(0) 工作良好
fputcsv($handle, $fields, ",", chr(0));
当你使用 fputcsv 输出 csv 时,如果存在任何中文字符,你可能会得到乱码。 那么你需要正确设置编码
fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF)); // 只需添加这一行
fputcsv($fp, ...);
受 boonerunner 函数的启发,我写了一个更小、更快、更灵活的函数,它也使用了更少的内存。
我还对它进行了重命名,以避免与 PHP 函数冲突或覆盖,并像 fputcsv() 使用的那样,为第 3 和第 4 个参数提供了默认值。
此函数将所有文本值放入 $enclosure 中,同时将 $enclosure 在值中加倍,并将数值保留原样。
但如果 $delimiter 存在于数值中,则此值也将放入 $enclosure 中(如果使用点作为 $delimiter,则可能会发生这种情况)。
function fwritecsv($handle, $fields, $delimiter = ',', $enclosure = '"') {
# 检查 $fields 是否为数组
if (!is_array($fields)) {
return false;
}
# 遍历数据数组
for ($i = 0, $n = count($fields); $i < $n; $i ++) {
# 只修正非数值
if (!is_numeric($fields[$i])) {
# 重复值内 $enclusure 并将值放入 $enclosure 中
$fields[$i] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $fields[$i]) . $enclosure;
}
# 如果 $delimiter 是点 (.),也修正数值
if (($delimiter == '.') && (is_numeric($fields[$i]))) {
# 将值放入 $enclosure 中
$fields[$i] = $enclosure . $fields[$i] . $enclosure;
}
}
# 使用 $delimiter 合并数据数组,并将其写入文件
$line = implode($delimiter, $fields) . "\n";
fwrite($handle, $line);
# 返回写入数据的长度
return strlen($line);
}
将 XML 字符串输出为 CSV,第一行作为列标题
<?php
// 在这种情况下,XML 是
// <records>
// <record>...</record>
// <record>...</record>
// </records>
if($xml = simplexml_load_string($string)){
// 保持内存不超过 12MB,如果超过则写入临时文件
$file = fopen('php://temp/maxmemory:'. (12*1024*1024), 'r+');
if($row = get_object_vars($xml->record[0])){ // 第一条记录
// 第一行包含列标题值
foreach($row as $key => $value){
$header[] = $key;
}
fputcsv($file, $header,',','"');
foreach ($xml->record as $record) {
fputcsv($file, get_object_vars($record),',','"');
}
rewind($file);
$output = stream_get_contents($file);
fclose($file);
return $output;
}else{
return '';
}
}
?>
希望这能有所帮助。
在某些服务器配置中,关联数组无法正常工作。在我的案例中,脚本停止运行,没有任何错误或消息,只是 fputcsv 返回 “false”。
通过调试,我发现关联数组在我的本地设置中可以正常工作,但在生产服务器上却不行。只需删除键就解决了问题。
因此,在调用 fputcsv() 之前删除键是更好的做法。
<?php
// 从数组中删除键
$csv_fields = array();
foreach($associative_array as $value) {
$csv_fields[] = $value;
}
fputcsv( $handler, $csv_fields);
?>
以下是上述代码的改编版本,它添加了对字段中双引号的支持。(根据 CSV 格式,单个双引号将被替换为一对双引号)。
<?php
function fputcsv($filePointer,$dataArray,$delimiter,$enclosure)
{
// 将一行写入文件
// $filePointer = 要写入的文件资源
// $dataArray = 要写入的数据
// $delimeter = 字段分隔符
// 构建字符串
$string = "";
// 没有前导分隔符
$writeDelimiter = FALSE;
foreach($dataArray as $dataElement)
{
// 将双引号替换为两个双引号
$dataElement=str_replace("\"", "\"\"", $dataElement);
// 在每个字段之前添加分隔符(第一个字段除外)
if($writeDelimiter) $string .= $delimiter;
// 用 $enclosure 括住每个字段,并将其添加到字符串中
$string .= $enclosure . $dataElement . $enclosure;
// 分隔符在每次使用时使用,第一个除外。
$writeDelimiter = TRUE;
} // end foreach($dataArray as $dataElement)
// 添加新行
$string .= "\n";
// 将字符串写入文件
fwrite($filePointer,$string);
}
?>
有一个更简单的解决方案可以获取 fputcsv 的结果到一个变量中。
<?php
$output = fopen('php://output', 'w');
ob_start();
fputcsv($output, $data);
fclose($output);
$csv = ob_get_clean();
?>
所以,这是我写的一个函数,用于从两个数组和一个名称中生成 CSV 导出。
你需要提供一个一维数组作为标题。一个多维数组作为实际内容。最后,你需要提供想要获取的文件名,去掉 “.csv” 扩展名,然后就可以使用它了。
<?php
# 我们将使用此函数生成 CSV
function exportCSV($headings=false, $rows=false, $filename=false)
{
# 确保我们有数据才能导出 CSV
if ((!empty($headings)) AND (!empty($rows)))
{
# 修改文件名
$name = ($filename !== false) ? $filename . ".csv" : "export.csv";
# 设置我们需要的标题
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=' . $name);
# 开始输出
$output = fopen('php://output', 'w');
# 创建标题
fputcsv($output, $headings);
# 然后循环遍历行
foreach($rows as $row)
{
# 将行添加到内容中
fputcsv($output, $row);
}
# 退出以关闭流
exit();
}
# 默认情况下失败
return false;
}
?>
一种更简单的方法
<?php
function fputcsv($hFile, $aRow, $sSeparator=',', $sEnclosure='"')
{
foreach ($aRow as $iIdx=>$sCell)
$aRow[$iIdx] = str_replace($sEnclosure, $sEnclosure.$sEnclosure, $sCell);
fwrite($hFile, join($aRow, $sSeparator)."\n");
}
?>