web-dev-qa-db-ja.com

PHPExcelで作成されたExcelファイルを開くと「Excelが読み取り不可能なコンテンツを見つけました」という警告

次のように PHPExcel を使用してExcelファイル(xlsx)をダウンロードしようとしています。

require_once("../../phpExcel/Classes/PHPExcel.php");
require_once("../../phpExcel/Classes/PHPExcel/IOFactory.php");

$objPHPExcel = new PHPExcel();

$objPHPExcel->getProperties()->setCreator("Tiny")
->setLastModifiedBy("Tiny")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.");

$objPHPExcel->setActiveSheetIndex(0);
$sheet=$objPHPExcel->getActiveSheet();
$sheet->setCellValue('A1', 'Hello');
$sheet->setCellValue('B2', 'world!');
$sheet->setCellValue('C1', 'Hello');
$sheet->setCellValue('D2', 'world!');

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="test.xlsx"');
header('Cache-Control: max-age=0');

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');

動作しますが、Excelファイルを開こうとすると、適合ダイアログで確認を求められます。

Excelが「test.xlsx」で読み取り不可能なコンテンツを検出しました。このワークブックの内容を復元しますか?このワークブックのソースを信頼する場合は、[はい]をクリックしてください。

私も次のようにヘッダーを変更しようとしました

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=test.xlsx");
header("Content-Transfer-Encoding: binary");

それでも同じ確認を求めます。ここで何が間違っているのですか?

18
Tiny

ユーザーTinyに自分のコメントで質問したところ、次のようになりました。

最後に、それはうまくいきました。 PHPスクリプトの最後(質問の最初のコードスニペットの最後)にexitを追加しました)。役立つヒントを提供してくれてありがとうございます。

この種の問題に関する建設的な追加のヒントを与えるには:

  • 良いヒントは、すべてのPHPスクリプトファイルで終了タグ_?>_を省略できることです。そうすれば、最後に追加の非表示の空白を送信していないことがわかります。それ。
  • また、誤って構成されたWebサーバー上のUTF-8でPHPスクリプトファイルをエンコードすると、スクリプトの開始時に望ましくない数バイトが送信される可能性があります。PHPファイルを開くNotepad ++で、UTF-8かどうかを確認し、その場合はANSIに変換します。それで機能する場合は、webserver/phpの構成を確認してください。
  • headerが呼び出される直前に、ヘッダーが誤って送信されていないかどうかを確認できます。

    if ( headers_sent() ) die("**Error: headers sent");

  • 一部の関数呼び出しが望ましくない文字列をブラウザに送信するのを防ぐことができない場合は、スクリプトの最初に使用して、すべての文字列を「消去」できます。

    ob_start();

    次に、最初のheaders呼び出しの直前に、次を使用します。

    ob_clean();

    そうすることで、エラーフィードバックを受け取れないように注意してください。

  • そして最後に、すでに述べたように、スクリプトのある時点で何も実行する必要がない場合は、exitまたはdieを呼び出します。

37
vicenteherrera

私はこの問題を抱えていました。私の解決策は、ヘッダーのContent-typeを次のように変更することでした。

header('Content-Type: application/openxmlformats-officedocument.spreadsheetml.sheet');

私は前に持っていた:

header('Content-Type: application/vnd.ms-Excel'); 

フォーマットをExcel2007に変更し、Excel 2003xlsフォーマットにExcel5を使用していました。

私はこのページと他のすべてのページのすべての解決策を同じ質問で試しましたが、運はありませんでした。つまり、基本的には、Excelの出力形式を変更しただけで、問題は解決しました。

4
PauZ

このエラーは、Content-Lengthヘッダーなしでファイルを提供することによってもトリガーできます。

php.netでここに示されている例を見てください

4
rafaCode

アクティブなシートにタイトルを付けます。

$sheet->setTitle('Some title string here');
2
Grissom

私はただ出口を置きます。後

PHPExcel_IOFactory :: createWriter($ phpExcelObject、 'Excel2007')-> save( "php:// output");

そしてそれは私のために働きます:)

   $file_name .= "_".\Carbon\Carbon::now()->format('d_m_Y_H_i').'.xlsx';

    // Prepare To Download
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment;filename='.$file_name);
    header('Cache-Control: max-age=0');
    header('Pragma: public');
    PHPExcel_IOFactory::createWriter($phpExcelObject, 'Excel2007')->save("php://output");
    exit;
0
Amir Etemad