データを保存する(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の表示を分離して開発を行うことができます。