当前位置:
首页 > 技术 > PHPExcel 导出大量数据缓存设置

PHPExcel 导出大量数据缓存设置

最近做项目,接触了几次PHPExcel,过程中遇到了几个问题,现对PHPExcel的一些常见用法和我遇到的问题及解决方法总结如下。(推荐还是要看一下PHPExcel官网的手册)

?

一、常见用法

??? 这个部分网站上有很多资料了,我这里不再一一罗列,只是将我用到的几个地方写了一下。

Php代码
  1. <?
  2. //首先要导入phpexcel
  3. require_once?($yourpath.'PHPExcel.php');
  4. //创建phpexcel对象
  5. $objPHPExcel?=?new?PHPExcel?();
  6. //设置属性
  7. $objPHPExcel->getProperties?()->setCreator?(?"Miss?Yang"?)
  8. ????????->setLastModifiedBy?(?"Miss?Yang"?)
  9. ????????->setTitle?(?"Office?2003?XLS?Document"?)
  10. ????????->setSubject?(?"Office?2003?XLS?Document"?)
  11. ????????->setDescription?(?"TrunkBow"?)
  12. ????????->setKeywords?(?"TrunkBow"?)
  13. ????????->setCategory?(?"TrunkBow"?);
  14. //设置当前的sheet索引,用于后续的内容操作。??
  15. //缺省情况下,PHPExcel会自动创建第一个sheet被设置SheetIndex=0??
  16. $objExcel->setActiveSheetIndex(0);
  17. $objActSheet?=?$objExcel->getActiveSheet();
  18. ?//设置当前活动sheet的名称??
  19. $objActSheet->setTitle('Sheet1');
  20. //设置单元格内容
  21. ?$objActSheet->setCellValue('A1',?'字符串内容');??//?字符串内容??
  22. ?$objActSheet->setCellValue('A2',?26);????????????//?数值??
  23. ?$objActSheet->setCellValue('A3',?true);??????????//?布尔值??
  24. ?$objActSheet->setCellValue('A4',?'=SUM(A2:A2)');?//?公式???
  25. //显式指定内容类型??
  26. ?$objActSheet->setCellValueExplicit('A5','8757584',PHPExcel_Cell_DataType::TYPE_STRING);
  27. //设置单元格格式
  28. $objActSheet?->getStyle?('A1'?)
  29. ?????????????->getFont?()
  30. ?????????????->getColor()
  31. ?????????????->setARGB(PHPExcel_Style_Color::COLOR_RED);
  32. $objActSheet?->getStyle?('A1'?)
  33. ?????????????->getFont?()
  34. ?????????????->setBold(true);
  35. $objActSheet?->getStyle?('A')
  36. ?????????????->getNumberFormat()
  37. ?????????????->setFormatCode?(?PHPExcel_Style_NumberFormat::FORMAT_TEXT?);
  38. $objActSheet?->getColumnDimension?('A')
  39. ?????????????->setWidth(20);
  40. $objActSheet?->getColumnDimension?('B')
  41. ?????????????->setAutoSize(true);
  42. $activeSheet?->getColumnDimension('C')
  43. ?????????????->setVisible(false);
  44. //生成下拉列表框
  45. $list?=?"item1,item2,item3";
  46. $objValidation1?=?$activeSheet->getCell('A1')->getDataValidation();
  47. $objValidation1->setType(?PHPExcel_Cell_DataValidation::TYPE_LIST?)
  48. ???????????????->setErrorStyle(PHPExcel_Cell_DataValidation::STYLE_INFORMATION?)
  49. ???????????????->setAllowBlank(false)
  50. ???????????????->setShowInputMessage(true)
  51. ???????????????->setShowErrorMessage(true)
  52. ???????????????->setShowDropDown(true)
  53. ???????????????->setErrorTitle('输入的值有误')
  54. ???????????????->setError('您输入的值不在下拉框列表内.')
  55. ???????????????->setPromptTitle('下拉选择框')
  56. ???????????????->setPrompt('请从下拉框中选择您需要的值!')
  57. ???????????????->setFormula1('"'?.?$list?.?'"');
  58. //下载输出
  59. $filename?=?"testphp.xls";
  60. $filename?=?iconv("utf-8",?'gbk',?$filename);
  61. $objWriter?=?PHPExcel_IOFactory::createWriter?(?$objPHPExcel,?'Excel5'?);
  62. header?(?'Content-Type:?application/vnd.ms-excel'?);
  63. header?(?"Content-Disposition:?attachment;filename=$filename"?);
  64. header?(?'Cache-Control:?max-age=0'?);
  65. $objWriter->save?(?'php://output'?);
  66. exit(0);

 

