我有一个大约24 MB大小的xlsx文件。即使我只读第一行也需要太多时间。如果spout逐一读取每一行,那么为什么只要我只读第一行就需要花费太多时间?
以下是完整的代码
require_once 'src/Spout/Autoloader/autoload.php';
$file_path = $_SERVER["DOCUMENT_ROOT"].'spout'.'/'.'testdata.xlsx';
use Box\Spout\Reader\ReaderFactory;
use Box\Spout\Common\Type;
libxml_disable_entity_loader(false);
try {
//Lokasi file excel
$reader = ReaderFactory::create(Type::XLSX); //set Type file xlsx
$reader->open($file_path); //open the file
$i = 0;
/**
* Sheets Iterator. Kali aja multiple sheets
**/
foreach ($reader->getSheetIterator() as $sheet) {
//Rows iterator
foreach ($sheet->getRowIterator() as $row) {
echo $i."<hr>";
if($i==0) // if first row
{
print_r($row);
exit; // exist after reading first row
}
++$i;
}
exit;
}
echo "Total Rows : " . $i;
$reader->close();
echo "Peak memory:", (memory_get_peak_usage(true) / 1024 / 1024), " MB";
}
catch (Exception $e) {
echo $e->getMessage();
exit;
}
你能帮我解决一下这个问题的原因吗?我怎么能快速做到? 您可以在http://www.mediafire.com/file/y369njsaeeah1ip/testdata.xlsx
找到测试xlsx文件Excel文件包含以下内容:
答案 0 :(得分:0)
有两种方法可以使用XLSX文件存储单元格数据:
方法2优化文件的大小,因为使用N次的值将仅存储一次(但是被引用N次)。但是,要读取这些值,您现在需要读取2个文件,并在读取结构时准备好映射。基本上,为了读取第一行,您将读取结构以获取单元格(A1,B1,C1),然后您需要使用ID来解析值。
内联方法更直接,因为所有内容都存储在同一个地方,因此您可以同时读取结构和值。不需要映射表。
现在回到你的问题!您尝试阅读的文件最有可能使用方法2(描述电子表格结构的文件+包含所有值的文件)。当Spout进入阅读器时,它会处理包含值的文件,以便每当我们开始准备好行时映射就会就绪。
如果有很多值,此处理可能需要很长时间。低于某个阈值(取决于可用的内存量),Spout加载映射[ID =&gt;值]进入内存,这是非常快的。但是,如果值太多,Spout会确定所有内容都不适合内存并缓存磁盘上映射的块。这个过程绝对是耗时的......
所以这就是你的情况。希望现在更有意义。 最终门槛将会提高,因为Spout目前处于超级防御状态以避免内存不足问题。