JavaScriptでZIP解凍することができるライブラリを紹介します。
zlib.js
https://github.com/imaya/zlib.js/
今回使用したJavaScriptライブラリのバージョンは下記の通りです。
Bootstrap: 3.3.7
jQuery: 3.3.1
zlib.js: 0.3.1
ライブラリの読み込み
unzip.min.js
を参照します。
<script type="text/javascript" src="../../lib/zlib/unzip.min.js"></script>
AjaxでZIPファイルを取得して、画面上に展開する
下記のようなJSONファイルを用意して、それをZIP圧縮したファイルを作成します。そのZIPファイルをAjaxで取得して、ZIP解凍後、画面上のテキストボックスやラジオボタン、プルダウンに展開します。
{
"inputText1": "あいうえお12345",
"inputRadio1": "1",
"select1": "3"
}
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の配列から文字列に変換する必要があります。
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ファイルを指定する方法は下記の通りです。
$('#import').on('change', function () {
var file = $(this).prop('files')[0];
importFile(file);
});
ZIPファイルからinputファイルに指定する
2つのファイルsample/upload1.json
とsample/upload2.zip
をZIP圧縮したファイルを作成します。
ZIPファイルを解凍した後、画面上のinputファイルに展開します。
画面上のinputファイルは、セキュリティの問題上、ユーザ操作以外でファイルを読み込ませることができませんので、下記のようにカスタムボタンを作る必要があります。
<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に変換します。
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);
以上です。