この記事は最終更新日から1年以上が経過しています。
@programming
投稿日 2021/12/22
更新日 2021/12/22 ✏
ブラウザ上でzip圧縮
ブラウザ上だけでファイルやデータをzip圧縮する方法のメモです。
目次:
サンプルコード
以下のサンプルでは、ブラウザ画面上のファイルINPUTでファイルを入力すると、それをzip圧縮したzipファイルをダウンロード風に出力します。処理は全てブラウザローカルだけで完結しています。 zip圧縮ライブラリにはJSZipモジュールを利用しています。 (動作確認はChromeブラウザのみ)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<input type="file" oninput="onFileInput(event)">
<script src="https://cdn.jsdelivr.net/npm/jszip@3.7.1/dist/jszip.min.js" integrity="sha256-yeSlK6wYruTz+Q0F+8pgP1sPW/HOjEXmC7TtOiyy7YY=" crossorigin="anonymous"></script>
<script type="text/javascript">
/**
* ファイル入力ハンドラ
* @param {Event} e
*/
function onFileInput(e) {
const filename = "example.zip";
const file = e.target.files && e.target.files.length >= 1 ? e.target.files[0] : null;
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
// ファイル内容:
const content = new Uint8Array(e.target.result); // as blob
// const content = e.target.result; // as text
return zipcompress([
["foo/" + file.name, content], // zip内のfoo/配下に読み込んだ内容を設置
// 圧縮対象ファイルの複数指定も可能:
// ["aaa.txt", "helloworld!"],
// ["bbb/bbb.txt", "helloworld!"],
], (err, result) => {
return download(result, filename);
});
};
reader.readAsArrayBuffer(file); // read as arraybuffer
// reader.readAsText(file); // read as text
}
/**
* [汎用] ブラウザでのダウンロード処理
* @param {String|Uint8Array} content
* @param {String} filename - filename of output data.
*/
function download(content, filename) {
// create a temporary "a" element.
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display:none";
const blob = new Blob([content], { type: "octet/stream" });
// or
// const blob = new Blob([new Uint8Array([72, 101, 108, 108, 111])], {...});
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url); // release the used object.
a.parentNode.removeChild(a); // delete the temporary "a" element
}
/**
* zip圧縮したデータを返します。
* @param {Array<[path,data]>} pathAndDataList
* @param {Function} cb
* @return {Blob}
*/
function zipcompress(pathAndDataList, cb) {
if (typeof JSZip === "undefined")
throw Error("JSZip must be installed.");
const zip = new JSZip();
for (let len = pathAndDataList.length, i = 0; i < len; i++) {
const [filename, data] = pathAndDataList[i];
zip.file(filename, data);
}
return zip.generateAsync({
type: "blob",
compression: "DEFLATE",
compressionOptions: {
/* compression level ranges from 1 (best speed) to 9 (best compression) */
level: 9
},
}).then(function(content) {
return cb && cb(null, content); // content is blob type.
});
}
</script>
</body>
</html>
実行
以上です。