在PHP开发的过程中有时候会有数据需要导出,可以利用各种框架中的一些包来直接获取数据然后丢入对应的处理方法就行了,但是当遇到大量的数据需要导出的时候,我们就需要用其他的方法来实现了。

一般处理大数据有如下几种解决办法: 通过添加或者修改事件触发脚本,生成数据;定时任务执行脚本生成数据;直接使用phpexcel导出大量数据;采用fputcsv实时数据流方式写入。用一张图表示如下:

 

 

这里主要记录下使用fputcsv方式导出数据。

  1. public function exportData()
  2. {
  3. set_time_limit(0);
  4. ini_set('memory_limit', '1024M');
  5. $columns = [ '列名1', '列名2', '列名3' //需要几列,定义好列名
  6. ]; //设置好告诉浏览器要下载excel文件的headers
  7.  
  8. header('Content-Description: File Transfer');
  9. header('Content-Type: application/vnd.ms-excel');
  10. header('Content-Disposition: attachment; filename="导出数据-'.date('Y-m-d', time()).'.csv"');
  11. header('Expires: 0');
  12. header('Cache-Control: must-revalidate');
  13. header('Pragma: public'); $fp = fopen('php://output', 'a');//打开output流
  14. mb_convert_variables('GBK', 'UTF-8', $columns);
  15. fputcsv($fp, $columns);//将数据格式化为CSV格式并写入到output流中
  16. //添加查询条件,获取需要的数据
  17.  
  18. $query = Model::class()->where();
  19. //获取总数,分页循环处理
  20.  
  21. $accessNum = $query->count();
  22. $perSize = 1000;
  23. $pages = ceil($accessNum / $perSize);
  24. for($i = 1; $i <= $pages; $i++) {
  25. $db_data = $query->limit($perSize)->offset(($i-1)*$perSize)->get();
  26. foreach($db_data as $key => $value) {
  27. $rowData = []; //获取每列数据,转换处理成需要导出的数据
  28. //需要格式转换,否则会乱码
  29. mb_convert_variables('GBK', 'UTF-8', $rowData);
  30. fputcsv($fp, $rowData);
  31. } //释放变量的内存
  32.  
  33. unset($db_data); //刷新输出缓冲到浏览器
  34.  
  35. ob_flush(); //必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。
  36.  
  37. flush();
  38. }
  39. fclose($fp);
  40. exit();
  41. }

这样会一边生成,一边写入下载文件,提高处理速度。
之前使用的包处理,生成一个25M的数据,要20分钟。这种方式处理需要1分多钟(也和实际处理的环境有关)。

 

版权声明:本文为itsuxinlong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/itsuxinlong/p/16133579.html