4
5

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.

第2回 - Web API と Web UI でファイルダウンロード(Web UI 編)

Posted at

はじめに

前回からファイルをダウンロードする簡単な Web API と Web UI のサンプルを紹介しています。
第1回目の前回は Node.js + Express.js での Web API を紹介しました。
第2回目の今回は Vue.js + Vuetify で簡単な Web UI を作り、前回の Web API を叩いて実際にファイルをダウンロードします。

  1. Web API 編
  2. Web UI 編(←イマココ)

環境

OS: macOS Mojave 10.14.6
Vue.js: 2.6.10
Vuetify: 2.1.0
axios: 0.19.0
file-saver: 2.0.2

Download.vue

Download.vue
<template>
    <v-container>
        <v-row>
            <v-col cols="2">
                <v-btn
                    v-on:click="click('sample.csv')"
                    color="primary"
                    block
                >
                    Download csv
                </v-btn>
            </v-col>

            <v-col cols="2">
                <v-btn
                    v-on:click="click('sample.png')"
                    color="primary"
                    block
                >
                    Download image
                </v-btn>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
import axios from 'axios'
import urljoin from 'url-join'
import { saveAs } from 'file-saver'

export default {
    methods: {
        async click (fileName) {
            const response = await axios.get(urljoin('http://localhost:3000/api/download'), {
                responseType: 'blob',
                params: {
                    'file': fileName
                }
            }).catch((error) => {
                console.log(error)
            })

            if (response && (200 == response.status)) {
                const contentDisposition = response.headers["content-disposition"]
                const contentDispositions = contentDisposition.split(';')
                const fileNames = contentDispositions[contentDispositions.length - 1].split('=')
                fileName = fileNames[fileNames.length - 1]
                saveAs(response.data, fileName)
            }
        }
    }
}
</script>

ボタンを2つ配置しただけのシンプルな UI です。
ダウンロードするファイルは CSV と PNG の2種類です。
ボタンをクリックすると対応するファイル名(sample.csv or sample.png)を引数にして Web API を実行します。
Web API 実行後、自動的にファイルを保存するようになっています。

Web API実行

Download.vue(抜粋)
    const response = await axios.get(urljoin('http://localhost:3000/api/download'), {
        responseType: 'blob',
        params: {
            'file': fileName
        }
    }).catch((error) => {
        console.log(error)
    })

解説

Web API の実行には axios を使用しています。
また、 responseType: 'blob' で受け取る型を Blob 型に指定します。
(後述の saveAs@file-saver で Blob 型のデータを指定するため)

ファイル保存

Download.vue(抜粋)
    const contentDisposition = response.headers["content-disposition"]
    const contentDispositions = contentDisposition.split(';')
    const fileNames = contentDispositions[contentDispositions.length - 1].split('=')
    fileName = fileNames[fileNames.length - 1]
    saveAs(response.data, fileName)

解説

Web API 側で content-disposition (ヘッダー)にファイル名を指定しており、保存時のファイル名に使用しています。
ファイルの保存は file-saver を使用します(とても便利)。
saveAs に Blob 型のデータとファイル名を指定すると自動でダウンロードが始まります。

動作確認

ファイルダウンロード.gif
第1回目のアプリケーションも合わせて起動します。
各ボタンの押下でファイルのダウンロードが始まっているのがわかります。

まとめ

2回に渡って Web API と Web UI でファイルダウンロードのサンプルを紹介しました。
複雑なコードを書かなくても、いくつかのライブラリを利用することで簡単に実装できました。
Web API でデータを取得し、保存用のモジュールでデータにデータを渡しているだけなので、アレンジもしやすいと思います。

今回、使用したコードはGitHubで公開しています。
https://github.com/ponko2bunbun/vuetify-file-download-sample

4
5
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
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?