[英]How to add multiple files to a zip with zip.js?
我正在使用 javascript zip.js庫。 我到處搜索,但找不到一個示例,其中向 zip 中添加了多個文件。
這是我的代碼,但它會生成一個“損壞的”zip。
var len = results.rows.length, i;
var k=1;
zip.createWriter(new zip.BlobWriter(), function(writer) {
for (i = 0; i < len; i++){
// get the image url from a sqlite request
url = results.rows.item(i).url;
var img = new Image();
img.onload = function() {
var a = document.createElement('a');
a.href = this.src;
var filename= a.pathname.split('/').pop(); // filename.php
timest = new Date().getTime();
// use a TextReader to read the String to add
writer.add(timest+".jpg", new zip.Data64URIReader(getBase64Image(img)), function() {
// onsuccess callback
k++;
if(k==len){
setTimeout(function(){
writer.close(function(blob) {
// blob contains the zip file as a Blob object
$('#test').attr("href", window.URL.createObjectURL(blob));
$('#test').attr("download", "woeii.zip");
});
},1000);
}
}, function(currentIndex, totalIndex) {
// onprogress callback
});
};
img.src = url;
}
});
有什么想法讓它工作嗎? :)
如果您正在尋找處理多個文件的良好代碼示例,請參見此處。 然后您可以查看源代碼。
這是演示的主要來源(稍作修改):
var obj = this;
var model = (function() {
var zipFileEntry, zipWriter, writer, creationMethod, URL = obj.webkitURL || obj.mozURL || obj.URL;
return {
setCreationMethod : function(method) {
creationMethod = method;
},
addFiles : function addFiles(files, oninit, onadd, onprogress, onend) {
var addIndex = 0;
function nextFile() {
var file = files[addIndex];
onadd(file);
// Modified here to use the Data64URIReader instead of BlobReader
zipWriter.add(file.name, new zip.Data64URIReader(file.data), function() {
addIndex++;
if (addIndex < files.length)
nextFile();
else
onend();
}, onprogress);
}
function createZipWriter() {
zip.createWriter(writer, function(writer) {
zipWriter = writer;
oninit();
nextFile();
}, onerror);
}
if (zipWriter)
nextFile();
else if (creationMethod == "Blob") {
writer = new zip.BlobWriter();
createZipWriter();
} else {
createTempFile(function(fileEntry) {
zipFileEntry = fileEntry;
writer = new zip.FileWriter(zipFileEntry);
createZipWriter();
});
}
},
getBlobURL : function(callback) {
zipWriter.close(function(blob) {
var blobURL = creationMethod == "Blob" ? URL.createObjectURL(blob) : zipFileEntry.toURL();
callback(blobURL);
zipWriter = null;
});
},
getBlob : function(callback) {
zipWriter.close(callback);
}
};
})();
用法:假設存在<a id="downloadLink">Download</a>
元素以在准備好后提供下載。
// Prepare your images
var files = [];
for (i = 0; i < len; i++) {
// Get the image URL from a SQLite request
var url = results.rows.item(i).url;
(function(url){
var img = new Image();
img.onload = function() {
// Add to file array [{name, data}]
var a = document.createElement('a');
a.href = this.src;
var filename= a.pathname.split('/').pop();
console.log("Loaded file " + filename);
files.push({name: filename, data: getBase64Image(img) });
}
img.src = url;
})(url);
}
// Wait for the image to load
var check = setInterval(function(){
if(files.length==images.length) {
clearInterval(check);
// Set the mode
model.setCreationMethod("Blob");
// Add the files to the zip
model.addFiles(files,
function() {
// Initialise Method
console.log("Initialise");
}, function(file) {
// OnAdd
console.log("Added file");
}, function(current, total) {
// OnProgress
console.log("%s %s", current, total);
}, function() {
// OnEnd
// The zip is ready prepare download link
// <a id="downloadLink" href="blob:url">Download Zip</a>
model.getBlobURL(function(url) {
document.getElementById("downloadLink").href = url;
document.getElementById("downloadLink").style.display = "block";
document.getElementById("downloadLink").download = "filename.zip";
});
});
}
}, 500);
您可以使用示例源代碼添加進度指示器。 希望這會有所幫助,這種方法的好處是,如果將 zip 模型設為自己的 JS 文件,則它很容易重用。
另一個想法:我假設您正在使用這里的getBase64Image
函數,如果是這樣並且您仍然遇到損壞問題,也許嘗試修改返回以簡單地return dataURL;
並注釋掉.replace(...
,因為Data64URIReader
可能需要前綴。
這是該演示的精簡版,僅使用 RAM 存儲。 它假定 zip.js 安裝中的 zip.js、z-worker.js 和 deflate.js 與下面的兩個文件以及FileSaver.js位於同一目錄中。
注意:這不是生產就緒代碼! 這是我制作的一個簡單的演示,所以我可以弄清楚發生了什么。 如果您以編程方式生成並保存 zip,您可能需要實現一個 nextFile() 迭代器,如上面的迭代器,以防止競爭條件用空文件填充 zip。 (有關此示例,請參見https://stackoverflow.com/a/29738675/738675 。)
演示.html:
<li>
add files into the zip
<input type="file" multiple id="file-input" onchange="addFiles(this.files)">
</li>
<li>
download the zip file
<a href="#" onclick="saveZip()">Download</a>
</li>
<script type="text/javascript" src="zip.js"></script>
<script type="text/javascript" src="demo.js"></script>
<script type="text/javascript" src="FileSaver.js"></script>
演示.js:
var zipWriter;
function addFiles(files) {
writer = new zip.BlobWriter();
zip.createWriter(writer, function(writer) {
zipWriter = writer;
for (var f = 0; f < files.length; f++) {
zipWriter.add(files[f].name,
new zip.BlobReader(files[f]), function() {});
}
});
}
function saveZip() {
zipWriter.close(function(blob) {
saveAs(blob, "Example.zip"); // uses FileSaver.js
document.getElementById("file-input").value = null; // reset input file list
zipWriter = null;
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.