BLOB オブジェクトと Web ページ ファイルのエクスポートとダウンロード

BLOB オブジェクトと Web ページ ファイルのエクスポートとダウンロード

この記事では、Web API での Blob オブジェクトの使用法と、Blob オブジェクトと URL インターフェイスを使用してファイル ストリームのダウンロード機能を実装する方法をまとめて記録します。また、CSV ファイルのフロントエンド ダウンロードと画像の圧縮ダウンロード プロセスについても紹介します。

1.ブロブオブジェクト

Blob オブジェクトは、不変の生データ ファイルのようなオブジェクトを表します。BLOB は必ずしも JavaScript のネイティブ形式でデータを表すわけではありません。File インターフェイスは BLOB に基づいており、BLOB の機能を継承し、ユーザー システム上のファイルをサポートするように拡張しています。

他の非 BLOB オブジェクトおよびデータから BLOB を構築するには、Blob() コンストラクターを使用します。

BLOB コンストラクター

Blob() コンストラクターは、新しい Blob オブジェクトを返します。BLOB の内容は、パラメーター配列で指定された値の連結で構成されます。

文法:

var aBlob = new Blob( array, options );

パラメータの中には次のものがあります。

  • Array: ArrayBuffer、ArrayBufferView、Blob、DOMString およびその他のオブジェクト、または Blob に配置される他の同様のオブジェクトの混合で構成される配列です。DOMStrings は UTF-8 としてエンコードされます。
  • options: はオプションの BlobPropertyBag ディクショナリであり、次の 2 つの属性を指定できます。
    • type: デフォルト値は "" で、BLOB に配置される配列コンテンツの MIME タイプを表します。
    • 末尾のデフォルト値は「透明」で、行終端文字 \n を含む文字列の書き込み方法を指定するために使用されます。これは、次の 2 つの値のいずれかです。
      • 「ネイティブ」は、行終端記号がホスト オペレーティング システムのファイル システムに適した改行に変更されることを意味します。または
      • 「透明」は、BLOB に保存されたターミネータが変更されないことを意味します。

のように:

var aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一个包含DOMString的数组
var oMyBlob = new Blob(aFileParts, {
    
    type : 'text/html'}); // 得到 blob

BLOB プロパティ

ブロブサイズ

読み取り専用Blob オブジェクトに含まれるデータのサイズ (バイト単位)。

BLOB タイプ

読み取り専用この Blob オブジェクトに含まれるデータの MIME タイプを示す文字列。タイプが不明な場合、値は空の文字列になります。

方法

Blob.slice([start[, end[, contentType]]])

ソース Blob オブジェクトの指定された範囲のデータを含む新しい Blob オブジェクトを返します。

Blob.close()

BLOB オブジェクトを閉じて、基礎となるリソースを解放できるようにします。

互換性

IEはIE10以上が必要で、モバイル端末は基本的に完全対応している。

念のため、互換性処理と互換性処理関数を実行することもできます。

/**
 * 获取blob对象的兼容性写法
 * @param buffer
 * @param format
 * @returns {*}
 */
function getBlob(buffer, format) {
    
    
    try {
    
    
        return new Blob(buffer, {
    
    type: format});
    } catch (e) {
    
    
        var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder);
        buffer.forEach(function(buf) {
    
    
            bb.append(buf);
        });
        return bb.getBlob(format);
    }
}

※複数アップロード

実際には、ファイルを複数の BLOB ファイルに分割し、1 つずつアップロードすることを意味します。のように:

const BYTES_PER_CHUNK = 1024 * 1024; // 每个文件切片大小定为1MB .
let blob = document.getElementById('file').files[0],	// 有个input,id叫file
	slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
let blobs = [];
slices.forEach(function(item, index) {
    
    
    blobs.push(blob.slice(index,index + 1));
});

// ajax上传...

2. 一般的なファイルタイプ(MIMEタイプ)

MIME (MultiPurpose Internet Mail Extensions) は、メッセージのコンテンツ タイプ、つまりファイルのメディア タイプを記述するためのインターネット標準です。ブラウザはそれに基づいてファイルを識別し、どのコンテンツをどのような形式で表示するかを決定できます。

