JavaScriptでZIP圧縮&ダウンロード

ブラウザのセキュリティ仕様で別ドメインの画像は取得できないので注意

ZIP DOWNLOAD

hi0a.com

https://github.com/eligrey/FileSaver.js

https://stuk.github.io/jszip/

https://stuk.github.io/jszip/documentation/api_jszip/file_data.html

https://knooto.info/jszip-snippets/

https://qiita.com/Chrysanthemum94/items/4a5deaeee1f2a9c63181

zzzz
9

xxxxxxxx

view source

JavaScript

var Downloader = function(){
  //https://github.com/eligrey/FileSaver.js
  //https://stuk.github.io/jszip/

  var zipFileName = 'download.zip';
  var imgs = [];
  var arraybufferList = [];

  this.setZipName = function(zipFileNameArg){
    zipFileName = zipFileNameArg;
    console.log(zipFileName);
    return this;
  }
  this.setImages = function(imgsArg){
    imgs = imgsArg;
    console.log(imgs);
    return this;
  }
  this.convertQueryToImages = function(query){
    imgs = [];
    var eles = document.querySelectorAll(query);
    console.log(eles);
    //eles.forEach is not a function
    for(var i=0,len=eles.length;i<len;i++){
      var ele  = eles[i];
      var attr;
      console.log(ele);
      console.log(ele.tagName);
      switch(ele.tagName){
        case 'A':
          attr = ele.getAttribute('href');
          break;
        case 'IMG':
          attr = ele.getAttribute('src');
          break;
      }
      console.log(attr);
      if(!attr){return;}
      imgs.push(attr);
    }
    console.log(imgs);
    return this;
  }
  this.run = function(){
    console.log(imgs);
    imgs.forEach(function(url){
      console.log(url);
      loadImg(url);
    });
  }

  var loadImg = function(imgUrl) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', imgUrl, true);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function() {
      var arraybuffer = this.response;
      
      var name = imgUrl;
      if(name.match('/')){
        name = name.split('/').pop();
      }
      var arraybufferData ={
        name : name,
        arraybuffer : arraybuffer,
      }
      arraybufferList.push(arraybufferData);
      if(arraybufferList.length === imgs.length){
        console.log(arraybufferList);
        downloadZip(arraybufferList);
      }
    };
    xhr.send();
  };


  //base64だとなぜか動作しない
  //img.file("smile.png", imgBase64Data, {base64: true});
  var downloadZip = function(arraybufferList){

    var zip = new JSZip();
    zip.file('readme.txt', 'fuck!\n');
    var img = zip.folder('images');
    arraybufferList.forEach(function(val){
      img.file(val.name, val.arraybuffer, {binary: true});
    });
    var content = zip.generate({type:'blob'});
    // see FileSaver.js
    saveAs(content, zipFileName);
  }


}




$(function(){
  async function downloadZip(){
    const zip = new JSZip();
    const image = await JSZipUtils.getBinaryContent('image.png'); // 画像ファイルのバイナリデータを取得
    zip.file('image.png', image, { binary: true });

  }
  $('#zipDL').text('zipDL').click(function(){
    downloadZip();
  });

});


new JSZip.external.Promise(function (resolve, reject) {
    JSZipUtils.getBinaryContent('image.png', function(err, data) {
        if (err) {
            reject(err);
        } else {
            resolve(data);
        }
    });
}).then(function (data) {
    console.log(data);
    zip = JSZip.loadAsync(data);
    console.log(zip);
    return zip;
})
.then(function(text){
  console.log(text);
});


const getImage = (imageUrl) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', imageUrl, true);
    xhr.responseType = "blob";
    xhr.onload = (e) => {
      let blobs = e.currentTarget.response;
      let fileName = imageUrl.split('/').pop();
      let data = {
        blobs:blobs,
        name:fileName,
      }
      resolve(data);
    };
    xhr.send();
  });
};
const generateZip = (images) => {
  return new Promise((resolve, reject) => {
    const zip = new JSZip();
    console.log(images);
    images.forEach((images, i) => {
      console.log(images);
      let imageData = images.blobs;
      let ext = '.'+images.name.split('.').pop();
      zip.file(`image${String(i).padStart(3, '0')}`+ext, imageData);
    });
    zip.generateAsync({ type: "blob" }).then(resolve);
  });
};
const imageUrls = [
  'image.png',
  'image.png',
];
Promise.all(
  imageUrls.map((url) => {return getImage(url);})
).then((images) => {
  generateZip(images).then((zip) => {
    var href = URL.createObjectURL(zip);
    console.log(href);
    $('#a').attr({download:'hi0a.com.zip', href:href});
  });
});

CSS

button{
  width:25%;
}
#a{
  display:inline-block;
  padding:20px;
  margin:8px;
  text-align:center;
  border:1px solid #333;
  border-radius:8px;
}

HTML

ページのソースを表示 : Ctrl+U , DevTools : F12

view-source:https://hi0a.com/demo/-js/js-zip/

ABOUT

hi0a.com 「ひまアプリ」は無料で遊べるミニゲームや便利ツールを公開しています。

プログラミング言語の動作デモやWEBデザイン、ソースコード、フロントエンド等の開発者のための技術を公開しています。

必要な機能の関数をコピペ利用したり勉強に活用できます。

プログラムの動作サンプル結果は画面上部に出力表示されています。

環境:最新のブラウザ GoogleChrome / Windows / Android / iPhone 等の端末で動作確認しています。

画像素材や音素材は半分自作でフリー素材配布サイトも利用しています。LINK参照。

動く便利なものが好きなだけで技術自体に興味はないのでコードは汚いです。

途中放置や実験状態、仕様変更、API廃止等で動かないページもあります。