要下载的PHP到CSV输出


PHP to CSV output to download

该片段读取新文件CSV中的输出流。这部分有效。我可以从服务器打开文件,它看起来很完美。问题出在通过浏览器下载到我硬盘的文件上。它将无法在Windows机器上的电子表格软件或Excel中正确打开和读取:

$NewFile = fopen($FileName,"w");
fwrite($NewFile, $output);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$FileName.'"'); 
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($NewFile));
ob_clean();
flush();
readfile($NewFile);

CSV的内容看起来��ࡱ�就像我从浏览器下载中打开它一样,但当我直接在服务器上打开它或使用FTP下载存储的文件时,它看起来很完美。

浏览器将application/octet-stream视为二进制类型。您需要text/plain内容类型:

header('Content-Type: text/plain');
// Or:
header('Content-Type: text/csv');
// Or: 
header('Content-Type: application/csv');

如果您正确设置了Content-Type,那么Content-Transfer-Encoding标头应该是不必要的,事实上,它可能会误导浏览器,使其认为它也收到了一个二进制文件:

// No need, possibly harmful. Remove it...
// header('Content-Transfer-Encoding: binary');

更新:

我看到了另一个问题。您不是将Content-Length设置为文件大小,而是将其设置为fopen()打开的文件句柄,这会错误地通知浏览器所需的字节数。filesize()将字符串文件名作为参数,而不是文件句柄。在调用filesize()之前,您可能需要关闭带有fclose($NewFile)的句柄。

// Instead of:
header('Content-Length: ' . filesize($NewFile));
// You mean to use $FileName
// close the file handle first...
fclose($NewFile);
header('Content-Length: ' . filesize($FileName));