Handsontableを使ってkintoneをExcelライクに入力しよう その3 - 上級編

著者名:kintoneエバンジェリスト 村濱 一樹 (External link)

目次

はじめに

Handsontableを使ってkintoneをExcelライクに入力しよう その1 その2 では、ライブラリHandsontableを利用してExcelライクにデータの入力ができるようカスタマイズしてきました。

ただし、上記記事で紹介したHandsontableは無償版(v6.2.2)ということで、少し古いバージョンとなっています。

古いバージョンの場合、たとえばkintoneのテーブルを複雑な表として表示できません。
この記事では最新のHandsontable(執筆時点で有償版v12.1.3)では何ができるか、ということを紹介したいと思います。

完成イメージ

今回はテーブルの内容(列:訪問日、訪問内容)を入れ子で表現してみます。
行に親子関係をもたせることができ、見やすくなります。

設定手順

まずはアプリの準備をします。

フィールドの設定

サンプルアプリのフィールドは以下です。
フィールド名とフィールドコードは同一にしました。

フィールド名(フィールドコード) フィールドタイプ 備考
レコード番号 レコード番号
会社名 文字列(1行)
先方担当者名 文字列(1行)
見込み時期 日付
確度 ラジオボタン
製品名 ドロップダウン
テーブル テーブル 下記「訪問日」「訪問内容」を内包する。
訪問日 文字列(1行) 「テーブル」内フィールドとして設定する。
訪問内容 文字列(1行) 「テーブル」内フィールドとして設定する。

一覧の設定

アプリの一覧は、カスタマイズビューを用います。
スプレッドシート表示のための要素をHTMLで記述します。

1
<div id="sheet"></div>

カスタマイズビューについての詳細は下記を参照ください。
カスタマイズビューを作成してみよう

JavaScript/CSSの設定

今回はお試しということで最新のHansontable(v12.2.0)の評価版を利用します。
Handsontableの公式サイトのダウンロードページ (External link) より、各種方法でJavaScript/CSSファイルをダウンロードできます。
ページ内の「Download ZIP」からファイルをダウンロードして、手動でkintoneにアップロードしましょう。
ZIPファイルを展開して、JavaScript/CSSファイルをkintoneのアプリにアップロードしましょう。
アプリにJavaScript/CSSファイルをアップロードする手順はヘルプ JavaScriptやCSSでアプリをカスタマイズする (External link) を参考してください。

  • JavaScriptファイル
    • 展開したZIPファイル:/handsontable/dist/handsontable.full.min.js
  • CSSファイル
    • 展開したZIPファイル:/handsontable/dist/handsontable.full.min.css

データの入力

確認のために、サンプルデータを先に数件入力しておきましょう。

サンプルコード

前述でアップロードしたファイルに加え、下記もアップロードします。
13行目のviewIdはご自身のアプリの一覧のviewIdをいれてください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
 * Edit kintone record like Excel by handsontable sample program
 * Copyright (c) 2022 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */
(() => {
  'use strict';

  // 一覧ビュー表示用のイベントハンドラ
  kintone.events.on(['app.record.index.show'], (event) => {
    if (event.viewId !== 5520500) return event;

    const container = document.getElementById('sheet');
    container.style.marginTop = '10px';
    container.style.marginLeft = '10px';

    // handsontable初期化
    new Handsontable(container, {
      data: event.records.map(row => {
        return {
          レコード番号: row.レコード番号.value,
          会社名: row.会社名.value,
          先方担当者名: row.先方担当者名.value,
          見込み時期: row.見込み時期.value,
          確度: row.確度.value,
          製品名: row.製品名.value,
          訪問日: null,
          訪問内容: null,
          __children: row.テーブル.value.map(trow => {
            return {
              訪問日: trow.value.訪問日.value,
              訪問内容: trow.value.訪問内容.value,
            };
          })

        };
      }),
      // 表示したいカラム
      colHeaders: ['レコード番号', '会社名', '先方担当者名', '見込み時期', '確度', '製品名', '訪問日', '訪問内容'],
      // 入れ子表現をONにする
      nestedRows: true,

      // その他設定
      licenseKey: 'non-commercial-and-evaluation',
      filters: true,
      height: 'auto',
      contextMenu: [],
    });
    return event;
  });
})();

サンプルコードの解説

