【发布时间】:2019-05-18 07:01:36
【问题描述】:
我想读取在 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;
}
...我搜索了canRead 的定义,但在/vendor/phpoffice/phpspreadsheet/ 的任何地方都没有找到。 canRead 是在哪里定义的? 我想如果我能读懂canRead 的定义,那么也许我会明白问题的根本原因是什么。
更新:
我从 cmets 和讨论中了解到 canRead() 是在 \PhpSpreadsheet\Reader\Xlsx.php 中定义的,从第 65 行开始。在 canRead() 中,$zip->open($pFilename) 返回错误代码 ZipArchive::ER_NOENT,意思是“No such file”。但是,该文件存在。 那么,为什么会出现这个错误?
更新 - 2018-12-18
This web page 表示有多种类型的 xlsx 文件。所以,我跑了file test.xlsx,它显示了Microsoft Excel 2007+。然后我在 LibreOffice Calc 中打开电子表格并将其保存为 OOXML 类型的 xlsx 文件并重新运行 file test.xlsx,显示 Microsoft OOXML。然后我重新运行了 PHP 脚本,但得到了同样的错误。所以,我的xlsx 文件类型似乎不是问题。
所以,我决定使用PHPExcel(尽管它已被弃用)来完成一些必要的工作。当我使用 PHPExcel 运行脚本时,我收到了关于 canRead() 无法检测到 xlsx 文件的类似错误。
所以,我继续阅读this web page 并遵循wesood 的最后一个建议,该建议来自this web page 上已接受的答案。这个解决方案对我有用:在文件/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 年 2 月 18 日更新:
根据 cmets 的建议,我使用通过 Google 搜索结果(例如,this file)找到的随机 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, 数组, 数组) #3 {main} 在第 176 行的 /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php 中抛出
【问题讨论】:
-
我只能假设,根据您所说的以及查看 GitHub 代码,您尝试加载的文件不是 phpsreadsheet 认为应该是的 xlsx 格式
-
你能用 7-zip 打开你的测试文件
Test.xlsx来验证它是一个 ZIP 文件吗?您正在存档中查找名为workbook.xml的文件 -
它不能给出相同的错误 - 它不使用相同的代码。
load函数位于我之前引用的同一文件的第 389 行。您能再检查一下load函数给出的错误吗? -
每当您提出问题时,请在问题中添加主标签。人们通常在看主要标签。我添加了 php 标签。如果您早点添加它,我会早点看到它。您的问题没有所需的可见性的原因之一是缺少 php 标签。
标签: php excel xlsx ziparchive phpspreadsheet