<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
- 結果