我正在使用javascript zip.js库。我一直在搜索,我找不到一个例子,其中拉链中添加了多个文件。
这是我的代码,但它会生成“损坏的”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;
}
});
有什么想法让它发挥作用? :)
答案 0 :(得分:6)
如果您正在寻找处理多个文件的代码的好例子,see here。然后,您可以view the source code。
这是演示的主要来源(略微修改):
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);
您可以使用示例源代码添加进度指示器。 希望这会有所帮助,这个方法的优点是如果你把它变成自己的JS文件,那么zip模型很容易重复使用。
另一个想法:我假设你使用getBase64Image
函数from here,如果是这样,你仍然遇到腐败问题,也许尝试将返回修改为return dataURL;
并注释掉{ {1}},因为.replace(...
可能需要前缀。
答案 1 :(得分:2)
这是that demo的精简版,只使用RAM存储空间。它假设zip.js安装的zip.js,z-worker.js和deflate.js与下面的两个文件位于同一目录中,同时还有FileSaver.js。
注意:这不是生产就绪代码!这是我做的一个简单的演示,所以我可以弄清楚发生了什么。如果以编程方式生成并保存zip,则可能需要实现类似上面的nextFile()迭代器,以防止竞争条件使用空文件填充zip。 (有关此示例,请参阅https://stackoverflow.com/a/29738675/738675。)
<强> demo.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:强>
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;
});
}