React Datasheet を使うと、Excel のような UI を実装することができます。

基本的な使用方法

まずは、React Datasheet をインストールします。

プロジェクトのターミナルで、npm install react-datasheet --saveを実行します。

react-datasheetからReactDataSheetreact-datasheet.cssをインポートします。

import ReactDataSheet from "react-datasheet"
import "react-datasheet/lib/react-datasheet.css"

データを格納するgridを作成します。

1 行毎で配列になっており、さらに配列の中に列となる配列が格納されています。

const grid: GridElement[][] = [
  [{ value: 1 }, { value: 3 }],
  [{ value: 2 }, { value: 4 }],
]

GridElementの型は、以下の通りです。

interface GridElement extends ReactDataSheet.Cell<GridElement, number> {
  value:
    | string
    | number
    | null
    | ReactDataSheet.CellRenderer<GridElement, number>
  expr?:
    | string
    | number
    | null
    | ReactDataSheet.CellRenderer<GridElement, number>
}

JSX のなかにReactDataSheetを設定します。

return (
  <div>
    <ReactDataSheet
      data={grid}
      valueRenderer={cell => cell.value}
      onCellsChanged={handleCellsChange}
    />
  </div>
)

dataの中に、格納するデータ、今回は grid を指定します。

valueRendererに表示する値、今回はgridの中のvalueを指定したいので、cell.valueを指定します。

onCellsChangedの中にhandleCellsChangeを設定しましたので、handleCellsChangeを作成します。

const handleCellsChange = (
  changes: ReactDataSheet.CellRenderer<GridElement, number | string>
) => {
  changes.forEach(
    ({
      cell,
      row,
      col,
      value,
    }: {
      cell: GridElement
      row: number
      col: number
      value: string | null
    }) => {
      grid[row][col] = { ...grid[row][col], value: Number(value) }
    }
  )
}

changesの中に、cellrowcolvalueが格納されているオブジェクトが配列となって格納されています。

valueの値は、string 型なので、数値を格納したい場合は、number 型へ変換しましょう。

一通り完成したので、ブラウザで確認してみましょう。

image2

マス目が表示されました。

試しに数値を変更すると、

image3

無事、数値が変わりました。

読み取り専用を追加する

ヘッダーのように読み取り専用のセルを作成したい場合は、gridの中にreadOnly:trueを設定します。

const grid: GridElement[][] = [
  [
    { readOnly: true, value: "header1" },
    { readOnly: true, value: "header2" },
  ],
  [{ value: 1 }, { value: 3 }],
  [{ value: 2 }, { value: 4 }],
]

ブラウザで確認すると、

image4

読み取り専用の部分の背景に色がつきました。

gridを以下の通りすると、

const grid: GridElement[][] = [
  [
    { readOnly: true, value: "" },
    { readOnly: true, value: "A" },
    { readOnly: true, value: "B" },
  ],
  [{ readOnly: true, value: "1" }, { value: 1 }, { value: 3 }],
  [{ readOnly: true, value: "2" }, { value: 2 }, { value: 4 }],
]

image5

Excel のような UI が出来上がりました。

ブログ一覧