gdata API を使って GAE から Apps のスプレッドシートを参照してみた。

Apps のスプレッドシートがそもそも何かって言うとエクセルの Webアプリ版だと思えば良い。 もちろん機能的にはエクセルに及ばないが複数の人が同時に編集出来るなど WEbアプリならではの機能も有る。

エクセルのテンプレートで社内文書を提出させる会社は多いと思うが Appsのスプレッドシート -> GAE の流れとすればクラウド上で完結することができる。 FORMと違って提出文書はそのまま残るのでサーバ側は処理結果だけ持っていれば 良く実装量も減るはず。

と言うわけでいつもの用に WSJS でお試し。

まずは gdata API のライブラリを落してくる。

  • http://code.google.com/intl/ja/apis/apps/libraries_and_samples.html

    で、jar を自前クラスローダから読み込まそうとしただがエラーになった。

    java.lang.NullPointerException
    com.google.appengine.runtime.Request.process-8c1503d338b4a612(Request.java)
    java.io.ByteArrayInputStream.(ByteArrayInputStream.java:106)
    org.kotemaru.wsjs.RepositoryClassLoader.getJarStream(RepositoryClassLoader.java:90)
    org.kotemaru.wsjs.RepositoryClassLoader.findClassForJarFile(RepositoryClassLoader.java:62)
    org.kotemaru.wsjs.RepositoryClassLoader.findClass(RepositoryClassLoader.java:33)
    java.lang.ClassLoader.loadClass(ClassLoader.java:114)
              :
    

    com.google.** のパッケージはシステムのクラスローダしか受け付け無いらしい。

    あきらめて WEB-INF/lib の下に以下の jar をコピーして Upload しなおし。

     gdata-core-1.0.jar
     gdata-client-meta-1.0.jar
     gdata-client-1.0.jar
     gdata-spreadsheet-meta-3.0.jar
     gdata-spreadsheet-3.0.jar
     google-collect-1.0-rc1.jar
     jsr305.jar
    

    スプレッドシートにアクセスする為には最低限、以下の情報が必要。

    • スプレッドシートの名前
    • アクセス権の有るユーザの名前
    • アクセス権の有るユーザのパスワード
    ユーザ/パスワードは OAuth でも行けるかもしれない。

    スプレッドシート名/ユーザ/パスワード を受け取って シートの内容をCSVで吐き出すサンプルを書いてみる。

    /* 自前クラスローダはダメっぽいのでコメントアウト __ENV__.addClassPath("gdata-core-1.0.jar"); __ENV__.addClassPath("gdata-client-meta-1.0.jar"); __ENV__.addClassPath("gdata-client-1.0.jar"); __ENV__.addClassPath("gdata-spreadsheet-meta-3.0.jar"); __ENV__.addClassPath("gdata-spreadsheet-3.0.jar"); __ENV__.addClassPath("google-collect-1.0-rc1.jar "); __ENV__.addClassPath("jsr305.jar"); */ // imports. var FeedURLFactory = Packages.com.google.gdata.client.spreadsheet.FeedURLFactory; var ListQuery = Packages.com.google.gdata.client.spreadsheet.ListQuery; var SpreadsheetQuery = Packages.com.google.gdata.client.spreadsheet.SpreadsheetQuery; var SpreadsheetService = Packages.com.google.gdata.client.spreadsheet.SpreadsheetService; var CustomElementCollection = Packages.com.google.gdata.data.spreadsheet.CustomElementCollection; var ListEntry = Packages.com.google.gdata.data.spreadsheet.ListEntry; var ListFeed = Packages.com.google.gdata.data.spreadsheet.ListFeed; var SpreadsheetEntry = Packages.com.google.gdata.data.spreadsheet.SpreadsheetEntry; var SpreadsheetFeed = Packages.com.google.gdata.data.spreadsheet.SpreadsheetFeed; var WorksheetEntry = Packages.com.google.gdata.data.spreadsheet.WorksheetEntry; function doGet(req, res) { var html = <html> <head> </head> <body> <form name="form1" method="POST"> Spread sheet:<input type="text" name="spreadsheet"/><br/> <!--Word sheed:<input type="text" name="worksheet"/><br/>--> User:<input type="text" name="username"/><br/> Pass:<input type="password" name="password"/><br/> <input type="submit" value="送信"/> </form> <p/> </body> </html>; res.setContentType("text/html; charset=utf-8"); res.writer.write(html); } function doPost(req, res) { var spreadsheet = req.getParameter("spreadsheet"); //var worksheet = req.getParameter("worksheet"); var username = req.getParameter("username"); var password = req.getParameter("password"); // サービス開始 var service = new SpreadsheetService("Sample"); service.setUserCredentials(username, password); // spread-sheet 取得 var urlFactory = FeedURLFactory.getDefault(); var spreadsheetQuery = new SpreadsheetQuery(urlFactory.getSpreadsheetsFeedUrl()); spreadsheetQuery.setTitleQuery(spreadsheet); // 検索である事に注意。複数取れちゃうよ。 var spreadsheetFeed = service.query(spreadsheetQuery, SpreadsheetFeed); var spreadsheetEntry = spreadsheetFeed.getEntries().get(0); // work-sheet 取得。全部取るなら getWorksheets()。 worksheetEntry = spreadsheetEntry.getDefaultWorksheet(); // work-sheetの中身取得。 var listQuery = new ListQuery(worksheetEntry.getListFeedUrl()); var listFeed = service.query(listQuery, ListFeed); var list = listFeed.getEntries(); // 項目名一覧取得。 var tags = listFeed.getEntries().get(0).getCustomElements().getTags(); // データ出力。 res.setContentType("text/plain; charset=utf-8"); var writer = res.writer; var ite = tags.iterator(); while(ite.hasNext()){ var name = ite.next(); writer.write(name+","); } writer.write("\n"); for (var i=0; i<list.size(); i++) { var elements = list.get(i).getCustomElements(); var ite = tags.iterator(); while(ite.hasNext()){ var name = ite.next(); var val = elements.getValue(name); writer.write(val+","); } writer.write("\n"); } }

    まず取得対象のスプレッドシートを "test" と言う名前で作成。

    サンプルページにアクセスして スプレッドシート名/ユーザ/パスワード を入力。

    スプレッドシートの内容が CSV で取れている。

    スプレッドシートへの出力も可能なようなので結果ページをメールで送信して ワークフローとかも作れちゃいそうだね。

    参考ページ: http://www.atmarkit.co.jp/fwcr/rensai2/spreadsheetsapi01/02.html