今回の例では一覧画面のeventオブジェクトから取得できるevent.recordsを使って、レコードを表示します。

Handsontableのdataオブジェクトにevent.records.mapでオブジェクトの配列を作成し渡しています(21行目)。
このとき、colHeaders(41行目)で指定した配列のキー名と一致させておく必要がありますので注意してください。
mapなどの利用方法は forEach, map, filterなどをつかってkintoneのrecords配列をもっと上手に扱う (External link) を参考にしてみてください。

完成イメージのように、テーブルの内容を入れ子で表示するには、__childrenへ入れ子にしたいテーブルの内容を配列で渡します(31行目)。

nestedRowstrueにする必要があります(43行目)。

また、今回は評価版なので、licenseKeyは評価用のキーを指定します(46行目)。

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// handsontable初期化
new Handsontable(container, {
  data: event.records.map(row => {
    return {
      レコード番号: row.レコード番号.value,
      会社名: row.会社名.value,
      先方担当者名: row.先方担当者名.value,
      見込み時期: row.見込み時期.value,
      確度: row.確度.value,
      製品名: row.製品名.value,
      訪問日: null,
      訪問内容: null,
      __children: row.テーブル.value.map(trow => {
        return {
          訪問日: trow.value.訪問日.value,
          訪問内容: trow.value.訪問内容.value,
        };
      })

    };
  }),
  // 表示したいカラム
  colHeaders: ['レコード番号', '会社名', '先方担当者名', '見込み時期', '確度', '製品名', '訪問日', '訪問内容'],
  // 入れ子表現をONにする
  nestedRows: true,

  // その他設定
  licenseKey: 'non-commercial-and-evaluation',
  filters: true,
  height: 'auto',
  contextMenu: [],
});

有償版のHandsontableについて

料金体系

有料プランにすると、最新のHandsontableの機能を利用できます。
料金は開発者ごとに発生し、使用するエンドユーザーへの課金は発生しないライセンスとなっています。
また、スタンダードプランでは月に2回のサポートを受けられるため開発で困ったことをきくこともできます。

プランと詳細については 価格ページ (External link) を確認してください。

有償版で追加された機能

無償版のv6.2.2から現在のバージョンはv12までになっていますので、やれることはかなり増えています。
無償版との利用できる機能の違いをいくつか紹介します。

Column menu (External link)

列にメニューをもたせることができる機能です。
画像にあるように、左右に列を追加したり列を削除したり、さまざまなコンテキストメニューを用意できます。

Nested headers (External link)

列のヘッダーを入れ子で表現できます。

Column filter (External link)

filterをカスタムでき、複雑なフィルターリングや自由なUIでのフィルターリングが可能です。

Row sorting (External link)

ソートの制御がより自由にできます。
次の例では一番左の列のみオフにする、という制御をしています。

Row parent-child (External link)

今回のサンプルで紹介した機能です。
行に親子関係をもたせることができ、見やすくなります。

CSV export (External link)

表示されているものをそのままCSVにエクスポートするということが可能です。

React/Vue/Angularとの統合

React/Vue/Angular向けに、統合的に開発できるようパッケージが公開されています。

kintoneカスタマイズでの使い所

  • 社内用ツールとして作り込む。
    ライセンスは開発者単位になるため、Handsontableを使ったカスタマイズが適用されたアプリの利用者にはライセンス料がかかりません。
    社内向けにHandsontableを利用して、kintoneをより使いやすくカスタマイズするのに向いています。
  • 販売用にkintoneプラグインを開発する。
    社内用ツールとして知見がたまったらプラグインとしても販売を検討していいかと思います。
    同じくエンドユーザー課金ではないのでプラグインを作成してしまえば自由に公開できます。

kintoneに組み込んだ例

実際に最新バージョンで利用できる機能を利用しつつ、kintoneへ入れ込むとこのようになります。

  • 表示されているデータをダウンロードできるよう、CSVのダウンロードボタンを設置
  • テーブルの内容(列:訪問日、訪問内容)を親子構造で表現
  • フィルター機能を追加し、列ごとに検索をかけやすく(画像下)

おわりに

今回紹介した Handsontableの機能 (External link) を用いることで、kintoneのデータの表現方法や編集方法がぐんと広がるかと思います。
社内やプラグイン開発にむけてより快適なExcelライクな入力を提供したいと思ったときにぜひ検討してみてください。