LoginSignup
3
0

More than 3 years have passed since last update.

Laravel5.4 ファイル複数ダウンロード(画像でもテキストでも)

Last updated at Posted at 2019-04-16

ファイルダウンロード処理の実装

主な方法
・Response::download
(サーバー上のファイルダウンロード)(IEだと文字化け可能性)
・Response::make()
(文字化けはないが、ファイル内容をキャストしてコピーするので、大容量には向かない)
・Storage::disk()->download (バージョン的に使えない)
・phpの処理で作る (カスタマイズできる)

ダウンロード参考記事
大容量・laravel・phpファイルダウンロード参考記事

今回は、ファイル内容はそんなに重くなく、また既にファイルの中身をバイナリデータで持っていたので、Response::make()を使用することにした。
(Storage->disk('s3')->get(ファイルパス)でバイナリデータは取得していた。)

$headers = [
                'Content-Type' => $mineType,
                'Content-Disposition' => 'attachment; filename="' . $fileName . '"'
           ];
return Response::make($fileBinaryData, 200, $headers);

これでファイルダウンロードは完了。

複数ダウンロードを実装する

{{Form::button('ダウンロード', ['class' => 'on-download'])}}
<script>
$('.on-download').on('click', function(){
    handleDownload("samplel1.jpg");
    handleDownload("samplel2.jpg");
    handleDownload("samplel3.jpg");
});

function handleDownload(name) {

    const route = "{{route(download)}}";

    // IE
    if (window.navigator.msSaveBlob) {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", route, true);
        xhr.responseType = "blob";
        xhr.onload = function (e) {
            var blob = xhr.response;
            window.navigator.msSaveBlob(blob, name);
        }
        xhr.send();
        return;
    }

    // chrome,firefox
    const a = document.createElement('a');
    a.download = name;
    a.href = route;

    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);


}
</script>

aタグのdownload属性を使用して、ダウンロード処理を実装する。download属性を持つaタグを生成してclickで実行させ、消すを繰り返す.
IEはdownload属性をサポートしていないので、一つのファイルがダウンロードされるくらいなので、IE用に処理を分岐させる。ダウンロードする画像数分タブが表示されては消えるようにしているため、msSaveBlobで保存する。

今回こうやって使用した

僕が今回実際に使ったときは、テーブルの行ごとの先頭にチェックボックスが存在し、チェックが入ったレコードのファイルだけをダウンロードさせるというものだった。

なので、checkboxにdata属性でfileIdとfileNameを渡す必要があった。ダウンロードボタンを押した瞬間に、checkが入ってるもののチェックボックスからfileIdとfileNameを取り出して、それをeach文で、handleDownload(fileId, fileName)(fileIdはrouteを生成するときにどのファイルをダウンロードさせるかを判定するためにくっつけて渡す)を複数回実行させることで、課題をクリアした。

aタグのdownload属性を使って、直接ファイルをダウンロードさせる方法もあるが、僕の場合ダウンロード履歴をDBに保存する必要があったため、いったんスクリプトを経由した。

参考記事

まとめ

複数画像ファイルをダウンロードさせることにすごいはまった。
つぎからはいけそう。
今度はダウンロード後を検知する方法を知りたいなぁ。

3
0
1

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
0