阅读目录
CSV,是Comma Separated Value(逗号分隔值)的英文缩写,通常都是纯文本文件。
一、CSV数据导入函数fgetcsv()
fgetcsv() 函数从文件指针中读入一行并解析 CSV 字段。
与 fgets() 类似,不同的是 fgetcsv() 解析读入的行并找出 CSV 格式的字段,然后返回一个包含这些字段的数组。
fgetcsv() 出错时返回 FALSE,包括碰到文件结束时。
具体使用时封装函数如下:

/**
* 导入Excel数据表格
* @param string $fileName 文件名
* @param int $line 读取几行,默认全部读取
* @param int $offset 从第几行开始读,默认从第一行读取
* @return bool|array
*/
public function importCsv($fileName, $line=0, $offset=0){
//set_time_limit(0);//防止超时
//ini_set("memory_limit", "512M");//防止内存溢出
$handle = fopen($fileName,'r');
if(!$handle){
return '文件打开失败';
}
$i = 0;
$j = 0;
$arr = [];
while($data = fgetcsv($handle)){
//小于偏移量则不读取,但$i仍然需要自增
if($i < $offset && $offset){
$i++;
continue;
}
//大于读取行数则退出
if($i > $line && $line){
break;
}
foreach ($data as $key => $value) {
$content = iconv("gbk","utf-8//IGNORE",$value);//转化编码
$arr[$j][] = $content;
}
$i++;
$j++;
}
return $arr;
}

二、CSV数据导出函数fputcsv()
前言:Excel表格最高支持104W行,导出数据达到上万的量,PHPExcel就显得有点无力了,经常卡死或者内存溢出,若做普通的数据导出功能,建议使用fputcsv()函数,因为此函数要比PHPexcel要高效的多,二十万数据导出大概需要2到3秒。
fputcsv() 函数将行格式化为 CSV 并写入一个打开的文件。
该函数返回写入字符串的长度。若出错,则返回 false。
具体使用时封装函数如下:
(注意点:
参数:$exportUrl分两种情况,根据需求选择其一
1.$exportUrl = 'php://output' 表示表示直接输出到浏览器自动下载。
2.𝑒𝑥𝑝𝑜𝑟𝑡𝑈𝑟𝑙="服务器目录地址/文件名.𝑐𝑠𝑣"表示输出到指定路径文件下。举例:exportUrl="服务器目录地址/文件名.csv"表示输出到指定路径文件下。举例:exportUrl = "/data/a.csv")。

/**
* 导出Excel数据表格
* @param array $dataList 要导出的数组格式的数据
* @param array $headList 导出的Excel数据第一列表头
* @param string $fileName 输出Excel表格文件名
* @param string $exportUrl 直接输出到浏览器or输出到指定路径文件下
* @return bool|false|string
*/
public static function toExcel($dataList,$headList,$fileName,$exportUrl){
//set_time_limit(0);//防止超时
//ini_set("memory_limit", "512M");//防止内存溢出
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$fileName.'.csv"');
header('Cache-Control: max-age=0');
//打开PHP文件句柄,php://output 表示直接输出到浏览器,$exportUrl表示输出到指定路径文件下
$fp = fopen($exportUrl, 'a');
//输出Excel列名信息
foreach ($headList as $key => $value) {
//CSV的Excel支持GBK编码,一定要转换,否则乱码
$headList[$key] = iconv('utf-8', 'gbk', $value);
}
//将数据通过fputcsv写到文件句柄
fputcsv($fp, $headList);
//计数器
$num = 0;
//每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
$limit = 100000;
//逐行取出数据,不浪费内存
$count = count($dataList);
for ($i = 0; $i < $count; $i++) {
$num++;
//刷新一下输出buffer,防止由于数据过多造成问题
if ($limit == $num) {
ob_flush();
flush();
$num = 0;
}
$row = $dataList[$i];
foreach ($row as $key => $value) {
$row[$key] = iconv('utf-8', 'gbk', $value);
}
fputcsv($fp, $row);
}
return $fileName;
}

另:导出csv数据Demo如下,可供参考:
<?php $headList = ['id', '姓名', '年龄']; $dataList = [[1, 'zhangsan', 10], [2, 'lisi', 20]]; toExcel($dataList, $headList, '测试文件名称', 'php://output');
浏览器请求,结果文件数据如下:
PHP 解决iconv()函数进行转码时遇到生僻字、特殊字符等出现数据丢失、乱码等问题
当我们在对数据进行csv文件转化的时候,经常需要对数据进行UTF-8、GBK的转码操作,如:
iconv('utf-8', 'gbk', $value);
但是当在实际使用中,会遇到转化后的csv文件中部分数据乱码、部分行、列丢失的显现。
这类原因是:在使用iconv()函数时以上方法会遇到一些特别字符时,如:"生僻字"、"—"、" "等字符,转换就断掉了,这些字符后的文字都没法继续转换了。
解决方法:
iconv('utf-8', 'gbk//IGNORE', $value); //IGNORE解决特殊字符转码问题
其中//IGNORE 会忽略错误,继续向下执行。
PHP 利用fputcsv()函数导出Excel,遇到数值精度超出15位后会自动置为0的解决方法
原因:
导出Excel/Csv文件时,列的数值精度为15位,超出15位后会自动置为0。
例如原始数据为:
[6708209641794310144,6708325755320795136,6708363343607894016,6709441113792450560]
导出CSV文件为:

解决方法:
业务处理结果转Excel文件时将数值项前后加制表符"\t"强制转化类型即可,如下:
//处理超出15位后重置0的数字->制表符的字符串
if (is_numeric($value) && strlen($value) > 15) {
$value = "\t" . $value . "\t";
}

本文详细介绍了PHP中用于CSV数据处理的两个关键函数:fgetcsv()用于导入CSV数据,fputcsv()用于导出CSV数据。文中提供了具体的函数封装示例,包括数据的读取、编码转换以及文件写入。此外,还讨论了在处理大量数据时,fputcsv()相对于PHPExcel的优势,以及如何解决iconv()转码时的特殊字符问题和数值精度问题。
281

被折叠的 条评论
为什么被折叠?



