データを保存する(1)
データの保存といえども、"とある値のみ保存する"のか、"帳票全体を保存"するのか等、決定しなければいけません。サンプルでは両方を実装していますが、まず、前者の"とある値のみ保存する"方法について紹介します。
管理するデータをJSONデータとして定義する
サーバー側で管理したいデータを帳票から切り出し、JSON形式のモデルとして定義します。例えば"請求書"では、次の図のように切り分けました。

赤枠がJSON形式のモデルとして定義する場所です。青枠は、Excelの数式のように、表示するときに計算される場所です。この青枠は、JSONモデルとして定義はしません(ただし、要件によっては、計算結果もサーバー側で管理することも考えられます)。
切り出したJSONモデルは次のようになります。
{
"publishDate": "2016-12-01",
"paymentDate": "2016-12-20",
"invoiceNumber": 10003,
"discount": 500,
"destination": {
"name": "杉本 昭 様",
"companyName": "杉本 昭 事務所",
"address1": "東京都",
"address2": "港区"
},
"publisher": {
"name": "山田 太郎",
"companyName": "山田 太郎 事務所",
"address1": "東京都",
"address2": "中央区"
},
"paymentInfo": {
"name": "山田 太郎",
"nameKana": "ヤマダタロウ",
"bankName": "銀行名",
"bankAccount": "1234567"
},
"items": [
{ "id": 1, "amount": 11, "name": "項目名1", "unitPrice": 1500, "sumPrice": 0 },
{ "id": 2, "amount": 13, "name": "項目名2", "unitPrice": 2500, "sumPrice": 0 },
//…続く
]
}
このようなJSONデータをサーバー側とAPIを通してやり取りすることにより、データの管理を行います。
SpreadJSにJSONデータを表示するには、「セルレベルバインディング」と「テーブルバインディング」の機能で実装します。バインディングにより、SpreadJSで編集した値は、クライアント側のObjectにも反映されます。詳細は、製品ヘルプの「データの連結」または連載第2回の「基本的な使い方(2)」をご参照ください。
次のコードは、バインディングの設定を行っているクライアント側のTypeScriptのコードです。JSONデータとSpreadJSの表示場所の関連付けを行い、テーブルを追加しています。テーブルはExcelファイルにて設定していても、Excelのインポート時に破棄されてしまうため、TypeScriptにて設定しています。
function BindSheet(sheet: GC.Spread.Sheets.Worksheet, data: any) {
let tableDataRowCount = data.items.length;
//請求書番号
sheet.setBindingPath(0, 1, "invoiceNumber");
//発行日
sheet.setBindingPath(1, 1, "publishDate");
//支払期日
sheet.setBindingPath(2, 1, "paymentDate");
//宛先
sheet.setBindingPath(4, 0, "destination.name");
sheet.setBindingPath(5, 0, "destination.companyName");
sheet.setBindingPath(6, 0, "destination.address1");
sheet.setBindingPath(7, 0, "destination.address2");
//発行者
sheet.setBindingPath(4, 2, "publisher.name");
sheet.setBindingPath(5, 2, "publisher.companyName");
sheet.setBindingPath(6, 2, "publisher.address1");
sheet.setBindingPath(7, 2, "publisher.address2");
//割引
sheet.setBindingPath(10 + tableDataRowCount, 3, "discount");
sheet.getCell(1, 1)
//支払情報
sheet.setBindingPath(16 + tableDataRowCount, 1, "paymentInfo.name");
sheet.setBindingPath(17 + tableDataRowCount, 1, "paymentInfo.nameKana");
sheet.setBindingPath(18 + tableDataRowCount, 1, "paymentInfo.bankName");
sheet.setBindingPath(19 + tableDataRowCount, 1, "paymentInfo.bankAccount");
//シートにテーブルをバインドします
let amountInfo = new GC.Spread.Sheets.Tables.TableColumn("数量");
amountInfo.name("数量");
amountInfo.dataField("amount");
let nameInfo = new GC.Spread.Sheets.Tables.TableColumn("項目");
nameInfo.name("項目");
nameInfo.dataField("name");
let unitPriceInfo = new GC.Spread.Sheets.Tables.TableColumn("単価");
unitPriceInfo.name("単価");
unitPriceInfo.dataField("unitPrice");
let sumPriceInfo = new GC.Spread.Sheets.Tables.TableColumn("金額");
sumPriceInfo.name("金額");
sumPriceInfo.dataField("sumPrice");
let table = sheet.tables.addFromDataSource("TableDetails", 9, 0, data.items, GC.Spread.Sheets.Tables.TableThemes.medium23);
table.bindColumns([amountInfo, nameInfo, unitPriceInfo, sumPriceInfo]);
//金額の列の計算式を設定します
table.setColumnDataFormula(3, "=[@単価]*[@数量]");
//小計の計算式を設定します
sheet.getCell(11 + tableDataRowCount, 3).formula("=SUM(TableDetails[金額])-Discount");
//シートにデータをバインディングします
sheet.setDataSource(new GC.Spread.Sheets.Bindings.CellBindingSource(itemData));
}
「数式」や「名前の定義」は、Excelインポートを行っても保持されるので、あらかじめExcelにて設定しておくとよいでしょう。サンプルでは、「割引」や「小計」「税」などに名前を設定しています。
このようなバインディング機能により、JSONデータとSpreadJSの表示を分離して開発を行うことができます。

