Прочитать файл Xlsx в PhpSpreadsheet - PullRequest
0 голосов
/ 18 декабря 2018

Я хочу прочитать файл 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, что означает " Нет такогофайл ».Тем не менее, файл существует. Итак, почему возникает эта ошибка ?

ОБНОВЛЕНИЕ - 2018-12-18

Эта веб-страница предполагает, что существует несколько типов 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.

ОБНОВЛЕНИЕ 2019-02-10:

Я пыталсязапускает скрипт сегодня и кажется, что добавление PHPExcel_Settings::setZipClass(\PHPExcel_Settings::PCLZIP); больше не работает.Итак, я снова застрял ...

Что я делаю не так? Любая помощь приветствуется!

ОБНОВЛЕНИЕ 2019-02-18:

Следуя рекомендациям из комментариев, я протестировал скрипт, используя случайные файлы XLSX, найденные в результатах поиска Google (например, этот файл ), которые имели тип Excel 2007+ или Microsoft OOXML и отображали ту же ошибку для PhpSpreadsheet:

Неустранимая ошибка: Uncaught 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 :: identifier ('файл: /// var / www ... ') # 2 /var/www/html/Function_Home.php(3748): Spreadsheet_Reader_1 (' / var / www / html / F ... ', 3746, Array, Array)# 3 {main} добавлено в /var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.php в строку 176

Ответы [ 2 ]

0 голосов
/ 31 марта 2019

Я столкнулся с той же самой ошибкой при попытке загрузить файл XLSX.Лично для себя я обнаружил очень простое решение, которое исправило мою проблему.Я вручную извлекал расширение из имени файла как xlsx.Я заметил, что мой другой код, использующий старую библиотеку PHP Spreadsheet, принимал расширение Xls.Поэтому я попытался загрузить в Xlsx, и он работал отлично.

Вот код, который я использую для правильной загрузки в расширение.Он просто захватывает все символы после последнего периода и затем захватывает первый символ этой подстроки.

$inputFileType = ucfirst(substr($cccFile, strrpos($cccFile, '.') + 1));

/**  Create a new Reader of the type defined in $inputFileType  **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

Как только я добавил в команду ucfirst, это решило проблему для меня.

0 голосов
/ 18 февраля 2019

Насколько я понимаю, вам не хватает кусочка.Почему бы вам сначала не создать ридер, а затем загрузить файл.

Попробуйте следующий код. Он может идентифицировать расширение и соответственно создать читателя этого типа.

$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>';
}

Это все проверенный и рабочий код, взятый из одного из моих проектов.Приветствия.

...