PHP强化之10 - CSV文件处理

一、生成CSV文件

1、主要函数:

fputcsv—将行格式化为 CSV 并写入文件指针

int fputcsv ( resource $handle , array $fields [, string $delimiter = ',' [, string $enclosure = '"' ]] )

1)函数说明:

fputcsv() 将一行(用 fields 数组传递)格式化为 CSV 格式并写入由 handle 指定的文件。

2)参数:

  • handle 文件指针必须是有效的,必须指向由fopen()或fsockopen()成功打开的文件(并还未由fclose()关闭)。
  • fields 值的一个数组。
  • delimiter 可选的delimiter参数设定字段分界符(只允许一个字符)。
  • enclosure 可选的enclosure参数设定字段字段环绕符(只允许一个字符)。

3)返回值:

返回写入字符串的长度, 或者在失败时返回false。

2、示例code:

//test data
$list = array (
    array('name', 'data', 'number', 'price'),
    array('iphone X', '2018/3/21', 123 ,8888),
    array('imax pro', '2018/3/23',20,12000),   
    array('Letv', '2018/3/27',99,1100),
);
$fp = fopen('./file.csv', 'w') or die('Can\'t open file.');
// fwrite($fp,chr(0xEF).chr(0xBB).chr(0xBF)); //解决出现中文编码的问题
foreach ($list as $fields) {
    if (fputcsv($fp, $fields) === false) {
        die('Can\'t write line.');
    }
}
fclose($fp) or die('Can\'t close file.');

如下为生成的CSV文件:


3、问题:

1)中文编码问题

//Windows下使用BOM来标记文本文件的编码方式
fwrite($fp,chr(0xEF).chr(0xBB).chr(0xBF));

二、输出CSV数据

要输出CSV格式的数据而不是写入文件,可以使用特殊的输出流php://output。

要把SCV格式的数据放入一个pb字符串,而不是输出或写至一个文件,可以结合输出缓冲区使用,具体代码如下:

$list = array (
    array('name', 'data', 'number', 'price'),
    array('iphone X', '2018/3/21', 123 ,8888),
    array('imax pro', '2018/3/23',20,12000),   
    array('Letv', '2018/3/27',99,1100),
);

ob_start();
$fp = fopen('php://output','w') or die('Can\'t open php://output');
foreach ($list as $fields) {
    if (fputcsv($fp, $fields) === false) {
        die('Can\'t write CSV line.');
    }
}
fclose($fp) or die('Can\'t close php://output');
$output = ob_get_contents();
ob_end_clean();
//echo $output;

三、解析CSV文件

1、主要函数

如果CSV数据在一个文件中(或可以通过一个URL得到),用fopen()打开文件,并使用fgetcsv()读入数据。

fgetcsv—从文件指针中读入一行并解析 CSV 字段。

array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = ',' [, string $enclosure = '"' [, string $escape = '\\' ]]]] )

1)函数说明:

和 fgets() 类似,只除了 fgetcsv() 解析读入的行并找出 CSV 格式的字段然后返回一个包含这些字段的数组。

2)参数:

  • handle 一个由 fopen()、popen() 或 fsockopen() 产生的有效文件指针。
  • length 必须大于 CVS 文件内最长的一行。在 PHP 5 中该参数是可选的。如果忽略(在 PHP 5.0.4 以后的版本中设为 0)该参数的话,那么长度就没有限制,不过可能会影响执行效率。
  • delimiter 设置字段分界符(只允许一个字符)。
  • enclosure 设置字段环绕符(只允许一个字符)。
  • escape 设置转义字符(只允许一个字符),默认是一个反斜杠。

3)返回值:返回包含读取字段的索引数组。

2、示例代码如下:

$fp = fopen('./file.csv','r') or die('Can\'t open file');
print '';
while($csv_line = fgetcsv($fp)) {
    print '';
    for($i = 0, $j = count($csv_line); $i < $j; $i++){
    print '';//将字符转换为 HTML 转义字符
}
print '';
}
print '
'.htmlentities($csv_line[$i]).'
'; fclose($fp) or die('Can\'t close file');

3、注意

默认地,fgetcsv()会读入一整行数据。如果平均行长度超过8192字节,还可以明确指定行的长度而不是让PHP来确定,这样一来,你的程序可以运行得更快。为此要为fgetcsv()提供第二个参数,这是比CSV文件中最大行长度更大的一个值(不要忘记统计行尾空白符)。如果传入长度为0,PHP应付采用默认行为。

可以向fgetcsv()传入可选的第三个参数,这个作为分隔符来取代逗号(,)。不过,使用CSV的目的是为了很容易地交换表格数据,而使用一个不同的分隔符可能对此会有些影响。

不要试图绕过fgetcsv(),而只想读入一行再使用explode()按逗号进行解析。CSV比这要复杂,它可以处理包含特殊符号的字段值,如字段值中可能包含直接量逗号,不能把这些逗号看作是字段分隔符。使用fgetcsv()可以避免这样一些微妙的错误。

四、下载CSV文件

结合使用header()函数来改变php程序输出的内容类型,并使用fputcsv()函数完成数据格式转化,从而可以将CSV文件发送到浏览器。

示例代码如下:

$list = array (
    array('name', 'data', 'number', 'price'),
    array('iphone X', '2018/3/21', 123 ,8888),
    array('imax pro', '2018/3/23',20,12000), 
    array('Letv', '2018/3/27',99,1100),
);
$fp = fopen('php://output','w') or die('Can\'t open php://output');
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="save.csv"');
foreach ($list as $fields) {
    if (fputcsv($fp, $fields) === false) {
        die('Can\'t write CSV line.');
    }
}
fclose($fp) or die('Can\'t close php://output');

你可能感兴趣的:(PHP强化之10 - CSV文件处理)