0
3

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 5 years have passed since last update.

NuxtとLaravelAPIでQRコード画像を生成してダウンロードする話

Posted at

概要

Nuxt側でQRコード生成ボタンを押下したあとにLaravel側でQRコード画像を生成し
ダウンロードさせる機能を実現したい

QRコードの内容はURLなどではなく
指定のIDに紐づく商品データをJson形式で埋め込んでおきたいため
QRコード生成には引数で商品Idを渡す必要がある

メモとして書いてるので違ったりこうしたほうが良いなどあればご指摘いただけたらと思います。

前提

Laravel 5.8
Nuxt 2.4

使ったモジュール

simple-qrcode

モジュールをインストール

composer.jsonに下記を追加

composer.json
"require": {
  "simplesoftwareio/simple-qrcode": "~2.0"
}

コマンドを実行

composer update

※Laravel5.4以下の場合はconfig/app.phpへサービスプロバイダとエイリアスを登録が必要となるため
公式サイトを見て登録してください

Laravel側の実装

指定のIdに紐づくデータをQRコード化したいため動的のURLで定義する

api.php
Route::get('/product/qr-code/{id}', 'QrcodeController@download');

ダウンロード用のコントローラの作成

php artisan make:controller QrcodeController

単純に埋め込みたい商品データをSimpleQrcodeのgenerate渡してあげるだけでできた

QrcodeController.php

class QrcodeController extends Controller
{
    /**
     * QRコードダウンロード
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function download(Request $request)
    {
        $product = Product::find($request->route('id'));
        $headers = [
            'Content-Type' => 'application/octet-stream',
            'Content-Disposition' => 'attachment; filename="' .$product->product_name. '.png"',
        ];
        $qrcodeImage = QrCode::format('png')->size(300)->generate($product);
        return response($qrcodeImage, 200, $headers);
    }
}

Nuxt側の実装

今回はQRコードをダウンロードするには、認証済みのユーザでなければならないので
単純にaタグに動的URLを埋め込むだけではできなかった
そのため、downloadメソッドを下記のように実装した

    async download(prodductItem) {
      await this.$axios
        .get(`/api/shop/product/qr-code/${prodductItem.id}`, {
          responseType: 'blob'
        })
        .then(response => {
          const blob = new Blob([response.data], {
            type: 'application/octet-stream'
          })

          const url = (window.URL || window.webkitURL).createObjectURL(blob)
          const a = document.createElement('a')
          a.href = url
          a.download = prodductItem.product_name + '.png'
          // aタグ要素を画面に一時的に追加する
          document.body.appendChild(a)
          a.click()
          // 不要になったら削除.
          document.body.removeChild(a)
        })
    }

まとめ

便利なモジュールが用意されておりさほど苦労せずに実装できたため
Laravelは本当に色々と自前で実装せずに済むので開発が楽でした。

もっとこんな方法が良いとかこの実装はあまりよくないなどあれば
教えてもらえると幸いです!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?