jqGrid フッター、ヘッダーに集計値表示

[ フッター配置例 ]

[ ヘッダー配置例 ]

[ jqGrid コード例 ]

デフォルトはフッター
footerrow, userDataOnFooter を true にする


footerrow: true,
userDataOnFooter: true,

ヘッダーにしたい時は、gridComplete で DOM操作して明細行と合計行の位置を入れ替える


  // フッター合計を上にする, 境界線スタイルを変える //
  var dtlobj = $('#gview_asivlist').children('div').eq(3);   // 明細行
  var fttlobj = $('#gview_asivlist').children('div').eq(4);  // 合計行
  $(fttlobj).css({
    "border-bottom-style": "solid",
    "border-bottom-color": '#008600',
    "border-bottom-width": "2px"
  }).insertBefore($(dtlobj));

[ Servlet コード例 ]

集計値用マップ


    // +++ 結果メッセージ用 +++ //
    HashMap<String, String> usrdata = new HashMap<String, String>();

検索後、集計値を格納


  /**
   * テーブルスキーマ情報取得
   *
   * @param usrdata 合計値マップ
   * @return テーブルスキーマ型リスト
   */
  public ArrayList<TableSchema> getTableSchemaList(HashMap<String, String> usrdata) {

    List list = null;
    try (SqlSession session = sqlSessionFactory.openSession()) {

      list = session.selectList("selTableSchemaList", this);
      System.out.println("getTableSchemaList ():" + list.size());

      // フッター用 //
      // ストリームで合計を格納 //
      ArrayList<TableSchema> slist = new ArrayList(list);
      int cntRow = (int)slist.stream().count();    // 件数 long なので intにキャスト     
      int colTotal = slist.stream().mapToInt(v -> v.getCntCol()).sum();     // 列数
      int rowTotal = slist.stream().mapToInt(v -> v.getCntRow()).sum();     // 行数
      int totalTotal = slist.stream().mapToInt(v -> v.getLenTotal()).sum(); // 合計サイズ
      int dataTotal = slist.stream().mapToInt(v -> v.getLenData()).sum();   // データサイズ
      int indexTotal = slist.stream().mapToInt(v -> v.getLenIndex()).sum(); // インデックスサイズ
      
      // HashMapに追加 //
      usrdata.put("cntCol", String.valueOf(colTotal));
      usrdata.put("cntRow", String.valueOf(rowTotal));
      usrdata.put("lenTotal", String.valueOf(totalTotal));
      usrdata.put("lenData", String.valueOf(dataTotal));
      usrdata.put("lenIndex", String.valueOf(indexTotal));
      usrdata.put("comment", "    Total " + String.valueOf(cntRow) + " Tables" );
      
    }
    catch (Exception se) {
      se.printStackTrace();
    }
    return new ArrayList(list);

  }

応答JSONのセット


    // +++ 結果返却用 +++ //
    JSONResultGrid loggrid = new JSONResultGrid();
    loggrid.setPage(1);
    loggrid.setTotal(1);
    loggrid.setRows(loglist);
    loggrid.setUserdata(usrdata);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String gsonstr = gson.toJson(loggrid);

応答データ


  "userdata": {
    "cntRow": "27494440",
    "lenTotal": "4135942",
    "cntCol": "1689",
    "lenData": "2479938",
    "comment": "    Total 173 Tables",
    "lenIndex": "1656004",
    "sidx": "1"
  }

JAVA 改良版 クラス指定デバッグ出力メソッド (JSON)

デバッグする時、NetBeansのデバッグで止めてチェックしたりするのが、じゃまくさく、時間かかるので、止めてみて終了させる必要ない場合用に、System.out.println() で見れるようにしてます。

昔作った、obj.getClass().getDeclaredFields()でのループ型で配列がとれない欠点があり、JSON出力にしてます。
null, getterのないフィールドがとれない欠点がありますが、PHPの var_dump() みたいなこと出来て便利です。

[ 出力例 ]


