GrapeCity.devlog

グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉の最新情報をお届けします。製品のTIPSや発売情報、イベントのお知らせなどをいち早く発信中です。

SpreadJSで実現する帳票画面(1)セルバインディング編

こんにちは。みなさんは「Excel帳票」をご存知でしょうか。Excelに顧客情報や販売データなどを入力し、マクロや数式を駆使しながらこのデータを請求書などの雛形に落とし込んで、最終的には印刷までを行う帳票システム構築のやり方です。

この際に必要なツールはExcelのみとなっており、高度な開発技術を持ちあわせていなくとも少々のExcel知識さえあれば誰でも実現が可能なため、さまざまな企業で広く採用されているやり方かと思います。

f:id:GrapeCity_dev:20180528120844p:plain

このExcel帳票は構築が簡単である一方、取り扱うデータ量の増加によって取り扱いが困難になるという特徴があります。データの蓄積が進んで一般的なExcelの用法では考えられないようなデータ量がシートに存在するようになってくると、もはや人の手ではデータが追えなくなり、入力ミスや数式の設定ミス、または計算におけるデータの関連づけなどに失敗するようになります。

このような問題に悩まされるようになったらExcel帳票からの卒業、システム化を検討されると良いかもしれません。

SpreadJSを使用したExcel帳票

ExcelライクなUIを提供するSpreadJS収録ライブラリ「Spread.Sheets」を使用すれば、これまでの「Excel帳票」と同じような考えかたで、帳票システムを構築することが可能です。

というわけで、今回はSpreadJSを使い「Excel帳票ライク」な帳票画面を作成する方法をご紹介したいと思います。なお、実現にあたってはSpread.Sheetsの機能をいくつか利用する必要があるため、各機能の利用方法ごとにブログ記事を分け、複数回にわたりこのテーマでお送りしたいと思います。まずはその1、Spread.Sheetsのセルバインディング編です。

シートの特定セルにデータ結合する「セルバインディング」

Excel帳票では、請求書などの雛形をシート上に用意し、そのなかの特定セルに向けて、顧客名や住所、請求額などのデータを流し込む、といった操作が行われます。

Spread.Sheetsの「セルバインディング」機能を利用すると、JavaScriptの連想配列をデータソースとして、クライアントに表示したスプレッドシートの特定箇所に、データソースの特定データを紐づけて表示させることが可能です。

今回は、Spread.Sheetsで以下のような請求書雛形を作成し、セルバインディングの機能を使って図の赤枠部分に顧客情報や請求額情報を表示してみたいと思います。

f:id:GrapeCity_dev:20180528114511p:plain

請求書雛形の作成

はじめにSpread.Sheetsのシート上に請求書の雛形を作成します。ヘルプを参照しながらSpread.SheetsのAPIを使って、シート内容が上図の雛形と同様になるように設定を行っていきます。

以下はそのサンプルコードです。

