8

我有一个脚本可以生成一个小 xls 表(~25x15)。它包含百分比和字符串,我有一个 if 运算符,它使用以下代码将当前单元格设置为百分比类型:

$this->objPHPExcel->getActiveSheet()->getStyle($coords)->getNumberFormat()->setFormatCode('0.00%');

但是当我导出并查看文件时,我发现它只设置了大约 20 个单元格的类型和样式。其余的都是默认设置。我调试它并意识到问题不在我的逻辑中。我阅读了有关增加 php 缓存内存的信息 - 尝试过但没有用。请帮忙,因为我需要导出至少 15 倍大的表。提前致谢!

4

3 回答 3

3

PHPExcel 分配了相当多的内存

虽然 PHPExcel 是一个漂亮的库,但使用它可能需要为 PHP 分配大量内存。

根据这个线程,只有5 个单元格可能会产生 6 MB的内存使用量:

<?php
require_once 'php/PHPExcelSVN/PHPExcel/IOFactory.php';
$objPHPExcel = PHPExcel_IOFactory::load("php/tinytest.xlsx");
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setCellValue('D2', 50);
echo $objPHPExcel->getActiveSheet()->getCell('D8')->getCalculatedValue() . "
";
echo date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB\r\n";
?>

I get 6MB of memory usage.

另一个用户甚至在 256MByte 内存设置上失败了。

虽然 PHPExcel 提供了减少内存占用的方法,但在我的情况下,所有减少都太小了。github 上的这个页面提供了 PHPExcel 的缓存管理选项的详细信息。例如,此设置序列化和 GZIP 工作表的单元格结构:

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;

PHPExcel_Settings::setCacheStorageMethod($cacheMethod);

PHPExcel 的常见问题解答解释了这一点:

致命错误:在 aaa 线上的 zzz 中,允许的 xxx 字节内存大小已用尽(试图分配 yyy 字节)

PHPExcel 拥有电子表格的“内存中”表示,因此它容易受到 PHP 的内存限制的影响。可以通过在 php.ini 文件中编辑 memorylimit 指令的值,或在代码中使用 iniset('memory_limit', '128M') 来增加 PHP 可用的内存(ISP 允许);

一些 Readers 和 Writers 比其他的更快,而且它们使用的内存量也不同。您可以在此处http://phpexcel.codeplex.com/Thread/View.aspx?ThreadId=234150找到不同版本的 PHPExcel 中不同 Readers 和 Writers 的相对性能和内存使用情况的一些指示

如果您已经将内存增加到最大值,或者无法更改内存限制,那么板上的这个讨论描述了一些可用于减少使用 PHPExcel 的脚本的内存使用的方法 http://phpexcel .codeplex.com/Thread/View.aspx?ThreadId=242712

PHP Excel 的测量结果

我检测了 PHPExcel 示例文件[01simple.php][5]并进行了一些快速测试

消耗92 KB

for( $n=0; $n<200; $n++ ) {
    $objPHPExcel->setActiveSheetIndex(0) ->setCellValue('A' . $n, 'Miscellaneous glyphs');
}

消耗4164 KB

for( $n=0; $n<200; $n++ ) {
    $objPHPExcel->setActiveSheetIndex(0) ->setCellValue('A' . $n, 'Miscellaneous glyphs');
    $objPHPExcel->getActiveSheet()->getStyle('A' . $n)->getAlignment()->setWrapText(true);
}

如果执行这个片段多次不变,每个片段消耗大约 4 MBytes。

检查您的应用在逻辑上是否正确

为确保您的应用程序在逻辑上正确,我建议首先增加 PHP 内存:

ini_set('memory_limit', '32M');

就我而言,我必须导出以导出在线评估应用程序的结果数据。虽然水平方向的单元格少于 100 个,但我需要导出多达 10.000 行。虽然单元格的数量很大,但我的每个单元格都包含一个数字或 3 个字符的字符串 - 没有公式,没有样式。

如果存在强大的内存限制或大型电子表格

在我的情况下,没有一个缓存选项可以减少所需的数量。此外,应用程序的运行时间大幅增长。

最后我不得不切换到老式的 CSV 数据文件导出。

于 2013-08-11T15:27:44.960 回答
2

我在本地运行了您的代码,发现您设置为该百分比的所有 26 个单元格都具有正确的格式和 % 符号。当然,我必须首先取消注释第 136-137 行。

这必须与您的设置有关。我无法想象您对于这种大小的电子表格的内存太少了。

供您参考,我确认它适用于 PHP 版本 5.4.16 和 php excel 版本版本 1.7.6,2011-02-27。我用 MS Excel 2007 打开了电子表格。

于 2013-08-12T15:58:10.957 回答
1
<?php
$file = 'output_log.txt';

function get_owner($file)
{
    $stat = stat($file);
    $user = posix_getpwuid($stat['uid']);
    return $user['name'];
}

$format = "UID @ %s: %s\n";

printf($format, date('r'), get_owner($file));

chown($file, 'ross');
printf($format, date('r'), get_owner($file));

clearstatcache();
printf($format, date('r'), get_owner($file));
?>

clearstatcache(); 可能有用。在 php 页面的开头加载此函数。

于 2013-08-05T05:23:32.657 回答