はじめに
前回は、ASP.NETの現状を確認し、帳票機能の開発に便利なSpreadJSライブラリを紹介しました。第2回はSpreadJSのはじめ方と基本的な使い方を紹介し、SpreadJSの概念と主な機能を学びます。
本稿で紹介する機能は、次のリストの通りです。
- 日本語化
- 初期化
- 値をシートに設定する(セル・テーブル・シート・CSV)
- 数式の使用
- セル型
- 行や列の固定
- クライアントサイドのExcelインポート・エクスポート
- テーブルスライサー
対象読者
- JavaScript 開発者
- スプレッドシートの機能に興味がある方
- ExcelのようなWebアプリを作成したい方
必要な環境
本稿では、次の環境で開発・動作確認をおこなっています。
- Chrome
- Visual Studio Code
- Windows 10
SpreadJSのドキュメントは?
SpreadJSにはどのような機能があるか、実装方法を調べるにはどのドキュメントを参照したらよいでしょうか。筆者がおすすめするSpreadJSのドキュメントをいくつか紹介します。
このチュートリアルデモのサイトでは、SpreadJSの機能を俯瞰できます。また、それぞれの詳細ページでは、サンプルと共に機能の説明・実装方法が記載されており、スクリプトを実際に実行し、その場で結果を確認できます。
このチュートリアルデモは製品にも付属しており、実際のコードを手元にて確認できます。
製品ヘルプでは、機能の仕様、メソッド名・引数・オプションの値などのAPIについて知ることができます。ページの左下から検索ができます。
これらのドキュメントは、SpreadJSのサイトよりアクセスできます。新着ニュースでは新しく公開された技術情報を通知しています。また不明な点があれば、サポートページにあるナレッジベースなどが活用できます。
SpreadJSのはじめ方
SpreadJSではトライアル版を入手して試すことができます。SpreadJSをはじめるには、まず、CSSやJavaScriptのファイルを配置します。手順は第1回にも掲載しておりますが、ここで簡単におさらいします。
ファイルパス | 説明 |
---|---|
css/gc.spread.sheets.excel2016colorful.9.20161.0.css | スプレッドシートのテーマ(本稿のサンプルではExcel2016テーマを使用) |
definition/GC.Spread.Sheets.d.ts | SpreadJSのTypeScript型定義ファイル。TypeScriptで記述する場合にのみ必要です。 |
scripts/gc.spread.sheets.all.9.20161.0.min.js | SpreadJSの本体ライブラリ |
scripts/resources/ja/gc.spread.sheets.resources.ja.9.20161.0.min.js | SpreadJSを日本語で表示するためのリソース |
それでは、これらのファイルを配置したという前提で、いくつかの機能を見ていきましょう。
サンプルについて
サンプルにはSpreadJSライブラリは含まれておりません。ご利用いただく場合には、別途SpreadJSのトライアル版(または製品版)をダウンロードする必要があります。ダウンロードした後、サンプル内のREADME.mdに従ってファイルを配置してください。
本稿に記載しているコードはTypeScriptでの記述です。また、記事中のコードは抜粋しているので、詳細はサンプルファイルをご参照ください。また、JavaScriptでの記述は、サンプルファイルにあるJavaScriptファイル(TypeScriptをコンパイルしたもの)をご参照ください。サンプルは、HTML、CSS、JavaScriptで構成しており、Sublime TextやVisual Studio Code等のエディターで確認できます。
基本的な使い方(1)
日本語化
まず、スプレッドシートを日本語で表示するために必要な設定を説明します。
先のセクションに記載した、日本語のリソースファイル「gc.spread.sheets.resources.ja.9.20161.0.min.js」を参照します。
<script src='.../spreadjs/resources/ja/gc.spread.sheets.resources.ja.9.20161.0.min.js' type='text/javascript'></script>
次に、スプレッドシートを表示するHTMLファイルのheadタグ内にmetaタグを配置し、次のように日本語を指定します。
<meta name="spreadjs culture" content="ja-jp" />
以上の手順により、スプレッドシートが日本語表記になります。
初期化
- サンプルファイル:index.html
SpreadJSの初期化には、HTMLファイルにスプレッドシートを表示する要素を配置し、次のように記述します。HTMLのdiv要素でid属性を指定します。
<div id="spreadjs-container" style="width:100%; height:500px;"></div>
style属性は、スプレッドシートのスタイルに合わせて任意に記述します。
window.onload = function () { let workbook = new GC.Spread.Sheets.Workbook(document.getElementById("spreadjs-container"), { sheetCount: 1 }); };
sheetCountは最初に出力するシートの数を設定しています。
コード中の「workbook」変数に代入された「Workbook」オブジェクトは、1つの「Worksheet」オブジェクトを持っています。「Workbook」はスプレッドシート全体を、「Worksheet」はシートを表します。本稿では、主にこの「Worksheet」に対してセルや装飾などの実装を行います。スプレッドシート全体に関わる機能は「Workbook」に対して操作します。
初期状態でも、Excelのような基本的な操作ができます。クリップボード操作(Ctrl+C/V/X)や、アンドゥ・リドゥ(Ctrl+Z/Y)、ドラッグアンドフィル、ドラッグによる移動が可能です。
基本的な使い方(2)
値をシートに設定する
なんらかの値をスプレッドシートに表示するには、主に次の方法があります。
- 1つのセルに対して値を設定する
- セルに対してデータソースをバインドする
- シートに対してデータソースをバインドする
- テーブルに対してデータソースをバインドする(テーブルはシートに配置する)
- CSVを読み込む
それぞれについて説明します。
1. 1つのセルに対して値を設定する
セルに対して値を設定するためには、セルの指定が必要です。SpreadJSでは、「行インデックス(row)」と「列インデックス(col)」の2つの座標によりセルを特定します。インデックスなので0から始まります。
次の例はあるセルに対して値を設定しています。第1引数が行インデックス、第2引数で列インデックスを指定します。
function WriteCell(sheet: GC.Spread.Sheets.Worksheet) { sheet.setValue(0, 0, "値A"); sheet.setValue(1, 1, 123); sheet.setValue(2, 1, new Date(2016, 6, 7)); }
また、次のように配列で設定することもできます。
let data = [ "項目1", "項目2", "項目3", "項目4" ]; sheet.setArray(4, 0, data);
SpreadJSの実装では、数値による座標指定が多く登場します。サンプルでは数値で直接指定していますが、実際にはなるべくマジックナンバーを避けることが望ましいです。
2. セルに対してデータソースをバインドする
- サンプルファイル:index.bind.html
バインドを使うと、オブジェクトに名前付けをし、名前を参照することで設定できます。またオブジェクトとスプレッドシートの双方向の連結が可能になります。バインドは、セル・テーブル・シートに対して行う方法があります。
次の例は、座標で指定したセルにJSONオブジェクトをバインドしています。
function BindCell(sheet: GC.Spread.Sheets.Worksheet) { let data = [ { name: "花子", birthday: new Date(2016, 4, 1), address: {zipcode: "1234567"}}, { name: "太郎", birthday: new Date(2016, 6, 7) , address: {zipcode: "1234567"}}, ] var source = new GC.Spread.Sheets.Bindings.CellBindingSource(data); sheet.setBindingPath(0, 0, "0.name"); sheet.setBindingPath(0, 1, "0.birthday"); sheet.setBindingPath(0, 2, "0.address.zipcode"); sheet.setBindingPath(1, 0, "1.name"); sheet.setBindingPath(1, 1, "1.birthday"); sheet.setBindingPath(1, 2, "1.address.zipcode"); sheet.setDataSource(source); }
JSONオブジェクトが配列の場合は、「0.name」というように要素のインデックスを指定します。また、オブジェクトが入れ子の場合は「.(ドット)」で区切ります。
3. シートに対してデータソースをバインドする
シートに対してデータソースをバインドする方法です。シートの場合は、セルと違い座標指定を行いません。また、列情報として書式や表示名を設定できます。
function BindSheet(sheet: GC.Spread.Sheets.Worksheet) { let data = [ { name: "花子", birthday: new Date(2016, 4, 1), address: {zipcode: "1234567"}}, { name: "太郎", birthday: new Date(2016, 6, 7) , address: {zipcode: "1234567"}}, ] sheet.setDataSource(data); let columnInfo = [ { name: "name", displayName: "名前", size: 100, }, { name: "birthday", displayName: "誕生日", size: 100, formatter: "yyyy/M/d" }, { name: "address.zipcode", displayName: "郵便番号", size: 100 } ]; sheet.bindColumns(columnInfo); }
4. テーブルに対してデータソースをバインドする
テーブルに対してデータソースをバインドする方法です。この方法を使うと、複数のデータソースを、シート上にある複数のテーブルへそれぞれバインディングできます。テーブルの配置には、座標指定が必要です。また、シートと同じように列情報を設定できます。
function BindTable(sheet: GC.Spread.Sheets.Worksheet) { let data = { staff: [ { name: "長嶋", birthday: new Date(2016, 4, 1), zipcode: "1234567"}, { name: "川西", birthday: new Date(2016, 6, 7) , zipcode: "1234567"}, { name: "堀", birthday: new Date(1991, 7, 3), zipcode: "1234567"}, { name: "小旗", birthday: new Date(1972, 7, 11), zipcode: "1234567"} ], cast: [ { name: "香川", birthday: new Date(2016, 4, 1), zipcode: "1234567"}, { name: "滝沢", birthday: new Date(2016, 6, 7) , zipcode: "1234567"}, { name: "新村", birthday: new Date(1991, 7, 3), zipcode: "1234567"}, { name: "堺", birthday: new Date(1972, 7, 11), zipcode: "1234567"} ] }; { let nameInfo = new GC.Spread.Sheets.Tables.TableColumn("name"); nameInfo.name("名前"); nameInfo.dataField("name"); //…省略 let table = sheet.tables.addFromDataSource("StaffTable", 2, 1, data.staff, GC.Spread.Sheets.Tables.TableThemes.light10); table.bindColumns([nameInfo, birthdayInfo, zipcodeInfo]); } }
それぞれのテーブルに対して並べ替えやフィルター処理を行うことができます。
5. CSVを読み込む
CSVを読み込んで、値である文字列をスプレッドシートに設定する方法です。座標・改行コードの指定・列区切り等を指定します。
function BindCsv(sheet: GC.Spread.Sheets.Worksheet) { sheet.setCsv(0, 0, csvString, "\n", ",", GC.Spread.Sheets.TextFileOpenFlags.none); } let csvString = `名前,ふりがな,アドレス,性別,年齢,誕生日,婚姻,都道府県,携帯,キャリア,カレーの食べ方 神崎 美月,かんざき みづき,kanzaki_miduki@example.com,女,70,1946/8/5,既婚,愛知県,090-4973-2862,ドコモ,奥ルー・ルー攻め派 浅川 咲,あさかわ さき,asakawa_saki`; //省略
基本的な使い方(3)
数式の使用
- サンプルファイル:index.formulaTextBox.html
SpreadJSでは、Excelのように組み込み数式・カスタム数式を使用できます。数式を使用する際は、数式テキストボックス(または、数式バー)も表示するとよいでしょう。
数式テキストボックスとは、次のExcelの図のように、計算式の入力を行う場所のことです。
SpreadJSでは、HTMLのinput要素のid属性を数式テキストボックスとして使うことができます。また、Excelのように数式の候補も表示されます。
数式テキストボックスを使うには、次のようにHTMLのinput要素を用意し、FormulaTextBoxインスタンスをWorkBook(WorkSheetではなく)に設定します。
<input type="text" id="formula-bar"/> <div id="spreadjs-container" style="width:100%; height:500px;"></div>
//数式テキストボックスの適用 var fbx = new GC.Spread.Sheets.FormulaTextBox.FormulaTextBox(document.getElementById('formula-bar'), workbook); fbx.workbook(workbook);
ここでは、HTMLのid属性の値を参照していることに注意してください。
実際に数式を使ってみましょう。次のようにTypeScriptを記述します。
sheet.setValue(0, 0, 100); sheet.setValue(1, 0, 250); sheet.setFormula(2, 0, "=SUM(A1,A2)");
Excelのように数式の候補や、セルの指定補助が表示されます。
また、バインドを利用して、数式内で名前を参照することもできます。これは、先述のテーブルに対してデータソースをバインドする必要があります。
table.setColumnDataFormula(3, "=[@単価]*[@数量]");
第1引数は、数式を入力する場所を表す、テーブル上の列インデックスを指定します。
合計欄に、単価*数量の結果が出力されています。
セル型
- サンプルファイル:index.cellbuttons.html
SpreadJSのセル型を使用することで、セルをボタン・コンボボックス・チェックボックス・ハイパーリンクとして表現できます。例えば、任意の行に対してアクションを起こしたい時、複数の項目から値を選択したいといった時に活用できます。
次の例は、ボタンを設定し、クリックしたときにアラートを出す処理です。
let buttonA = new GC.Spread.Sheets.CellTypes.Button(); buttonA.buttonBackColor("#ffcccc"); buttonA.text("Button A"); sheet.setCellType(1, 1, buttonA); workbook.bind(GC.Spread.Sheets.Events.ButtonClicked, function (e, args) { let sheet = args.sheet, row = args.row, col = args.col; let cellType = sheet.getCellType(row, col); if (cellType instanceof GC.Spread.Sheets.CellTypes.Button) { alert("Button Clicked, row:" + row + ", col:" + col); } });
行や列の固定
Excelにはウィンドウ枠の固定という機能があります。SpreadJSも同じように、四方の固定ができます。
実装では、例のように行数や列数を指定します。
sheet.frozenRowCount(1);//上 sheet.frozenColumnCount(2);//左 sheet.frozenTrailingRowCount(3);//下 sheet.frozenTrailingColumnCount(4);//右
基本的な使い方(4)
クライアントサイドのExcelインポート・エクスポート
- サンプルファイル:index.excel.html
SpreadJSでは、クライアントサイドでのExcelファイルのインポート・エクスポートにも対応しています。SpreadJSのサイトにオンラインのデモがありますので、こちらもご覧ください。
Excelファイルのエクスポートでは、ブラウザ側でファイルをダウンロードする仕組みが必要です。本稿のサンプルでは、「window.navigator.msSaveBlob(IE用)」と「aタグのdownload属性」を使用しています。
それでは、実装方法を紹介します。クライアントサイドExcelIOを使用するには、冒頭で挙げた必要なファイルの他に「gc.spread.excelio.9.20161.0.min.js」ファイルを配置し、参照します。
<script src="/scripts/spreadjs/gc.spread.excelio.9.20161.0.min.js"></script>
例として、次のようなExcelファイルを用意しました。
サンプルファイルにてこのExcelファイルをインポートすると、次のようにスプレッドシートに表示されます。
また、ここでExcelファイルのエクスポートを実行すると、次の図のようにファイルがダウンロードされます。
インポート・エクスポートの実装部分は、次のようになっています(一部省略しています。詳細はサンプルファイルをご参照ください)。
export function ImportFile() { let input: any = document.getElementById("fileDemo"); let excelFile = input.files[0]; excelIO.open(excelFile, function (json) { var workbookObj = JSON.parse(json); workbook.fromJSON(workbookObj); }, e => { console.log(e); }); }
export function ExportFile() { let input: any = document.getElementById("exportFileName"); var fileName = input.value; if (fileName.substr(-5, 5) !== ".xlsx") { fileName += ".xlsx"; } let json = JSON.stringify(workbook.toJSON(null)); excelIO.save(json, function (blob) { if(window.navigator.msSaveBlob) { window.navigator.msSaveBlob(blob, fileName); } else { var a: any= document.createElement("a"); a.href = URL.createObjectURL(blob); a.target = "_blank"; a.download = fileName; a.click(); document.removeChild(a); } }, e => { console.log(e); }); }
インポート・エクスポート機能により、Excelとスプレッドシート間で保持されるデータは、製品サンプルをご参照してください。
- ヘルプ:「クライアント側でのExcelファイルのインポートおよびエクスポート」
- 参照:「SpreadJSのクライアント側Excel入出力機能」(SPREAD Developer's blog)
また、クライアントサイドで処理されるので、大きなサイズのファイルの場合は注意しなければいけません。
テーブルスライサー
- サンプルファイル:index.slicer.html
Excel 2010以降では、ピボットテーブルのデータをフィルターする新しい方法としてスライサー機能が追加されています。SpreadJSにおいても、このスライサーを実現できます。
次の図は、上がExcelにてスライサーを挿入した図、下がSpreadJSにてスライサーを実装した図です。
スライサーの項目を選択すると、条件に合うデータが表示されます。
テーブルスライサーを実装するには、テーブルにデータソースをバインドし、それぞれの列に対してスライサーのオブジェクトを追加します。
let data = [ { name: "安 龍吉", group: "A", math: 100, english: 95, japanese: 100 }, { name: "多部 詩織", group: "B", math: 15, english: 85, japanese: 60 }, { name: "榎本 恵望子", group: "C", math: 60, english: 78, japanese: 50 }, { name: "山内 俊二", group: "A", math: 30, english: 20, japanese: 10 }, { name: "有田 あき", group: "B", math: 40, english: 55, japanese: 50 }, { name: "水田 勝久", group: "A", math: 85, english: 80, japanese: 60 } ]; let nameInfo = new GC.Spread.Sheets.Tables.TableColumn("name"); nameInfo.name("名前"); nameInfo.dataField("name"); let groupInfo = new GC.Spread.Sheets.Tables.TableColumn("group"); groupInfo.name("グループ"); groupInfo.dataField("group"); let mathInfo = new GC.Spread.Sheets.Tables.TableColumn("math"); mathInfo.name("数学"); mathInfo.dataField("math"); //…省略 //テーブルを追加します let table = sheet.tables.addFromDataSource("ScoreTable", 2, 1, data, GC.Spread.Sheets.Tables.TableThemes.light1); table.bindColumns([nameInfo, groupInfo, mathInfo, englishInfo, japaneseInfo]); //スライサーを追加します { let slicerStyle = GC.Spread.Sheets.Slicers.SlicerStyles.light1(); let slicer = sheet.slicers.add("slicer1", table.name(), "グループ", slicerStyle); } { let slicerStyle = GC.Spread.Sheets.Slicers.SlicerStyles.light1(); let slicer = sheet.slicers.add("slicer2", table.name(), "数学", slicerStyle); } //…省略
他、テーブルスライサーをカスタマイズしたり、スライサーをHTMLの要素として作成したりできます。
最後に
以上、SpreadJSの基本的な使い方をいくつかご紹介しました。本稿により、シートやセル、テーブルの概念に触れることができたかと思います。他にもSpreadJSにはさまざまな機能があります。冒頭に記載したドキュメント等から実装方法を知ることができますので、ぜひご参照ください。