我正在尝试创建一个页面,允许用户将SQL表的内容下载到excel文件中。
问题:当我打开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();
}
答案 0 :(得分:3)
如果您要下载xls
文件(BIFF),请使用PHPExcel_Writer_Excel5
Writer;如果您正在下载.xlsx
文件(OfficeOpenXML),请使用PHPExcel_Writer_Excel2007
作家:不要混合搭配......这就是您的问题。您正在使用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-Type
,Content-Disposition
可能被浏览器视为区分大小写,因此Content-Type
与Content-type
不同....我相信这也可能会给你带来麻烦
答案 1 :(得分: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();
答案 2 :(得分:0)
你可以这样使用
<?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>
答案 3 :(得分: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');
答案 4 :(得分:0)
我遇到了同样的问题,终于找到了导致它的原因。
在调用$objWriter->save('php://output')
之前的某个地方,输出缓冲区被无意中写入。
您可以在var_dump(ob_get_contents())
之前$objWriter->save('php://output')
对此进行测试。
快速解决方法是在脚本开头添加ob_start(),然后在ob_end_clean()
之前添加$objWriter->save('php://output')
,但完美的修复方法是找到输出缓冲区的填充位置英寸