PHPでcsvダウンロード際に文字化けする現象
受付中
回答 1
投稿
- 評価
- クリップ 0
- VIEW 1,433
【前提】
csvファイルに記載されているデータを画面に表示し、
それをcsvとして出力するという課題に取り組んでいます。
文字化けを回避するよう記述しているつもりが、なかなかうまくいかず
文字化けしてしまいます。
どなたか教えてください。
【元のcsvファイル】※仮のデータ
"tanaka",5000
"yoshida",1000
"suzuki",400
【ブラウザに表示したいデータ】
社員数:
売上合計:
平均売上:
上記をブラウザに表示しcsvファイルとしてダウンロードしたいという感じです。
サンプルコードは下記に記載致します。
csvファイルに記載されているデータを画面に表示し、
それをcsvとして出力するという課題に取り組んでいます。
文字化けを回避するよう記述しているつもりが、なかなかうまくいかず
文字化けしてしまいます。
どなたか教えてください。
【元のcsvファイル】※仮のデータ
"tanaka",5000
"yoshida",1000
"suzuki",400
【ブラウザに表示したいデータ】
社員数:
売上合計:
平均売上:
上記をブラウザに表示しcsvファイルとしてダウンロードしたいという感じです。
サンプルコードは下記に記載致します。
<?php
$datafile = 'sales.csv'; // CSV ファイル
$fh = fopen($datafile, 'r');
if ($fh) {
flock($fh, LOCK_SH);
$lst = array();
while ($line = fgets($fh)) { // ファイルから一行ずつ読み込む
$all = explode(',', chop($line)); // カンマで分割して配列に
while (($key = array_shift($all)) && ($val = array_shift($all))) { // 配列の先頭から名前と値を取り出す
$lst{$key} = $val; // 連想配列にセット
$lst{$key} = mb_convert_encoding($lst{$key}, "SJIS", 'utf-8');
}
}
$sum = 0;
$count = 0;
foreach ($lst as $name => $sale) {
$count += 1;
$sum += $sale;
$avr = $sum / $count;
}
echo "社員数:".$count."<br>";
echo "売上合計:".$sum."<br>";
echo "売上平均:".$avr."<br>";
$fileName = "report.csv";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $fileName);
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($fileName));
readfile($fileName);
flock($fh, LOCK_UN);
fclose($fh);
}
?>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
header()は全ての出力より前に無いといけません。
他にもあるかもしれませんが、とりあえずはこの部分をheader()より後に持ってきてみてください。
echo "社員数:".$count."<br>";
echo "売上合計:".$sum."<br>";
echo "売上平均:".$avr."<br>";
がheaderより先に出力されているため、headerは正常に機能していないはずです。
他にもあるかもしれませんが、とりあえずはこの部分をheader()より後に持ってきてみてください。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/11/05 22:30
ブラウザにデータを表示させつつCSVとしてダウンロードさせたいように見えますが、それを同じスクリプト内で実装することは無理なので(リダイレクトさせて、別のリクエストとして処理すれば可能です)まずは、
データを表示するだけ
ダウンロードするだけ
の二つのスクリプトを作ることが近道だと思います。