首页 » Web前端 » php导出excel下载技巧_实时生成并下载大年夜数据量的EXCEL文件用PHP若何实现

php导出excel下载技巧_实时生成并下载大年夜数据量的EXCEL文件用PHP若何实现

访客 2024-11-11 0

扫一扫用手机浏览

文章目录 [+]

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

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

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

php导出excel下载技巧_实时生成并下载大年夜数据量的EXCEL文件用PHP若何实现

其余由于excel数据是从数据库里逐步读出然后写入输出流的以是须要将PHP的实行韶光设长一点(默认30秒)set_time_limit(0)不对PHP实行韶光做限定。

php导出excel下载技巧_实时生成并下载大年夜数据量的EXCEL文件用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=\"大众' . $csvFileName . '\"大众'); 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,\公众\t\"大众);//将数据格式化为CSV格式并写入到output流中 $res = $this->mysqli->query('SELECT COUNT(`id`) AS `allCount`,MAX(`id`) AS `lastId` FROM `student`'); $result = $res->fetch_object(); $allCount = $result->allCount; $perSize = 1000;//每次查询的条数 $pages = ceil($allCount / $perSize); $lastId = $result->lastId; for ($i = 1; $i <= $pages; $i++) { $sqlTpl = 'SELECT FROM %s WHERE `created_at` >= %s AND `created_at` <= %s AND `id` %s %d ORDER BY `id` DESC LIMIT %d'; $symbol = $i === 1 ? \"大众<=\"大众 : \公众<\"大众; $sql = sprintf($sqlTpl, self::$tableName, $timeStart, $timeEnd, $symbol, $lastId, $perSize); $accessLog = $this->mysqli->query($sql); foreach ($accessLog as $rowData) { mb_convert_variables('GBK', 'UTF-8', $rowData); fputcsv($fp, $rowData,\公众\t\公众); $lastId = $rowData['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 FROM student WHERE `created_at` >= 1552110271 AND `created_at` <= 1552110271 AND `id` <= 20 ORDER BY `id` DESC LIMIT 1000;

标签:

相关文章

G98高速公路,我国交通发展的重要里程碑

近年来,我国高速公路建设取得了举世瞩目的成就。其中,G98高速公路作为国家高速公路网的重要组成部分,承载着连接东南沿海地区的重要使...

Web前端 2024-12-23 阅读0 评论0

g32代码,解码编程之美,引领技术革新

随着信息技术的飞速发展,编程已经成为现代社会不可或缺的一部分。在众多编程语言中,g32代码因其高效、简洁、易学等特点而备受关注。本...

Web前端 2024-12-23 阅读0 评论0

介绍10代码梗背后的编程文化底蕴

随着科技的飞速发展,编程已经成为现代社会不可或缺的一部分。而在这片广阔的编程领域,许多有趣的代码梗应运而生,成为程序员们交流的趣味...

Web前端 2024-12-23 阅读0 评论0

京东供货协议,构建高效供应链的基石

在当今电子商务迅猛发展的时代,供应链管理已成为企业核心竞争力的重要组成部分。京东作为我国领先的电商平台,其供货协议的制定与执行,不...

Web前端 2024-12-23 阅读0 评论0

Frm代码,现代金融风险管理的重要工具

随着金融市场的不断发展,金融风险也日益复杂化。为了有效管理金融风险,金融机构和投资者纷纷寻求先进的技术手段。Frm代码作为一种现代...

Web前端 2024-12-23 阅读0 评论0