javascript 如何使用 zip.js 将多个文件添加到 zip 文件中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17510979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add multiple files to a zip with zip.js?
提问by Paul Fournel
I am using the javascript zip.jslibrary. I've seach all around I a cannot find an example where more than one file is added to the zip.
我正在使用 javascript zip.js库。我到处搜索,但找不到一个示例,其中向 zip 中添加了多个文件。
Here is my code, but it generates a "corrupted" 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;
}
});
Any idea to make it work? :)
有什么想法让它工作吗?:)
采纳答案by Scott
If you are looking for a good example of code that handles multiple files, see here. You can then view the source code.
如果您正在寻找处理多个文件的良好代码示例,请参见此处。然后您可以查看源代码。
This is the key source of the demo (modified just slightly):
这是演示的主要来源(稍作修改):
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);
}
};
})();
Usage:
Assumes a <a id="downloadLink">Download</a>
element exists to provide the download once ready.
用法:假设<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);
You can use the example source code to add in progress indicators. Hope this helps, the nice thing about this method is the zip model is easily reusable if you make it it's own JS file.
您可以使用示例源代码添加进度指示器。希望这会有所帮助,这种方法的好处是,如果将 zip 模型设为自己的 JS 文件,则它很容易重用。
Another thought: I presume you are using the getBase64Image
function from here, if so and you still experience corruption issues, perhaps try modifying the return to simply return dataURL;
and comment out the .replace(...
, as the Data64URIReader
may expect the prefix.
另一个想法:我假设您正在使用这里的getBase64Image
函数,如果是这样并且您仍然遇到损坏问题,也许尝试将返回修改为简单并注释掉,因为可能期望前缀。return dataURL;
.replace(...
Data64URIReader
回答by meetar
Here's a stripped-down version of that demothat only uses RAM storage. It assumes that zip.js, z-worker.js, and deflate.js from the zip.js install are in the same directory as the two files below, along with FileSaver.js.
这是该演示的精简版,仅使用 RAM 存储。它假设 zip.js 安装中的 zip.js、z-worker.js 和 deflate.js 与下面的两个文件以及FileSaver.js位于同一目录中。
Note:This is not production-ready code! It is a bare-bones demo that I made so I could figure out what was going on. If you generate and save the zip programmatically, you may need to implement a nextFile() iterator like the one above to prevent a race condition from populating the zip with empty files. (See https://stackoverflow.com/a/29738675/738675for an example of this.)
注意:这不是生产就绪代码!这是我制作的一个简单的演示,所以我可以弄清楚发生了什么。如果您以编程方式生成和保存 zip,您可能需要实现一个 nextFile() 迭代器,如上面的迭代器,以防止竞争条件用空文件填充 zip。(有关此示例,请参见https://stackoverflow.com/a/29738675/738675。)
demo.html:
演示.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>
demo.js:
演示.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;
});
}