84

Webブラウザを使用してクライアント側でOpenOfficeファイル.odtおよび.odpを表示したい。

これらのファイルはzipファイルです。Ajaxを使用して、これらのファイルをサーバーから取得できますが、これらはzipファイルです。JavaScriptを使用して解凍する必要があります。inflate.js、http: //www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txtを使用してみましたが、成功しませんでした。

これどうやってするの?

4

8 に答える 8

60

私はJavascriptで解凍を書きました。できます。

これは、Andy GP Naのバイナリファイルリーダー、notmasteryetのRFC1951インフレートロジックに依存しています。ZipFileクラスを追加しました。

実例:
http ://cheeso.members.winisp.net/Unzip-Example.htm (リンク切れ)

ソース:
http ://cheeso.members.winisp.net/srcview.aspx?dir = js-unzip (デッドリンク)

注意:リンクは無効です。すぐに新しいホストを見つけます。

ソースには、ZipFile.htmデモページと、3つの異なるスクリプトが含まれています。1つはzipfileクラス用、1つはinflateクラス用、もう1つはバイナリファイルリーダークラス用です。デモはjQueryとjQueryUIにも依存しています。js-zip.zipファイルをダウンロードするだけで、必要なソースがすべてそこにあります。


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));
    }
}

デモはいくつかのステップで機能しreadFileます。fnはクリックによってトリガーされ、zipファイルを読み取るZipFileオブジェクトをインスタンス化します。読み取りが完了したときの非同期コールバックがあります(通常、適度なサイズのzipの場合は1秒未満で発生します)-このデモでは、コールバックはdoneReadingローカル変数で保持されますextractEntries。 ZIPファイル。実際のアプリでは、抽出するエントリの一部を選択する可能性があります(ユーザーが選択できるようにするか、プログラムで1つ以上のエントリを選択できるようにします)。

fnはextractEntriesすべてのエントリを繰り返し処理し、extract()各エントリを呼び出してコールバックを渡します。エントリの解凍には時間がかかります。zipファイルのエントリごとに1秒以上かかる場合があります。これは、非同期が適切であることを意味します。抽出コールバックは、抽出されたコンテンツをページ上のjQueryアコーディオンに追加するだけです。コンテンツがバイナリの場合、そのようにフォーマットされます(表示されていません)。


動作しますが、効用はやや限られていると思います。

一つには、それは非常に遅いです。PKWareから140kAppNote.txtファイルを解凍するのに約4秒かかります。同じ解凍は、.NETプログラムで.5秒未満で実行できます。 編集:Javascript ZipFileは、IE9とChromeで、これよりもかなり速く解凍されます。コンパイルされたプログラムよりもまだ低速ですが、通常のブラウザの使用には十分高速です。

別の場合:ストリーミングは行いません。基本的に、zipファイルの内容全体をメモリに丸呑みします。「実際の」プログラミング環境では、zipファイルのメタデータ(たとえば、エントリあたり64バイト)のみを読み込んでから、必要に応じて他のデータを読み込んで解凍することができます。私の知る限り、JavaScriptでそのようなIOを実行する方法はありません。したがって、唯一のオプションは、zip全体をメモリに読み込み、ランダムアクセスを実行することです。これは、大きなzipファイルのシステムメモリに不当な要求を課すことを意味します。小さいzipファイルではそれほど問題にはなりません。

また、「一般的なケース」のzipファイルは処理されません。ZIP暗号化、WinZip暗号化、zip64、UTF-8でエンコードされたファイル名など、解凍ツールに実装する必要がなかったzipオプションがたくさんあります。の上。(編集-UTF-8でエンコードされたファイル名を処理するようになりました)。ただし、ZipFileクラスは基本を処理します。これらのいくつかは、実装するのが難しくないでしょう。JavascriptにAES暗号化クラスがあります暗号化をサポートするために統合することができます。Zip64のサポートは、4 GBを超えるzipファイルをサポートすることを目的としているため、Javascriptのほとんどのユーザーにとっておそらく役に立たないでしょう。ブラウザーでそれらを抽出する必要はありません。

また、バイナリコンテンツを解凍するケースもテストしていません。現在、テキストを解凍します。zip形式のバイナリファイルがある場合は、ZipFileクラスを編集して適切に処理する必要があります。私はそれをきれいに行う方法を理解していませんでした。 現在、バイナリファイルも実行しています。


編集-JS解凍ライブラリとデモを更新しました。テキストに加えて、バイナリファイルを実行するようになりました。より弾力性があり、より一般的になりました。テキストファイルを読み取るときに使用するエンコーディングを指定できるようになりました。また、デモが拡張されています。特に、ブラウザでXLSXファイルを解凍する方法が示されています。

ですから、有用性と関心は限られていると思いますが、機能します。Node.jsで動作すると思います。

于 2010-01-19T21:38:28.753 に答える
27

私はzip.jsを使用していますが、非常に便利なようです。一見の価値があります!

たとえば、解凍デモを確認してください。

于 2012-06-17T00:58:46.330 に答える
19

jszipは非常に便利だと思いました。私はこれまで読書のためだけに使用しましたが、作成/編集機能もあります。

コード的には次のようになります

var new_zip = new JSZip();
new_zip.load(file);
new_zip.files["doc.xml"].asText() // this give you the text in the file

私が気づいたことの1つは、ファイルがバイナリストリーム形式である必要があるように見えることです(FileReader()の.readAsArrayBufferを使用して読み取ります。そうでない場合、zipファイルが破損している可能性があるというエラーが発生していました。

編集:2.xから3.0.0へのアップグレードガイドからの注意

load()メソッドとデータを含むコンストラクター(新しいJSZip(data))は、loadAsync()に置き換えられました。

ありがとうuser2677034

于 2014-12-09T17:18:13.717 に答える
7

他のフォーマットもサポートする必要がある場合、または単に優れたパフォーマンスが必要な場合は、このWebAssemblyライブラリを使用できます

それは約束されたベースであり、スレッド化にWebWorkersを使用し、APIは実際には単純なESモジュールです

于 2018-10-30T20:36:49.193 に答える
3

私は「JavaScript用のバイナリツール」を作成しました。これは、解凍、解凍、解凍する機能を含むオープンソースプロジェクトです:https ://github.com/codedread/bitjs

私の漫画本の読者で使用されています:https ://github.com/codedread/kthoom (これもオープンソースです)。

HTH!

于 2014-07-11T22:05:46.033 に答える
2

コード例は、作成者サイトのに記載されています。バベルフィッシュを使ってテキストを翻訳することができます(日本語から英語)。

私が日本語を理解している限り、このzip膨張コードは、ZIPアーカイブではなくZIPデータ(ストリーム)をデコードすることを目的としています。

于 2010-01-19T18:20:15.950 に答える
2

私もそのためのクラスを書きました。 http://blog.another-d-mention.ro/programming/read-load-files-from-zip-in-javascript/ クラスメソッドを使用して、javascript / css/imagesなどの基本的なアセットをzipから直接読み込むことができます。それが役に立てば幸い

于 2011-08-07T16:33:52.080 に答える
2

リモートサーバーでホストされているzipファイルから画像やその他のバイナリファイルを読み取っている場合は、次のスニペットを使用して、jszipライブラリを使用してzipオブジェクトをダウンロードおよび作成できます。

// 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)
    })
  })

これで、zipObjを使用して、ファイルにアクセスし、そのsrcurlを作成できます。

var fname = 'myImage.jpg'
zipObj.file(fname).async('blob').then((blob) => {
var blobUrl = URL.createObjectURL(blob)
于 2020-11-18T09:52:18.733 に答える