LoginSignup
3
3

More than 1 year has passed since last update.

【Typescript】クライアント側でCSVをparseする

Posted at
<script setup lang="ts">
import { ref } from 'vue'
import Papa, { ParseResult } from 'papaparse'

interface WorldCity {
  name: string;
  country: string;
  subCountry: string;
  geoNamId: number;
};
const worldCities = ref<WorldCity[]>([])

const uploadCsv = (e: Event) => {
  const target = e.target as HTMLInputElement
  const fileList = target.files as FileList
  if (!fileList.length) return

  const splitedFileName = fileList[0].name.split('.')
  const extension = splitedFileName[splitedFileName.length - 1]
  if (extension !== 'csv') return

  Papa.parse(fileList[0], {
    complete: (results: ParseResult<WorldCity>) => {
      console.log(results.data)
      worldCities.value = results.data
    },
    header: true,
    dynamicTyping: true,
    error: () => {
      alert('エラーが発生しました')
    },
  })
}
</script>

<template>
  <input type="file" @change="uploadCsv" />
</template>

解説

クライアント側でimportしたCSVを加工するために papaparse を使用します。

yarn add papaparse
yarn add @types/papaparse -D
  • Papaとparse完了後の型をimport
  • CSVをparse後に加工したい型定義
  • 代入するref定義
import Papa, { ParseResult } from 'papaparse'

interface WorldCity {
  name: string;
  country: string;
  subCountry: string;
  geoNamId: number;
};

const worldCities = ref<WorldCity[]>([])
  • アップロードされたファイルの拡張子がCSVかチェック
<script setup lang="ts">
const uploadCsv = (e: Event) => {
  const target = e.target as HTMLInputElement
  const fileList = target.files as FileList
  if (!fileList.length) return

  const splitedFileName = fileList[0].name.split('.')
  const extension = splitedFileName[splitedFileName.length - 1]
  if (extension !== 'csv') return
}
</script>

<template>
  <input type="file" @change="uploadCsv" />
</template>
  • Papa.parseの第1引数にFileオブジェクトを指定
  • 第2引数にParse Config Objectを指定
  • complete
    • parse完了後のコールバック。resultsでparse結果を受け取る
  • header
    • trueでCSVの1行目のヘッダーをkeyに持つオブジェクトを返す
  • dynamicTyping
    • 数値やbooleanが存在する場合にstringから型変換を行なって返す
  • error
    • parse失敗時にコールバック
Papa.parse(fileList[0], {
  complete: (results: ParseResult<WorldCity>) => {
    console.log(results.data)
    worldCities.value = results.data
  },
  header: true,
  dynamicTyping: true,
  error: () => {
    alert('エラーが発生しました')
  },
})
  • 読み込みCSV
name,country,subcountry,geonameid
les Escaldes,Andorra,Escaldes-Engordany,3040051
Andorra la Vella,Andorra,Andorra la Vella,3041563
Umm al Qaywayn,United Arab Emirates,Umm al Qaywayn,290594
Ras al-Khaimah,United Arab Emirates,Raʼs al Khaymah,291074
Khawr Fakkān,United Arab Emirates,Ash Shāriqah,291696
  • 結果

スクリーンショット 2022-02-07 9.06.50.jpg

3
3
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
3
3