1

I'm using PHP (PHPExcel) to handle all the excel files. Currently I have saved a "New Template.xlsx" in a folder. And now I want the users to be able to download the "New Template.xlsx" at a click of a button.

How do i do that with php or phpexcel (i'm using Yii PHP framework as well)?

I'm not sure how to start, all I have now is

   $filePath = Yii::app()->basePath . '\\vendors\\Excel Template\\New Template.xlsx';
    Yii::import('application.vendors.PHPExcel', true);
    $objPHPExcel = PHPExcel_IOFactory::load($filePath);
    $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');

Edit

Thanks to Miqi180's comments, I'm now able to download the excel file, however I am unable to open it because of invalid file extension/file format.

Here are my codes:

<?php

ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script

//$path = "/absolute_path_to_your_files/"; // change the path to fit your websites document structure
$path = Yii::app()->basePath . '\\vendors\\Excel Template\\';
//$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\].]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\].]|[\.]{2,})", '', 'NewTemplate.xlsx'); // simple file name validation
$dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
$fullPath = $path.$dl_file;

if ($fd = fopen ($fullPath, "r")) {
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "xlsx":
        //header("Content-type: application/vnd.ms-excel");
        header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
        break;
        // add more headers for other content types here
        default;
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
        break;
    }
    header("Content-length: $fsize");
    header("Cache-control: private"); //use this to open files directly
    while(!feof($fd)) {
        $buffer = fread($fd, 2048);
        echo $buffer;
    }
}
fclose ($fd);
exit;

2 Answers2

1
  • Stop Yii from sending its own headers and output
  • Send the appropriate headers for an xlsx file
  • Save the file to php://output

Look at some of the examples in the PHPExcel Examples folder like 01simple-download-xlsx.php

But unless you're changing the template between loading it and sending it to the user, there's no need to use PHPExcel for this

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
1

Basically, what you need to do is execute a php script which fires when another page is loaded, e.g. "download.php" and then send the file through the header commands in that script.

Complete working code example taken from here:

<?php

ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script

$path = "/absolute_path_to_your_files/"; // change the path to fit your websites document structure
$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\].]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
$dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
$fullPath = $path.$dl_file;

if ($fd = fopen ($fullPath, "r")) {
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "pdf":
        header("Content-type: application/pdf");
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
        break;
        // add more headers for other content types here
        default;
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
        break;
    }
    header("Content-length: $fsize");
    header("Cache-control: private"); //use this to open files directly
    while(!feof($fd)) {
        $buffer = fread($fd, 2048);
        echo $buffer;
    }
}
fclose ($fd);
exit;

However, you need to set the content-type correctly first (see this post).

from

header("Content-type: application/pdf");

to

header("Content-type: application/vnd.ms-excel");

or for For Excel2007 and above .xlsx files

header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

Edit:

According to this MSDN blog article, the correct Extension MIME type for Excel .xlsx files actually is:

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Community
  • 1
  • 1
Miqi180
  • 1,670
  • 1
  • 18
  • 20
  • Hi, thanks for the reply. I'm facing another issue. I'm able to download the excel file in .xlsx format, however, i'm unable to open up the file. "Excel cannot open the file because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file" – DoubleClickOnThis Mar 16 '15 at 19:17
  • What does the file look like in Notepad? Is there data in it or is it empty? – Miqi180 Mar 16 '15 at 19:25
  • It is not empty, is has a bunch of random scribbles. I used the "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" value that you've provided. – DoubleClickOnThis Mar 17 '15 at 06:46
  • If MIME types for the Open XML formats is not supported on the web server you use, then this won't work either. It could be the problem here. Either check your settings, or contact your service provider, – Miqi180 Mar 17 '15 at 07:08