サフィックス MIME タイプ
.html テキスト/html
。TXT テキスト/プレーン
.csv テキスト/プレーン
.rtf アプリケーション/rtf
.gif 画像/gif
.ipeg、.jpg 画像/jpeg
.au オーディオ/基本
.mid、.midi オーディオ/MIDI、オーディオ/X-MIDI
.ra、.ram audio/x-pn-realaudio
.avi ビデオ/x-msvideo
.doc アプリケーション/msword
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
.xls アプリケーション/vnd.ms-excel
.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.ppt アプリケーション/vnd.ms-powerpoint
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
.gz アプリケーション/x-gzip
。タール アプリケーション/x-tar

その他のタイプについては、 http://tool.oschina.net/commons/またはhttps://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_typesを参照してください。

3. フロントエンド CSV ファイルのダウンロードを実装する

※CSVファイル

カンマ区切り値 (CSV) は、区切り文字がカンマである必要がないため、文字区切り値とも呼ばれ、表形式のデータ (数値とテキスト) をプレーン テキストで保存するファイルです。プレーン テキストとは、ファイルが一連の文字であり、2 進数のように解釈する必要があるデータが含まれていないことを意味します。CSV ファイルは、何らかの改行文字で区切られた任意の数のレコードで構成されます。各レコードはフィールドで構成され、フィールド間の区切り文字は他の文字または文字列 (最も一般的にはカンマまたはタブ) です。通常、すべてのレコードにはまったく同じ一連のフィールドがあります。通常、これらはプレーン テキスト ファイルです。WORDPADやメモ帳で開き、新規保存してからEXCELで開くのも方法の一つです。

簡単に言うと、これはデータセットファイル形式です。

配列からCSVへ

インターフェイスが返すかローカル データを返すかに関係なく、js データ形式はほとんどが JSON 形式であることは誰もが知っているため、JSON を CSV 文字列に変換する方法が特に重要です。

関数に直接移動します。

/**
 * @function arrayToCSV
 * @param {array} arr 
 * @param {string} delimiter 
 */
export function arrayToCSV(arr, delimiter = ',') {
    
    
    return arr.map(v => v.map(x => `"${
      
      x}"`).join(delimiter)).join('\n');
}

たとえば、次のようなデータがあります。

let data = [
	['tit', 'val', 'date'],
	['csv', '10', '2019-10-18'],
	['jpg', '8', '2019-10-17'],
	['docx', '1', '2019-10-16'],
];

arrayToCSV(data);	// '"tit","val","date"\n"csv","10","2019-10-18"\n"jpg","8","2019-10-17"\n"docx","1","2019-10-16"'

BLOB を使用してファイルを生成する

let dataString = arrayToCSV(data);
let blobContent = new Blob(
        [dataString],
        {
    
    type: `text/plain`}	// csv的MIME TYPE
    );

ファイルが生成された後、ブラウザのダウンロード イベントをトリガーする必要がありますが、このとき、次の URL インターフェイスの助けが必要です。

中国語のエンコーディング

データの内容に中国語が含まれている場合は、中国語のエンコードに注意する必要があります。現時点での解決策は、文字セットを設定し、識別プレフィックスを追加することです。のように

let blobContent = new Blob(
        ['ufeff' + dataString],	// 添加前缀
        {
    
    type: 'text/plain,charset=utf-8'}	// utf-8
    );

URLインターフェースオブジェクト

