LoginSignup
18
16

More than 5 years have passed since last update.

[zlib.js] JavaScriptでZIP解凍する

Last updated at Posted at 2018-12-26

JavaScriptでZIP解凍することができるライブラリを紹介します。

zlib.js
https://github.com/imaya/zlib.js/

今回使用したJavaScriptライブラリのバージョンは下記の通りです。

JavaScriptライブラリ
Bootstrap: 3.3.7
jQuery: 3.3.1
zlib.js: 0.3.1

ライブラリの読み込み

unzip.min.jsを参照します。

index.html
<script type="text/javascript" src="../../lib/zlib/unzip.min.js"></script>

AjaxでZIPファイルを取得して、画面上に展開する

下記のようなJSONファイルを用意して、それをZIP圧縮したファイルを作成します。そのZIPファイルをAjaxで取得して、ZIP解凍後、画面上のテキストボックスやラジオボタン、プルダウンに展開します。

sample/sample001.json
{
    "inputText1": "あいうえお12345",
    "inputRadio1": "1",
    "select1": "3"
}

Ajaxで作成したZIPファイルを取得します。

AjaxでZIPファイル取得する
var url = $('#importFile').val();
var xhr = new XMLHttpRequest
xhr.onload = function () {
    importFile(new Blob([xhr.response]));
}
xhr.open('GET', url, true)
xhr.responseType = 'arraybuffer'
xhr.send();

unzip.getFilenames()でZIPファイル内のファイルパス一覧を取得します。unzip.decompress()でZIP解凍します。JSONファイル内のデータはutf8ArrayToStr()でUTF-8の配列から文字列に変換する必要があります。

ZIP解凍して画面に展開する
var zipReader = new FileReader();
zipReader.onload = function () {
    try {
        var zipArr = new Uint8Array(zipReader.result);
        var unzip = new Zlib.Unzip(zipArr);
        var importFileList = unzip.getFilenames();

        var filePath = 'sample/sample001.json';
        var isExist = false;

        for (var i in importFileList) {
            var importFile = importFileList[i];
            if (importFile === filePath) {
                isExist = true;
            }
        }

        if (!isExist) {
            log('JSON file does not exist. filePath=' + filePath);
            return;
        }

        var jsonBuffer = utf8ArrayToStr(unzip.decompress(filePath));
        var jsonObj = null;

        try {
            jsonObj = JSON.parse(jsonBuffer);
            log('file=\n' + jsonBuffer);
        } catch (e) {
            log('JSON syntax is incorrect.' + e.message);
            return;
        }

        diplayImportFile(jsonObj); // テキストボックスなどの表示を行う
    } catch (e) {
        log(e.message);
    }
}
zipReader.readAsArrayBuffer(file);

デモはこちら
ソースファイルはこちら

inputファイルでZIPファイルを指定して、画面上に展開する

input type="file"でZIPファイルを指定する方法は下記の通りです。

index.html
$('#import').on('change', function () {
    var file = $(this).prop('files')[0];
    importFile(file);
});

デモはこちら
ソースファイルはこちら

ZIPファイルからinputファイルに指定する

2つのファイルsample/upload1.jsonsample/upload2.zipをZIP圧縮したファイルを作成します。
ZIPファイルを解凍した後、画面上のinputファイルに展開します。

画面上のinputファイルは、セキュリティの問題上、ユーザ操作以外でファイルを読み込ませることができませんので、下記のようにカスタムボタンを作る必要があります。

index.html
<input class="hidden inputFile" type="file" id="uploadFile2" />
<input class="btn btn-default inputFileCustom" type="button" id="uploadFile2Custom" value="uploadFile2" />
<span class="fileStatus">not selected.</span>

カスタムボタンはユーザ操作にも対応するために下記のような読み込みイベントを実装します。

カスタムボタンのイベント
$('.inputFileCustom').on('click', function () {
    $(this).parent().find('.inputFile').click();
});

$('.inputFile').on('change', function () {
    var id = $(this).attr('id');
    var file = $(this).prop('files')[0];
    var fileName = file ? file.name : null;
    setInputFile(id, file, fileName);
    $(this).val('');
});

unzip.decompress()でZIP解凍した後、ファイルをアップロードするためにはBlobに変換します。

ZIP解凍して画面に展開する
var zipReader = new FileReader();
zipReader.onload = function () {
    try {
        var zipArr = new Uint8Array(zipReader.result);
        var unzip = new Zlib.Unzip(zipArr);
        var importFileList = unzip.getFilenames();

        var uploadFile1Path = 'sample/upload1.json';
        var uploadFile2Path = 'sample/upload2.zip';

        for (var i in importFileList) {
            var importFile = importFileList[i];

            if (importFile === uploadFile1Path) {
                var fileBuffer = unzip.decompress(uploadFile1Path);
                var fileBlob = new Blob([fileBuffer], { type: 'application/octet-stream' });
                setInputFile('uploadFile1', fileBlob, getFileName(uploadFile1Path));
            }

            if (importFile === uploadFile2Path) {
                var fileBuffer = unzip.decompress(uploadFile2Path);
                var fileBlob = new Blob([fileBuffer], { type: 'application/octet-stream' });
                setInputFile('uploadFile2', fileBlob, getFileName(uploadFile2Path));
            }
        }
    } catch (e) {
        log(e.message);
    }
}
zipReader.readAsArrayBuffer(file);

デモはこちら
ソースファイルはこちら

以上です。

関連記事

[zlib.js] JavaScriptでZIP解凍する
[zlib.js] JavaScriptでZIP圧縮する

18
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
16