PHPExcel内存溢出解决方案

一、当PHPEXCEL导出大数据时,PHP内存溢出时,可使用Table把数据分页追加到Excel文件

存在的问题:这种方法最多只能写入 65536 条数据,解决方案 请移步 >>> ThinkPhp 使用 PHP_XLSXWriter 代替 PHPExcel 百万级数据单次导出

namespace app\index\controller; class Ablog extends Base * 入口方法 * 当PHPEXCEL导出大数据时,PHP内存溢出时,可使用该方法把数据分页追加到Excel文件 public function run(){ $title = self::getTitle(); //获取字段与标题的对应关系 $data = self::randData(); //生成所有数据 $count = count($data); //总记录数 $filePath = self::copyTableToExcel($title, $data, $count); echo '文件保存路径为:[ ' . $filePath . ' ]'; exit(); * 分页把table追加存入excel中 * @param $title 字段与标题的对应关系 * @param $data 所有数据 * @param $count 数据的总量 * @param int $limit 分页数量 * @return string 结果路径 public function copyTableToExcel($title, $data, $count, $limit = 10){ $path = 'download'; //设置文件保存的路径 if(!file_exists($path)){ //如果目录不存在,则创建 mkdir($path, 0777, true); $fileName = '数据分页导出:' . time() . '_' . mt_rand(1000, 9999) . '.xlsx'; //文件名 $filePath = $path . '/' . $fileName; //文件保存目录 $number = ceil($count / $limit); for($i = 1; $i <= $number; $i++) { //处理分页数据 $tableHtml = '<table border="1" cellspacing="0">'; if($i == 1){ //第一次分页才需要设置标题,其他分页只需设置table-body即可 $tableHtml .= '<tr>'; foreach ($title as $value) { $tableHtml .= "<th>{$value}</th>"; $tableHtml .= '</tr>'; //array_slice函数模拟分页数据 $start = $limit * ($i-1); $pageSize = $limit; $pageData = array_slice($data, $start, $pageSize); $tableHtml .= self::getTableBody($pageData, $title); file_put_contents($filePath, $tableHtml, FILE_APPEND); //unlink(str_replace('\\','/', $filePath)); //删除本地文件 return $filePath; * 处理表格Body数据 * @param $data 当前页的数据 * @param $title 字段与标题的对应关系 * @return string html字符串 public function getTableBody($data, $title){ $bodyHtml = ''; // 拼接表格body数据 foreach ($data as $value){ //一行数据 $bodyHtml .= '<tr>'; foreach ($title as $field => $name){ //一行中的一列数据 $bodyHtml .= "<td>{$value[$field]}</td>"; //$bodyHtml .= "<td style='vnd.ms-excel.numberformat:@'>{$value[$field]}</td>"; $bodyHtml .= '</tr>'; return $bodyHtml . '</table>'; * 设置表格第一列数据 * @return array public function getTitle(){ $title = [ 'id' => 'ID', 'order_sn' => '订单号', 'amount' => '订单金额', 'payed_name' => '下单人', 'create_time' => '创建时间' return $title; * 生成$number条随机数据 * @param int $number 数据的数量 * @return array public function randData($number = 100){ $data = []; for ($x = 0; $x < $number; $x++){ //订单号随机生成 $prefix = ''; if ($x%2 == 0){ $prefix = 'HELLO'; $orderSn = $prefix . 123456 . mt_rand(1000, 9999) . mt_rand(100, 999) . 999; //创建时间随机生成 $createTime = 1572 . mt_rand(100, 999) . mt_rand(100, 999); $data[] = [ 'id' => ($x+1), 'order_sn' => $orderSn, 'amount' => mt_rand(100, 999), 'payed_name' => '下单人', 'create_time' => date('Y-m-d H:i:s', $createTime) return $data;

2、【情况1】执行的结果:订单号为十几位数字时,被转成了科学计数法;创建时间也不整齐。

3、【情况2】修改

注释这一行

$bodyHtml .= "<td>{$value[$field]}</td>";

打开这一行

$bodyHtml .= "<td style='vnd.ms-excel.numberformat:@'>{$value[$field]}</td>";

4、【情况1】11KB 和【情况2】29KB 的文件大小对比,

二、php导出数据到excel,防止身份证等数字字符格式变成科学计数的方法

#以下内容来自 https://www.cnblogs.com/jcz1206/p/3837723.html
1、首先,我们了解一下excel从web页面上导出的原理。
当我们把这些数据发送到客户端时,我们想让客户端程序(浏览器)以excel的格式读取它,所以把mime类型设为:application/vnd.ms-excel,
当excel读取文件时会以每个cell的格式呈现数据,如果cell没有规定的格式,则excel会以默认的格式去呈现该cell的数据。
这样就给我们提供了自定义数据格式的空间,当然我们必须使用excel支持的格式。

2、下面就列出常用的一些格式:

