"Excel found unreadable content" warning when opening Excel files made with PHPExcel

Tiny picture Tiny · May 29, 2012 · Viewed 19.5k times · Source

I'm trying to download Excel files (xlsx) using PHPExcel as follows.

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');

It works but when I try to open the Excel file, it asks for a confirmation in a conform dialog.

Excel found unreadable content in 'test.xlsx'. Do you want to recover the contents of this workbook? If you trust the source of this workbook, click Yes.

I also tried to change the header as follows

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");

It still asks for the same confirmation. What am I doing wrong here, please?

Answer

vicenteherrera picture vicenteherrera · May 30, 2012

As told by questioning user Tiny on his own comment:

Finally, it worked. I just added exit at the end of my PHP script (at the end of the first code snippet in the question). Thanks very much all of you for giving me useful hints.

To give some constructive additional tips on this kind of problems:

  • A good tip is that you can omit the closing tag ?> on all your PHP script files, that way you know that you're not sending any aditional invisible whitespace at the end of it.
  • Also enconding PHP script files on UTF-8 on wrongfully configured web server can send an undesirable couple bytes at the begining of the script. Open the PHP file on Notepad++, check if it's UTF-8, and in that case, convert it to ANSI. If that makes it work, check your webserver/php configuration.
  • Just before the header calls, you can check if headers has been wrongfully sent with:

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

  • If you can't prevent that some function call sends undesirable strings to the browser, you can "erase" all of it using at the very beginning of your script:

    ob_start();

    and then, just before the first headers call, use:

    ob_clean();

    Be careful that with doing so will prevent you for receiving error feedback.

  • And lastly, as already said, if nothing has to be executed afterwards some point on the script, call exit or die.