php使用fputcsv实现大数据的导出操作详解


Posted in PHP onFebruary 27, 2020

本文实例讲述了php使用fputcsv实现大数据的导出操作。分享给大家供大家参考,具体如下:

为了实验大数据的导出,我们这里先自已创建一张大表,表结构如下:

CREATE TABLE `tb_users` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
 `name` varchar(32) DEFAULT '' COMMENT '用户名',
 `age` tinyint(3) DEFAULT '0' COMMENT '用户年龄',
 `desc` varchar(255) DEFAULT '' COMMENT '用户描述',
 `phone` varchar(11) DEFAULT '' COMMENT '用户手机',
 `qq` varchar(16) DEFAULT '' COMMENT '用户QQ',
 `email` varchar(64) DEFAULT '' COMMENT '用户邮箱',
 `addr` varchar(255) DEFAULT '' COMMENT '用户地址',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 然后写个php脚本往这个表插入数据,代码如下:

<?php
set_time_limit(0);
ini_set('memory_limit', '128M');

//使用TP3.2的String类,php7下会报错,注意把类名换一下
require './String.class.php';
use Org\Util\NewString;

$begin = microtime(true);

$db = new mysqli('127.0.0.1', 'root', '', 'test');

if($db->connect_error) {
  die('connect error');
}
//数据插入语句
$insSql = '';

//一百万数据,分200步,每步插入5000条
$step = 200;
$nums = 5000;

for($s = 0; $s < $step; ++$s) {
  $insSql = 'INSERT INTO tb_users VALUES';
  for($n = 0; $n < $nums; ++$n) {
    $name = NewString::randString(3, 4);
    $age = mt_rand(1, 120);
    $desc = NewString::randString(64, 4);
    $phone = NewString::randString(11, 1);
    $qq = NewString::randString(13, 1);
    $email = $qq . '@qq.com';
    $addr = NewString::randString(128, 4);
    $insSql .= "(NULL, '{$name}', $age, '{$desc}', '{$phone}', '{$qq}', '{$email}', '{$addr}'),";
  }
  $insSql = rtrim($insSql, ',');
  $db->query($insSql);
}
$end = microtime(true);
echo '用时:', $end - $begin;

$db->close();

里面用到的TP3.2的String类大家自行上TP官网下载。整个用时2个多小时,最后数据大小662M。

现在我们用php提供的fputcsv来导出这一百万的数据,原理就是打开一个标准输出流,然后把数据按一万条来分割,每一万条就刷新缓冲区。

<?php
set_time_limit(0);
ini_set('memory_limit', '128M');

$fileName = date('YmdHis', time());
header('Content-Type: application/vnd.ms-execl');
header('Content-Disposition: attachment;filename="' . $fileName . '.csv"');

$begin = microtime(true);

//打开php标准输出流
//以写入追加的方式打开
$fp = fopen('php://output', 'a');

$db = new mysqli('127.0.0.1', 'root', '', 'test');

if($db->connect_error) {
  die('connect error');
}

//我们试着用fputcsv从数据库中导出1百万的数据
//我们每次取1万条数据,分100步来执行
//如果线上环境无法支持一次性读取1万条数据,可把$nums调小,$step相应增大。
$step = 100;
$nums = 10000;

//设置标题
$title = array('ID', '用户名', '用户年龄', '用户描述', '用户手机', '用户QQ', '用户邮箱', '用户地址');
foreach($title as $key => $item) {
  $title[$key] = iconv('UTF-8', 'GBK', $item);
}
//将标题写到标准输出中
fputcsv($fp, $title);

for($s = 1; $s <= $step; ++$s) {
  $start = ($s - 1) * $nums;
  $result = $db->query("SELECT * FROM tb_users ORDER BY id LIMIT {$start},{$nums}");
  
  if($result) {
    while($row = $result->fetch_assoc()) {
      foreach($row as $key => $item) {
        //这里必须转码,不然会乱码
        $row[$key] = iconv('UTF-8', 'GBK', $item);
      }
      fputcsv($fp, $row);
    }
    $result->free();
    
    //每1万条数据就刷新缓冲区
    ob_flush();
    flush();
  }
}

$end = microtime(true);
echo '用时:', $end - $begin;

整个过程用时5分钟,最终生成的csv文件大小420M。

php使用fputcsv实现大数据的导出操作详解

php使用fputcsv实现大数据的导出操作详解

php使用fputcsv实现大数据的导出操作详解

对于如何用phpexcel导出大数据,并没有什么比较好的方案,phpexcel提供的一些缓存方法,数据压缩,虽然内存使用小了,但所用时间则加长了,时间换空间,显然并不是最好的方案。比较靠谱的方法还是生成多个下载链接地址,把你要下载的数据,以get形式传递当前页数,后台进行数据分页然后导出。

<a href="/downSearchData.php?参数1=值1&参数2=值2&page=1" rel="external nofollow" >下载汇总结果1</a>
<a href="/downSearchData.php?参数1=值1&参数2=值2&page=2" rel="external nofollow" >下载汇总结果2</a>
<a href="/downSearchData.php?参数1=值1&参数2=值2&page=3" rel="external nofollow" >下载汇总结果3</a>

 比如你有一个查询数据表单,ID为searchFrm,然后你想把导出数据按1万条分割(phpexcel一次导出1万条是没有问题的,效率还行)

<form id="searchFrm">
  姓名<input type="text" name="uname">
  <input type="button" id="searchDataBtn" value="导出汇总结果">
</form>
<div id="searchDataList"></div>

<script type="script">
  $("#searchDataBtn").on("click", function() {
    var params = $("#searchFrm").serialize();
    
    //获取查询数据的条数
    $.get("/getSearchDataRows?" + params, function(data) {
      var downDataList = "";
      if(data["rows"]) {
        //rows是数据总条数,pageSize是一页多少条
        var pageNum = Math.ceil(data["rows"] / data["pageSize"]);
        for(var i = 1; i <= pageNum; ++i) {
          downDataList += "<a href='/downSearchData.php?'" + params + "&page=" + i + ">下载汇总结果" + i + "</a>  ";
        }
        $("#searchDataList").html(downDataList);
      } else {
        $("#searchDataList").text("没有数据");
      }
    }, "json");
    return false;
  });
</script>

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP读取MySQL数据代码
Jun 05 PHP
PHP 七大优势分析
Jun 23 PHP
PHP 获取客户端真实IP地址多种方法小结
May 15 PHP
php 抽象类的简单应用
Sep 06 PHP
探讨PHP JSON中文乱码的解决方法详解
Jun 06 PHP
php使用curl和正则表达式抓取网页数据示例
Apr 13 PHP
php生成百度sitemap站点地图类函数实例
Oct 17 PHP
php操作memcache缓存方法分享
Jun 03 PHP
PHPExcel中文帮助手册|PHPExcel使用方法(分享)
Jun 09 PHP
php图片合成方法(多张图片合成一张)
Nov 25 PHP
PHP ajax+jQuery 实现批量删除功能实例代码小结
Dec 06 PHP
thinkphp整合系列之极验滑动验证码geetest功能
Jun 18 PHP
gearman中任务的优先级和返回状态实例分析
Feb 27 #PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
Feb 27 #PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
Feb 27 #PHP
gearman管理工具GearmanManager的安装与php使用方法示例
Feb 27 #PHP
php使用gearman进行任务分发操作实例详解
Feb 26 #PHP
php实现根据身份证获取精准年龄
Feb 26 #PHP
ThinkPHP5与单元测试PHPUnit使用详解
Feb 23 #PHP
You might like
php数据库连接
2006/10/09 PHP
javascript 清除输入框中的数据
2009/04/13 Javascript
JQuery 学习笔记 element属性控制
2009/07/23 Javascript
回车直接实现点击某按钮的效果即触发单击事件
2014/02/27 Javascript
js手动播放图片实现图片轮播效果
2016/09/17 Javascript
小程序实现带年月选取效果的日历
2018/06/27 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
2018/09/20 jQuery
基于JavaScript伪随机正态分布代码实例
2019/11/07 Javascript
jquery 插件重新绑定的处理方法分析
2019/11/23 jQuery
jquery实现点击弹出对话框
2020/02/08 jQuery
[03:12]TI9战队档案 - Virtus Pro
2019/08/20 DOTA
python sqlobject(mysql)中文乱码解决方法
2008/11/14 Python
Python subprocess模块学习总结
2014/03/13 Python
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
在python中使用正则表达式查找可嵌套字符串组
2017/10/24 Python
python登录并爬取淘宝信息代码示例
2017/12/09 Python
python中ASCII码字符与int之间的转换方法
2018/07/09 Python
python实现Virginia无密钥解密
2019/03/20 Python
python实现趣味图片字符化
2019/04/30 Python
详解Django定时任务模块设计与实践
2019/07/24 Python
Python GUI编程学习笔记之tkinter控件的介绍及基本使用方法详解
2020/03/30 Python
CSS3的文字阴影—text-shadow的使用方法
2012/12/25 HTML / CSS
Hotter Shoes美国官网:英国最受欢迎的舒适鞋
2018/08/02 全球购物
俄罗斯GamePark游戏商店网站:购买游戏、游戏机和配件
2020/03/13 全球购物
财务会计专业应届毕业生求职信
2013/10/18 职场文书
亲子读书活动方案
2014/02/22 职场文书
2014年大学庆元旦迎新年活动方案
2014/03/09 职场文书
借款协议书范本
2014/04/22 职场文书
主要负责人任命书
2014/06/06 职场文书
物价局领导班子四风问题整改措施
2014/10/26 职场文书
工伤私了协议书范本
2014/11/24 职场文书
2015年超市工作总结
2015/04/09 职场文书
2015年幼儿园中班工作总结
2015/04/25 职场文书
三好学生主要事迹怎么写
2015/11/03 职场文书
pytorch 预训练模型读取修改相关参数的填坑问题
2021/06/05 Python
《仙剑客栈2》第一弹正式宣传片公开 年内发售
2022/04/07 其他游戏