【Laravel】StreamでLeague\Csv\WriterのsetOutputBOMは効かない
こんにちは、フリーランスエンジニアの太田雅昭です。
LaravelのStream
LaravelではStreamを以下のように書けます。
response()->stream(
function () {
echo 'Hello World!';
},
200,
[
'Content-Type' => 'text/plain; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
]
);
CSVをBOMと共に出力する
BOMを指定しないと、Microsoft Excelなどの一部のソフトで文字化けします。League WriterはBOMを出力する関数を持っていますが、LaravelのStreamと併用する場合は、なぜか正常に動きません。ヘッダー処理が競合しているためと思われます。
そのため、以下のように直接echoします。
response()->stream(
function () {
$csv = Writer::createFromPath('php://output', 'w');
// 直接BOMを出力する
echo chr(0xEF) . chr(0xBB) . chr(0xBF);
// 以下は効かない
// $csv->setOutputBOM(Writer::BOM_UTF8);
$csv->insertOne(['a','b','c']);
},
200,
[
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
]
);