二、问题总结

1.单元格内容为长数字的,输出时,总是转成科学计数法。

??? 这个问题网上也有不少资料提到的,大多是说要修改几个地方的源码。但是我一直没找到对应的源码在哪里,可能是版本不同的原因。我是这样解决的:

 

Php代码
  1. //显示指定内容类型
  2. ?$objActSheet->setCellValueExplicit('A5','8757584',PHPExcel_Cell_DataType::TYPE_STRING);

 

2.PHPExcel占用内存过大。

PHPExcel是一个很强大的处理Excel的PHP开源类,但是很大的一个问题就是它占用内存太大,从1.7.3开始,它支持设置cell的缓存方式,但是推荐使用目前稳定的版本1.7.6,因为之前的版本都会不同程度的存在bug。

官网上是这么说的:PHPExcel平均下来使用1k/单元格的内存,因此大的文档会导致内存消耗的也很快。单元格缓存机制能够允许PHPExcel将内存中的小的单元格对象缓存在磁盘或者APC,memcache或者Wincache中,尽管会在读取数据上消耗一些时间,但是能够帮助你降低内存的消耗。默认情况下,PHPExcel依然将单元格对象保存在内存中,但是你可以自定义。你可以使用PHPExcel_Settings::setCacheStorageMethod()方法,将缓存方式作为参数传递给这个方法来设置缓存的方式。

 

Php代码
  1. $cacheMethod?=?PHPExcel_CachedObjectStorageFactory::cache_in_memory;
  2. PHPExcel_Settings::setCacheStorageMethod($cacheMethod);

 

setCacheStorageMethod()方法会返回一个BOOL型变量用于表示是否成功设置(比如,如果APC不能使用的时候,你设置使用APC缓存,将会返回false)。每一个worksheet都会有一个独立的缓存,当一个worksheet实例化时,就会根据设置或配置的缓存方式来自动创建。一旦你开始读取一个文件或者你已经创建了第一个worksheet,就不能在改变缓存的方式了。目前,有以下几种缓存方式可以使用:

1). PHPExcel_CachedObjectStorageFactory::cache_in_memory;

默认情况下,如果你不初始化任何缓存方式,PHPExcel将使用内存缓存的方式。

2).PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized;??

使用这种缓存方式,单元格会以序列化的方式保存在内存中,这是降低内存使用率性能比较高的一种方案。

3). PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;

与序列化的方式类似,这种方法在序列化之后,又进行gzip压缩之后再放入内存中,这回跟进一步降低内存的使用,但是读取和写入时会有一些慢。

4). PHPExcel_CachedObjectStorageFactory::cache_to_discISAM;

当使用cache_to_discISAM这种方式时,所有的单元格将会保存在一个临时的磁盘文件中,只把他们的在文件中的位置保存在PHP的内存中,这会比任何一种缓存在内存中的方式都慢,但是能显著的降低内存的使用。临时磁盘文件在脚本运行结束是会自动删除。

5). PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;

????? 类似cache_to_discISAM这种方式,使用cache_to_phpTemp时,所有的单元格会还存在php://temp I/O流中,只把他们的位置保存在PHP的内存中。PHP的php://memory包裹器将数据保存在内存中,php://temp的行为类似,但是当存储的数据大小超过内存限制时,会将数据保存在临时文件中,默认的大小是1MB,但是你可以在初始化时修改它:

 

Php代码
  1. $cacheMethod?=?PHPExcel_CachedObjectStorageFactory::?cache_to_phpTemp;
  2. $cacheSettings?=?array(?'?memoryCacheSize?'?=>?'8MB'?);
  3. PHPExcel_Settings::setCacheStorageMethod($cacheMethod,?$cacheSettings);

 

 

php://temp文件在脚本结束是会自动删除。

6). PHPExcel_CachedObjectStorageFactory::cache_to_apc;

当使用cach_to_apc时,单元格保存在APC中,只在内存中保存索引。APC缓存默认超时时间时600秒,对绝大多数应用是足够了,当然你也可以在初始化时进行修改:

 

