PHP实现实时生成并下载超大数据量的EXCEL文件详解


Posted in PHP onOctober 23, 2017

前言

最近在工作中接到一个需求,通过选择的时间段导出对应的用户访问日志到excel中, 由于用户量较大,经常会有导出50万加数据的情况。而常用的PHPexcel包需要把所有数据拿到后才能生成excel, 在面对生成超大数据量的excel文件时这显然是会造成内存溢出的,所以考虑使用让PHP边写入输出流边让浏览器下载的形式来完成需求。

我们通过如下的方式写入PHP输出流

$fp = fopen('php://output', 'a');
fputs($fp, 'strings');
....
....
fclose($fp)

php://output是一个可写的输出流,允许程序像操作文件一样将输出写入到输出流中,PHP会把输出流中的内容发送给web服务器并返回给发起请求的浏览器

另外由于excel数据是从数据库里逐步读出然后写入输出流的所以需要将PHP的执行时间设长一点(默认30秒)set_time_limit(0)不对PHP执行时间做限制。

注:以下代码只是阐明生成大数据量EXCEL的思路和步骤,并且在去掉项目业务代码后程序有语法错误不能拿来直接运行,请根据自己的需求填充对应的业务代码!

/**
  * 文章访问日志
  * 下载的日志文件通常很大, 所以先设置csv相关的Header头, 然后打开
  * PHP output流, 渐进式的往output流中写入数据, 写到一定量后将系统缓冲冲刷到响应中
  * 避免缓冲溢出
  */
 public function articleAccessLog($timeStart, $timeEnd)
 {
  set_time_limit(0);
  $columns = [
   '文章ID', '文章标题', ......
  ];
  $csvFileName = '用户日志' . $timeStart .'_'. $timeEnd . '.xlsx';
  //设置好告诉浏览器要下载excel文件的headers
  header('Content-Description: File Transfer');
  header('Content-Type: application/vnd.ms-excel');
  header('Content-Disposition: attachment; filename="'. $fileName .'"');
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');
  $fp = fopen('php://output', 'a');//打开output流
  mb_convert_variables('GBK', 'UTF-8', $columns);
  fputcsv($fp, $columns);//将数据格式化为CSV格式并写入到output流中
  $accessNum = '1000000'//从数据库获取总量,假设是一百万
  $perSize = 1000;//每次查询的条数
  $pages = ceil($accessNum / $perSize);
  $lastId = 0;
  for($i = 1; $i <= $pages; $i++) {
   $accessLog = $logService->getArticleAccessLog($timeStart, $timeEnd, $lastId, $perSize);
   foreach($accessLog as $access) {
    $rowData = [
     ......//每一行的数据
    ];
    mb_convert_variables('GBK', 'UTF-8', $rowData);
    fputcsv($fp, $rowData);
    $lastId = $access->id;
   }
   unset($accessLog);//释放变量的内存
   //刷新输出缓冲到浏览器
   ob_flush();
   flush();//必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。
  }
  fclose($fp);
  exit();
 }

好了, 其实很简单,就是用逐步写入输出流并发送到浏览器让浏览器去逐步下载整个文件,由于是逐步写入的无法获取文件的总体size所以就没办法通过设置header("Content-Length: $size");在下载前告诉浏览器这个文件有多大了。不过不影响整体的效果这里的核心问题是解决大文件的实时生成和下载。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
php自动获取目录下的模板的代码
Aug 08 PHP
PHP学习之正则表达式
Apr 17 PHP
PHP实现HTML生成PDF文件的方法
Nov 07 PHP
给PHP开发者的编程指南 第一部分降低复杂程度
Jan 18 PHP
深入理解PHP中的empty和isset函数
May 26 PHP
php框架CodeIgniter主从数据库配置方法分析
May 25 PHP
微信企业转账之入口类分装php代码
Oct 01 PHP
PHP PDOStatement::nextRowset讲解
Feb 01 PHP
laravel dingo API返回自定义错误信息的实例
Sep 29 PHP
Laravel第三方包报class not found的解决方法
Oct 13 PHP
Laravel 类和接口注入相关的代码
Oct 15 PHP
漂亮的thinkphp 跳转页封装示例
Oct 16 PHP
Laravel学习教程之model validation的使用示例
Oct 23 #PHP
laravel实现批量更新多条记录的方法示例
Oct 22 #PHP
利用PHP获取汉字首字母并且分组排序详解
Oct 22 #PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
Oct 22 #PHP
PHP高效获取远程图片尺寸和大小的实现方法
Oct 20 #PHP
PHP静态延迟绑定和普通静态效率的对比
Oct 20 #PHP
php+ajax实现仿百度查询下拉内容功能示例
Oct 20 #PHP
You might like
模拟OICQ的实现思路和核心程序(一)
2006/10/09 PHP
php后退一页表单内容保存实现方法
2012/06/17 PHP
thinkphp分页集成实例
2017/07/24 PHP
DOMAssitant最新版 DOMAssistant 2.5发布
2007/12/25 Javascript
extjs 初始化checkboxgroup值的代码
2011/09/21 Javascript
js nextSibling属性和previousSibling属性概述及使用注意
2013/02/16 Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
2013/05/08 Javascript
php与js的区别是什么
2013/08/05 Javascript
PHP开发者必须掌握的6个关键字
2014/04/14 Javascript
js编写三级联动简单案例
2016/12/21 Javascript
BootStrap导航栏问题记录
2017/07/31 Javascript
jQuery UI Draggable + Sortable 结合使用(实例讲解)
2017/09/07 jQuery
微信小程序访问豆瓣电影api的实现方法
2019/03/31 Javascript
[37:02]OG vs INfamous 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python实现数通设备端口监控示例
2014/04/02 Python
python类继承用法实例分析
2014/10/10 Python
Python标准异常和异常处理详解
2015/02/02 Python
python使用正则表达式替换匹配成功的组
2017/11/17 Python
Python通过OpenCV的findContours获取轮廓并切割实例
2018/01/05 Python
python 串口读取+存储+输出处理实例
2019/12/26 Python
JavaScript+Canvas实现自定义画板的示例代码
2019/05/13 HTML / CSS
前端实现打印图像功能
2019/08/27 HTML / CSS
世界上最全面的汽车零部件和配件集合:JC Whitney
2016/09/04 全球购物
100%有机精油,美容油:House of Pure Essence
2018/10/30 全球购物
女大学生毕业找工作的自我评价
2013/10/03 职场文书
办公室副主任岗位职责
2013/11/25 职场文书
革命先烈的英雄事迹材料
2014/02/15 职场文书
模具专业求职信
2014/06/26 职场文书
党支部活动策划方案
2014/08/18 职场文书
现场活动策划方案
2014/08/22 职场文书
施工安全协议书范本
2014/09/26 职场文书
教师业务学习材料
2014/12/16 职场文书
大学生村官驻村工作心得体会
2016/01/23 职场文书
vue前端工程的搭建
2021/03/31 Vue.js
JavaGUI模仿QQ聊天功能完整版
2021/07/04 Java/Android
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers