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。

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

<a href="/downSearchData.php?参数1=值1&参数2=值2&page=1">下载汇总结果1</a>
<a href="/downSearchData.php?参数1=值1&参数2=值2&page=2">下载汇总结果2</a>
<a href="/downSearchData.php?参数1=值1&参数2=值2&page=3">下载汇总结果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>&nbsp;&nbsp;";
                }
                $("#searchDataList").html(downDataList);
            } else {
                $("#searchDataList").text("没有数据");
            }
        }, "json");
        return false;
    });
</script>
时间: 2024-10-03 23:28:59

php使用fputcsv进行大数据的导出的相关文章

ajax大数据排队导出+进度条

描述 :我们现在有很多数据,分表存放,现在需要有精度条的导出.最后面有完整源码. 效果图: 点击导出,实现 点击导出 统计完成之后 点击确定 前面导出操作简单,从第二个导出操作开始: 点击"确定"调用exportCsv函数 <a class="on" href="javascript:exportCsv();"><em>导出</em></a> exportCvs函数如下 function expor

使用内存映射文件MMF实现大数据量导出时的内存优化

前言 导出功能几乎是所有应用系统必不可少功能,今天我们来谈一谈,如何使用内存映射文件MMF进行内存优化,本文重点介绍使用方法,相关原理可以参考文末的连接 实现 我们以单次导出一个excel举例(csv同理),excel包含1~n个sheet,在每个sheet中存储的按行和列的坐标在单元格存储具体数据,如果我们要使用MMF,第一个要考虑的就是如何将整个excel合理的存储到MMF中.这里我们引入MMF两个对象: MemoryMappedFile --表示内存映射文件 MemoryMappedVie

SQL Server大数据导入导出:将一张表的数据导入到另一张表

今天下午休息的时候又被扔给一项任务:把全国的街道数据导入街道表.但是他们扔给我的SQL脚本是从网上down的一个,跟平台这边的数据库设计的完全不一样. 当时的思路是:先把扔给我的脚本在本地生成一个表,然后选出要的数据,批量插入到开发库所在服务器的表. 然后,按照这个思路做了个测试: INSERT INTO dbo.test_Street(Code,CountyCode,CnName,VersionNo,Creator,CreateTime,ValidStatus) /*要插入数据的表*/ SEL

java使用poi实现大数据量导出为EXCEL

总体的实现思想为: 每次查询出2w数据,并写入到临时文件 然后把这些文件写入到一个EXCEL里边,或者把这些文件压缩为zip文件,然后把Zip文件提供给下载(这里使用zip打包是因为,在Linux上也能进行Zip打包). //这个zip打包工具类 package net.szh.zip;      import java.io.File;      import org.apache.tools.ant.Project;   import org.apache.tools.ant.taskdef

POI实现大数据EXCLE导入导出,解决内存溢出问题

使用POI能够导出大数据保证内存不溢出的一个重要原因是SXSSFWorkbook生成的EXCEL为2007版本,修改EXCEL2007文件后缀为ZIP打开可以看到,每一个Sheet都是一个xml文件,单元格格式和单元格坐标均用标签表示.直接使用SXSSFWorkbook来到导出EXCEL本身就是POI为了大数据量导出而量身定制的,所以导出可以直接使用SXSSFWorkbook方式. 为了保险起见可以采用多Sheet的方式保证内存不溢出.需要注意的是Sheet名称不能重复:下载的时候需要定义好返回

导出查询数据(大数据量)

1.右击数据库,"任务"--"导出数据" 2.向导页点击"下一步",然后录入登陆信息,再点击"下一步" 3.选择导出类型及路径,然后点击"下一步"(如:Excel文档) 4.选择数据源,直接从表或试图中导出,或者通过sql语句查询导出,然后"下一步".(此处sql查询为例) 5.录入查询语句,然后"下一步"(可分析sql语句是否有效) 6.之后的步骤就是一路"

大数据导入Excel

在平时的项目中,将数据导出到Excel的需求是很常见的,在此对一些常见的方法做以总结,并提供一种大数据量导出的实现. OLEDB   使用OLEDB可以很方便导出Excel,思路很简单,处理时将Excel当做Access处理,利用SQL建表.插入数据.不多说了,直接看代码  使用OLEDB导出Excel public static void Export(DataTable dt, string filepath, string tablename) { //excel 2003格式 strin

关于大数据查询与导出

上周末,帮朋友处理了一个关于大数据的查询与导出问题,整理一下,在此记录一下用以备忘,同时也为有类似需要的朋友提供一个参考. 背景: 数据库服务使用: SqlServer2008 ; 查询的流水表总数据量约在 800W 条左右 ; 需要展示的字段需要从流水表+基础资料表中 导出需要 加载指定模板 ; 要求查询响应时间<=2s,导出<=10s; (当然每次仅处理符合条件的数据) . 该系统运行了大概2年时间,系统刚上线的时候,各项性能指标还ok,目前该功能点查询和导出时直接卡死. 该项目为 常规

java 导出Excel 大数据量

出处: http://lyjilu.iteye.com/ 分析导出实现代码,XLSX支持: /** * 生成<span style="white-space: normal; background-color: #ffffff;">XLSX</span>,2007版本的excel,每个sheet无6.5W的行数限制,但是到了一定数量,可能内存溢出, * 次方法适合在预计10W以下的数据导出时使用,本机测试,14W可以导出.列数量在8列左右 * * @param