18

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?

Tiny
  • 27,221
  • 105
  • 339
  • 599
  • 3
    Open the file in a text editor, and look to see if there are any white space characters at the beginning or end of the file, or any obvious error messages visible. – Mark Baker May 29 '12 at 21:06
  • In text editor (Notepad), it displays something like this `PK ¾@G’D²X ð [Content_Types].xml­”MNÃ0…÷œ"ò%nY „švAa •(0ö¤±êØ–gúw{&i‰@ÕnbEö{ßøyìÑdÛ¸l mð¥‘×ÁX¿(ÅÛü)¿’òF¹à¡;@1_滘±Øc)j¢x/%ê…Eˆày¦ ©QÄ¿i!£ÒKµ y3ÜJ<§œZ1½0?YÙL%zV cäÖIb7؇û‰ìa/lÙ¥P1:«qáríÍjªÊj0A¯–Íuë""íàÙ(Œ ”Á€WìMä)Tjå` and much more content. – Tiny May 29 '12 at 21:43
  • 1
    Your content type headers are simply being overwritten by the last call, can you try "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", also can i suggest adding a "Content-length" (header with the byte count of the document)[http://stackoverflow.com/a/10630871/61795] using strlen, there may be download issues. – Scuzzy May 29 '12 at 21:44
  • That's more or less what I'd expect to see, certainly at the beginning of the file.... as I said, check for anything like a new line or a space at the beginning or end, and scroll through looking for any PHP errors that might have been written to the file. It's also worth checking your PHP and Web server log files to see if there's anything been written there. – Mark Baker May 29 '12 at 21:44
  • Do the PHPExcel tests scripts work? – Mark Baker May 29 '12 at 21:45
  • 6
    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. – Tiny May 29 '12 at 22:25
  • 2
    @Tiny could you add that to the answer section and mark it as correct so people in future know what the solution was – Chris May 30 '12 at 05:22
  • Odds are then, that it was a trailing whitespace character in the script – Mark Baker May 30 '12 at 07:57
  • @Chris I'm not of the age to answer any questions on this site. If someone still answers it, I can accept it. Thank you. – Tiny May 30 '12 at 08:46

7 Answers7

40

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.

vicenteherrera
  • 1,442
  • 17
  • 20
5

Well I had this problem, my solution was changing the header Content-type to :

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

I had before:

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

and I changed the format to Excel2007, I was using Excel5 for excel 2003 xls format.

I tried all the solutions from this page and all the other pages with the same question but not luck. So basically, I just changed the output format of my excels and that solved the problem.

PauZ
  • 51
  • 1
  • 3
4

This error can also be triggered by serving the file without the Content-Length headers.

Look at the example given here in php.net

rafaCode
  • 121
  • 5
2

Give the active sheet a title:

$sheet->setTitle('Some title string here');
Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358
Grissom
  • 31
  • 2
0

I Put just exit; After

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

and it work's for me :)

   $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;
Amir Etemad
  • 106
  • 1
  • 5
0

This might help to someone who tries to download excel using https://github.com/Maatwebsite/Laravel-Excel package in laravel with get route with ajax

I got response something like PK ¾@G’D²X ð [Content_Types].xml­”MNÃ0…÷œ"ò%nY „švAa •(0ö¤±êØ–gúw{&i‰@ÕnbEö{ßøyìÑdÛ¸l mð¥‘×ÁX¿(ÅÛü)¿’òF¹à¡;@1_滘±Øc)j¢x/%ê…Eˆày¦ ©QÄ¿i!£ÒKµ y3ÜJ<§œZ1½0?YÙL%zV cäÖIb7؇û‰ìa/lÙ¥P1:«qáríÍjªÊj0A¯–Íuë""íàÙ(Œ ”Á€WìMä)Tjå and much more content

i tried many of the solution but fails

finally i achieved by doing this in onclick event

$(document).on('click','#elementId',function(e){
  e.preventDefault();
  window.location.assign('your action url'+'?param='+ param_data);
}
Deepak
  • 614
  • 1
  • 7
  • 20
0

my php : 7.4.1 os: Ubuntu 18.04 frameword: Yii2.0.37
I had also this problem and my solution is that
I use exit and ob_clean()

$objPHPExcel = new \PHPExcel();

    $objPHPExcel->getProperties()->setCreator("Murodjon Abduvohidov")
        ->setLastModifiedBy("Murodjon Abduvohidov");
    $objPHPExcel->getActiveSheet()->getPageSetup()-> setOrientation(\PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)
        ->setPaperSize(\PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
    $objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(70);
    $objPHPExcel->getActiveSheet()->getSheetView()->setZoomScaleNormal(82);
    $objPHPExcel->getActiveSheet()->getSheetView()->setView(\PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW);
    $objPHPExcel->getActiveSheet()->getPageSetup()->setScale(63);
    $objPHPExcel->getActiveSheet()->getPageMargins()->setTop(0.4);
    $objPHPExcel->getActiveSheet()->getPageMargins()->setRight(0.4);
    $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft(0.4);
    $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom(0.4);
    $objPHPExcel->getDefaultStyle()->getFont()->setName('Arial');
    $objPHPExcel->getDefaultStyle()->getFont()->setSize(10); $objPHPExcel->getActiveSheet()->getCell('A2')->setValue('salom');
    $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');ob_clean();
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment;filename="abdulqodir.xlsx"');
    header('Cache-Control: max-age=0');
    header('Cache-Control: max-age=1');
    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
    header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');        header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
    header('Pragma: public'); // HTTP/1.0
    $objWriter->save("php://output");exit;`