web-dev-qa-db-ja.com

PhpSpreadsheetでXlsxファイルを読み取る

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

このファイルは、私のPHP v7.2スクリプト、Ubuntu 18.04上のApacheで読み書き可能です。いくつかのフォーラム投稿を読んで、以下のことを提案しています。

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()は65行目前後の\PhpSpreadsheet\Reader\Xlsx.phpで定義されていることがわかりました。canRead()では、$Zip->open($pFilename)はエラーコードZipArchive::ER_NOENTを返します。これは、「- そのようなファイルはありません "。ただし、ファイルは存在します。 では、なぜこのエラーが発生するのですか

アップデート-2018-12-18

このWebページ は、複数のタイプの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 を読み続け、_ this web page で受け入れられた回答から得られた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:

コメントの推奨事項に従って、Google検索結果から見つかったランダムなXLSXファイル(例: this file )を使用してスクリプトをテストしました。これらは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}が/var/www/html/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/IOFactory.phpにスローされますライン176

6
Arya

XLSXファイルをロードしようとすると、これとまったく同じエラーが発生しました。個人的には、問題を解決する非常に簡単な修正を発見しました。ファイル名から拡張子をxlsxとして手動で取得していました。古いPHPスプレッドシートライブラリを使用している他のコードが拡張子Xlsを取り込んでいることに気づきました。そのため、Xlsxにロードしてみましたが、完全に機能しました。

拡張機能を正しく読み込むために使用しているコードは次のとおりです。最後のピリオド以降のすべての文字を取得し、その部分文字列の最初の文字を大文字にします。 ucfirstは、渡された文字列の最初の文字を単に大文字にします。 substrは部分文字列を返します。最初のパラメータは取得する文字列で、2番目のパラメータは指定された文字列で部分文字列を開始するインデックスです。そして最後に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コマンドを追加すると、問題は解決しました。

1
dmikester1

Macのgitリポジトリに.xlsxファイルを追加した後、同じ問題が発生しました。
問題は、gitが行末を自動変換することでした。

解決策は、これらの行を.gitattributesファイルに追加することでした:

*.xls   binary
*.xlsx  binary
0
lewis