我想读取一个在Microsoft Excel中创建的xlsx
文件,但是当我运行以下代码时...
$Source_File = "test.xlsx";
$Spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($Source_File);
我收到以下错误信息:
Fatal error: Uncaught PhpOffice\PhpSpreadsheet\Reader\Exception: Unable to identify a reader for this file in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php:163
Stack trace:
#0 /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php(93): PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile('file:///home/ar...')
#1 /var/www/html/Function_Spreadsheet.php(480): PhpOffice\PhpSpreadsheet\IOFactory::load('file:///home/ar...')
#2 /var/www/html/Function_Home.php(3747): Spreadsheet_Reader_1('/var/www/html/F...', 3745, Array, Array)
#3 {main} thrown in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php on line 163
如果我使用$Spreadsheet = IOFactory::load($Source_File);
代替,我将会得到相同的错误。
如果我使用$Spreadsheet = $reader->load($Source_File);
代替,我将会得到以下错误。
Warning: ZipArchive::getFromName(): Invalid or uninitialized Zip object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 311
Warning: ZipArchive::getFromName(): Invalid or uninitialized Zip object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 313
Notice: Trying to get property 'Relationship' of non-object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 350
Warning: Invalid argument supplied for foreach() in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 350
Warning: ZipArchive::getFromName(): Invalid or uninitialized Zip object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 311
Warning: ZipArchive::getFromName(): Invalid or uninitialized Zip object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 313
Notice: Trying to get property 'Relationship' of non-object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 397
Warning: Invalid argument supplied for foreach() in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 397
Warning: ZipArchive::getFromName(): Invalid or uninitialized Zip object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 311
Warning: ZipArchive::getFromName(): Invalid or uninitialized Zip object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 313
Notice: Trying to get property 'Override' of non-object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 1855
Warning: Invalid argument supplied for foreach() in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 1855
Warning: ZipArchive::close(): Invalid or uninitialized Zip object in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 1883
我使用在Ubuntu 18.04上的Apache中的PHP v7.2脚本可以读取和打开文件。我阅读了几篇论坛帖子,建议如下操作:
我尝试在LibreOffice中打开该文件,并将其另存为xlsx
格式,但仍然出现相同错误(如果保存为xls
则不会有错误)。
我可以创建一个读取器$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
,但当我运行$Spreadsheet = $reader->load($Source_File);
或$Spreadsheet = IOFactory::load($Source_File);
时,我得到相同的错误。
此外,我可以创建一个可以读取xls
文件的xls读取器。我还可以创建一个xlsx读取器,但它无法读取xlsx文件,尝试读取xlsx文件时会出现同样的错误。那么,为什么对于xlsx
文件会出现错误?
我还阅读了错误消息所指向的源代码(IOFactory.php
),并找到了错误发生的位置(大约在第139行附近)...
//Let's see if we are lucky
if (isset($reader) && $reader->canRead($filename))
{
return $reader;
}
......而我搜索了/vendor/phpoffice/phpspreadsheet/
中的所有内容,却找不到canRead
的定义。 canRead
的定义在哪里呢?我认为如果我能阅读canRead
的定义,那么或许我就能理解问题的根本原因。
更新:
我从评论和讨论中了解到,canRead()
在\PhpSpreadsheet\Reader\Xlsx.php
中定义,大约从第65行开始。 在canRead()
中,$zip->open($pFilename)
返回一个错误代码ZipArchive::ER_NOENT
,这意味着"没有这个文件"。然而,文件是存在的。 那么,为什么会发生这种错误?
更新-2018-12-18
这个网页表明有多种类型的xlsx文件。因此,我运行file test.xlsx
,显示Microsoft Excel 2007+
。然后我在LibreOffice Calc中打开电子表格,并将其保存为OOXML类型的xlsx文件,然后重新运行file test.xlsx
,显示Microsoft OOXML
。然后我重新运行PHP脚本,但是仍然得到相同的错误。因此,似乎我的xlsx
文件类型不是问题所在。
因此,我决定使用PHPExcel(尽管它已被弃用)完成一些必要的工作。当我使用PHPExcel运行脚本时,我收到了一个关于canRead()
无法检测到xlsx
文件的类似错误。
所以,我继续阅读这个网页并遵循wesood
的最后建议,该建议来自这个网页中接受的答案。这个解决方案对我有用:在文件/PHPExcel/IOFactory.php
中,我在if (isset($reader) && $reader->canRead($filename))
之前立即添加了PHPExcel_Settings::setZipClass(\PHPExcel_Settings::PCLZIP);
。
然而,我仍然想知道如何在PhpSpreadsheet中解决这个问题。看来我需要了解更多关于pclzip的工作原理,以及是否需要对PhpSpreadsheet执行类似的操作。
更新2019年2月10日:
今天我尝试运行脚本,似乎添加PHPExcel_Settings::setZipClass(\PHPExcel_Settings::PCLZIP);
不再起作用了。所以,我又卡住了......
我做错了什么? 欢迎任何帮助!
更新2019-02-18:
根据评论中的建议,我使用在谷歌搜索结果中找到的随机XLSX文件(例如这个文件),它们要么是Excel 2007+
类型,要么是Microsoft OOXML
类型,但是PhpSpreadsheet仍然显示相同的错误:
致命错误:未捕获的PhpOffice\PhpSpreadsheet\Reader\Exception: 无法识别该文件的读取程序, 位于/var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php:176 堆栈跟踪:#0 /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php(113): PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile('file:///var/www...') #1 /var/www/html/Function_Spreadsheet.php(798): PhpOffice\PhpSpreadsheet\IOFactory::identify('file:///var/www...') #2 /var/www/html/Function_Home.php(3748): Spreadsheet_Reader_1('/var/www/html/F...', 3746, Array, Array) #3 {main} thrown in /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php on line 176
Test.xlsx
来验证它是否是一个ZIP压缩文件吗?你要在压缩文件中寻找一个名为workbook.xml
的文件。 - Martinload
函数在我之前提到的同一文件的第389行。你能再次检查一下load
函数会给出什么错误吗? - Martin