80

hello i am new to phpexcel, and i was wondering if there is some way send the excel i have created to the clients download without saving it on my server or to delete it right after he downloads it

i am trying to create an "export button" on a page that will give the user a "pop-up" with the excel that he wants that i have just created.

now after i create the table i do :

$objXLS->getActiveSheet()->getColumnDimension("A")->setAutoSize(true);
$objXLS->getActiveSheet()->getColumnDimension("B")->setAutoSize(true);

$objXLS->getActiveSheet()->setTitle('Test Stats');

$objXLS->setActiveSheetIndex(0);

$objWriter = PHPExcel_IOFactory::createWriter($objXLS, 'Excel5');
$objWriter->save(__DIR__."/test1.xls");

but that saves it to my server

thank you

pnuts
  • 58,317
  • 11
  • 87
  • 139
Dvir Levy
  • 8,018
  • 11
  • 39
  • 60

8 Answers8

173

Instead of saving it to a file, save it to php://output­Docs:

$objWriter->save('php://output');

This will send it AS-IS to the browser.

You want to add some headers­Docs first, like it's common with file downloads, so the browser knows which type that file is and how it should be named (the filename):

// We'll be outputting an excel file
header('Content-type: application/vnd.ms-excel');

// It will be called file.xls
header('Content-Disposition: attachment; filename="file.xls"');

// Write file to the browser
$objWriter->save('php://output');

First do the headers, then the save. For the excel headers see as well the following question: Setting mime type for excel document.

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
  • 1
    im getting a file to download but its not what i have created and when i do $objWriter->save('php://output') it messes up my hole page =\ – Dvir Levy Dec 19 '11 at 19:32
  • 2
    Take care that the only thing you output on that page is the output from the two `header` lines and the `->save()` action. You need to decide between a) displaying a page *or* b) offer a download. Both does not work with one script easily. You can however create one script for the download and one for the page and when the page script has been exectued, redirect to the download script which will make the browser offer the save-as dialog. – hakre Dec 19 '11 at 20:50
  • my problem is that i am using joomla and i cant find a way to load it from an empty page. every time i try i get the hole joomla page with menus and all. do you know where i could find an answer to this problem? i dont want to spam stack overflow... – Dvir Levy Dec 20 '11 at 22:35
  • Dvir - use &format=raw in your url. In your mvc, create a view.raw.php file. – MSD Oct 31 '13 at 19:27
  • 1
    How can you set the `Content-Length` header when using `php://output`? – tonix Nov 17 '15 at 03:01
  • @tonix: As usual, you need the number of bytes for it. Either `$objWriter` has it for you or you need to keep track of the output site. In that case you probably want to output into a templfile first, obtain the size of the file and then stream to the browser. – hakre Nov 18 '15 at 08:47
  • I am trying to build a PPT Using PHPPowerpoint, exactly did the mentioned steps, but changing the `MIME` Type to `application/vnd.openxmlformats-officedocument.presentationml.presentation`, it is downloading the file on my system but saying that `File can't be opened`. File was working when the code was writing it to the server. – void Jan 16 '16 at 08:16
  • @void: try with a program that is compatible with the file format. And also, reduce the file-operation you do to a blank / empty file and just download that one and see if it generally works first. – hakre Jan 16 '16 at 09:55
  • @hakre I made it work, there was `echo` command which was creating the issue. Thanks. – void Jan 16 '16 at 10:08
  • If anyone is having difficulties (excel is unable to open file), make sure there are no `echo` statements in the page. Nothing should be printed, other than the headers and save. – blackandorangecat Jun 30 '16 at 22:14
22
$excel = new PHPExcel();
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="your_name.xls"');
header('Cache-Control: max-age=0');

// Do your stuff here

$writer = PHPExcel_IOFactory::createWriter($excel, 'Excel5');

// This line will force the file to download
$writer->save('php://output');
Rob Watts
  • 6,866
  • 3
  • 39
  • 58
matino
  • 17,199
  • 8
  • 49
  • 58
  • hello and thank you for the answer. i put the line $writer->save('php://output'); and it doesn't download the file it prints garbage out on the page. do you know why this happens? – Dvir Levy Dec 22 '11 at 15:07
  • Have you set the headers as well? – matino Dec 22 '11 at 15:11
  • I am trying to build a PPT Using PHPPowerpoint, exactly did the mentioned steps, but changing the `MIME` Type to `application/vnd.openxmlformats-officedocument.presentationml.presentation`, it is downloading the file on my system but saying that `File can't be opened`. File was working when the code was writing it to the server. – void Jan 16 '16 at 08:17
  • Worked perefect for me. Thanks¡ – Jam Dec 19 '17 at 06:11
7

Use this call

$objWriter->save('php://output');

To output the XLS sheet to the page you are on, just make sure that the page you are on has no other echo's,print's, outputs.

