vuejs

Nuxt.js(Vue.js)+ Buefy でCSVファイルをアップロードしてテーブル表示する

はじめに

Nuxt.jsでBuefyを使っており、csvファイルをアップロードして読み込ませる必要がったので実装してみました。この記事では、Buefyというコンポーネントセットを使っています。もしBuefyについて興味がある方は、以下に使い方などをまとめているので見てみてください。

Vue.jsアプリの見た目を良くするコンポーネントセットBuefyを使うための準備

BuefyはBulmaというUIコンポーネントセットをベースにしたVue.js用のUIコンポーネントセットです。Bootstrapのようにあらかじめ用意されたHTMLタグやCSSクラスを使うことで簡単にそれなりの見た目になります。ここでは、Vue.jsアプリでBuefyを使えるようにするための準備手順と、最後にmarginやpadding用のクラスをBeufyに追加する方法をメモします。

できるようになること

以下のGIF画像のように、csvファイルをドロップすると、csvファイルの中身がテーブル表示されます。

アップロードしたcsvファイルの中身は以下です。

前提と環境

ここでは、Nuxt.jsにnuxt-buefyをインストールして使っている前提ですが、おそらくVue.jsや他のコンポーネントセットでも対応を見れば分かると思います。ただし、エラー処理などは実装しておりませんのでそれら処理は各自で実装の必要があると思います。

  • Nuxt.js : 2.9.0
  • nuxt-buefy: 0.3.14

nuxt-buefyの公式リポジトリは以下です。

Nuxt Buefy

It’s really very simple to start with nuxt. But we can make it even simpler by adding nuxt-buefy.

csvファイルをアップロードして表示するコンポーネント

全体コードを以下に載せます。コード内にコメントを加えているのでおおまかに分かると思います。

<template>
  <section class="section">
    <b-field>
      <b-upload
        v-model="dropFile"
        drag-drop
      >
        <section class="section">
          <div class="content has-text-centered">
            <p>
              <b-icon
                icon="upload"
                size="is-large"
              />
            </p>
            <p>ファイルをドロップするか、ここをクリックしてアップロードするファイルを選択してください。</p>
          </div>
        </section>
      </b-upload>
    </b-field>
    <div v-if="dropFile" class="block">
      <div class="tags">
        <span class="tag is-primary">
          {{ dropFile.name }}
          <button
            class="delete is-small"
            type="button"
            @click="deleteDropFile(index)"
          />
        </span>
      </div>
      <button class="button is-primary" @click="uploadedData()">
        読み込む
      </button>
    </div>
    <div class="table-wrapper">
      <table class="table">
        <thead>
          <tr>
            <th>氏名</th>
            <th>カタカナ</th>
            <th>生年月日</th>
            <th>会社名</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in csvData" :key="item.id">
            <td>{{ item.lastname }} {{ item.firstname }}</td>
            <td>{{ item.lastkana }} {{ item.firstkana }}</td>
            <td>{{ item.birthday }}</td>
            <td>{{ item.company }}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </section>
</template>

<script>
export default {
  name: 'UploadForm',
  data () {
    return {
      dropFile: null,
      csvData: [] // csvデータ格納用
    }
  },
  methods: {
    // アップロードしたファイル削除用
    deleteDropFile (index) {
      this.dropFile = null
    },
    // アップロードしたcsvファイルをcsvDataに格納する用
    uploadedData () {
      this.csvData = [] // csvDataを初期化
      const csvfile = this.dropFile
      const reader = new FileReader()

      const loadCSV = () => {
        const lines = reader.result.split('\n') // 改行毎にデータを分ける
        lines.shift() // csvファイルの先頭(ヘッダ)を削除
        // csvファイルの各行をcsvDataにオブジェクトとしてpushする
        lines.forEach((element, index) => {
          const workerData = element.split(',') // 区切り文字はカンマ
          if (workerData.length !== 6) { return } // 読み込んだ行のデータが欠けている場合は無視
          this.csvData.push(
            {
              id: index,
              lastname: workerData[0],
              firstname: workerData[1],
              lastkana: workerData[2],
              firstkana: workerData[3],
              birthday: new Date(workerData[4]),
              company: workerData[5]
            }
          )
        })
      }
      reader.onload = loadCSV
      reader.readAsText(csvfile)
    }
  }
}
</script>

上記のコードでは、HTML5から使用できるFile APIのFileReaderを使用しています。詳しくは以下に記載されています。

FileReader

FileReader オブジェクトを使うと、ユーザーのコンピューター内にあるファイル (もしくはバッファ上の生データ) をウェブアプリケーションから非同期的に読み込むことが出来ます。読み込むファイルやデータは File ないし Blob オブジェクトとして指定します。

また、Buefyのアップロード部分については以下の公式ドキュメントをほぼそのまま使用しています。

Upload | Buefy

Upload one or more files

まとめ

Nuxt.jsとBuefyの組み合わせによって大体のことは簡単に実装できおすすめです。

SPONSORED LINK

コメントを残す

メールアドレスが公開されることはありません。