Я хочу прочитать файл xlsx
, созданный в Microsoft Excel, но когда я запускаю следующий код ...
$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
Файл доступен для чтения и открытия моим сценарием PHP v7.2 в Apache на Ubuntu 18.04. Я прочитал несколько сообщений на форуме, в которых предлагалось следующее, что я и сделал:
Я попытался открыть файл в 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
, то, может быть, я пойму, в чем основная причина проблемы.
Из комментариев и обсуждений я узнал, что canRead()
определен в \PhpSpreadsheet\Reader\Xlsx.php
, начиная со строки 65. В canRead()
$zip->open($pFilename)
возвращает код ошибки ZipArchive::ER_NOENT
, что означает «Файл не найден». Однако файл существует. Итак, почему возникает эта ошибка?
Эта веб-страница предполагает, что существует несколько типов файлов xlsx. Итак, я запустил file test.xlsx
, который отобразил Microsoft Excel 2007+
. Затем я открыл электронную таблицу в LibreOffice Calc и сохранил ее как файл xlsx типа OOXML и повторно запустил file test.xlsx
, который отобразил Microsoft OOXML
. Затем я повторно запустил PHP-скрипт, но получил ту же ошибку. Итак, похоже, проблема не в моем типе файла xlsx
.
Итак, я решил использовать PHPExcel (хотя он устарел), чтобы выполнить некоторую необходимую работу. Когда я запустил скрипт с помощью PHPExcel, я получил аналогичную ошибку о том, что canRead()
не может обнаружить файл xlsx
.
Итак, я продолжил читать эта веб-страница и последовал последнему предложению wesood
, которое было получено из принятого ответа на эта веб-страница. Это решение сработало для меня: в файле /PHPExcel/IOFactory.php
я добавил PHPExcel_Settings::setZipClass(\PHPExcel_Settings::PCLZIP);
непосредственно перед if (isset($reader) && $reader->canRead($filename))
.
Однако я все еще хочу знать, как решить эту проблему в PhpSpreadsheet. Кажется, мне нужно больше узнать о том, как работает pclzip, и нужно ли выполнить аналогичное действие с PhpSpreadsheet.
Я попробовал запустить сценарий сегодня, и кажется, что добавление PHPExcel_Settings::setZipClass(\PHPExcel_Settings::PCLZIP);
больше не работает. Итак, я снова застрял ...
Что я делаю неправильно? Любая помощь приветствуется!
Следуя рекомендациям из комментариев, я протестировал скрипт с использованием случайных файлов XLSX, найденных в результатах поиска Google (например, этот файл), которые были либо типами Excel 2007+
, либо Microsoft OOXML
, и такая же ошибка отображается для PhpSpreadsheet:
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:176 Stack trace: #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
Я могу только предположить, исходя из того, что вы сказали, и глядя на код GitHub, что файл, который вы пытаетесь загрузить, не имеет формат xlsx, который, по мнению phpsreadsheet, должен быть
Можете ли вы открыть свой тестовый файл Test.xlsx
с помощью 7-zip, чтобы убедиться, что это архив ZIP? Вы ищете файл с именем workbook.xml
внутри архива.
@MartinParkin - какой еще формат xlsx есть? Кроме того, да, я могу открыть файл xlsx как zip. Если я изменю расширение на .zip, то смогу извлечь его и увидеть xml-код.
Вы сказали, что можете сами создать программу чтения Xlsx и прочитать файл, но получите ту же ошибку. Этого не может быть - какую ошибку вы получите, если попытаетесь прочитать файл напрямую с помощью программы чтения Xlsx?
Тогда мне нужно уточнить свой пост: я могу создать читалку xlsx сам, но он не может читать файл xlsx, он дает ту же ошибку. Кроме того, я сам могу создать программу для чтения xls, и я могу читать файл xls без ошибок.
Он не может выдать ту же ошибку - он не использует тот же код. Функция load
находится в строке 389 того же файла, на который я ссылался ранее. Не могли бы вы еще раз проверить, какую ошибку выдает функция load
?
Да, я только что обновил свое сообщение, чтобы показать другое сообщение об ошибке, которое я получаю. Если я использую IOFactory::load($Source_File);
или \PhpOffice\PhpSpreadsheet\IOFactory::load($Source_File);
, я получаю ту же ошибку, но если я использую $reader->load($Source_File);
, я получаю другое сообщение об ошибке.
Позвольте нам продолжить обсуждение в чате.
Пожалуйста, добавляйте главный тег к вопросу всякий раз, когда вы его задаете. Обычно люди смотрят основные теги. Я добавил тег php. Если бы вы добавили его раньше, я бы увидел его раньше. Одна из причин, по которой ваш вопрос не был виден должным образом, - это отсутствие тега php.
@shazyriver: Хорошо. Я тоже просто добавил xlsx
в качестве тега.
Я получаю ту же ошибку при чтении файла xlsx
. Пришел сюда в надежде найти ответ, надеюсь, скоро ....
@ dmikester1 Как настроен ваш компьютер? Возможно, это поможет нам сузить причину проблемы, такую как ОС, версия PHP, одна из zip-библиотек и т. д.
Хорошо, ответ на мой был очень прост. Возможно, для вас это будет не так просто. Но я вручную брал расширение из файла как xlxs
. Я узнал, что если я переключил его на Xlxs
, он работал нормально.
@ dmikester1 Не могли бы вы объяснить больше о «захвате расширения из файла»? Например, вы изменили расширение файла с xlsx
на Xlsx
, прежде чем читать из него, или вы использовали $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
(который не работал у меня) или что-то еще? Возможно, вы сможете уточнить свое решение в качестве ответа.
Насколько я понимаю, вам не хватает части. Почему бы вам сначала не создать читалку, а потом загрузить файл.
Попробуйте следующий код. Он может идентифицировать расширение и соответственно создавать читателя этого типа.
$inputFileName = "Text.xlsx";
/** Identify the type of $inputFileName **/
$inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($inputFileName);
/** Create a new Reader of the type that has been identified **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
/** Convert Spreadsheet Object to an Array for ease of use **/
$schdeules = $spreadsheet->getActiveSheet()->toArray();
Теперь вы можете просто запустить цикл foreach для массива результатов.
foreach( $schdeules as $single_schedule )
{
echo '<div class = "row">';
foreach( $single_schedule as $single_item )
{
echo '<p class = "item">' . $single_item . '</p>';
}
echo '</div>';
}
Это проверенный и рабочий код.
Я получаю следующую ошибку с $inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($inputFileName);
: Fatal error: Uncaught PhpOffice\PhpSpreadsheet\Reader\Exception: Unable to identify a reader for this file
Есть ли у вас какие-либо мысли о том, почему возникает эта ошибка? Я использую входной файл XLSX типа Microsoft Excel 2007+
.
Тогда, вероятно, в вашем файле есть ошибка. Почему бы вам не попробовать с образцом файла? Вот ссылка на github стандартных образцов github.com/PHPOffice/PhpSpreadsheet/tree/master/samples/Read er /…
Если это работает для образца, вы можете проверить, в чем проблема с вашим файлом и разница между вашим файлом и рабочим файлом.
Ни один из примеров по ссылке на github, которую вы предоставили, не является файлом XLSX, я вижу только файлы CSV, TSV и XLS. Есть ли файл XLSX, который я не замечаю?
Я загрузил пару других файлов XLSX [file-examples.com/wp-content/uploads/2017/02/…, которые были либо Excel 2007+
, либо Microsoft OOXML
, и одна и та же ошибка по-прежнему отображается для всех из них. Итак, похоже, проблема не в файле XLSX. Возможно, это конфигурация моей системы, но что это может быть?
Я невозможно прочитать файл Excel
Я столкнулся с той же самой ошибкой при попытке загрузить файл XLSX. Лично я обнаружил очень простое решение, которое устранило мою проблему. Я вручную взял расширение имени файла как xlsx
. Я заметил, что какой-то другой мой код, использующий старую библиотеку PHP Spreadsheet, принимает расширение Xls
. Я попробовал загрузить Xlsx
, и он отлично сработал.
Вот код, который я использую для правильной загрузки расширения. Он просто захватывает все символы после последней точки, а затем записывает первый символ этой подстроки. ucfirst
просто вводит в верхний регистр первую букву переданной в него строки. substr
возвращает подстроку, где первый параметр - это строка, из которой нужно извлечь, а второй параметр - с какого индекса начинать подстроку в данной строке. И, наконец, strrpos
находит последнее вхождение подстроки в заданной строке.
https://www.php.net/manual/en/function.ucfirst.php
https://www.php.net/manual/en/function.strrpos
https://www.php.net/manual/en/function.substr.php
$inputFileType = ucfirst(substr($cccFile, strrpos($cccFile, '.') + 1));
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
Однажды я добавил команду ucfirst
, и она решила проблему для меня.
Пожалуйста, объясните, что делает первая строка.
Я объяснил это довольно ясно во втором абзаце.
Я понимаю код, но тот, кто не понимает, что означает strrpos
, substr + 1
и / или ucfirst
в коде, может запутаться.
Честно говоря, я постараюсь добавить поясняющий текст.
У меня была такая же проблема после добавления файлов .xlsx в репозиторий git на моем Mac. Проблема заключалась в том, что git автоматически конвертировал окончания строк.
Решением было добавить эти строки в файл .gitattributes
:
*.xls binary
*.xlsx binary
Использовать это. Он покажет .xlsx
$inputFileName = public_path('asset/docs/Filename.xlsx');
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);
$writer = IOFactory::createWriter($spreadsheet, 'Html');
$message = $writer->save('php://output');
У меня возникла аналогичная проблема на моей странице Drupal, где я использовал "private: // ..." в качестве пути к файлу. getFromZipArchive в PHPExcel (должно быть аналогично в PhpSpreadsheet) не может читать схему пути к файлу, такую как "private: // ...". После перевода на локальный путь он работает.
В вашем случае у вас есть схема пути, такая как «file: /// home / ar ...». Так что используйте вместо этого "/ home / ar ...".
Код, который вы ищете: github.com/PHPOffice/PhpSpreadsheet/blob/develop/src/…