Chcę wyświetlać pliki OpenOffice , .odt i .odp po stronie klienta za pomocą przeglądarki internetowej.
Te pliki są plikami spakowanymi. Używając Ajax, mogę pobrać te pliki z serwera, ale są to pliki spakowane. Muszę je rozpakować za pomocą JavaScript , próbowałem użyć inflate.js, http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt , ale bez powodzenia.
Jak mogę to zrobić?
javascript
zip
unzip
user69260
źródło
źródło
Odpowiedzi:
Napisałem unzipper w Javascript. To działa.
Opiera się na czytniku plików binarnych Andy GP Na i logice inflacji RFC1951 z notmasteryet . Dodałem klasę ZipFile.
działający przykład:
http://cheeso.members.winisp.net/Unzip-Example.htm (martwy link)
Źródło:
http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip (martwy link)
Uwaga : linki są martwe; Niedługo znajdę nowego gospodarza.
W źródle znajduje się strona demonstracyjna ZipFile.htm oraz 3 różne skrypty, jeden dla klasy zipfile, jeden dla klasy inflate i jeden dla klasy czytnika plików binarnych. Demo zależy również od interfejsu użytkownika jQuery i jQuery. Jeśli po prostu pobierzesz plik js-zip.zip, znajdziesz tam całe potrzebne źródło.
Oto jak wygląda kod aplikacji w JavaScript:
// In my demo, this gets attached to a click event. // it instantiates a ZipFile, and provides a callback that is // invoked when the zip is read. This can take a few seconds on a // large zip file, so it's asynchronous. var readFile = function(){ $("#status").html("<br/>"); var url= $("#urlToLoad").val(); var doneReading = function(zip){ extractEntries(zip); }; var zipFile = new ZipFile(url, doneReading); }; // this function extracts the entries from an instantiated zip function extractEntries(zip){ $('#report').accordion('destroy'); // clear $("#report").html(''); var extractCb = function(id) { // this callback is invoked with the entry name, and entry text // in my demo, the text is just injected into an accordion panel. return (function(entryName, entryText){ var content = entryText.replace(new RegExp( "\\n", "g" ), "<br/>"); $("#"+id).html(content); $("#status").append("extract cb, entry(" + entryName + ") id(" + id + ")<br/>"); $('#report').accordion('destroy'); $('#report').accordion({collapsible:true, active:false}); }); } // for each entry in the zip, extract it. for (var i=0; i<zip.entries.length; i++) { var entry = zip.entries[i]; var entryInfo = "<h4><a>" + entry.name + "</a></h4>\n<div>"; // contrive an id for the entry, make it unique var randomId = "id-"+ Math.floor((Math.random() * 1000000000)); entryInfo += "<span class='inputDiv'><h4>Content:</h4><span id='" + randomId + "'></span></span></div>\n"; // insert the info for one entry as the last child within the report div $("#report").append(entryInfo); // extract asynchronously entry.extract(extractCb(randomId)); } }
Demo działa w kilku krokach:
readFile
fn jest wyzwalany przez kliknięcie i tworzy instancję obiektu ZipFile, który odczytuje plik zip. Istnieje asynchroniczne wywołanie zwrotne po zakończeniu odczytu (zwykle dzieje się to w mniej niż sekundę dla zamków błyskawicznych o rozsądnych rozmiarach) - w tym demie wywołanie zwrotne jest przechowywane w zmiennej lokalnej doneReading, która po prostu wywołujeextractEntries
, która po prostu ślepo rozpakowuje całą zawartość podanego plik zip. W prawdziwej aplikacji prawdopodobnie wybrałbyś niektóre wpisy do wyodrębnienia (pozwoliłbyś użytkownikowi wybrać lub wybrać programowo jeden lub więcej wpisów itp.).W
extractEntries
fn iteracje nad wszystkimi wpisami, a rozmowyextract()
na temat każdego z nich, mijając zwrotnego. Dekompresja wpisu zajmuje trochę czasu, może 1 s lub więcej dla każdego wpisu w pliku zip, co oznacza, że asynchronia jest odpowiednia. Wyodrębnianie wywołania zwrotnego po prostu dodaje wyodrębnioną zawartość do akordeonu jQuery na stronie. Jeśli zawartość jest binarna, zostanie odpowiednio sformatowana (nie pokazana).Działa, ale myślę, że narzędzie jest nieco ograniczone.
Po pierwsze: jest bardzo powolny. Rozpakowanie 140k pliku AppNote.txt z PKWare zajmuje około 4 sekund. To samo rozpakowanie można wykonać w czasie krótszym niż .5s w programie .NET.EDYCJA : Javascript ZipFile rozpakowuje się znacznie szybciej niż teraz, w IE9 i Chrome. Jest nadal wolniejszy niż program skompilowany, ale jest wystarczająco szybki dla normalnego użytkowania przeglądarki.Po drugie: nie obsługuje przesyłania strumieniowego. Zasadniczo siorbi całą zawartość pliku zip do pamięci. W „prawdziwym” środowisku programistycznym można było wczytać tylko metadane pliku zip (powiedzmy 64 bajty na wpis), a następnie odczytać i rozpakować inne dane według potrzeb. O ile wiem, nie ma sposobu, aby zrobić takie IO w javascript, dlatego jedyną opcją jest wczytanie całego pliku zip do pamięci i zrobienie w nim swobodnego dostępu. Oznacza to, że duże pliki zip będą wymagały nieracjonalnego wykorzystania pamięci systemowej. Nie jest to duży problem w przypadku mniejszego pliku zip.
Ponadto: nie obsługuje pliku zip „ogólnego przypadku” - istnieje wiele opcji zip, których nie zawracałem sobie głowy zaimplementowaniem w rozpakowywaczu - takie jak szyfrowanie ZIP, szyfrowanie WinZip, zip64,
zakodowane nazwy plików w formacie UTF-8itd. na. ( EDYCJA - teraz obsługuje nazwy plików zakodowane w UTF-8). Klasa ZipFile obsługuje jednak podstawy. Niektóre z tych rzeczy nie byłyby trudne do wdrożenia. Mam klasę szyfrowania AES w JavaScript; które można by zintegrować w celu obsługi szyfrowania. Obsługa Zip64 byłaby prawdopodobnie bezużyteczna dla większości użytkowników Javascript, ponieważ jest przeznaczona do obsługi plików zip> 4 GB - nie trzeba ich rozpakowywać w przeglądarce.Nie testowałem też przypadku rozpakowywania zawartości binarnej. W tej chwili rozpakowuje tekst. Jeśli masz spakowany plik binarny, musisz edytować klasę ZipFile, aby poprawnie go obsłużyć. Nie wymyśliłem, jak to zrobić czysto.Teraz obsługuje również pliki binarne.EDYCJA - zaktualizowałem bibliotekę rozpakowywania JS i wersję demonstracyjną. Teraz oprócz tekstu obsługuje pliki binarne. Uczyniłem go bardziej odpornym i bardziej ogólnym - możesz teraz określić kodowanie, które ma być używane podczas czytania plików tekstowych. Rozbudowano również demo - pokazuje m.in. rozpakowywanie pliku XLSX w przeglądarce.
Tak więc, chociaż myślę, że ma ograniczoną użyteczność i zainteresowanie, działa. Myślę, że zadziałaby w Node.js.
źródło
Używam zip.js i wydaje się, że jest całkiem przydatny. Warto zajrzeć!
Sprawdź na przykład demo Rozpakuj .
źródło
pako.inflate(binaryData, { to: 'string' })
Uważam, że jszip jest całkiem przydatny. Do tej pory używałem tylko do czytania, ale mają również możliwości tworzenia / edycji.
Kod mądry wygląda mniej więcej tak
var new_zip = new JSZip(); new_zip.load(file); new_zip.files["doc.xml"].asText() // this give you the text in the file
Jedną rzeczą, którą zauważyłem, jest to, że wydaje się, że plik musi być w formacie strumienia binarnego (czytaj za pomocą .readAsArrayBuffer z FileReader (), w przeciwnym razie otrzymywałem błędy informujące, że mogę mieć uszkodzony plik zip
Edycja: Uwaga z przewodnika aktualizacji 2.x do 3.0.0 :
Dzięki user2677034
źródło
Jeśli potrzebujesz obsługiwać również inne formaty lub po prostu potrzebujesz dobrej wydajności, możesz użyć tej biblioteki WebAssembly
Jest oparty na obietnicy, wykorzystuje WebWorkers do obsługi wątków, a API jest w rzeczywistości prostym modułem ES
źródło
Napisałem „Binary Tools for JavaScript”, projekt typu open source, który obejmuje możliwość rozpakowywania, rozpakowywania i rozpakowywania: https://github.com/codedread/bitjs
Używany w moim czytniku komiksów: https://github.com/codedread/kthoom (również open source).
HTH!
źródło
Przykład kodu jest podany na stronie autora . Możesz użyć babelfish do tłumaczenia tekstów (z japońskiego na angielski).
O ile rozumiem język japoński, ten kod nadmuchiwania ZIP ma na celu dekodowanie danych ZIP (strumieni), a nie archiwum ZIP.
źródło
W tym celu również napisałem klasę. http://blog.another-d-mention.ro/programming/read-load-files-from-zip-in-javascript/ Możesz załadować podstawowe zasoby, takie jak javascript / css / images, bezpośrednio z pliku zip, używając metod klas. Mam nadzieję, że to pomoże
źródło
Jeśli ktoś czyta obrazy lub inne pliki binarne z pliku zip hostowanego na serwerze zdalnym, możesz użyć następującego fragmentu kodu, aby pobrać i utworzyć obiekt zip za pomocą biblioteki jszip .
// this function just get the public url of zip file. let url = await getStorageUrl(path) console.log('public url is', url) //get the zip file to client axios.get(url, { responseType: 'arraybuffer' }).then((res) => { console.log('zip download status ', res.status) //load contents into jszip and create an object jszip.loadAsync(new Blob([res.data], { type: 'application/zip' })).then((zip) => { const zipObj = zip $.each(zip.files, function (index, zipEntry) { console.log('filename', zipEntry.name) }) })
Teraz używając zipObj możesz uzyskać dostęp do plików i utworzyć dla nich adres URL src.
var fname = 'myImage.jpg' zipObj.file(fname).async('blob').then((blob) => { var blobUrl = URL.createObjectURL(blob)
źródło