Für das folgende Beispiel brauchen wir Dateien, die anschließend in eine ZIP gepackt werden sollen.
Hierfür nutzen wir ein input vom type=file womit sich clientseitig Dateien auswählen lassen.
<input type="file" multiple />
Sobald der „ok“ Button des FileDialog betätigt wird, sollen die Dateien eingelesen werden.
Hierfür fügen wir einen EventListener „change“ dem obigen input im „window.onload“ hinzu.
window.onload = () => {
document.querySelector("input").addEventListener("change", (e) => {
});
}
Für die weitere Verarbeitung bietet sich das Erstellen einer Hilfsklasse an, die einen Namen und den Blob einer Datei erwartet.
class Doc {
constructor(name, blob) {
this.name = name;
this.blob = blob;
}
}
Das input liefert uns über das ChangeEvent „(e)“ eine „FileList“, welche nicht so schön zu iterieren ist wie ein Array.
Abhilfe liefert hier die ES6 Schreibweise, welche die Dateien in ein Array kopiert.
if (e.target.files) {
let files = [...e.target.files];
let documents = files.map(file => new Doc(file.name, file));
}
Das Einlesen der Dateien, das anschließende Hinzufügen zu einer ZIP Datei und das Herunterladen sollen in einer Hilfsklasse ausgelagert werden.
Hierfür erstellen wir eine „Service“ Klasse, mit den Methoden „saveAsZip“ und „readFile“.
class ZipService {
saveAsZip(){
}
readFile(){
}
}
Als erstes implementieren wird die Funktion „readFile“, welche den Callback eines FileReader als Promise zurückreichen soll.
Dies ermöglicht uns die Funktion mit „await“ aufzurufen und so den Code sauberer zu strukturieren.
readFile(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = (e) => resolve(e.target.result);
reader.onerror = (e) => reject(e);
reader.readAsArrayBuffer(file);
});
}
Die Funktion „saveAsZip“ erhält als Parameter die „Dokumente“, iteriert diese, liest sie über „readFile“ ein und fügt sie mittels JSZip zur zip Datei hinzu.
Das anschließende „saveAs“ von FileSaver löst den Download der zip Datei aus.
async saveAsZip(documents) {
let zipFile = new JSZip();
for (let document of documents) {
try {
let docAsArrayBuffer = await this.readFile(document.blob);
zipFile.file(document.name, docAsArrayBuffer);
}
catch(err){ console.error(err) }
}
let blob = zipFile.generate({ type: "blob" });
saveAs(blob, "download.zip");
}
Nun erstellen wir eine neue Instanz von ZipService und geben die zuvor aufbereiteten Dokumente als Parameter in die Funktion.
let zipService = new ZipService();
zipService.saveAsZip(documents);
Ersteller der Webseite MuchaDev. Selbstständiger IT Constultant für Frontend Technologien.