Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

モダンブラウザなら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好きな人にも大丈夫ですね!!

参考サイト

wadahiro
nri
NRIは「コンサルティング」「金融 ITソリューション」「産業 ITソリューション」「IT 基盤サービス」の4事業でお客様のビジネスや快適な社会、暮らしを支えています。※各記事の内容は個人の見解であり、所属する組織の公式見解ではありません。
https://www.nri.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした