128 lines
3.1 KiB
Markdown
128 lines
3.1 KiB
Markdown
|
---
|
||
|
title: React Datagrid
|
||
|
pagination_prev: demos/frontend/index
|
||
|
pagination_next: demos/net/index
|
||
|
---
|
||
|
|
||
|
:::note
|
||
|
|
||
|
This demo was last tested on 2023 April 18 with `react-data-grid 7.0.0-beta.28`,
|
||
|
`create-react-app` 5.0.1 and React 18.2.0.
|
||
|
|
||
|
:::
|
||
|
|
||
|
|
||
|
The demo creates a site that looks like the screenshot below:
|
||
|
|
||
|
![react-data-grid screenshot](pathname:///rdg/rdg1.png)
|
||
|
|
||
|
## Integration Details
|
||
|
|
||
|
#### Rows and Columns state
|
||
|
|
||
|
`react-data-grid` state consists of an Array of column metadata and an Array of
|
||
|
row objects. Typically both are defined in state:
|
||
|
|
||
|
```jsx
|
||
|
import DataGrid, { Column } from "react-data-grid";
|
||
|
|
||
|
export default function App() {
|
||
|
const [rows, setRows] = useState([]);
|
||
|
const [columns, setColumns] = useState([]);
|
||
|
|
||
|
return ( <DataGrid columns={columns} rows={rows} onRowsChange={setRows} /> );
|
||
|
}
|
||
|
```
|
||
|
|
||
|
The most generic data representation is an array of arrays. To sate the grid,
|
||
|
columns must be objects whose `key` property is the index converted to string:
|
||
|
|
||
|
```ts
|
||
|
import { WorkSheet, utils } from 'xlsx';
|
||
|
import { textEditor, Column } from "react-data-grid";
|
||
|
|
||
|
type Row = any[];
|
||
|
type AOAColumn = Column<Row>;
|
||
|
type RowCol = { rows: Row[]; columns: AOAColumn[]; };
|
||
|
|
||
|
function ws_to_rdg(ws: WorkSheet): RowCol {
|
||
|
/* create an array of arrays */
|
||
|
const rows = utils.sheet_to_json(ws, { header: 1 });
|
||
|
|
||
|
/* create column array */
|
||
|
const range = utils.decode_range(ws["!ref"]||"A1");
|
||
|
const columns = Array.from({ length: range.e.c + 1 }, (_, i) => ({
|
||
|
key: String(i), // RDG will access row["0"], row["1"], etc
|
||
|
name: utils.encode_col(i), // the column labels will be A, B, etc
|
||
|
editor: textEditor // enable cell editing
|
||
|
}));
|
||
|
|
||
|
return { rows, columns }; // these can be fed to setRows / setColumns
|
||
|
}
|
||
|
```
|
||
|
|
||
|
In the other direction, a worksheet can be generated with `aoa_to_sheet`:
|
||
|
|
||
|
```ts
|
||
|
import { WorkSheet, utils } from 'xlsx';
|
||
|
|
||
|
type Row = any[];
|
||
|
|
||
|
function rdg_to_ws(rows: Row[]): WorkSheet {
|
||
|
return utils.aoa_to_sheet(rows);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
:::caution
|
||
|
|
||
|
When the demo was last refreshed, row array objects were preserved. This was
|
||
|
not the case in a later release. The row arrays must be re-created.
|
||
|
|
||
|
The snippet defines a `arrayify` function that creates arrays if necessary.
|
||
|
|
||
|
```ts
|
||
|
import { WorkSheet, utils } from 'xlsx';
|
||
|
|
||
|
type Row = any[];
|
||
|
|
||
|
// highlight-start
|
||
|
function arrayify(rows: any[]): Row[] {
|
||
|
return rows.map(row => {
|
||
|
var length = Object.keys(row).length;
|
||
|
for(; length > 0; --length) if(row[length-1] != null) break;
|
||
|
return Array.from({length, ...row});
|
||
|
});
|
||
|
}
|
||
|
// highlight-end
|
||
|
|
||
|
function rdg_to_ws(rows: Row[]): WorkSheet {
|
||
|
return utils.aoa_to_sheet(arrayify(rows));
|
||
|
}
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
## Demo
|
||
|
|
||
|
1) Create a new TypeScript `create-react-app` app:
|
||
|
|
||
|
```bash
|
||
|
npx create-react-app sheetjs-rdg --template typescript
|
||
|
cd sheetjs-rdg
|
||
|
```
|
||
|
|
||
|
2) Install dependencies:
|
||
|
|
||
|
```bash
|
||
|
npm i -S https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz react-data-grid
|
||
|
```
|
||
|
|
||
|
3) Download [`App.tsx`](pathname:///rdg/App.tsx) and replace `src/App.tsx`.
|
||
|
|
||
|
```bash
|
||
|
curl -L -o src/App.tsx https://docs.sheetjs.com/rdg/App.tsx
|
||
|
```
|
||
|
|
||
|
4) run `npm start`. When you load the page in the browser, it will attempt to
|
||
|
fetch <https://sheetjs.com/pres.numbers> and load the data.
|