JavaScriptでFileの作成が手軽にできるようになりました。
ユーザのローカルに任意でDownLoadして貰いたい場合
APIから取ってきたデータをローカルに貯めたい場合
とにかくサーバーにファイル貯めたくない場合
できると嬉しいから、とりあえず手っ取り早くおしえてくれよ!
という意見にお答えします!
INDEX
JavaScriptってファイル生成できるの?
結論:ブラウザによります。
FileAPIとBlobに対応していれば、生成できます。
IE11(多分10も動作するはず)、Firefox70.0、
Chorome78.0、Edge44では動作しました。
仕様書とか書いている人には申し訳ない。
どういう仕組みでJavaScriptでファイル生成できるの?
感覚を掴んで貰いたいので箇条書きしますね。
- ※BlobURLをJavaScriptで生成する
- 生成したBlobURLを、aタグのhref属性に設定する
- ダウンロード属性付けたaタグをクリックする
- ファイルのダウンロードができる
※BlobURLはダウンロードさせたいデータです
これで感覚は掴めましたでしょうか。
それでは、JavaScriptでファイル作成を行う肝の部分を一緒に勉強していきましょう。
JavaScriptでファイル作成を行う際の肝
せっかくですし、一緒にお勉強しましょう。
コードはよ!って人は画面下部へスクロールしていってください。
Blobを定義する
BlobとはJSのクラスです。
定義しておけば、データの取り扱いが簡単になります。
Blobで定義できるデータをまとめます。
- ファイル … 画像とか
- バイナリ … 生データ
(画像の大きさ変更とかデータの加工とかする時に利用する) - 文字列 … 二文字以上の文字
- html … HyperTextMarkupLanguage
Blobとして定義できるのはこれだけです。
それでは表現方法を見て行きましょう。
var imageData = new Blob([file], { type: "image/png" });
var binaryData = new Blob([binary], { type: "application/octet-binary" });
var stringData = new Blob(["文字列"], { type: "text/plain" });
var htmlData = new Blob(["<html>"], { type: "text/plain;charset=UTF-8" });
BlobURLを生成する
作成したBlobをBlobURL作成する関数の引数に設定します。
BlobURLが生成され、これをデータとしてダウンロードすることができます。
BlobURLの作成は、URL.createObjectURLという関数で行います。
BlobURLをAタグのhref属性にセットすることで、ダウンロードが可能です。
ここまで分かると、コードが書きたくなってきたのではないでしょうか。
次からコードを書いて行きます。
JavaScriptでファイル作成する為のソースコード
この記事の目標は
「最初の方で挙げたブラウザでファイルのダウンロードができるプログラムをJSで作る」です。
その為に行わなければならないことは
- Blobの定義をすること
- BlobURLの生成をすること
- AタグのhrefへBlobURLを付与すること
たったの3つなので、コードも簡単です。
<html>
<haed>
<meta charset="UTF-8" />
</haed>
<script>
function downloadText() {
// 変更し易いようにパラメータは変数で定義してます。
// 定数使わない理由はIEで調子崩すような気がして怖いからです。
var string = 'ダウンロードできたかな?';
var title = 'testfile.txt';
var blobType = 'text/plain';
var linkTagId = 'getLocal';
var linkTag = document.getElementById(linkTagId);
var linkTagAttr = ['href','download'];
var msSave = window.navigator;
var stringObject = new Blob([string], { type: blobType });
var objectURL = window.URL.createObjectURL(stringObject);
var UA = window.navigator.userAgent.toLowerCase();
// UAで判定しなくても、window.navigator.msSaveBlobでの判定も可能
// ただ、Edgeまで対象になるので、こうしてます。
// msSave使いたいのは、IEだけです。
if(UA.indexOf('msie') != -1 || UA.indexOf('trident') != -1) {
// IEの時はmsSaveOrOpenBlobかmsSaveBlobを利用します。
window.navigator.msSaveOrOpenBlob(stringObject, title);
} else {
linkTag.setAttribute(linkTagAttr[0],objectURL);
linkTag.setAttribute(linkTagAttr[1],title);
}
};
</script>
<body>
<a id="getLocal" href="#" onClick="downloadText()">ダウンロードしてね</a>
</body>
</html>
なんとなくレガシーな感じがしますが、各ブラウザで動作します。
ダウンロードしてねをクリックするとダウンロードが開始されますよ。
以上です。JavaScriptは進化していきますね…。