URL インターフェイスは、URL を作成するためのいくつかの静的メソッドを含むオブジェクトです。(このコンストラクターを実装していないユーザー エージェントを使用する場合、このオブジェクトには Window.URL プロパティを通じてアクセスできます (Webkit および Blink カーネルに基づくブラウザーは代わりに Window.webkitURL を使用できます)。

URL.createObjectURL()

URL.createObjectURL() 静的メソッドは、引数で指定されたオブジェクトを表す URL を含む DOMString を作成します。この URL のライフサイクルは、URL が作成されたウィンドウ内のドキュメントにバインドされます。この新しい URL オブジェクトは、指定された File オブジェクトまたは Blob オブジェクトを表します。

文法:

objectURL = window.URL.createObjectURL(object);
URL.revokeObjectURL()

URL.revokeObjectURL() 静的メソッドは、URL.createObjectURL() の呼び出しによって作成された以前の既存の URL オブジェクトを解放するために使用されます。URL オブジェクトの使用が終了したら、このメソッドを呼び出して、メモリ内にファイルへの参照を保持する必要がなくなったことをブラウザに知らせる必要があります。

revokeObjectURL() は、sourceopen の処理後いつでも呼び出すことができます。これは、createObjectURL() が単にメディア要素の src 属性を MediaSource オブジェクトに関連付けることを意味するためです。revokeObjectURL() を呼び出すと、基になるオブジェクトが元の場所に返され、プラットフォームが適切なタイミングでガベージ コレクションを実行できるようになります。

文法:

window.URL.revokeObjectURL(objectURL);

URL インターフェース オブジェクトとタグを使用してダウンロードを実装する

let blobUrl = window.URL.createObjectURL(blobContent);	// 之前生成的字符串
let eleLink = document.createElement('a');

if (!('download' in eleLink)) return false;	// 是否支持a标签下载

eleLink.download = `test.csv`;	// 文件名
eleLink.style.display = 'none';
eleLink.href = blobUrl;

document.body.appendChild(eleLink);
eleLink.click();	// 模拟点击事件
document.body.removeChild(eleLink)

4. 画像圧縮とダウンロードを実装する

画像圧縮

キャンバスの助けを借りて。解決策は 2 つあります。1 つは画像のサイズを小さくすること、もう 1 つは画像のカラー値の精度を弱めることです。関数に直接移動します。

/**
 * @function compressImg
 * @param {image object} img
 * @param {number} rate
 * @return {string} image base64
 */
export function compressImg(img, rate = 0.9) {
    
    
  let canvas = document.createElement("canvas"),
	  ctx = canvas.getContext('2d');
  
  let tCanvas = document.createElement("canvas"),
	  tctx = tCanvas.getContext("2d");

  let width = img.width;
  let height = img.height;
  
  // 如果图片过大,缩小
  let ratio;
  if ((width > 700 || height > 700) && (ratio = width * height / 500000) > 1) {
    
    
    ratio = Math.sqrt(ratio);
    width /= ratio;
    height /= ratio;
  } else {
    
    
    ratio = 1;
  }
  
  let count;
  
  canvas.width = width;
  canvas.height = height;
  
  ctx.fillStyle = "#fff";	// 铺底色
  ctx.fillRect(0, 0, width, height);
  if ((count = width * height / 600000) > 1) {
    
    
    count = ~~(Math.sqrt(count) + 1); // 分成多少块瓦片
    // 每块瓦片的宽和高
    let nw = ~~(width / count);
    let nh = ~~(height / count);
    tCanvas.width = nw;
    tCanvas.height = nh;
    for (var i = 0; i < count; i++) {
    
    
      for (var j = 0; j < count; j++) {
    
    
        tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
        ctx.drawImage(tCanvas, i * nw, j * nh);
      }
    }
  } else {
    
    
    ctx.drawImage(img, 0, 0, width, height);
  }
  
  let ndata = canvas.toDataURL('image/jpeg', rate);

  tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
  return ndata;
}

たとえば、このような画像リンク: の場合http://blog.michealwayne.cn/images/icons/js.png、呼び出しは次のようになります。

let _img = new Image();
_img.onload = () => {
    
    
	let base64 = compressImg(_img, 0.8);	// 压缩后的图片base64
}
_img.src = 'http://blog.michealwayne.cn/images/icons/js.png'

アップロードされた画像ファイルを入力する場合は、URL.createObjectURL() を使用してまず URL に変換し、次に Base64 に変換する必要があります。

Base64 をイメージ BLOB に変換する

window.atob 関数と Uint8Array() 関数を使用する必要があります。「ブラウザーでの Base64 エンコードとデコード」を参照してください。

let text = window.atob(base64.split(',')[1]);
let buffer = new Uint8Array(text.length);

for (let i = 0; i < text.length; i++) {
    
    
    buffer[i] = text.charCodeAt(i);
}

let blobContent = new Blob([buffer], 'image/jpeg');

ダウンロードを実現

let blobUrl = window.URL.createObjectURL(blobContent);	// 之前生成的字符串
let eleLink = document.createElement('a');

if (!('download' in eleLink)) return false;

eleLink.download = `test.jpg`;	// 文件名
eleLink.style.display = 'none';
eleLink.href = blobUrl;

document.body.appendChild(eleLink);
eleLink.click();	// 模拟点击事件
document.body.removeChild(eleLink)

それを終わらせて、それで終わりです。


関連リンク

おすすめ

転載: blog.csdn.net/qq_24357165/article/details/102719483