2014-01-29 135 views
1

我想創建一個頁面,允許用戶將一個SQL表格的內容下載到一個excel文件中。PHPExcel下載不能正常工作

問題:當我打開excel文件時,它只包含隨機亂碼。一個例子 -

PKQ=DG’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¦ 

這是我的代碼 -

<?php 
error_reporting(E_ALL); 
ini_set('display_errors', TRUE); 
ini_set('display_startup_errors', TRUE); 

$download=""; 
if (isset($_GET['surveyid'])) { 
//Survey ID 
$download = $_GET['surveyid']; 
require_once('../Classes/PHPExcel.php'); 

$query="SELECT b.question_id as qid, 
       a.question as ques, 
       b.response as response, 
       count(b.response) as cnt 
      FROM v3_sai.survey_responses b 
      INNER JOIN v3_sai.survey_questions a 
      ON a.id = b.question_id 
       AND a.survey_id=".intval($download)." 
      group by b.response, a.question 
      order by b.question_id"; 
      var_dump($query); 
$resultdl= mysql_query($query) or die(mysql_error()); 
$objPHPExcel = new PHPExcel(); 
$objPHPExcel->setActiveSheetIndex(0); 
$rowcount=1; 
while($row = mysql_fetch_array($resultdl)){ 
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$rowcount, $row['qid']); 
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$rowcount, $row['ques']); 
$objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowcount, $row['response']); 
$objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowcount, $row['cnt']); 
$rowCount++; 
} 
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); 
header('Content-type: application/vnd.ms-excel'); 
header('Content-Disposition: attachment; filename="file.xls"'); 
$objWriter->save('php://output'); 
die(); 
} 

回答

1

您可以使用這樣

<?php 
header("Content-type: application/octet-stream"); 
header("Content-Disposition: attachment; filename=abc".xls"); 
header("Pragma: no-cache"); 
header ("Expires: 0"); 
?> 
    <table width="100%" border="1"> 
     <tr> 
      <td> 
       <h1> qid</h1> 
      </td> 
      <td> 
       <h1> ques</h1> 
      </td> 
      <td> 
       <h1> response</h1> 
      </td> 
      <td> 
       <h1> cnt</h1> 
      </td> 
     </tr> 

    while($row = mysql_fetch_array($resultdl)){ 
     <tr> 
      <td> 
       <?php echo $row['qid']; ?> 
      </td> 
      <td> 
       <?php echo $row['ques']; ?> 
      </td> 
      <td> 
       <?php echo $row['response']; ?> 
      </td> 
      <td> 
       <?php echo $row['cnt']; ?> 
      </td> 
     </tr> 

    <?php } ?> 

    </table> 
+0

哇謝謝你這個出色的作品 –

+1

哦ye神,接受的答案是創建HTML標記,假裝這是一個Excel文件....什麼世界來? –

+1

它的確行得通......其他解決方案都不起作用:| –

0

試試這個,禁用錯誤報告。

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=file.xls"); 
header("Content-Transfer-Encoding: binary "); 
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); 
$objWriter->setOffice2003Compatibility(true); 
$objWriter->save('php://output'); 
+0

試過這個。沒有變化:(仍然是亂碼 –

3

如果youre下載一個xls文件(BIFF),使用PHPExcel_Writer_Excel5作家;如果您正在下載.xlsx文件(OfficeOpenXML),請使用PHPExcel_Writer_Excel2007 Writer:不要混搭......這就是您的問題。您正在使用Excel2007 Writer創建.xlsx(OfficeOpenXML)文件,但設置標題以告知瀏覽器預計.xls(BIFF)文件

.xls(BIFF)下載的推薦標題爲:

// Redirect output to a client’s web browser (Excel5) 
header('Content-Type: application/vnd.ms-excel'); 
header('Content-Disposition: attachment;filename="01simple.xls"'); 
header('Cache-Control: max-age=0'); 
// If you're serving to IE 9, then the following may be needed 
header('Cache-Control: max-age=1'); 

// 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 

用於.XLSX(OfficeOpenXML)下載推薦標頭是:

// Redirect output to a client’s web browser (Excel2007) 
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 
header('Content-Disposition: attachment;filename="01simple.xlsx"'); 
header('Cache-Control: max-age=0'); 
// If you're serving to IE 9, then the following may be needed 
header('Cache-Control: max-age=1'); 

// 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 

注意Content-TypeContent-Disposition,可以通過瀏覽器區分大小寫的處理,使Content-Type是不一樣Content-type ....我相信也可能會給你帶來問題

+0

這樣做的錯誤是 - 「Excel can not打開文件'01simple-1.xlsx',因爲文件格式或文件擴展名無效。確認文件沒有被損壞,並且文件擴展名與文件的格式相匹配。「 –

+0

Excel仍然打開 –

+1

某些版本的Excel會抱怨與文件擴展名不匹配的文件格式....這就是爲什麼您應該發送符合您創建的文件類型的正確標題:但是,你不清楚你是否看到了'PKQ =DG'D²Xð[Content_Types] .xml「MNÃ0...÷」ò%nY「švAa •(0â±êØ-gúw{&iñnbEö{ßøyìÑdÛrl 在瀏覽器中,或者在MS Excel中打開文件時 –

0

我遇到了同樣的問題,最後發現是什麼原因造成的。 在調用$objWriter->save('php://output')之前的某個地方,輸出緩衝區被無意中寫入。 你可以在$objWriter->save('php://output')之前通過var_dump(ob_get_contents())來測試。

速戰速決是添加ob_開始()在腳本的開頭,然後ob_​end_​clean()只是$objWriter->save('php://output')之前,但完美的解決將是尋找到輸出緩衝區被填充。

1

我知道我可能對此有點遲到,但以上都不適合我。這是真的使用ob_clean();將刪除任何緩存的材料,以便它不會干擾返回的標題+文件內容。重要的是你在哪裏清理額外的亂碼。所以經過幾天我的頭腦,我注意到你需要在標題前ob_clean();。如果你在別的地方做,你會遇到同樣的問題。這是一個適用於我的示例代碼。

  ob_clean(); 
      $fileName = "Test.xlsx"; 
      # Output headers. 
      header("Set-Cookie: fileDownload=true; path=/"); 
      header("Cache-Control: private"); 
      header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 
      header("Content-Disposition: attachment; filename='".$fileName."'"); 
      // If you're serving to IE 9, then the following may be needed 
      header('Cache-Control: max-age=1'); 
      // 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 
      # Output file. 
      $return->save('php://output'); 
      die(); 
+0

這與@Mark Ba​​rker關於「不混合和匹配」解決方案的答案結合起來。 ob_clean並在最後死亡使它工作。 –