PHP 高效导入导出Excel(csv)方法之fgetcsv()和fputcsv()函数

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');

浏览器请求,结果文件数据如下:

 

posted @ 2019-03-13 10:26  申文哲  阅读(9557)  评论(7编辑  收藏  举报