GWTでサーバを使用せずにZipファイルをクライアントへ保存

外部JavaScript(JS)ライブラリとJSNIを使って実装する。FileSaverとJSZipを利用する。

Shift_JISは扱えません!!

  • 使用するjsライブラリ
  • war/js に使用するJSファイルを入れておく
  • htmlファイルでJSファイルをリンクしておくのも忘れずに
  • javaファイルでは、JSNIで外部JSライブラリにアクセス($wndを忘れずに)。JSNI内部ではjava.util.Mapが使えないようなので、JSONObjectを使用する。
  • JSONObjectを使うために、.gwt.xmlファイルにinheritsを追加する必要がある。

参考
gwt - Java Hashmap and Mutlidimensional array type sig in JSNI? - Stack Overflow
eligrey/FileSaver.js · GitHub
JSZip



 *.html

(前略)
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link type="text/css" rel="stylesheet" href="/css/global.css" />
    <script language="javascript" src="js/jszip.js"></script>
    <script language="javascript" src="js/FileSaver.js"></script>
</head>

(後略)

 *.java

        public void onModuleLoad() {

            Button save = new Button("保存");
            save.addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    //JSONObject がMap代わりに使える
                    JSONObject obj = new JSONObject();
                    for (int i = 0; i < 3; i++) {
                        obj.put("k"+i, new JSONString("v"+i));
                    }
                    JavaScriptObject jsObj = obj.getJavaScriptObject();
                    saveAsZip(jsObj);
                }
            });

        RootPanel.get().add(save);
    }

    /**
     * @param fileMap
     *            key:ファイル名 value:ファイル内容
     * @return
     */
    private native boolean saveAsZip(JavaScriptObject fileMap) /*-{
		var zip = new $wnd.JSZip();

		for (key in fileMap) {
			zip.file(key + ".txt", fileMap[key]);
		}
		var blob = zip.generate({
			type : "blob"
		});
		$wnd.saveAs(blob, "text.zip");
		return true;
    }-*/;

*.gwt.xml

<module>
	<inherits name="com.google.gwt.user.User" />
	<inherits name="com.google.gwt.user.theme.standard.Standard" />
	<inherits name="com.google.gwt.json.JSON" />

	<entry-point class="(エントリーポイントクラス)" />
	<source path="client" />
</module>