かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript Blobオブジェクトでファイルを作成してダウンロードしてみる

A Blob object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system.
出典: Blob | MDN

JavaScriptで扱える生のデータで、HTML5で追加されたFile APIで追加されていた機能だそうです。 (知らなかった

blob
Can I use... Support tables for HTML5, CSS3, etc

すでに殆どのブラウザで利用可能なようです。(IEも10からOKだった...だと..... クッコロ....

Blobオブジェクトの作り方

var aBlob = new Blob( array[, options]);
  • array は、Blob の中に入れられることになるもの—— ArrayBuffer オブジェクト、ArrayBufferView オブジェクト、Blob オブジェクト、DOMString オブジェクト、またはそういったオブジェクトのうち任意のものを混在させたもの——からなる Array です。DOMString はUTF-8 で符号化されます。
  • options は、以下の二つの属性を指定できるオプショナルな BlobPropertyBag ディクショナリです。
    • type は、 blob の中に入れられることになる配列の中身の MIME タイプを表し、デフォルト値は "" です。
    • endings は、行末文字\n を含む文字列をどのように書き出すべきかを指定するもので、デフォルト値は "transparent" です。endings は、次の二つの値のうちのどちらかです。すなわち、ホスト OS のファイルシステムの慣行に合うように行末文字を変更することを意味する "native"か、変更せずに行末を blob の中にそのまま格納することを意味する "transparent" です。

出典: Blob() コンストラクタ | MDN

ファイルにしたい情報を配列形式で渡して、第二引数でMINIタイプを指定すれば良さそうです。

Blobでファイルを作成してダウンロードさせてみる

chrome v71 のコンソールで実験しました。

const str = "星宮いちご, 霧矢あおい, 紫吹蘭\n大空あかり, 氷上すみれ, 新条ひなき\n";
// Blobでファイルを作成
const file = new Blob([str, "神崎美月, 夏樹みくる"], {
  type: "text/csv;charset=utf-8"
});

// ダウンロード
const a = document.createElement('a');
// ダウンロードされるファイル名
a.download = 'aikatsu.csv';
a.href = URL.createObjectURL(file);
// ダウンロード開始
a.click();

👇 ブラウザからaikatsu.csv がダウンロードされました! aikatsu.csv

星宮いちご, 霧矢あおい, 紫吹蘭
大空あかり, 氷上すみれ, 新条ひなき
神崎美月, 夏樹みくる

第一引数の配列のデータが結合されるようです。
new Blob([ "...新条ひなき", "神崎美月, 夏樹みくる" ]) と結合した時にCSVではなくなる状態にすると、神崎美月, 夏樹みくるはBlobオブジェクトには含まれていてもダウンロードされたファイルでは消えていました。

ファイルの文字コード

上の例では type: "text/csv;charset=utf-8文字コードの指定をしています。

const file = new Blob([str], {
  type: "text/csv;charset=SJIS"
});

でも試してみましたが、ダウンロードされたファイルはUTF-8エンコードされていました。
MDNのサイトの引数の説明にあるようにDOMString はUTF-8 で符号化されるようですから、typeでcharasetは指定する意味は無さそうです。

思った以上に簡単にJavaScriptだけでファイルが生成できてびっくりしました!
知らないことが沢山で色んな所にアンテナ張っておきたいけど、フロント周りだけでもいろんな事がありすぎて遅れを取り戻すキャッチアップしながらだと中々大変です…


[参考]

(仮)MiMiCHeRi アイカツ! (4個入) 食玩・ガム (アイカツ!)

(仮)MiMiCHeRi アイカツ! (4個入) 食玩・ガム (アイカツ!)

クリスマスもやっぱりアイカツ!だね♡