5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.jsでCSVファイルをダウンロード (Shift-JIS)

Last updated at Posted at 2021-05-20

概要

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に変換しています。

参考サイト

以上

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?