最近做一个php项目,需要导出excel。按照例子编码完成,导出时却没有弹出另存为窗口,而是直接输出了文件内容且内容是乱码。
怎么回事呢?打开chrome调试工具,发现返回的文档类型竟然是:text/html。这就奇怪了,我明明使用php的header函数设置了其它文档类型。如下:
header('Content-Type: application/vnd.ms-excel;charset=utf-8');
经过各种调试,期间在百度上多次搜索,愣是解决不了问题。有的说可能是文件BOM头的问题,可是我明明使用sublime除去了文件的BOM头了呀!
就这样折腾了几天无果。
最后无奈,决定将服务器上的所有文件检测一遍,看看是否有文件存在BOM头。以前在网络上下载过一个自动去除文件BOM头脚本,赶快翻出来传到服务器目录,执行脚本后发现原来是配置文件config.php含有BOM头。除去此文件的BOM头后,excel导出功能果然正常了。
回想起来,自己曾经从服务器上下载此文件,并使用Windows记事本修改后上传到了服务器,就是这个操作导致了config.php含有了BOM头,又因为本地的config.php没有经过记事本编辑并不包含BOM头,所以我在本机无论如何检测都没有问题。万恶的记事本程序,以后要记住再也不要用它编辑任何东西!切记切记!!!
最后附上自动去除文件BOM头的脚本程序,此脚本为网上下载,已忘记出自哪位大侠之手,还请大侠原谅。注:原脚本会检测所有类型的文件,我将其修改为只检测.php类型的文件。
/*检测并清除BOM*/
if(isset($_GET['dir'])){
$basedir=$_GET['dir'];
}else{
$basedir = '.';
}
$auto = 1;
checkdir($basedir);
function checkdir($basedir){
if($dh = opendir($basedir)){
while(($file = readdir($dh)) !== false){
if($file != '.' && $file != '..'){
if(!is_dir($basedir."/".$file) && pathinfo($file, PATHINFO_EXTENSION)=='php'){
echo "filename: $basedir/$file ".checkBOM("$basedir/$file")." <br>";
}else if(is_dir($basedir."/".$file)){
$dirname = $basedir."/".$file;
checkdir($dirname);
}
}
}//end while
closedir($dh);
}//end if
}//end checkdir
function checkBOM($filename){
global $auto;
$contents = file_get_contents($filename);
$charset[1] = substr($contents, 0, 1);
$charset[2] = substr($contents, 1, 1);
$charset[3] = substr($contents, 2, 1);
if(ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191){
if($auto == 1){
$rest = substr($contents, 3);
rewrite ($filename, $rest);
return "<font color=red>BOM found, automatically removed.</font>";
}else{
return ("<font color=red>BOM found.</font>");
}
}
else return ("BOM Not Found.");
}//end checkBOM
function rewrite($filename, $data){
$filenum = fopen($filename, "w");
flock($filenum, LOCK_EX);
fwrite($filenum, $data);
fclose($filenum);
}//end rewrite