PHP downloading excel file becomes corrupt

2019-05-11 19:18发布

问题:

I have an excel file that i want a user to be able to download from my server. I have looked at a lot of questions on here but i cannot find a way to correctly download the file w/o corruption. I am assuming it is the headers but i haven't had a working combination of them yet. This is what i have right now and in the corrupt file that i receive i can see the column names of the spreadsheet i want but its all messed up.

$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';        
header("Content-type: application/octet-stream");
header("Content-type: application/vnd-ms-excel");
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header("Pragma: no-cache");
header("Expires: 0");
readfile($filename);

edit: Solution I forgot to add that i was using Zend and it was corrupting the files when trying to use native php methods. My finsihed code was to place a link to another action in my controller and have the files download from there

public function downloadAction(){
        $file = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
        header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment; filename="Spreadsheet.xls"');
    readfile($file);

    // disable the view ... and perhaps the layout
    $this->view->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);


    }

回答1:

try doing it this way

 ob_get_clean();
 echo file_get_contents($filename);
 ob_end_flush();


回答2:

For one, only specify Content-Type once. You can use the excel-specific header but the generic application/octet-stream may be a safer bet just to get it working (the real difference will be what the browser shows the user with regards to "what would you like to open this file with", but basic browsers can rely on the extension as well)

Also, make sure you specify Content-Length and dump the size (in bytes) of the file you're outputting. The browser needs to know how big the file is and how much content it's expecting to receive (so it doesn't stop in the middle or a hiccup doesn't interrupt the file download).

So, the entire file should consist of:

<?php
  $filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';

  header("Content-Disposition: attachment; filename=ExcelFile.xls;");
  header('Content-Type: application/octet-stream');
  header('Content-Length: ' . filesize($filename));
  header("Pragma: no-cache");
  header("Expires: 0");

  @readfile($filename);


回答3:

$file_name = "file.xlsx";

// first, get MIME information from the file
$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$mime =  finfo_file($finfo, $file_name);
finfo_close($finfo);

// send header information to browser
header('Content-Type: '.$mime);
header('Content-Disposition: attachment;  filename="download_file_name.xlsx"');
header('Content-Length: ' . filesize($file_name));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

//stream file
ob_get_clean();
echo file_get_contents($file_name);
ob_end_flush();