JoshStrange
  • 1,121
  • 1
  • 7
  • 22
  • When working in shared hosting, I get an error (maybe related to file and folder permissions) when using $objWriter->save('php://output'); Uncaught exception 'PHPExcel_Writer_Exception' with message 'Could not open php://output for writing.' in third_party/PHPExcel/Writer/Excel2007.php:241 Stack trace: #0 – Enrique Oct 28 '15 at 15:42
  • I am trying to build a PPT Using PHPPowerpoint, exactly did the mentioned steps, but changing the `MIME` Type to `application/vnd.openxmlformats-officedocument.presentationml.presentation`, it is downloading the file on my system but saying that `File can't be opened`. File was working when the code was writing it to the server. – void Jan 16 '16 at 08:17
  • Holding the whole code between ob_start(); and ob_end_clean(); solves the problem. – Hussein mahyoub Feb 14 '22 at 14:55
6

FOR XLSX USE

SET IN $xlsName name from XLSX with extension. Example: $xlsName = 'teste.xlsx';

$objPHPExcel = new PHPExcel();

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$xlsName.'"');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');

FOR XLS USE

SET IN $xlsName name from XLS with extension. Example: $xlsName = 'teste.xls';

$objPHPExcel = new PHPExcel();

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$xlsName.'"');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
Rogerio de Moraes
  • 1,527
  • 18
  • 15
  • 3
    **PSI.: XLS format is default define 'Excel5' and XLSX is 'Excel2007'.** – Rogerio de Moraes Dec 10 '14 at 15:10
  • I am trying to build a PPT Using PHPPowerpoint, exactly did the mentioned steps, but changing the `MIME` Type to `application/vnd.openxmlformats-officedocument.presentationml.presentation`, it is downloading the file on my system but saying that `File can't be opened`. File was working when the code was writing it to the server. – void Jan 16 '16 at 08:17
  • The content type for xlsx should read: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet". See http://filext.com/faq/office_mime_types.php – kojow7 May 02 '16 at 16:38
3

posible you already solved your problem, any way i hope this help you.

all files downloaded starts with empty line, in my case where four empty lines, and it make a problem. No matter if you work with readfile(); or save('php://output');, This can be fixed with adding ob_start(); at the beginning of the script and ob_end_clean(); just before the readfile(); or save('php://output');.

evtuhovdo
  • 335
  • 2
  • 16
  • The problem you have is with your error logging and reporting: you do not see the warnings which would have pointed you to the problem: headers already sent. This is outlined in this reference question: http://stackoverflow.com/q/8028957/367456 – hakre Sep 26 '14 at 06:59
  • 2
    `ob_end_clean()` not `od_end_clean()` – turson May 06 '15 at 08:35
3
 header('Content-type: application/vnd.ms-excel');

 header('Content-Disposition: attachment; filename="file.xlsx"');

 header('Cache-Control: max-age=0');

 header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT');

 header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');

 header ('Cache-Control: cache, must-revalidate');

 header ('Pragma: public');

 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

 $objWriter->save('php://output');
harsimer
  • 55
  • 7
  • I am trying to build a PPT Using PHPPowerpoint, exactly did the mentioned steps, but changing the `MIME` Type to `application/vnd.openxmlformats-officedocument.presentationml.presentation`, it is downloading the file on my system but saying that `File can't be opened`. File was working when the code was writing it to the server. – void Jan 16 '16 at 08:18
0

I tried the $writer->save('php://output'); command proposed by most answers.

But this happened to download a corrupted file.

To fix it, I had to do this:

    $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
    header('Content-type: application/vnd.ms-excel');
    header('Content-Disposition: attachment; filename="filename.xlsx"');
    header('Cache-Control: max-age=0');
    $path = 'path/to/temp/file.xlsx';
    // save content to temporary file
    $objWriter->save($path);
    // This header was key to me, in order to get it working
    header("Content-Length: ".filesize($path));
    // output file content
    readfile($path);
    // delete temporary file
    unlink($path);
luis.ap.uyen
  • 1,314
  • 1
  • 11
  • 29
0

It is important to state that sometimes for the codeigniter folks using grocery crud v2.9 - v3, you may find that your exported excel files are corrupt and cannot be opened.

You may need to actually modify code sections handling your export to excel in GroceryCrud (even though not recommended to change source code). in particular the exportToExcel() function within ExportState.php, add ob_end_clean() before and after the code block as highlighted below:

// rest of code above....

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

        // If you're serving to IE over SSL, then the following may be needed
        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'); // always modified
        header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
        header ('Pragma: public'); // HTTP/1.0
        ob_end_clean();

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

The obs_end_clean() will clean out outputs and thus wont intefere with what you really want to send to browser which may cause the corrupt file issue.

Hope it helps in your own implementations apart from GroceryCrud. The trick is / or could be the adding of obs_end_clean() before and after your headers.