===============================
Time : 2019-01-08 19:16:29.204
Class : vesselsch.Polygon
Comment : ポリゴン追加
-------------------------------
{
  "lats": [
    35.68114829375634,
    35.680799702175534,
    35.6783595184685,
    35.67561015535696,
    35.67561015535696,
    35.67700460322533,
    35.677771539167104,
    35.678956789306746,
    35.679026509354955,
    35.68114829375634,
    35.68114829375634
  ],
  "lons": [
    139.97815035776364,
    139.98261355356442,
    139.98287104562985,
    139.98201273874508,
    139.9794378180908,
    139.97892283395993,
    139.9801244635986,
    139.9801244635986,
    139.97840784982907,
    139.97815035776364,
    139.97815035776364
  ],
  "id_poly": 0,
  "nm_poly": "1916",
  "cd_unlo": "JPFNB",
  "tp_poly": "CY",
  "nm_route": "",
  "cnt_corner": 0,
  "latmid": 0.0,
  "lonmid": 0.0,
  "m_depth": 0.0
}

[ コード例 ]


      // JSONデコードはリフレクションで行う //  
      Polygon PL = new Polygon();
      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      Type type = new TypeToken<Polygon>() {
      }.getType();
      PL = gson.fromJson(jsn, type);
      // デバッグ出力 //
      FieldValuePrint fvp = new FieldValuePrint(PL, "ポリゴン追加");

[ 出力用クラス ]


package vesselsch;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.lang.time.DateFormatUtils;

/**
 * 指定クラスJSON出力
 * @author 田中尚
 */
public class FieldValuePrint {
  
  private Object obj;
  private String comment;
  
  /**
   * 引数付コンストラクタ
   * @param obj クラスオブジェクト 
   */
  public FieldValuePrint(Object obj) {  
    this.obj = obj;
    this.printToJSON();
  }
  
  /**
   * 引数付コンストラクタ
   * @param obj クラスオブジェクト
   * @param comment コメント
   */
  public FieldValuePrint(Object obj, String comment) {  
    this.obj = obj;
    this.comment = comment;
    this.printToJSON();
  }
  
  /**
   * クラスのフィールド名、フィールド値一覧チェック出力
   *
   */
  public void printToJSON() {

    // JSON出力 //
    Gson gsondbg = new GsonBuilder().setPrettyPrinting().create();
    System.out.println("===============================");
    System.out.println("Time : " + DateFormatUtils.format(new java.util.Date(), "yyyy-MM-dd HH:mm:ss.SSS"));
    System.out.println("Class : " + this.obj.getClass().getCanonicalName());
    if (this.comment != null) {
      System.out.println("Comment : " + this.comment);
    }
    System.out.println("-------------------------------");
    System.out.println(gsondbg.toJson(this.obj));

  }

}

[ 送信データ画面例 ]

JAVA クラス指定デバッグ出力メソッド

デバッグする時、NetBeansのデバッグで止めてチェックしたりするのが、じゃまくさく、時間かかるので、止めてみて終了させる必要ない場合用に、System.out.println() で見れるようにしてます。

[ 出力例 ]