    1) 文本:vnd.ms-excel.numberformat:@
    2) 日期:vnd.ms-excel.numberformat:yyyy/mm/dd
    3) 数字:vnd.ms-excel.numberformat:#,##0.00
    4) 货币:vnd.ms-excel.numberformat:¥#,##0.00
    5) 百分比:vnd.ms-excel.numberformat: #0.00%

这些格式你也可以自定义,比如年月你可以定义为:yy-mm等等。

3、那么知道了这些格式,怎么去把这些格式添加到cell中呢?
很简单,我们只需要把样式添加到对应的标签对(即闭合标签)即可。
如<td></td>,给标签对<td></td>添加样式,如下:

<td style="vnd.ms-excel.numberformat:@">410522198402161833</td>

同样,我们也可以给<div></div>添加样式,也可以给<tr></tr>,<table></table>添加样式;
当我们在父标签对和子标签对都添加样式时,数据会以哪一个样式呈现呢?经过测试,会以离数据最近的样式呈现.

4、转文本使用案例如下:
1)、直接在浏览器弹出框下载

echo "<td style='vnd.ms-excel.numberformat:@'>{$orderSn}</td>";

2)、拼接字符串,直接下载到项目中

$table = "<td style='vnd.ms-excel.numberformat:@'>{$orderSn}</td>";
PHP开发者在工作中经常会遇到,后台系统功能,每开发一个数据查询列表功能,都少不了对应的数据导出功能。PHP的技术栈中,通常会采用 PHPExcel 这个开源的库来解决数据导出问题。但在实际使用过程中,总是会遇到导出报超时,或超内存的问题,为业务方所诟病。这篇文章,我们分别从超时和超内存两个方面,分析原因,及提出对应的 解决方案 。超内存原因(1)导出内容过多。这是很容易理解的一个原因。导出的列与行越多,... phpExcel 将读取的单元格信息保存在内存中,我们可以通过复制代码 代码如下: PHPExcel _Settings::setCacheStorageMethod()来设置不同的缓存方式,已达到降低内存消耗的目的!1、将单元格数据序列化后保存在内存中复制代码 代码如下: PHPExcel _CachedObjectStorageFactory::cache_in_memory_serialized;2、... $objReader= PHPExcel _IOFactory::createReader('Excel2007'); $objReader->setReadDataOnly(true);//使用文件流读取文... 最近我们公司的项目的在导出excel的时候偶尔出现 内存溢出 错误,经过测试发现当数据量大于5000条就出现这个问题(默认php.ini memory 是128M)Allowedmemorysizeof134217728bytesexhausted(triedtoallocate43bytes)解决 内存溢出 问题方法如下增加内存了,修改php.ini中memo... 本篇文章给大家带来的内容是关于 phpExcel 在导出文件时 内存溢出 的解决方法,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。在使用 PHPExcel 导出文件时,经常会因为文件过大导致PHP 内存溢出 报错,为了解决这个问题,可以使用 PHPExcel 提供的参数进行优化。这里说的Excel文件过大并不一定是文件大小,更关键的在于文件内存放的数据和格式,如果数据很多,格式又比较丰富,那很容易会... php使用 phpexcel 读取excel的时候,如果excel本身行列较多,很容易引起Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes)内存不够的报错,于是我写了一段脚本,利用 phpexcel 过滤器实现块级读取,但是每次读取完毕了,占用的内存不会释放掉,造成多次读取以后还是会报出Allowe... 在使用 PHPExcel 导出文件时,经常会因为文件过大导致PHP 内存溢出 报错,为了解决这个问题,可以使用 PHPExcel 提供的参数进行优化。这里说的Excel文件过大并不一定是文件大小,更关键的在于文件内存放的数据和格式,如果数据很多,格式又比较丰富,那很容易会将PHP的内存耗尽。 资料2中指出,Excel中一个单元格在不启用缓存的情况下大概占用内存是1K,一个8000行、31列的表格(2... phpExcel 导出大量数据出现 内存溢出 错误解决办法我们经常会使用 phpExcel 导入或导入xls文件,但是如果一次导出数据比较大就会出现 内存溢出 错误,下面我来总结解决办法。 phpExcel 将读取的单元格信息保存在内存中,我们可以通过代码如下复制代码 PHPExcel _Settings::setCacheStorageMethod()来设置不同的缓存方式,已达到降低内存消耗的目的!1、将单元格数据序...