PHPExcel
の使用時に発生したいくつかの問題
私は最近、あるプロジェクトに取り組んでいて、何度か PHPExcel に遭遇しました。その過程でいくつかの問題が発生しました。PHPExcel と私が遭遇した問題の解決策を以下にまとめます。 (PHPExcel 公式 Web サイトにあるマニュアルを読むことをお勧めします)
?
1. 一般的な使用法
??? ウェブサイトのこの部分には多くの情報がありますので、ここでは 1 つずつ記載しません。使用した場所。
?
<? //首先要导入phpexcel require_once ($yourpath.'PHPExcel.php'); //创建phpexcel对象 $objPHPExcel = new PHPExcel (); //设置属性 $objPHPExcel->getProperties ()->setCreator ( "Miss Yang" ) ->setLastModifiedBy ( "Miss Yang" ) ->setTitle ( "Office 2003 XLS Document" ) ->setSubject ( "Office 2003 XLS Document" ) ->setDescription ( "TrunkBow" ) ->setKeywords ( "TrunkBow" ) ->setCategory ( "TrunkBow" ); //设置当前的sheet索引,用于后续的内容操作。 //缺省情况下,PHPExcel会自动创建第一个sheet被设置SheetIndex=0 $objExcel->setActiveSheetIndex(0); $objActSheet = $objExcel->getActiveSheet(); //设置当前活动sheet的名称 $objActSheet->setTitle('Sheet1'); //设置单元格内容 $objActSheet->setCellValue('A1', '字符串内容'); // 字符串内容 $objActSheet->setCellValue('A2', 26); // 数值 $objActSheet->setCellValue('A3', true); // 布尔值 $objActSheet->setCellValue('A4', '=SUM(A2:A2)'); // 公式 //显式指定内容类型 $objActSheet->setCellValueExplicit('A5','8757584',PHPExcel_Cell_DataType::TYPE_STRING); //设置单元格格式 $objActSheet ->getStyle ('A1' ) ->getFont () ->getColor() ->setARGB(PHPExcel_Style_Color::COLOR_RED); $objActSheet ->getStyle ('A1' ) ->getFont () ->setBold(true); $objActSheet ->getStyle ('A') ->getNumberFormat() ->setFormatCode ( PHPExcel_Style_NumberFormat::FORMAT_TEXT ); $objActSheet ->getColumnDimension ('A') ->setWidth(20); $objActSheet ->getColumnDimension ('B') ->setAutoSize(true); $activeSheet ->getColumnDimension('C') ->setVisible(false); //生成下拉列表框 $list = "item1,item2,item3"; $objValidation1 = $activeSheet->getCell('A1')->getDataValidation(); $objValidation1->setType( PHPExcel_Cell_DataValidation::TYPE_LIST ) ->setErrorStyle(PHPExcel_Cell_DataValidation::STYLE_INFORMATION ) ->setAllowBlank(false) ->setShowInputMessage(true) ->setShowErrorMessage(true) ->setShowDropDown(true) ->setErrorTitle('输入的值有误') ->setError('您输入的值不在下拉框列表内.') ->setPromptTitle('下拉选择框') ->setPrompt('请从下拉框中选择您需要的值!') ->setFormula1('"' . $list . '"'); //下载输出 $filename = "testphp.xls"; $filename = iconv("utf-8", 'gbk', $filename); $objWriter = PHPExcel_IOFactory::createWriter ( $objPHPExcel, 'Excel5' ); header ( 'Content-Type: application/vnd.ms-excel' ); header ( "Content-Disposition: attachment;filename=$filename" ); header ( 'Cache-Control: max-age=0' ); $objWriter->save ( 'php://output' ); exit(0);
?
?
?
2. 問題の概要
1.セルの内容が長い数値の場合、出力時に必ず科学表記法に変換されます。
?
??? この問題についてはオンラインで多くの情報があり、そのほとんどはソース コードの複数の場所を変更する必要があると述べています。しかし、バージョンが異なるため、対応するソースコードが見つかりませんでした。これが私がそれを解決した方法です:
?
//显示指定内容类型 $objActSheet->setCellValueExplicit('A5','8757584',PHPExcel_Cell_DataType::TYPE_STRING);
??
2.PHPExcel はメモリを大量に消費します。
?
PHPExcel は、Excel を処理するための非常に強力な PHP オープンソース クラスですが、メモリを大量に消費するという大きな問題があります。 1.7.3 以降では、cell のキャッシュ方法の設定がサポートされていますが、以前のバージョンではないため、現在の安定バージョン 1.7.6 を使用することをお勧めします。 バグが存在します。
公式 Web サイトには次のように書かれています: PHPExcel は平均して 1k/ 個のセル メモリを使用するため、大きなドキュメントではメモリの消費が非常に速くなります。セル キャッシュ メカニズムにより、 PHPExcel はディスク上のメモリ、または APC、memcache、または Wincache に小さなセル オブジェクトをキャッシュできます。データの読み取りに時間がかかるため、メモリ消費量を削減できます。デフォルトでは、PHPExcel はセル オブジェクトをメモリに保存しますが、カスタマイズすることができます。 PHPExcel_Settings::setCacheStorageMethod() メソッドを使用し、キャッシュ メソッドをパラメータとしてこのメソッドに渡して、キャッシュ メソッドを設定できます。
??
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory; PHPExcel_Settings::setCacheStorageMethod($cacheMethod);
?
?
setCacheStorageMethod() メソッドは、設定が成功したかどうかを示す BOOL 型変数を返します (たとえば、APC が成功できない場合) APC キャッシュを使用するように設定した場合、false が返されます)。各 ワークシート は独立したキャッシュを持ちます。ワークシート がインスタンス化されると、設定または構成されたキャッシュ メソッドに従って自動的に作成されます。ファイルの読み取りを開始するか、最初のワークシートを作成した後は、キャッシュ方法を変更することはできません。現在、次のキャッシュ方法が利用可能です:
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,但是你可以在初始化时修改它:
$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp; $cacheSettings = array( ' memoryCacheSize ' => '8MB' ); PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
?
?
php://temp文件在脚本结束是会自动删除。
?
6). PHPExcel_CachedObjectStorageFactory::cache_to_apc;
当使用cach_to_apc时,单元格保存在APC中,只在内存中保存索引。APC缓存默认超时时间时600秒,对绝大多数应用是足够了,当然你也可以在初始化时进行修改:
?
?
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_APC; $cacheSettings = array( 'cacheTime' => 600 ); PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); ?
?
?
当脚本运行结束时,所有的数据都会从APC中清楚(忽略缓存时间),不能使用此机制作为持久缓存。
?
7).PHPExcel_CachedObjectStorageFactory::cache_to_memcache
??????? 使用cache_to_memory时,单元格对象保存在memcache中,只在内存中保存索引。默认情况下,PHPExcel会在localhost和端口11211寻找memcache服务,超时时间600秒,如果你在其他服务器或其他端口运行memcache服务,可以在初始化时进行修改:
?
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache; $cacheSettings = array( 'memcacheServer'=> 'localhost', 'memcachePort' => 11211, 'cacheTime' => 600 ); 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)时,该下拉列表会显示不正确(我遇到的情况是:该下拉列表显示了别的正常的下拉列表的数据来源).
以下是我的解决办法:
//解决下拉框数据来源字串长度过大:将每个来源字串分解到一个空闲的单元格中
$str_list = "item1,item2,item3,......" ;
$str_len = strlen($str_list);
if($str_len>=255){
$str_list_arr = explode(',', $str_list);
if($str_list_arr)
foreach($str_list_arr as $i =>$d){
$c = "P".($i+1);
$activeSheet->setCellValue($c,$d);
}
$endcell = $c;
$activeSheet->getColumnDimension('P')->setVisible(false);
}
$objValidation2 = $activeSheet->getCell("A1")->getDataValidation();
$objValidation2->setType( PHPExcel_Cell_DataValidation::TYPE_LIST )
->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION )
->setAllowBlank(true)
->setShowInputMessage(true)
->setShowErrorMessage(true)
->setShowDropDown(true)
->setErrorTitle('输入的值有误')
->setError('您输入的值不在下拉框列表内.')
->setPromptTitle('下拉选择框')
->setPrompt('请从下拉框中选择您需要的值!');
if($str_len<255)
$objValidation2->setFormula1('"' . $str_list . '"');
else
$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需要他的支持
?
?
?