===============================
Class : vesselsch.Polygon
——————————-
lats : [D@de31cc6
lons : [D@2cdf0ade
polynm : null
latsList : null
lonsList : null
id_poly : 0
nm_poly : 謎の海域ふな
cd_unlo : JPFNB
tp_poly : OT
nm_route :
cnt_corner : 0
latmid : 0.0
lonmid : 0.0
m_depth : 0.0
===============================

配列型がとれてないので、改良予定

[ クラス例 ]


package vesselsch;

import java.util.ArrayList;
import java.util.Arrays;


/**
 * GoogleMap 多角形型
 * @author 田中尚
 */
public class Polygon {
  
  private double[] lats;      // 座標緯度
  private double[] lons;      // 座標経度
  private String polynm;
  
  private ArrayList<Double> latsList = null;    // 未使用
  private ArrayList<Double> lonsList = null;    // 未使用
  
  private int id_poly;
  private String nm_poly;
  private String cd_unlo;
  private String tp_poly;
  private String nm_route;
  
  private short cnt_corner;
  private double latmid;
  private double lonmid;
  
  private float m_depth;       // 水深

[ 埋め込み例 ]

JSONリクエストのセット状況


    // JSONデコードはリフレクションで行う // 
    PolygonDtl POD = new PolygonDtl();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    Type type = new TypeToken<PolygonDtl>() {
    }.getType();
    POD = gson.fromJson(jsn, type);

    // Javascriptで"が消せないので //
    //POD.setCd_facil(POD.getCd_facil().replaceAll("\"", ""));
    if (POD.getCd_facil() != null) {
      if (POD.getCd_facil().equals("")) {
        POD.setCd_facil("ZZZZZ");
      }
      else {
        POD.setCd_facil(POD.getCd_facil().substring(0, 5));
      }
    }

    // -- debug
    MyBatisParent mb = new MyBatisParent();
    mb.printFieldValueList(POD);

gson デコード 複数レコード

[ JSONデコードサンプル ]



import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;

  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {

    // ++ リクエストパラメータ取得 ++ //
    String jsnlist = request.getParameter("fclist");

    // JSONデコードはリフレクションで行う //
    ArrayList<Facility> fcList = new ArrayList();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    Type type = new TypeToken <ArrayList<Facility>>() {
    }.getType();
    fcList = gson.fromJson(jsnlist, type);

gson デコード 単レコード

[ JSONリクエストパラメーター値 (実際は未整形)]


{
    "cd_unlo": "JPUKB",
    "tp_facil": "OT",
    "lat": 34.729880639820365,
    "lon": 135.25307087456054,
    "nm_facil": "未決定 788",
    "nm_facil_e": "UNKNOWN 788"
}

[ JSONリクエストデコードサンプル ]


  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {

    // ++ リクエストパラメータ取得 ++ //
    String latlonsjsn = request.getParameter("latlons");        

    // JSONデコードはリフレクションで行う // 
    PortLatLon PLL = new PortLatLon();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    Type type = new TypeToken<PortLatLon>() {
    }.getType();
    PLL = gson.fromJson(latlonsjsn, type);

[ JAVAクラス ]


package vesselsch;

/**
 * GoogleMap用陸上施設型 
 * @author 田中尚
 */
public class Facility {
  
  private int id;
  private int fid;
  private String tp_facil;
  private String nm_facil;
  private String no_zip;
  private String nm_addr;
  private double lat = 0;
  private double lon = 0;
  private String nm_url;
  private String no_tel;
  private String tm_add;
  private String tm_updt;
  private String tm_lastupdt;
  private String nm_rmtaddr;
  private String nm_remark;
  private String cd_unlo;
  
  private String nm_facil_e = "";
  private String nm_addr_e = "";
  
  private String file1 = "";
  private short is_imgexist;
  
  // 保税蔵置場経緯度更新時リフレクションでセットする用 //
  private String flgbarea;
  private String cd_naccs;
  // US Broker経緯度更新時リフレクションでセットする用 //
  private String flgusbroker;
  
  

  /**
   * @return the id
   */
  public int getId() {
    return id;
  }

  /**
   * @param id the id to set
   */
  public void setId(int id) {
    this.id = id;
  }

  /**
   * @return the fid
   */
  public int getFid() {
    return fid;
  }

  /**
   * @param fid the fid to set
   */
  public void setFid(int fid) {
    this.fid = fid;
  }

  /**
   * @return the tp_facil
   */
  public String getTp_facil() {
    return tp_facil;
  }

  /**
   * @param tp_facil the tp_facil to set
   */
  public void setTp_facil(String tp_facil) {
    this.tp_facil = tp_facil;
  }

  /**
   * @return the nm_facil
   */
  public String getNm_facil() {
    return nm_facil;
  }

  /**
   * @param nm_facil the nm_facil to set
   */
  public void setNm_facil(String nm_facil) {
    this.nm_facil = nm_facil;
  }

  /**
   * @return the no_zip
   */
  public String getNo_zip() {
    return no_zip;
  }

  /**
   * @param no_zip the no_zip to set
   */
  public void setNo_zip(String no_zip) {
    this.no_zip = no_zip;
  }

  /**
   * @return the nm_addr
   */
  public String getNm_addr() {
    return nm_addr;
  }

  /**
   * @param nm_addr the nm_addr to set
   */
  public void setNm_addr(String nm_addr) {
    this.nm_addr = nm_addr;
  }

  /**
   * @return the lat
   */
  public double getLat() {
    return lat;
  }

  /**
   * @param lat the lat to set
   */
  public void setLat(double lat) {
    this.lat = lat;
  }

  /**
   * @return the lon
   */
  public double getLon() {
    return lon;
  }

  /**
   * @param lon the lon to set
   */
  public void setLon(double lon) {
    this.lon = lon;
  }

  /**
   * @return the nm_url
   */
  public String getNm_url() {
    return nm_url;
  }

  /**
   * @param nm_url the nm_url to set
   */
  public void setNm_url(String nm_url) {
    this.nm_url = nm_url;
  }

  /**
   * @return the no_tel
   */
  public String getNo_tel() {
    return no_tel;
  }

  /**
   * @param no_tel the no_tel to set
   */
  public void setNo_tel(String no_tel) {
    this.no_tel = no_tel;
  }

  /**
   * @return the tm_add
   */
  public String getTm_add() {
    return tm_add;
  }

  /**
   * @param tm_add the tm_add to set
   */
  public void setTm_add(String tm_add) {
    this.tm_add = tm_add;
  }

  /**
   * @return the tm_updt
   */
  public String getTm_updt() {
    return tm_updt;
  }

  /**
   * @param tm_updt the tm_updt to set
   */
  public void setTm_updt(String tm_updt) {
    this.tm_updt = tm_updt;
  }

  /**
   * @return the tm_lastupdt
   */
  public String getTm_lastupdt() {
    return tm_lastupdt;
  }

  /**
   * @param tm_lastupdt the tm_lastupdt to set
   */
  public void setTm_lastupdt(String tm_lastupdt) {
    this.tm_lastupdt = tm_lastupdt;
  }

  /**
   * @return the nm_rmtaddr
   */
  public String getNm_rmtaddr() {
    return nm_rmtaddr;
  }

  /**
   * @param nm_rmtaddr the nm_rmtaddr to set
   */
  public void setNm_rmtaddr(String nm_rmtaddr) {
    this.nm_rmtaddr = nm_rmtaddr;
  }

  /**
   * @return the nm_remark
   */
  public String getNm_remark() {
    return nm_remark;
  }

  /**
   * @param nm_remark the nm_remark to set
   */
  public void setNm_remark(String nm_remark) {
    this.nm_remark = nm_remark;
  }

  /**
   * @return the cd_unlo
   */
  public String getCd_unlo() {
    return cd_unlo;
  }

  /**
   * @param cd_unlo the cd_unlo to set
   */
  public void setCd_unlo(String cd_unlo) {
    this.cd_unlo = cd_unlo;
  }

  /**
   * @return the nm_facil_e
   */
  public String getNm_facil_e() {
    return nm_facil_e;
  }

  /**
   * @param nm_facil_e the nm_facil_e to set
   */
  public void setNm_facil_e(String nm_facil_e) {
    this.nm_facil_e = nm_facil_e;
  }

  /**
   * @return the nm_addr_e
   */
  public String getNm_addr_e() {
    return nm_addr_e;
  }

  /**
   * @param nm_addr_e the nm_addr_e to set
   */
  public void setNm_addr_e(String nm_addr_e) {
    this.nm_addr_e = nm_addr_e;
  }

  /**
   * @return the file1
   */
  public String getFile1() {
    return file1;
  }

  /**
   * @param file1 the file1 to set
   */
  public void setFile1(String file1) {
    this.file1 = file1;
  }

  /**
   * @return the is_imgexist
   */
  public short getIs_imgexist() {
    return is_imgexist;
  }

  /**
   * @param is_imgexist the is_imgexist to set
   */
  public void setIs_imgexist(short is_imgexist) {
    this.is_imgexist = is_imgexist;
  }

  /**
   * @return the flgbarea
   */
  public String getFlgbarea() {
    return flgbarea;
  }

  /**
   * @param flgbarea the flgbarea to set
   */
  public void setFlgbarea(String flgbarea) {
    this.flgbarea = flgbarea;
  }

  /**
   * @return the cd_naccs
   */
  public String getCd_naccs() {
    return cd_naccs;
  }

  /**
   * @param cd_naccs the cd_naccs to set
   */
  public void setCd_naccs(String cd_naccs) {
    this.cd_naccs = cd_naccs;
  }

  /**
   * @return the flgusbroker
   */
  public String getFlgusbroker() {
    return flgusbroker;
  }

  /**
   * @param flgusbroker the flgusbroker to set
   */
  public void setFlgusbroker(String flgusbroker) {
    this.flgusbroker = flgusbroker;
  }
  
  
  
  
  
}
 

gson エンコード サンプルコード リスト

[ リストオブジェクト複レコード ]



import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

    // 検索処理 //
    ParamExRateSS PE = new ParamExRateSS(vessel);
    ArrayList reslist = new ArrayList(PE.selectExRateSSList());

    // ++ JSONオブジェクトに格納 ++ //
    JSONResultGrid grid = new JSONResultGrid();
    grid.setPage(1);
    grid.setTotal(1);
    grid.setRecords(reslist.size());
    grid.setRows(reslist);
    //grid.setUserdata(usrdata);

    //Gson gson = new Gson();                   // 整形なし    
    Gson gson = new GsonBuilder().setPrettyPrinting().create();   // 整形
    String gsonstr = gson.toJson(grid);

    // ++ レスポンスを返す ++ //
    try {
      byte[] res = gsonstr.getBytes("UTF-8");   // <=== UTF-8にしないと文字化けする
      response.setContentType(CONTENT_TYPE);
      response.setContentLength(res.length);
      OutputStream os = response.getOutputStream();
      os.write(res);
      os.close();
    }
    catch (Exception e) {
      e.printStackTrace();
    }

応答文字列


{
  "page": 1,
  "total": 1,
  "records": 1,
  "rows": [
    {
      "id": 182077,
      "vessel": "APL CHINA",
      "voy": "221W",
      "ss": "APL",
      "port": "Yokohama",
      "dt_atb": "01/01 (Sat)",
      "dt_atd": "01/01 (Sat)",
      "dt_imp": "11/15 (Thu)",
      "rt_imp": 116.65,
      "dt_exp": "11/15 (Thu)",
      "rt_exp": 116.65,
      "tm_add": "12/02 08:28",
      "url_link": "http://aplinfo.apl.com/japan/html/daily_schedule.html"
    }
  ]
}

gson エンコード サンプルコード 単レコード

[ 単純クラスオブジェクト ]




import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
    // curlをRunTimeで実行 //
    Forecast fc = PF.getCurrentForecast();
    
    // UTC => MyTM 変換があるのでクラスに入れたのを文字列に戻す //
    //Gson gson = new Gson();                                      // 整形なし
    Gson gson = new GsonBuilder().setPrettyPrinting().create();    // 改行整形
    String gsonstr = gson.toJson(fc);

応答テキスト


{
  "DESTINATION": "JP TYO R",
  "ETA": "19/01/07 07:00 (UTC)",
  "ETA_CALC": "19/01/09 06:31 (UTC)",
  "ETA_MY": "19/01/07 16:00 (Asia/Tokyo)",
  "ETA_CALC_MY": "19/01/09 15:31 (Asia/Tokyo)",
  "NEXT_PORT_NAME": "TOKYO",
  "NEXT_PORT_UNLOCODE": "JPTYO",
  "LAST_PORT": "SHANGHAI",
  "nowtmjst": "19/01/04 14:22 (JST)",
  "cdCntryLast": "CN",
  "cdCntryNext": "JP"
}

gson 使って何がうれしいか

Javascript + AJax でのフロントエンドが主流となってきて、受信データ型式がJSONが普通と思います。

主に、jqGridのデータ取得バックエンドのJavaで使ってます。

PHPとかでは、JSONへのエンコードが、すぱっとワンステートメントで出来るところ、gsonの存在がわからぬ頃、StringBuffer にJavaオブジェクトのデータをgetして追加、文字列にして応答するという、煩雑で間違いやすく、メンテナンス性の悪い方法を使ってました。

gson使ってからは、JSON型式文字列への変換が、単純配列、単純リストはもちろん、JavaBeanのリストなんかもワンメソッドで出来、コード量削減、間違い減少、メンテナンス性大幅向上してます。

リフレクション使えば、デコードも短いコードでさっと出来て、JSON型式でのリクエストパラメータなんかも簡単に扱えます。