4

このスニペットは、新しいファイル 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 の内容は、ブラウザのダウンロードから開いたときは .

4

1 に答える 1

4

ブラウザはapplication/octet-streamをバイナリ型として認識します。text/plainコンテンツ タイプが必要です。

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

正しく設定されている場合、Content-Transfer-Encodingヘッダーは不要なはずです。Content-Type実際には、ブラウザーにバイナリ ファイルも受信したと誤解させている可能性があります。

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

アップデート:

別の問題が見えます。Content-Lengthをファイルのサイズではなく、 によって開かれたファイル ハンドルに設定しています。これによりfopen()、予期されるバイト数がブラウザに誤って通知されます。filesize()ファイルハンドルではなく、文字列ファイル名を引数として取ります。fclose($NewFile)を呼び出す前に、おそらく でハンドルを閉じる必要がありfilesize()ます。

// Instead of:
header('Content-Length: ' . filesize($NewFile));

// You mean to use $FileName
// close the file handle first...
fclose($NewFile);
header('Content-Length: ' . filesize($FileName));
于 2012-08-30T01:33:42.817 に答える