概要
CSVファイルのダウンロードを実装したいときに、調べた内容をメモしておきます。
※ Windows環境で、操作するので「 Shift-JIS 」である必要がある
サーバ側の実装 (PHP)
サーバサイドのAPIは、Laravelで実装する。
GET /csv/download
ルーティングを実装する。
/routes/api.php
Route::namespace('Csv')
->prefix('/csv')
->group(function () {
Route::get('/download', 'DownloadController')
->name('csv.download');
});
コントローラーは、以下のように実装しています。
※「 Maatwebsite\Excel
」を使っています
App/Http/Controllers/Csv/DownloadController.php
<?php
namespace App\Http\Controllers\Csv;
use App\Http\Controller;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Maatwebsite\Excel\Excel;
use App\Exports\Csv\SampleExport;
class DownloadController extends Controller
{
public function __invoke(SampleExport $export): BinaryFileResponse
{
return $export->download('sample.csv', Excel::CSV, [
'Content-Type' => 'text/csv'
]);
}
}
エクスポート処理は、以下のように実装しました。
App/Exports/SampleExport.php
<?php
namespace App\Exports\Csv;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
use Maatwebsite\Excel\Concerns\WithHeadings;
class SampleExport implements WithHeadings, WithCustomCsvSettings
{
use Exportable;
/**
* @return array
*/
public function headings(): array
{
return [
'商品ID',
'商品コード',
'商品名',
'数量',
'登録日時',
'更新日時',
];
}
/**
* @return array
*/
public function getCsvSettings(): array
{
return [
'use_bom' => true,
];
}
}
フロント側の実装 (Vue.js)
Vue.jsのコンポーネントに組み込みました。
/resources/js/components/Sample.vue
<template>
<div>
<button @click="download">ダウンロード</button>
</div>
</template>
<script>
import axios from 'axios'
import { saveAs } from 'file-saver';
import Encoding from 'encoding-japanese';
export default {
name: 'Sample',
methods: {
download () {
axios.get('/csv/download')
.then((res) => {
// convert encoding. (utf-8 → shift-jis)
const unicodeList = Encoding.stringToCode(res.data);
const shiftJisCodeList = Encoding.convert(unicodeList, 'sjis', 'unicode');
const shiftJisString = new Uint8Array(shiftJisCodeList);
// save
const fileName = 'サンプル.csv'
let blob = new Blob([shiftJisString], {type: 'text/csv;charset=sjis'})
saveAs(blob, fileName);
}).catch(e => {
this.$message.error(e.response.data.message)
})
}
}
}
</script>
まとめ
サーバ側で、Shift-JISエンコードのCSVファイルを出力しても、
ブラウザからダウンロードされるのは、UTF-8 (MacOS - Chrome)でした...
また、「 Maatwebsite\Excel
」でCSVをエクスポートするとUTF-8だったので、そのままだと文字化けしてしまいました。
結論としては、フロント側のJSで「 Encoding
」でShift-JISに変換しています。
参考サイト
- Vue.js で SJIS コードの CSV をダウンロードさせる
- ブラウザのJavaScriptでShiftJISのcsvを作ってダウンロードさせる
- 令和の時代に、JavaScriptで Shift-JISファイル作成 全 ... - web帳
以上