Php代码
  1. $cacheMethod?=?PHPExcel_CachedObjectStorageFactory::cache_to_APC;
  2. $cacheSettings?=?array(?'cacheTime'?=>?600?);
  3. PHPExcel_Settings::setCacheStorageMethod($cacheMethod,?$cacheSettings);

 

 

当脚本运行结束时,所有的数据都会从APC中清楚(忽略缓存时间),不能使用此机制作为持久缓存。

7).PHPExcel_CachedObjectStorageFactory::cache_to_memcache

??????? 使用cache_to_memory时,单元格对象保存在memcache中,只在内存中保存索引。默认情况下,PHPExcel会在localhost和端口11211寻找memcache服务,超时时间600秒,如果你在其他服务器或其他端口运行memcache服务,可以在初始化时进行修改:

Php代码
  1. $cacheMethod?=?PHPExcel_CachedObjectStorageFactory::cache_to_memcache;
  2. $cacheSettings?=?array(?'memcacheServer'=>?'localhost',
  3. ???????????????????????????????????????'memcachePort'?=>?11211,
  4. ???????????????????????????????????????'cacheTime'?=>?600?);
  5. PHPExcel_Settings::setCacheStorageMethod($cacheMethod,?$cacheSettings);

???????从初始化设置的形式上看,MS还不支持多台memcache服务器轮询的方式,比较遗憾。

?当脚本结束时,所有的数据都会从memcache清空(忽略缓存时间),不能使用该机制进行持久存储。

3.下拉列表的数据来源过长

??? 我们还是先来看手册是怎么说的:

It is important to remember that any string participating in an Excel formula is allowed to be maximum 255 characters (not bytes).

???? 当下拉列表的数据来源过长(more than 255 characters)时,该下拉列表会显示不正确(我遇到的情况是:该下拉列表显示了别的正常的下拉列表的数据来源).

以下是我的解决办法:

 

Php代码
  1. //解决下拉框数据来源字串长度过大:将每个来源字串分解到一个空闲的单元格中
  2. $str_list?=?"item1,item2,item3,......"?;
  3. $str_len?=?strlen($str_list);
  4. if($str_len>=255){
  5. ????????$str_list_arr?=?explode(',',?$str_list);
  6. ????????if($str_list_arr)
  7. ??????????????foreach($str_list_arr?as?$i?=>$d){
  8. ?????????????????????$c?=?"P".($i+1);
  9. ?????????????????????$activeSheet->setCellValue($c,$d);
  10. ???????????????}
  11. ?????????$endcell?=?$c;
  12. ?????????$activeSheet->getColumnDimension('P')->setVisible(false);
  13. }
  14. $objValidation2?=?$activeSheet->getCell("A1")->getDataValidation();
  15. $objValidation2->setType(?PHPExcel_Cell_DataValidation::TYPE_LIST?)
  16. ????????????????->setErrorStyle(?PHPExcel_Cell_DataValidation::STYLE_INFORMATION?)
  17. ???????????????->setAllowBlank(true)
  18. ???????????????->setShowInputMessage(true)
  19. ???????????????->setShowErrorMessage(true)
  20. ???????????????->setShowDropDown(true)
  21. ???????????????->setErrorTitle('输入的值有误')
  22. ???????????????->setError('您输入的值不在下拉框列表内.')
  23. ???????????????->setPromptTitle('下拉选择框')
  24. ???????????????->setPrompt('请从下拉框中选择您需要的值!');
  25. if($str_len<255)
  26. ???????$objValidation2->setFormula1('"'?.?$str_list?.?'"');
  27. else
  28. ???????$objValidation2->setFormula1("sheet1!P1:{$endcell}");

4.本地运行正常,服务器上PHPExcel不能运行

官网:

????????? The following software is required to develop using PHPExcel:

?????????? ? PHP version 5.2.0 or newer

?????????? ? PHP extension php_zip enabled *)

???????????? PHP extension php_xml enabled

???????????? PHP extension php_gd2 enabled (if not compiled in)

? 另外,请检查iconv扩展是否正常,PHPExcel需要他的支持

PHPExcel 导出大量数据缓存设置:等您坐沙发呢!

发表评论

您必须 [ 登录 ] 才能发表留言!