CSVダウンロード機能を実装するにあたり、少しはまった部分があったので備忘録です。
流れ
- 出力データを用意
- 出力データをカンマ区切りで配列にセット
- 改行区切りの文字列に変換
- 一時的にCSVファイルを作成
- CSVファイルに書き込み
- ダウンロードレスポンスを返す。
実装
はまったポイント
- 金額など、値にカンマが含まれる文字の扱い -> 値をクオートで囲むことで1つの値として評価される。
- 出力結果が改行されnai -> 改行コードをダブルコートで囲むことで改行コードとして評価される。
- Excelで開いたときに文字化けする -> SJISにエンコーディングする。
public function downloadCsv()
{
// 1. 出力データをを用意
$csvHeader = ["No,", 師匠名, ふりがな];
$csvData = [
[0001, 春風亭助羊, しゅんぷうてい すけよう],
[0002, 桂左志郎, かつら さしろう],
[0003, 三遊亭遊智, さんゆうてい ゆうち],
[0004, 月亭がた枝, つきてい がたし],
[0005, 春雨や雷扇, はるさめや らいおう],
[0006, 桂喜八宝, かつら きゃぽう],
[0007, 翁家八ゑ千代, おきなや やえちよ],
[0008, 春雨や雷海, はるさめや らいかい],
];
// 2. 出力データをカンマ区切りで配列にセット
$downloadData = [];
$downloadData[] = implode(',', $csvHeader);
foreach ($csvData as $record) {
// 念の為ダブルクオートで囲む
foreach ($record as $i => $v) {
$record[$i] = '"' . $v . '"';
}
$downloadData[] = implode(',', $record);
}
// 3. 改行区切りの文字列に変換
$downloadData = implode("\r", $downloadData); // 改行コードはダブルクオートで囲む
// Excel対応
$downloadData = mb_convert_encoding($downloadData, "SJIS", "UTF-8");
// 4. 一時的にcsvファイルを作成
if (! file_exists(storage_path('csv'))) {
$bool = mkdir(storage_path('csv'));
if (! $bool) {
throw new Exception("ディレクトリを作成できませんでした。", 500);
}
}
$name = 'test.csv';
$pathToFile = storage_path('csv/' . $name);
// 5. CSVファイルを作成
if (! file_put_contents($pathToFile, $csvData)) {
throw new Exception("ファイルの書き込みに失敗しました。", 500);
}
// 6. ダウンロードレスポンスを返却
return response()->download($pathToFile, $name)->deleteFileAfterSend(true);
}
参考
https://gray-code.com/php/download-for-csv-file/
https://teratail.com/questions/2199
https://bayashita.com/p/entry/show/49
https://qiita.com/ikemonn/items/f2bc4f9f834c989084ff
https://www.megasoft.co.jp/support/mifes/faq/miw8faq/faq017.html