PR

App Engineから読み取ったデータの書き込みと、スプレッドシートのUIで表示する処理

2013年11月28日(木)
清野 克行

今回は、App Engine側で読み取ったスプレッドデータのDatastore書き込み、およびそれぞれのデータ読み取り表示をスプレッドシート風のUI表示で行う処理内容について見ていきます。前回からJavaのプログラミングに入っていますが、今回もJavaによるスプレッドデータの処理が中心となります。

図1:Spread Sheet 年月別店舗売上(グリッド表示)(クリックで拡大)

図1のように、スプレッドデータをApp Engineから読み込んで、また簡易形式で画面表示する部分は前回の連載で見てきましたが、今回は読み取ったスプレッドデータをDatastoreに書き込んでみます。またDrive上およびDatastoreに書き込まれたスプレッドデータをグリッド表示するサンプルを紹介します。

スプレッドデータの表示形式では前回は簡易表示でしたが、今回はスプレッドシートの表示を、ActiveWidgetsを使用したサンプルとParamQuery gridを使用したサンプルの2種類紹介します。

1. Drive上のスプレッドデータをApp Engineから読み込みDatastoreに書き込む

最初はスプレッドデータのDatastore書き込みです。前回はスプレッドデータをApp Engineから読み込む処理について解説しましたが、今回は更にそのデータをDatastoreに書き込む処理について見ていきます。

ここで、スプレッドデータのDatastore書き込みでは、App EngineのLow-Level APIを使用しますが、Low-Level APIについてはThinkITにも下記の連載で解説していますので参考にしてください。

Think IT連載『Google App EngineのLow-Level APIを極める』

1.1 サーブレットのコード記述

リスト1 サーブレット(SpreadServlet.java)

package com.google.gdata;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.*;
@SuppressWarnings("serial")
public class SpreadServlet extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.setContentType("text/plain");
      resp.setContentType("text/html; charset=utf-8");
      PrintWriter out = resp.getWriter();
      String mode = req.getParameter("mode"); 
      String sheet = req.getParameter("sheet");
      SpreadBean ss = new SpreadBean(); 
      ////////////////////////////////////////////////////////////////////
      //  For Sales data
      if (mode.equals("getdsallshopym")) {
        String rv = ss.getDsAllShopYm(sheet);		//(1)
        out.println(rv);
      } else if (…) {
        :
      }
  }
  
  public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.setContentType("text/plain");
    resp.setContentType("text/html; charset=utf-8");
    PrintWriter out = resp.getWriter();
    String mode = req.getParameter("mode"); 
    String sheet = req.getParameter("sheet");
    SpreadBean ss = new SpreadBean(); 
    ////////////////////////////////////////////////////////////////////
    //  For Sales data
    if (mode.equals("addspreadallshoptodsym")) {
      String rv = ss.addSpreadAllShopToDsYm(sheet);		//(2)
      out.println(rv);
    } else if (…) {
      :
    }
  }
}

サーブレットの処理は連載前回のリスト2への追加で行われており、(1)のgetDsAllShopYmメソッドではDatastoreに書き込まれたスプレッドデータの読み取り、(2)のaddSpreadAllShopToDsYmメソッドではDriveから読み込んだスプレッドデータのDatastore書き込み処理を行っています。

1.2 ビーンズコード記述

リスト2 addSpreadAllShopToDsYmメソッド(SpreadBean.java)

public String addSpreadAllShopToDsYm(String sheet)  { 
  // このアプリケーションの名称。任意の名前を設定
  String appliName = "cyberspace-SpreadsheetSearch-1";
  String username = "xxxxxxxxxxxxxxxxxxxxxxxxx";
  String password = "xxxxxxxxxxxxxxx";
  try {
    /////////////////////////////////////////////////////////
    //  [I] Driveにあるスプレッドデータを読み取る
    //  認証処理
    SpreadsheetService spreadsheetservice = new SpreadsheetService(appliName);
    spreadsheetservice.setUserCredentials(username, password);
    // 検索対象のスプレッドシートを特定
    FeedURLFactory feedurlfactory = FeedURLFactory.getDefault();
    SpreadsheetQuery spreadsheetquery = 
    new SpreadsheetQuery(feedurlfactory.getSpreadsheetsFeedUrl());
    spreadsheetquery.setTitleQuery(sheet); // 検索対象のスプレッドシート名を指定している
    SpreadsheetFeed spreadFeed =
      spreadsheetservice.query(spreadsheetquery, SpreadsheetFeed.class);
    SpreadsheetEntry spreadsheetentry = spreadFeed.getEntries().get(0);
    // 検索対象のワークシートを特定
    WorksheetEntry worksheetentry = spreadsheetentry.getDefaultWorksheet();
    //  クエリでワークシート内を検索
    ListQuery listquery = new ListQuery(worksheetentry.getListFeedUrl()); 
    ListFeed listfeed = spreadsheetservice.query(listquery, ListFeed.class); 
    /////////////////////////////////////////////////////////
    //     [II] 読み取ったスプレッドデータをDatastoreに書き込む
    DatastoreService ds = DatastoreServiceFactory.getDatastoreService();     		//(1)
    int i = 0;
    for (ListEntry listentry : listfeed.getEntries()) { 
      CustomElementCollection customelementcollection = listentry.getCustomElements();
                                                   	//(2)
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
      String moddate = df.format(new Date()); 
      Entity sales = null; 
      if (!customelementcollection.getValue("店舗名").equals("売上合計")) {   	//(3)
        Key saleskey = KeyFactory.createKey								//(4)
        ("salesym", sheet + customelementcollection.getValue("店舗名")); 
        sales = new Entity(saleskey);									  	//(5)
        sales.setProperty("seq", i++); 
      } else {
        Key saleskey = KeyFactory.createKey
        ("salesymtotal", sheet + customelementcollection.getValue("店舗名"));	 //(6)
        sales = new Entity(saleskey);										//(7)
      }
      sales.setProperty("shop", customelementcollection.getValue("店舗名"));		//(8)
      sales.setProperty("yyyymm", sheet);
      sales.setProperty("food", customelementcollection.getValue("食品"));
      sales.setProperty("electric", customelementcollection.getValue("家電"));
      sales.setProperty("bedding", customelementcollection.getValue("寝具")); 
      sales.setProperty("other", customelementcollection.getValue("その他"));
      sales.setProperty("moddate", moddate); 
      ds.put(sales);       													//(9)
    }
    return "スプレッドデータのDatastore登録成功"; 
  } catch (AuthenticationException e) {
    e.printStackTrace();
    return "スプレッドデータのDatastore登録不成功 :" + e;
  } catch (IOException e) {
    e.printStackTrace();
    return "スプレッドデータのDatastore登録不成功 :" + e;
  } catch (ServiceException e) {
    e.printStackTrace();
    return "スプレッドデータのDatastore登録不成功 :" + e;
  }
}

