最近接到一个需求,通过选择的时间段导出对应的用户访问日志到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文件的headersheader('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");在下载前告诉浏览器这个文件有多大了。不过不影响整体的效果这里的核心问题是解决大文件的实时生成和下载。


更新: 说一下我数据库查询这里的思路,因为逐步写入EXCEL的数据实际上来自Mysql的分页查询,大家知道其语法是LIMIT offset, num 不过随着offset越来越大Mysql在每次分页查询时需要跳过的行数就越多,这会严重影响Mysql查询的效率(包括MongoDB这样的NoSQL也是不建议skip掉多条来取结果集),所以我采用LastId的方式来做分页查询。 类似下面的语句:

SELECT columns FROM `table_name`
WHERE `created_at` >= 'time range start'
AND `created_at` <= 'time range end'
AND  `id` < LastId
ORDER BY `id` DESC
LIMIT num 

PHP实时生成并下载超大数据量的EXCEL文件 1相关推荐

  1. PHP实时生成并下载超大数据量的EXCEL文件

    最近接到一个需求,通过选择的时间段导出对应的用户访问日志到excel中, 由于用户量较大,经常会有导出50万加数据的情况.而常用的PHPexcel包需要把所有数据拿到后才能生成excel, 在面对生成 ...

  2. 1.3.8 excel for mysql_实时生成并下载大数据量的EXCEL文件,用PHP如何实现

    有一个这样的需求,通过选择的时间段导出对应的用户访问日志到excel中, 由于用户量较大,经常会有导出50万加数据的情况.而常用的PHPexcel包需要把所有数据拿到后才能生成excel, 在面对生成 ...

  3. 使用Python处理百万数据量的Excel文件:删除列、切分换行、替换去重

    使用Excel或WPS打开几十万.几百万行数据的文件十分缓慢,进行数据处理很容易卡死崩溃.这几天在处理一份数据文件的时候我尝试边学边用Python,获得了预想的效果. 记录一下处理过程中学到的知识点: ...

  4. 超大数据量的xlsx格式的excel文件的读取和解析,解决了POI方式的内存溢出和性能问题

    在之前的博文< POI读取并解析xlsx格式的excel文件>中,在小数据量的情况下是可以轻松愉快的处理的,但是当excel文件的数据量达到百万级的时候, InputStream is = ...

  5. 大数据导出excel大小限制_大数据量导出Excel的方案

    测试共同条件: 数据总数为110011条,每条数据条数为19个字段. 电脑配置为:P4 2.67GHz,1G内存. 一.POI.JXL.FastExcel比较 POI.JXL.FastExcel均为j ...

  6. 使用tushare下载指定股票日线数据并存为excel文件

    freepy下载 前一篇介绍转换本机通达信软件下载的个股日线数据,这一篇内容是从网络下载个股数据并存为excel文件. 也是使用freepy工具,这个工具的优点是不需要安装庞大的python开发环境, ...

  7. java poi导出Excel表格超大数据量解决方案

    Java实现导出excel表格功能,大部分都会使用apache poi,apache poi API 地址 POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小效果 ...

  8. jvm性能调优实战 - 47超大数据量处理系统是如何OOM的

    文章目录 Pre Case 针对Kafka故障设计的高可用场景 无法释放的内存最终导致OOM 故障修复 Pre 之前我们已经用代码给大家都演示过几种不同的内存溢出的场景了,但是光看代码演示可能大家还是 ...

  9. 超大数据量存储常用数据库分表分库算法总结

    这篇文章主要介绍了超大数据量存储常用数据库分表分库算法总结,本文讲解了按自然时间来分表/分库.按数字类型hash分表/分库.按md5值来分表/分库三种方法,以及分表所带来的问题探讨,需要的朋友可以参考 ...

最新文章

  1. 工具 | 四元数长什么样?这个小工具将旋转量可视化+相互转换,效果直观!
  2. Python XML的解析与创建
  3. 随机洗牌算法 银行家算法
  4. java链表寻找中间节点
  5. SASS初学者入门(转)
  6. ConcurrentSkipListMap深入分析
  7. 天气预报中的风向到底有啥用?
  8. SAP CRM WebClient UI Text Type 显示的过滤逻辑
  9. Java:根据字节数截取字符串,但是汉字不能截取半个。
  10. JAVA—HTTP客户端警告:Going to buffer response body of large or unknown size.
  11. ubuntu 10.04   花屏   启动缓慢   处理办法
  12. cpu —>内存—>硬盘这种方式是不是更慢?
  13. 最简单的基于FFmpeg的移动端例子:IOS 视频转码器
  14. 修改SRVINSTW支持sys文件
  15. 你手机里装过最牛的软件是什么,精选15款分享,有一个你没用过
  16. autojs和按键精灵哪个好?按键精灵打包开始收费了,是弃坑还是继续杠?
  17. 《雍正皇帝·九王夺嫡》物质文化专有词泰译研究(二)
  18. RadioButtonList功能汇总
  19. Android Studio 加载arr文件.arr文件
  20. 免费计算机论文 阅读,计算机方面的论文

热门文章

  1. 内存泄露部分检测工具
  2. Mysql 获取年级每个班前十学生的信息
  3. 关于ORACLE MYSQL NOT IN和NOT exists需要注意的 NULL值
  4. Linux C编程如何使用联机帮助来解决编程问题?
  5. WebLogic 12c与Oracle Database 12c的集成
  6. IPsec   在企业网中的应用
  7. 4.4 一个完整的Google Maps应用
  8. php购物车(session)
  9. 使用Apache Kudu和Impala实现存储分层
  10. TCP/IP学习笔记