phpexcel的大量数据导出[内存溢出测试验证]

PHPExcel导出文件会耗费大量资源,我采用默认的配置导出excel只能导出三万多条加下下列配置可以到达十万+

用中需要注意,PHPExcel的内存优化参数并不在PHPExcel对象中,需要在PHPExcel实例化之前设置。

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;
$cacheSettings = array('memoryCacheSize'=>'2048MB');
PHPExcel_Settings::setCacheStorageMethod($cacheMethod,$cacheSettings);
$oExcel = new PHPExcel();
PHPExcel_Settings::setCacheStorageMethod() 的几个参数

将单元格数据序列化后保存在内存中

PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized;

将单元格序列化后再进行Gzip压缩,然后保存在内存中(不使用mencache情况下推荐使用这个)

PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;

缓存在临时的磁盘文件中,速度可能会慢一些

PHPExcel_CachedObjectStorageFactory::cache_to_discISAM;

保存在php://temp

PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;

保存在memcache中

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache; 
$cacheSettings = array( 'memcacheServer'  => 'localhost', 
    'memcachePort'    => 11211, 
    'cacheTime'       => 600 
); 
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);

其它降低内存使用的方法 如果不需要读取Excel单元格格式,可以设置为只读取数据。

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load("test.xlsx”);

如果Excel中有多个Sheet,但是我们只需要读取其中几个,为了减少内存消耗,也可以设置。

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setLoadSheetsOnly( array("Worksheet1", "Worksheet2") );
$objPHPExcel = $objReader->load("test.xlsx”);

如果只需要读取Sheet中一定区域,也可以设置过滤器。

class MyReadFilter implements PHPExcel_Reader_IReadFilter
{
    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }
        return false;
    }
}
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadFilter( new MyReadFilter() );
$objPHPExcel = $objReader->load("test.xlsx”);

最后我用的版本是1.8,所有没有下面这个方法,这是参考其他大佬的

// 如果是因为特殊字符引起的,可以在load方法之前加上setReadDataOnly(意思是忽略任何格式的信息)方法,就可以避免
$objReader->setReadDataOnly(true);//只需要添加这个方法
$objPHPExcel = $objReader->load($uploadFilePath);

下面是使用相同数据导出测试的结果相信大家就知道用哪个了

cache_in_memory_gzip 
10:58:44 写入Workbook中耗时 0.0248 秒EOL
10:58:44 当前内存使用情况: 4.5 MBEOL
10:58:44 内存使用峰值: 4.75 MBEOL

cache_in_memory_serialized
11:00:35 写入Workbook中耗时 0.0246 秒EOL
11:00:35 当前内存使用情况: 5 MBEOL
11:00:35 内存使用峰值: 5.25 MBEOL

cache_to_discISAM
11:02:00 写入Workbook中耗时 0.0235 秒EOL
11:02:00 当前内存使用情况: 5.25 MBEOL
11:02:00 内存使用峰值: 5.5 MBEOL


cache_to_phpTemp
11:03:23 写入Workbook中耗时 0.0239 秒EOL
11:03:23 当前内存使用情况: 5.25 MBEOL
11:03:23 内存使用峰值: 5.5 MBEOL

测试代码也发下

        $callStartTime = microtime(true);
        $objWriter = PHPExcel_IOFactory::createWriter($this->obj, 'Excel2007');
        $callEndTime = microtime(true);
        $callTime = $callEndTime - $callStartTime;
        echo date('H:i:s'), ' 写入Workbook中耗时 ', sprintf('%.4f', $callTime), " 秒", EOL;
        echo PHP_EOL;
        echo date('H:i:s'), ' 当前内存使用情况: ', (memory_get_usage(true) / 1024 / 1024), " MB", EOL;
        echo PHP_EOL;
        echo date('H:i:s'), " 内存使用峰值: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL;
        echo PHP_EOL;

总结:我再相服务器情况下不加缓存只能导出三万多天数据,加上缓存后可以导出10万+条,当然设置了程序执行时间和设置php可使用内存

        ini_set('memory_limit', '-1');// 设置php可使用内存
        set_time_limit(0);  # 设置执行时间最大值

大海技术博客
请先登录后发表评论
  • latest comments
  • 总共1条评论
大海技术博客 大海技术博客

dahaipublic大海技术博客

2021-03-29 09:27:31 回复