[I] Driveにあるスプレッドデータを読み取る

Drive上のスプレッドデータ読み取りは、前回記事のリスト3と同じですので省略します。

[II] 読み取ったスプレッドデータをDatastoreに書き込む

(1)DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
App EngineのDatastoreにアクセスする場合は、最初にDatastoreServiceのインスタンス(ここではds)を生成します。

(2)次に、読み込んだスプレッドデータを1行ずつ読み取っての繰り返し処理に入ります。

(3)if~else文
・読み取ったデータが売上合計でない場合はif文内の(4)でキーを作成した後、kind名が「salesym」のエンティティをDatastore書き込み用に生成します(5)。
・読み取ったデータが売上合計の場合はelse以下で処理しており、(6)でキーを作成した後、(7)で「salesymtotal」のエンティティを生成しています。
その後は(8)以下で書き込むエンティティ(sales)にプロパティ項目をセットし、(9)のputメソッドで書き込み処理を行います。

2.Datastoreに書き込まれたスプレッドデータをApp Engineから読み取る

リスト3 getDsAllShopYmメソッド (SpreadBean.java)

public String getDsAllShopYm(String yyyymm) throws IOException, ServiceException { 
  try {
    DatastoreService ds = DatastoreServiceFactory.getDatastoreService();				//(1)
    Filter ymFilter = new FilterPredicate("yyyymm", FilterOperator.EQUAL, yyyymm);	//(2)
    Query q = new Query("salesym").setFilter(ymFilter).addSort("seq", SortDirection.ASCENDING);
                                                                                      //(3)
    PreparedQuery pq = ds.prepare(q);												    //(4) 
    String rv = "[";																    //(7)
    for (Entity res : pq.asIterable()) {												//(5)
      String shop = (String) res.getProperty("shop");								    //(6)
      String food = (String) res.getProperty("food");
      String electric = (String) res.getProperty("electric");
      String bedding = (String) res.getProperty("bedding");
      String other = (String) res.getProperty("other");
      rv 	+= "[\"" + shop + "\"," 
          + "\"" + food + "\"," 
          + "\"" + electric + "\"," 
          + "\"" + bedding + "\"," 
          + "\"" + other + "\"],";  					  //(7)
    } 
    rv = rv.substring(0, rv.length() - 1) + "]";										//(7)
    return rv;																	    //(8)
  } catch (Exception e) {
    e.printStackTrace();
    return "参照不成功 Exception:" + e;
  }
}

Datastoreに書き込まれたスプレッドデータを読み取る処理は、よりシンプルなコード記述になります。

(1)で前と同様にDatastoreServiceのインスタンス(ds)を生成し、(3)でDatastore検索用のQueryを生成しています。Queryはフィルタやソート条件を追加して検索データの絞り込みや、並べ替えを指定することができますが、ここでは(2)のフィルタ指定で年月指定を行い、ソート条件でseq(シークエンス)プロパティを昇順で並べ替える指定を行っています。

次に、(4)prepareで実行するクエリを作成し、(5)ではasIterableで(4)で作成したクエリを実行し、 Entity項目を Iterable(反復可能)として取得します。その後(6)以下のgetPropertyでプロパティ名に対応した値を取得し、(7)でWebクライアントでの処理に対応したJSONの配列形式にフォーマット後(8)でクライアントへ送ります。

有限会社サイバースペース
慶應義塾大学工学部電気科卒。日本IBM、日本HPなどにおいて、製造装置業を中心とした業務系/基幹業務系システムのSE/マーケティングや、3階層C/Sアーキテクチャによる社内業務システム開発などに携わる。現在は、Ajax/Web 2.0関連のセミナー講師/コンサルティング、書籍執筆などを行っている。情報処理学会会員。http://www.at21.net/

連載記事一覧

Think IT会員サービスのご案内

Think ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。会員登録を済ませてThink ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスのご案内

関連記事