// 請求書雛形の作成処理
function setTemplate(spread){
var sheet = spread.getActiveSheet();

// ヘッダ、スクロールバー、タブを非表示に設定します
spread.options.showVerticalScrollbar = false;
spread.options.showHorizontalScrollbar = false;
spread.options.tabStripVisible = false;
sheet.options.colHeaderVisible = false;
sheet.options.rowHeaderVisible = false;

// シートが行列数の最大範囲を超えてスクロールしないように設定します
spread.options.scrollbarMaxAlign = true;
spread.options.scrollbarShowMax = true;

// シートのグリッド線を非表示に設定します
//sheet.options.gridline = {showVerticalGridline: false, showHorizontalGridline: false};

// セル文字列のオーバーフローを許可します
sheet.options.allowCellOverflow = true;

// シートのスタイルを設定します
var basicFont = "normal normal 15px Meiryo";
var ds = sheet.getDefaultStyle();
ds.font = basicFont;
ds.vAlign = GC.Spread.Sheets.VerticalAlign.center;
sheet.setDefaultStyle(ds);

// 行列数を設定します
var ROW_NUM = 13;
var COL_NUM = 6;
sheet.setRowCount(ROW_NUM);
sheet.setColumnCount(COL_NUM);

// 基本の行列サイズを設定します
var ROW_HEIGHT = 30;
var COLUMN_WIDTH = 135;
sheet.defaults.rowHeight = ROW_HEIGHT;
sheet.defaults.colWidth = COLUMN_WIDTH;

// 作成したい雛形に併せて各列のサイズを設定します
var COL_WIDTH_SMALL = 37;
sheet.setColumnWidth(0, COL_WIDTH_SMALL);
sheet.setColumnWidth(5, COL_WIDTH_SMALL);

// 「請求書」行を設定します
var ROW_HIGHT_BIG = 48;
sheet.setRowHeight(1, ROW_HIGHT_BIG);
// 見出しを設定します
sheet.setValue(1,1,"請求書");
// 見出しのスタイルを設定します
var titleStyle = new GC.Spread.Sheets.Style();
var titleFont = "normal normal 24px Meiryo";
titleStyle.font = titleFont;
titleStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
sheet.setStyle(1,1,titleStyle);
// セルを結合します
sheet.addSpan(1,1,1,4);
// 罫線を設定します
var GCNS = GC.Spread.Sheets;
var range = sheet.getRange(1,1,1,4);
range.borderBottom(new GC.Spread.Sheets.LineBorder("black", GCNS.LineStyle.medium));

// 「様」セルを設定します
sheet.setValue(6,2,"様");

// 「下記の通り〜」行を設定します
sheet.setValue(8,1,"下記の通り、ご請求申し上げます。");
// 見出しのスタイルを設定します
var titleStyle = new GC.Spread.Sheets.Style();
titleStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
sheet.setStyle(8,1,titleStyle);
// セルを結合します
sheet.addSpan(8,1,1,4);

// 「合計」セルを設定します
sheet.setValue(11,3,"合計金額");
// スタイルを設定します
var totalStrStyle = new GC.Spread.Sheets.Style();
totalStrStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
sheet.setStyle(11,3,totalStrStyle);

// 合計金額セルにスタイルを設定します
var totalStyle = new GC.Spread.Sheets.Style();
var totalFont = "normal normal 17px Meiryo";
totalStyle.font = titleFont;
sheet.setStyle(11,4,totalStyle);
// 合計金額セルに書式を設定します
sheet.setFormatter(11,4,"¥#,##0");
// 罫線を設定します
range = sheet.getRange(11,3,1,2);
range.borderBottom(new GC.Spread.Sheets.LineBorder("black", GCNS.LineStyle.thin));
}

window.onload = function(){
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
var sheet = spread.getActiveSheet();

//描画処理を一時停止します
sheet.suspendPaint();

//請求書の雛形を設定します
setTemplate(spread);

//描画処理を再開します
sheet.resumePaint();
};

雛形完成時の外観は以下のようになります。

f:id:GrapeCity_dev:20180528120318p:plain

なお、このサンプルコードをみて「コードによるシートのデザイン設定は大変だな」と感じた方もいるかもしれません。そんな時、SpreadJSにはGUIでSpread.Sheetsのデザイン設定ができる「Spread.Sheetsデザイナ」が付属していますので、そちらの活用もご検討いただければと思います。

f:id:GrapeCity_dev:20180529114040p:plain

Spread.Sheets デザイナ

セルバインディング

作成した雛形に対し、以下のようなデータをセルバインディングします。

// 連結データ
var data = { postNumber: "〒981-3205",
             address: "宮城県仙台市泉区紫山3-1-4",
             name: "グレープ太郎",
             total: 128000 };

前述のデザイン設定に比べると、セルバインディングの設定は拍子抜けするほど簡単です。連結データからセルバインディング用のデータソースを作成し、各セルとデータ名の紐付け(バインディングパスの設定と言います)を行うだけで、あっという間にデータ結合の完了です。以下に該当処理のサンプルコードを示します。

// 連結データ
var data = { postNumber: "〒981-3205",
		 address: "宮城県仙台市泉区紫山3-1-4",
		 name: "グレープ太郎",
		 total: 128000 };

//雛形上の各セルにデータをバインドします
var source = new GC.Spread.Sheets.Bindings.CellBindingSource(data);
sheet.setBindingPath(3, 1, "postNumber");
sheet.setBindingPath(4, 1, "address");
sheet.setBindingPath(6, 1, "name");
sheet.setBindingPath(11, 4, "total");
sheet.setDataSource(source);    

これで、Spread.Sheetsで表示した請求書雛形の特定セルに、各種データを流し込むことができるようになりました。実際の動作とソースコードはこちらで確認可能です。

この状態でもちょっとした請求書アプリとして通用しそうですが、この画面には顧客がなにをどれくらい買ったか、という明細情報がありません。購入データを一覧表にして、計算式を駆使し小計なども表示できたら良いな、と思いませんか?

その動作、Spread.Sheetsなら可能です!

次回はSpread.Sheetsに備わるもう一つのデータ結合機能「テーブルバインディング」を使用し、この画面に明細表を追加したいと思います。どうぞお楽しみに!

※「テーブルバインディング編」2018.6.11(月)更新
devlog.grapecity.co.jp

グレープシティ株式会社ではエンジニア経験者を幅広く募集しています。