JavaScriptでファイルダウンロード処理を実現する

  • 304
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

はじめに

モダンブラウザならJavaScriptでファイルダウンロード処理を実現することができます。SPA(シングルページアプリケーション)など、クライアント側にデータを持つようなアプリケーションであればサーバアクセスなしにメモリの内容からファイルを生成してダウンロードさせることができます。

実装方法

やり方は

  1. リンクのHTML5のdownload属性を使用してダウンロードファイル名を設定
  2. File APIのBlobを使用してデータを作成
  3. window.URL.createObjectURLでBlobからURLを生成しそれをリンク先に設定

とするだけです。これでChromeとFireFoxはいけます(download属性のブラウザ実装状況を見るとを見ると、試せていないですがEdgeとOperaもいけそう)。加えてIEをサポートする場合は、IE10/11であればwindow.navigator.msSaveBlob(またはmsSaveOrOpenBlob)を使うことで同様のことができます(IE9以下はBlobが使えないため対応できません)。Safariに関してはまた別の方法で対応することができるようで、saveAsのpolyfillであるFileSaver.jsではSafariにも対応している模様実装はこのあたり

サンプルコード

下記はChrome/FireFox/IE11で動作確認したサンプルコードになります。「ダウンロード」リンクをクリックすると「あいうえお」と書かれたテキストファイル(test.txt)がダウンロードされます。

ダウンロードサンプル
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Download Sample</title>
    </head>
    <body>
        <script type='text/javascript'>
            function handleDownload() {
                var content = 'あいうえお';
                var blob = new Blob([ content ], { "type" : "text/plain" });

                if (window.navigator.msSaveBlob) { 
                    window.navigator.msSaveBlob(blob, "test.txt"); 

                    // msSaveOrOpenBlobの場合はファイルを保存せずに開ける
                    window.navigator.msSaveOrOpenBlob(blob, "test.txt"); 
                } else {
                    document.getElementById("download").href = window.URL.createObjectURL(blob);
                }
            }
        </script>
        <a id="download" href="#" download="test.txt" onclick="handleDownload()">ダウンロード</a>
    </body>
</html>

おまけ: 日本語を含むCSVファイルのダウンロード

ファイルダウンロード処理でよくありがちなCSVファイルのダウンロードを本方式で行うと、UTF-8のためそのままではExcelでは開けないという問題があります。実はExcelはBOM付きにするとUTF-8で開くことができますので、BOMを付与してダウンロードさせればOK。以下、CSVファイルダウンロードのサンプルコードです。

CSVダウンロードサンプル
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Download Sample</title>
    </head>
    <body>
        <script type='text/javascript'>
            function handleDownload() {
                var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
                var content = 'あいうえお,かきくけこ,さしすせそ';
                var blob = new Blob([ bom, content ], { "type" : "text/csv" });

                if (window.navigator.msSaveBlob) { 
                    window.navigator.msSaveBlob(blob, "test.csv"); 

                    // msSaveOrOpenBlobの場合はファイルを保存せずに開ける
                    window.navigator.msSaveOrOpenBlob(blob, "test.csv"); 
                } else {
                    document.getElementById("download").href = window.URL.createObjectURL(blob);
                }
            }
        </script>
        <a id="download" href="#" download="test.csv" onclick="handleDownload()">ダウンロード</a>
    </body>
</html>

これでExcel好きな人にも大丈夫ですね!!

参考サイト