由于使用PHPExcel超时,我正在尝试Spout。
我了解它与PHPExcel的不同之处在于它一次读取一行。我尝试了一个具有116,652行(约21MB)的文件,在代码中的特定位置插入了日志记录,以跟踪所需的时间。
令我惊讶的是(使用ReaderFactory类实例化$ reader之后):
$reader->open($inputFileName);
花30分钟执行。
我缺少某些设置吗?我没有做任何与here相同的指示。
答案 0 :(得分:0)
116,000行30分钟绝对不正常。使用open
时,sharedStrings
函数可能要花一些时间(与inlineStrings
相反)。 Excel默认情况下使用共享字符串(优化XLSX文件的大小),而Spout默认情况下使用内联字符串(优化未来的读取性能)。
要了解可能出什么问题,让我解释一下open
函数中所做的事情:
XLSX文件是压缩在一起的一堆XML文件。每个XML文件都包含描述电子表格的特定数据。有一个描述电子表格结构的XML文件(行1>单元格A1> A1值-单元格B1> B1值-行2>单元格A2> A2值,...)。
单元格的值可以是内联的,因此直接存在于此文件中,或者对于字符串,这些值可能仅包含引用。因此,例如,A1的值是带有引用1的字符串,A2的值是引用3的字符串,依此类推。这对于空间优化很有用,因为重复的值将只存储一次。仅其参考文献将被复制。共享字符串就是这样工作的。
因此,当Spout读取使用共享字符串的XLXS文件时,它需要知道哪个字符串对应于引用1或3。为此,它首先需要读取包含所有这些字符串的文件并将映射存储在某个位置(字符串1 =“ foo”,字符串3 =“ bar”),以便在读取包含电子表格结构的文件时,可以将“带参考1的字符串”转换为“ foo”。
如果包含共享字符串的文件很大,则Spout不会尝试将映射“字符串引用” =>“实际值”保留在内存中,而是将此文件拆分为较小的块。整个过程(读取+拆分)需要一段时间,因此在open
执行过程中需要很长时间。
现在,除非您有大量的单元格,否则应该不需要30分钟。 最可能的原因是您的电子表格包含多个工作表(它们可能是隐藏的,但Spout仍会处理所有字符串)。
因此请检查,如果不是这个原因,请create an issue on Github,附加有问题的文件。