VueでCSVからデータを読み込む方法

## はじめに

- Vueを使ったアプリでCSVデータを取り込んで、オブジェクトにして使いたい！
- CSVを取り込んでデータに変換ってどうするの？

そんな悩みを抱えていませんか？

アプリで会員データや商品リストなど、CSVファイルをアプリで利用する場面はよくあります。

ただ、いざ実装してみると難しくて手が止まった人も多いのではないでしょうか？

この記事では、「CSVデータをアプリ内で使いたい！」という方に向けて、[**Papa Parse**](https://www.papaparse.com/) というライブラリを使ったシンプルな方法をお伝えします。

### できること

たとえば、以下のようなCSVデータがあるとします。
```csvs
 "名前", "年齢", "職業" // ヘッダー
 "太郎", 18, "学生"
 "花子", 19, "学生"
```

スプシに書き出したので、よかったらダウンロードして使ってください。

https://docs.google.com/spreadsheets/d/1sK5_N43l8aAvC_iH4sPef5QXnSle9CCJC9HX2PMI5YA/edit?usp=sharing

これをオブジェクトに変換して、他のコードで使える状態を目指します。
```javascript
[
 { name: "太郎", age: "18", job: "学生" },
 { name: "花子", age: "19", job: "学生" }
]

// 例
> data.name
"太郎"
```

P.S
実際にVueアプリを作りました。実際触ってみると、完成をイメージしやすいと思います↓

https://play.vuejs.org/#eNp9VU+P20QU/yoPX+pIwS6iXEISWpYgCgutdldc4hxce5J4154ZzYyzG6WWyAYJKlQV9cKhAiRULkV7QCABEtAPY+0qfAvezNipk1Y9OfP+/t5vfm+ycG5x7s1y4nScriIZT0NF+gEF6CaU5wrUnJNe4IyTlAQO3IymIZ1oA6N7cvYhWveMBX0+pplE3i/Pn5ar38rV9+Xq73L1dbn8rlz+WK6+0sfz5x1YLCI5+yBUYVF0fY55Xb/RG48yEglXIInKOaTYADsqGTjoTTLOhIIFCDKGAsaCZXANB7i2cd0NeWjtgcPxNw+FRIDv6sp6HDg6IBET8aESCZ1AD+yxK825Dfbbx/iIUamgwoqB2LK7lTwc9d3hqKUrj3MaqYRR2GHGJTNCVQcG+tOChabI1rUE98AEeCoUE6IglPDR0af7t7VvkJIMXQikTtHXsJ/gj57N9rRBmskAkjG4b2wi7t/fRHspoRM1hV6vB9dbOIXKBd2pihXr8OH1UVXRugUJYyIwgJJT0IMdGIPbMiWs12M0ZWGMQaGc0whc0oJe305b10EeN5STat73PEFknpq5Le+mKKZY0r1ZmOYanL3bvcPP3U0Z279ootCfW/KInClXT6MjCj2K78Pl0wdXj55UUlx+uf7m1/WzH8rzx1dP/iyXj+q7npo6nZckYga5/Pbh5YOHHZQVDTNUVNsY//r9v39+0sZQr4GxrZd/XP18oW3H7J6xaZQGBk6ATdfPLsrl8/W/uA5fNKTziiE7FS2tHUzDUVNKC4i1QgtEqtXvGclvS7X/oma7vpd6WiVyYoADyJOEDzKu5vsJJbLhKjSZlmotH9PQy0LuuoKdmstGKDMi1CdkLo2tyX55fmGW/3HF+/IXex+N4XfSd+bd2pwqlMQHL8Xpu7JkA4yZANdmDJlIJgkNUyzfBiOqEbAx3Ll3TCLl4ZaJhFSwt1WLosccLGvJahYa6SVrnGvpNtANbfoI801TK9ktIpvhlrGub98/fO2cNr57GDFOJt6xZBSfaYMucCKWcZS4uMM1e/g24rNq+6MS05SdfmxsjavFnCmJTl5hP5Zn2hY4d3EbiZjVOtY+u6fWPTj8DFer4cxYnOs/htc4D4hkaa4x2rD3cxoj7EacQXvbSB8v8EgOzhShsh5KAzWkmfjAwad+7zWjv4D7tnejIrtAFu1qvYmC3eHROraLNP41NOSpUlx2fD+KqSdP5jyMTryYzPxN2M13vBveW4Gz6Vf8D7pIrd0=

[![Image from Gyazo](https://i.gyazo.com/903bd484c6e191537a58baa2475ca8a9.gif)](https://gyazo.com/903bd484c6e191537a58baa2475ca8a9)

## 対象読者

この記事は以下のような方を対象としています。
- VueやJavaScript(TS)を使ってる  
- アプリでCSVデータを使いたい

できるだけわかりやすく解説してるので、学びたての人でも読めますよ。

## 使用技術
- Vue.js
- JavaScript
  - (TypeScript化したコードも載せてます)

## コード例

### 事前準備

`papaparse`をインストールしておきましょう。

```zsh
npm install papaparse
```

また、以下のコードに処理を追加します。
```javascript
import Papa from "papaparse";

function importCSV() {
  // ここに処理を書く
}
```

### 1. CSVデータを読み込む

`parse`メソッドを使うと、CSVを読めます。

```javascript
import Papa from "papaparse";

// csvDataを受け取って、オブジェクトに変換する
function importCSV(csvData) {
  const { data } = Papa.parse(csvData, {
    header: true,
    skipEmptyLines: true
  });

  return data;
}

// dataは以下になります↓
// [
//   { "名前": "太郎", "年齢": "18", "職業": "学生" },
//   { "名前": "花子", "年齢": "19", "職業": "学生" }
// ]
```

### 2. ヘッダーを英語に変換する
今のままでも良いのですが、キーが日本語だと使いづらいので英語にします。
```javascript
// before
[
  { "名前": "太郎", "年齢": "18", "職業": "学生" },
  { "名前": "花子", "年齢": "19", "職業": "学生" }
]

> data["名前"]
"太郎"

// after
[
  { name: "太郎", age: "18", job: "学生" },
  { name: "花子", age: "19", job: "学生" }
]

> data.name
"太郎"
```

日本語ヘッダーを英語に変えるための対応表(`header`)を定義します。  
それを使って`data`の各行のキーを変換します。

```javascript
import Papa from "papaparse";

// 変換したい英語を書く
const header = {
  名前: "name",
  年齢: "age",
  職業: "job",
};

function importCSV(csvData) {
  // CSVを読み込む
  const { data } = Papa.parse(csvData, {
    header: true,
    skipEmptyLines: true,
  });

  return data.map((row) => convertKeys(row));
}

// キーを英語に変換(複雑なので、コピペOKです)
function convertKeys(row) {
  const convertedRow = {};

  for (const [originalKey, value] of Object.entries(row)) {
    const newKey = header[originalKey] || originalKey;
    convertedRow[newKey] = value;
  }

  return convertedRow;
}

// importCSVが返すデータ
// [
//   { name: "太郎", age: "18", job: "学生" },
//   { name: "花子", age: "19", job: "学生" }
// ]
```

### 完成

これで完成しました。

JavaScript版
```javascript
import Papa from "papaparse";

// 変換したい英語を書く(みなさんのアプリに応じて変換してください)
const header = {
  名前: "name",
  年齢: "age",
  職業: "job",
};

function importCSV(csvData) {
  // CSVを読み込む
  const { data } = Papa.parse(csvData, {
    header: true,
    skipEmptyLines: true,
  });

  return data.map((row) => convertKeys(row));
}

// キーを英語に変換(複雑なので、コピペOKです)
function convertKeys(row) {
  const convertedRow = {};

  for (const [originalKey, value] of Object.entries(row)) {
    const newKey = header[originalKey] || originalKey;
    convertedRow[newKey] = value;
  }

  return convertedRow;
}
```

TypeScript版はこちらです↓
```typescript
import Papa from "papaparse";
type TRecordString = Record<string, string>;

// 変換したい英語を書く(みなさんのアプリに応じて変換してください)
const header: TRecordString = {
  名前: "name",
  年齢: "age",
  職業: "job",
};

function importCSV(csvData: string): TRecordString[] {
  // CSVを読み込む
  const { data } = Papa.parse<TRecordString>(csvData, {
    header: true,
    skipEmptyLines: true,
  });

  return data.map((row) => convertKeys(row));
}

// キーを英語に変換(複雑なので、コピペOKです)
function convertKeys(row: TRecordString) {
  const convertedRow: TRecordString = {};

  for (const [originalKey, value] of Object.entries(row)) {
    // もしheaderで対応があればそれを使い、なければ元のキーを使う
    const newKey = header[originalKey] || originalKey;
    convertedRow[newKey] = value;
  }

  return convertedRow;
}
```

## おわりに
この記事では、`Papa Parse`を使ってCSVデータをオブジェクト化する方法を紹介しました。

またできるだけわかりやすく解説したつもりですが、
- ここがわかりにくかった
- 僕の場合ってどんなコードにしたら良いの？

などあれば、遠慮なくコメントいただけると幸いです！

それでは！