• PHP导出百万大数据【解决方案】


    最近开发项目,遇到一个问题,通常导出数据我们都会使用 PHPExcel 来导出数据,但是遇到大数据,这个方法就不行了。

    例如:我的项目,3.5W个学生信息,需要导出做数据备份,使用【PHPExcel】来导出就不行了,需要另谋它法:

    不考虑PHPExcel就只能考虑导出CSV:

    具体实现思路:

    按照一定的数量,例如:5000条,导出CSV文件,多个CSV文件进行压缩为ZIP,最后导出ZIP里面就有所有数据。例如:3.5w条数据,最终有5个CSV文件,生成一个ZIP压缩文件。

    代码:

    public function exportCSV()
    {
        $limit = 5000;//每次只从数据库取50000条以防变量缓存太大
        // buffer计数器
        $cnt = 0;
        $xlsTitle = ['序号','姓名','性别'];
        /******************** 调整位置开始 ***************************/
        $sqlCount = 3000; // 这里需要查询出总条数
        /******************** 调整位置结束 ***************************/
        $fileName = iconv('utf-8', 'gb2312', 'students');//文件名称
        $fileName = $fileName . date('_YmdHis');// 文件名称可根据自己情况设定
        $zipname = 'zip-' . $fileName . ".zip";
        // 输出Excel文件头,可把user.csv换成你要的文件名
        header('Content-Type: application/vnd.ms-excel;charset=utf-8');
        header('Content-Disposition: attachment;filename="' . $zipname . '"');
        header('Cache-Control: max-age=0');
        $fileNameArr = array();
        // 逐行取出数据,不浪费内存
        for ($i = 0; $i < ceil($sqlCount / $limit); $i++) {
            $fp = fopen($fileName . '_' . ($i+1) . '.csv', 'w'); //生成临时文件 
            // chmod('attack_ip_info_' . $i . '.csv',777);//修改可执行权限 
            $fileNameArr[] = $fileName . '_' . ($i+1) . '.csv'; // 将数据通过fputcsv写到文件句柄 
            fputcsv($fp, $xlsTitle);
            $start = $i * $limit;
            /******************** 调整位置开始 ***************************/
            $dataArr = $this->model->getList($start,$limit); // 每次查询limit条数据
            /******************** 调整位置结束 ***************************/
            foreach ($dataArr as $a) {
                $cnt++;
                if ($limit == $cnt) {
                    // 刷新一下输出buffer,防止由于数据过多造成问题
                    ob_flush();
                    flush();
                    $cnt = 0;
                }
                fputcsv($fp, $a);
            }
            fclose($fp); // 每生成一个文件关闭
        }
    
        // 进行多个文件压缩
        $zip = new \ZipArchive();
        $zip->open($zipname, $zip::CREATE); // 打开压缩包
        foreach ($fileNameArr as $file) {
            $zip->addFile($file, basename($file)); // 向压缩包中添加文件
        }
        $zip->close();  // 关闭压缩包
        foreach ($fileNameArr as $file) {
            unlink($file); // 删除csv临时文件
        }
    
        // 输出压缩文件提供下载
        header("Cache-Control: max-age=0");
        header("Content-Description: File Transfer");
        header("Content-Type: application/zip"); // zip格式
        header("Content-Transfer-Encoding: binary");
        header('Content-Length: ' . filesize($zipname));
        @readfile($zipname); // 输出文件
        unlink($zipname); // 删除压缩包临时文件
    }

    参考:

    https://cloud.tencent.com/developer/article/1990268

    打完收工!

  • 相关阅读:
    UVA 11776
    NEFU 117
    hihocoder 1331
    NEFU 84
    虚拟机类加载机制
    动态规划 -- 01背包问题和完全背包问题
    动态规划 ---- 最长回文子串
    动态规划 ---- 最长公共子序列(Longest Common Subsequence, LCS)
    动态规划 ---- 最长不下降子序列(Longest Increasing Sequence, LIS)
    动态规划(Dynamic Programming, DP)---- 最大连续子序列和 & 力扣53. 最大子序和
  • 原文地址:https://www.cnblogs.com/e0yu/p/16650013.html
Copyright © 2020-2023  润新知