forked from sheetjs/docs.sheetjs.com
mui
This commit is contained in:
parent
e6fc787cd2
commit
e1584a41a3
@ -161,7 +161,11 @@ However, this does not handle merge cells well!
|
||||
|
||||
The `sheet_to_html` function generates HTML that is aware of merges and other
|
||||
worksheet features. React `dangerouslySetInnerHTML` attribute allows code to
|
||||
set the `innerHTML` attribute, effectively inserting the code into the page:
|
||||
set the `innerHTML` attribute, effectively inserting the code into the page.
|
||||
|
||||
In this example, the component attaches a `ref` to the `DIV` container. During
|
||||
export, the first `TABLE` child element can be parsed with `table_to_book` to
|
||||
generate a workbook object.
|
||||
|
||||
```jsx title="src/SheetJSReactHTML.js"
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
|
229
docz/docs/03-demos/02-grid/18-mui.md
Normal file
229
docz/docs/03-demos/02-grid/18-mui.md
Normal file
@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Material UI
|
||||
pagination_prev: demos/frontend/index
|
||||
pagination_next: demos/net/index
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
This demo covers the traditional Material UI Table as well as the MUI Data Grid.
|
||||
|
||||
## Material UI Table
|
||||
|
||||
The `Table` component abstracts the `<table>` element in HTML. `table_to_book`
|
||||
can process a `ref` attached to the `Table` element:
|
||||
|
||||
```tsx
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import Table from '@mui/material/Table';
|
||||
// ...
|
||||
// highlight-next-line
|
||||
import { useRef } from "react";
|
||||
|
||||
// ...
|
||||
export default function BasicTable() {
|
||||
// highlight-next-line
|
||||
const tbl = useRef<HTMLTableElement>(null);
|
||||
return ( <>
|
||||
<button onClick={() => {
|
||||
// highlight-next-line
|
||||
const wb = utils.table_to_book(tbl.current);
|
||||
writeFileXLSX(wb, "SheetJSMaterialUI.xlsx");
|
||||
}}>Export</button>
|
||||
<TableContainer {...}>
|
||||
// highlight-next-line
|
||||
<Table {...} ref={tbl}>
|
||||
{/* ... material ui table machinations ... */}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<>);
|
||||
}
|
||||
```
|
||||
|
||||
#### MUI Table Demo
|
||||
|
||||
<details open><summary><b>Complete Example</b> (click to hide)</summary>
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last run on 2023 May 11 against Material UI 5.13.0 paired with
|
||||
Emotion 11.11.0
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new TypeScript `create-react-app` app:
|
||||
|
||||
```bash
|
||||
npx create-react-app sheetjs-mui --template typescript
|
||||
cd sheetjs-mui
|
||||
```
|
||||
|
||||
2) Install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @mui/material@5.13.0 @emotion/react@11.11.0 @emotion/styled@11.11.0`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Download [`App.tsx`](pathname:///mui/table/App.tsx) and replace `src/App.tsx`.
|
||||
|
||||
```bash
|
||||
curl -L -o src/App.tsx https://docs.sheetjs.com/mui/table/App.tsx
|
||||
```
|
||||
|
||||
4) Start the development server:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
The script should open the live demo in a web browser. Click the "Export" button
|
||||
to save the file. Open the generated file in a spreadsheet editor.
|
||||
|
||||
</details>
|
||||
|
||||
## Material UI Data Grid
|
||||
|
||||
[A complete example is included below.](#muidg-demo)
|
||||
|
||||
**Rows and Columns State**
|
||||
|
||||
MUI Data Grid state consists of an Array of column metadata and an Array of row
|
||||
objects. Typically both are defined in state:
|
||||
|
||||
```js
|
||||
// highlight-next-line
|
||||
import { DataGrid, GridColDef } from "@mui/x-data-grid";
|
||||
|
||||
export default function App() {
|
||||
const [rows, setRows] = useState([]);
|
||||
const [columns, setColumns] = useState([]);
|
||||
|
||||
return ( <DataGrid columns={columns} rows={rows} /> );
|
||||
}
|
||||
```
|
||||
|
||||
The most generic data representation is an array of arrays. To sate the grid,
|
||||
columns must be objects whose `field` property is the index converted to string:
|
||||
|
||||
```ts
|
||||
import { WorkSheet, utils } from 'xlsx';
|
||||
import { GridColDef } from "@mui/x-data-grid";
|
||||
|
||||
type Row = any[];
|
||||
type RowCol = { rows: Row[]; columns: GridColDef[]; };
|
||||
|
||||
function ws_to_muidg(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) => ({
|
||||
field: String(i), // MUIDG will access row["0"], row["1"], etc
|
||||
headerName: utils.encode_col(i), // the column labels will be A, B, etc
|
||||
editable: true // 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`:
|
||||
|
||||
:::caution
|
||||
|
||||
`x-data-grid` does not properly preserve row array objects, so the row arrays
|
||||
must be re-created. The snippet defines a `arrayify` function.
|
||||
|
||||
:::
|
||||
|
||||
```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 muidg_to_ws(rows: Row[]): WorkSheet {
|
||||
return utils.aoa_to_sheet(arrayify(rows));
|
||||
}
|
||||
```
|
||||
|
||||
**Editing Cells**
|
||||
|
||||
The `processRowUpdate` prop receives the new row data, allowing for easy
|
||||
state mutation:
|
||||
|
||||
```tsx
|
||||
import { GridRowModel } from "@mui/x-data-grid";
|
||||
|
||||
export default function App() {
|
||||
// ...
|
||||
|
||||
const processRowUpdate = useCallback((rowNew: GridRowModel, rowOld: GridRowModel) => {
|
||||
/* scan each column and manually set state entries */
|
||||
for(var j = 0; j < columns.length; ++j) if(rowNew[j] != null) {
|
||||
rows[rowNew.id][j] = isNaN(+rowNew[j]) ? rowNew[j] : +rowNew[j];
|
||||
}
|
||||
/* force a state update */
|
||||
setRows(rows);
|
||||
/* commit the new row */
|
||||
return rowNew;
|
||||
}, [columns, rows]);
|
||||
|
||||
return ( <DataGrid columns={columns} rows={rows} processRowUpdate={processRowUpdate} /> );
|
||||
}
|
||||
```
|
||||
|
||||
<!-- spellchecker-disable -->
|
||||
|
||||
#### MUIDG Demo
|
||||
|
||||
<!-- spellchecker-enable -->
|
||||
|
||||
<details open><summary><b>Complete Example</b> (click to hide)</summary>
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last run on 2023 May 11 against MUI data grid 6.3.1 paired with
|
||||
Emotion 11.11.0
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new TypeScript `create-react-app` app:
|
||||
|
||||
```bash
|
||||
npx create-react-app sheetjs-muidg --template typescript
|
||||
cd sheetjs-muidg
|
||||
```
|
||||
|
||||
2) Install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @mui/x-data-grid @emotion/react @emotion/styled`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Download [`App.tsx`](pathname:///mui/dg/App.tsx) and replace `src/App.tsx`.
|
||||
|
||||
```bash
|
||||
curl -L -o src/App.tsx https://docs.sheetjs.com/mui/dg/App.tsx
|
||||
```
|
||||
|
||||
4) Start the development server:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
When the page loads, it will fetch and process <https://sheetjs.com/pres.numbers>
|
||||
|
||||
</details>
|
@ -102,117 +102,7 @@ with other buttons and components on the page.
|
||||
|
||||
### Material UI Data Grid
|
||||
|
||||
Material UI Data Grid and React Data Grid share many state patterns and idioms.
|
||||
Differences from ["React Data Grid"](/docs/demos/grid/rdg) will be highlighted.
|
||||
|
||||
[A complete example is included below.](#muidg-demo)
|
||||
|
||||
:::warning
|
||||
|
||||
Despite presenting an editable UI, Material UI Data Grid version `5.17.0` does
|
||||
not update the state when values are changed. The demo uses the React Data Grid
|
||||
editable structure in the hopes that a future version does support state.
|
||||
|
||||
Until the issues are resolved, "React Data Grid" is an excellent choice.
|
||||
|
||||
:::
|
||||
|
||||
**Rows and Columns State**
|
||||
|
||||
The analogue of `Column` is `GridColDef`. The simple structure looks like:
|
||||
|
||||
```js
|
||||
// highlight-next-line
|
||||
import { DataGrid, GridColDef } from "@mui/x-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 `field` property is the index converted to string:
|
||||
|
||||
```ts
|
||||
import { WorkSheet, utils } from 'xlsx';
|
||||
// highlight-next-line
|
||||
import { GridColDef } from "@mui/x-data-grid";
|
||||
|
||||
type Row = any[];
|
||||
type RowCol = { rows: Row[]; columns: GridColDef[]; };
|
||||
|
||||
function ws_to_muidg(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) => ({
|
||||
// highlight-start
|
||||
field: String(i), // MUIDG will access row["0"], row["1"], etc
|
||||
headerName: utils.encode_col(i), // the column labels will be A, B, etc
|
||||
editable: true // enable cell editing
|
||||
// highlight-end
|
||||
}));
|
||||
|
||||
return { rows, columns }; // these can be fed to setRows / setColumns
|
||||
}
|
||||
```
|
||||
|
||||
In the other direction, a worksheet can be generated with `aoa_to_sheet`:
|
||||
|
||||
:::caution
|
||||
|
||||
`x-data-grid` does not properly preserve row array objects, so the row arrays
|
||||
must be re-created. The snippet defines a `arrayify` function.
|
||||
|
||||
:::
|
||||
|
||||
```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 muidg_to_ws(rows: Row[]): WorkSheet {
|
||||
return utils.aoa_to_sheet(arrayify(rows));
|
||||
}
|
||||
```
|
||||
|
||||
<!-- spellchecker-disable -->
|
||||
|
||||
#### MUIDG Demo
|
||||
|
||||
<!-- spellchecker-enable -->
|
||||
|
||||
<details><summary><b>Complete Example</b> (click to show)</summary>
|
||||
|
||||
0) [Follow the React Data Grid demo](#rdg-demo) and generate the sample app.
|
||||
|
||||
1) Install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @mui/x-data-grid @emotion/react @emotion/styled`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Download [`App.tsx`](pathname:///muidg/App.tsx) and replace `src/App.tsx`.
|
||||
|
||||
3) 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.
|
||||
|
||||
</details>
|
||||
**[The exposition has been moved to a separate page.](/docs/demos/grid/mui#material-ui-data-grid)**
|
||||
|
||||
<!-- spellchecker-disable -->
|
||||
|
||||
@ -282,154 +172,8 @@ document.body.removeChild(tbl);
|
||||
|
||||
### React
|
||||
|
||||
The typical solution is to attach a Ref to the table element. The `current`
|
||||
property will be a live reference which plays nice with `table_to_book`:
|
||||
|
||||
```jsx
|
||||
// highlight-next-line
|
||||
import { useRef } from "react";
|
||||
|
||||
export default function ReactTable() {
|
||||
// highlight-next-line
|
||||
const tbl = useRef(null);
|
||||
|
||||
return ( <>
|
||||
<button onClick={() => {
|
||||
// highlight-next-line
|
||||
const wb = XLSX.utils.table_to_book(tbl.current);
|
||||
XLSX.writeFile(wb, "ReactTable.xlsx");
|
||||
}}>Export</button>
|
||||
// highlight-next-line
|
||||
<table ref={tbl}>
|
||||
{/* ... TR and TD/TH elements ... */}
|
||||
</table>
|
||||
</> );
|
||||
}
|
||||
```
|
||||
**[The exposition has been moved to a separate page.](/docs/demos/frontend/react#html)**
|
||||
|
||||
### Material UI Table
|
||||
|
||||
The `Table` component abstracts the `<table>` element in HTML.
|
||||
|
||||
```tsx
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import Table from '@mui/material/Table';
|
||||
// ...
|
||||
// highlight-next-line
|
||||
import { useRef } from "react";
|
||||
|
||||
// ...
|
||||
export default function BasicTable() {
|
||||
// highlight-next-line
|
||||
const tbl = useRef<HTMLTableElement>(null);
|
||||
return ( <>
|
||||
<button onClick={() => {
|
||||
const wb = utils.table_to_book(tbl.current);
|
||||
writeFileXLSX(wb, "SheetJSMaterialUI.xlsx");
|
||||
}}>Export</button>
|
||||
<TableContainer {...}>
|
||||
// highlight-next-line
|
||||
<Table {...} ref={tbl}>
|
||||
{/* ... material ui table machinations ... */}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<>);
|
||||
}
|
||||
```
|
||||
|
||||
<details><summary><b>Complete Example</b> (click to show)</summary>
|
||||
|
||||
1) Create a new TypeScript `create-react-app` app:
|
||||
|
||||
```bash
|
||||
npx create-react-app sheetjs-mui --template typescript
|
||||
cd sheetjs-mui
|
||||
```
|
||||
|
||||
2) Install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @mui/material`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Replace `src/App.tsx` with the following code. This is based on the official
|
||||
Material UI Table example. Differences are highlighted.
|
||||
|
||||
```tsx title="src/App.tsx"
|
||||
// highlight-start
|
||||
import React, { useEffect, useState, useRef, ChangeEvent } from "react";
|
||||
import { utils, writeFileXLSX } from 'xlsx';
|
||||
// highlight-end
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Paper from '@mui/material/Paper';
|
||||
|
||||
function createData(
|
||||
name: string,
|
||||
calories: number,
|
||||
fat: number,
|
||||
carbs: number,
|
||||
protein: number,
|
||||
) {
|
||||
return { name, calories, fat, carbs, protein };
|
||||
}
|
||||
|
||||
const rows = [
|
||||
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
|
||||
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
|
||||
createData('Eclair', 262, 16.0, 24, 6.0),
|
||||
createData('Cupcake', 305, 3.7, 67, 4.3),
|
||||
createData('Gingerbread', 356, 16.0, 49, 3.9),
|
||||
];
|
||||
|
||||
export default function BasicTable() {
|
||||
// highlight-start
|
||||
const tbl = useRef<HTMLTableElement>(null);
|
||||
return ( <>
|
||||
<button onClick={() => {
|
||||
const wb = utils.table_to_book(tbl.current);
|
||||
writeFileXLSX(wb, "SheetJSMaterialUI.xlsx");
|
||||
}}>Export</button>
|
||||
// highlight-end
|
||||
<TableContainer component={Paper}>
|
||||
// highlight-next-line
|
||||
<Table sx={{ minWidth: 650 }} aria-label="simple table" ref={tbl}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Dessert (100g serving)</TableCell>
|
||||
<TableCell align="right">Calories</TableCell>
|
||||
<TableCell align="right">Fat (g)</TableCell>
|
||||
<TableCell align="right">Carbs (g)</TableCell>
|
||||
<TableCell align="right">Protein (g)</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.name}
|
||||
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
|
||||
>
|
||||
<TableCell component="th" scope="row">
|
||||
{row.name}
|
||||
</TableCell>
|
||||
<TableCell align="right">{row.calories}</TableCell>
|
||||
<TableCell align="right">{row.fat}</TableCell>
|
||||
<TableCell align="right">{row.carbs}</TableCell>
|
||||
<TableCell align="right">{row.protein}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
// highlight-next-line
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
||||
4) run `npm start`. Click the "Export" button and inspect the generated file.
|
||||
|
||||
</details>
|
||||
**[The exposition has been moved to a separate page.](/docs/demos/grid/mui#material-ui-table)**
|
||||
|
@ -170,8 +170,8 @@ const aoa = [ ["Hash"], [key] ].concat(Object.entries(values));
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on 2023 February 23 with Redis 7.0.8, Redis connector
|
||||
module 4.6.4 and NodeJS 18.14.2.
|
||||
This demo was last tested on 2023 May 11 with Redis 7.0.11, Redis connector
|
||||
module 4.6.6 and NodeJS 20.1.0.
|
||||
|
||||
:::
|
||||
|
||||
@ -179,19 +179,28 @@ module 4.6.4 and NodeJS 18.14.2.
|
||||
|
||||
The most recent version of the `redis` node module does not work with most
|
||||
versions of NodeJS. It is "ESM-only", requiring NodeJS 18 or later. As a result,
|
||||
this demo also requires NodeJS version 18.
|
||||
|
||||
Questions regarding the `redis` library and the decision to drop traditional
|
||||
NodeJS "CommonJS" module support should be directed to the Redis team.
|
||||
this demo also requires NodeJS version 18 or later.
|
||||
|
||||
:::
|
||||
|
||||
0) Set up and start a local Redis server. On Intel macOS:
|
||||
0) Set up and start a local Redis server.
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on Intel macOS. Redis was installed with:
|
||||
|
||||
```bash
|
||||
brew install redis@7.0.8
|
||||
brew install redis@7.0.11
|
||||
```
|
||||
|
||||
The following command started the server process:
|
||||
|
||||
```bash
|
||||
/usr/local/opt/redis/bin/redis-server /usr/local/etc/redis.conf
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
1) Download the following scripts:
|
||||
|
||||
- [`SheetJSRedis.mjs`](pathname:///nosql/SheetJSRedis.mjs)
|
||||
@ -202,13 +211,18 @@ curl -LO https://docs.sheetjs.com/nosql/SheetJSRedis.mjs
|
||||
curl -LO https://docs.sheetjs.com/nosql/SheetJSRedisTest.mjs
|
||||
```
|
||||
|
||||
2) Install dependencies and run:
|
||||
2) Install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.4
|
||||
node SheetJSRedisTest.mjs`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.6`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Run the test script:
|
||||
|
||||
```bash
|
||||
node SheetJSRedisTest.mjs
|
||||
```
|
||||
|
||||
Inspect the output and compare with the data in `SheetJSRedisTest.mjs`.
|
||||
|
||||
Open `SheetJSRedis.xlsx` and verify the columns have the correct data
|
||||
|
@ -5,11 +5,22 @@ sidebar_position: 2
|
||||
# Hyperlinks
|
||||
|
||||
<details>
|
||||
<summary><b>Format Support</b> (click to show)</summary>
|
||||
<summary><b>File Format Support</b> (click to show)</summary>
|
||||
|
||||
**Cell Hyperlinks**: XLSX/M, XLSB, BIFF8 XLS, XLML, ODS, HTML
|
||||
| Formats | Link | Tooltip | Storage Representation |
|
||||
|:------------------|:-----:|:-------:|:-----------------------|
|
||||
| XLSX / XLSM | ✔ | ✔ | Cell Link + Tooltip |
|
||||
| XLSB | ✔ | ✔ | Cell Link + Tooltip |
|
||||
| XLS (BIFF8) | ✔ | ✔ | Cell Link + Tooltip |
|
||||
| XLML | ✔ | ✔ | Cell Link + Tooltip |
|
||||
| ODS / FODS / UOS | ✔ | | Span Link + Tooltip |
|
||||
| HTML | ✔ | * | Span Link |
|
||||
| NUMBERS | | * | Span Link ** |
|
||||
|
||||
**Tooltips**: XLSX/M, XLSB, BIFF8 XLS, XLML
|
||||
Asterisks (*) mark features that are not supported by the file formats.
|
||||
|
||||
For "Span Link" formats, parsers apply the first hyperlink to the entire cell
|
||||
and writers apply the hyperlink to the entire cell text.
|
||||
|
||||
</details>
|
||||
|
||||
@ -26,9 +37,19 @@ ws["A1"].l = { Target: "https://sheetjs.com", Tooltip: "Find us @ SheetJS.com!"
|
||||
|
||||
:::note
|
||||
|
||||
Following traditional software, hyperlinks are applied to entire cell objects.
|
||||
Some formats (including HTML) attach links to text spans. The parsers apply the
|
||||
first link to the entire cell. Writers apply links to the entire cell text.
|
||||
|
||||
:::
|
||||
|
||||
:::caution
|
||||
|
||||
Excel does not automatically style hyperlinks. They will be displayed using
|
||||
the default cell style. <a href="https://sheetjs.com/pro">SheetJS Pro Basic</a>
|
||||
extends this export with support for hyperlink styling.
|
||||
the default cell style.
|
||||
|
||||
<a href="https://sheetjs.com/pro">SheetJS Pro Basic</a> includes support for
|
||||
general hyperlink styling.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState, ChangeEvent } from "react";
|
||||
import { DataGrid, GridColDef } from "@mui/x-data-grid";
|
||||
import React, { useCallback, useEffect, useState, ChangeEvent } from "react";
|
||||
import { DataGrid, GridColDef, GridRowModel } from "@mui/x-data-grid";
|
||||
import { read, utils, WorkSheet, writeFile } from "xlsx";
|
||||
|
||||
import './App.css';
|
||||
@ -87,6 +87,12 @@ export default function App() {
|
||||
writeFile(wb, "SheetJSMUIDG." + ext);
|
||||
}
|
||||
|
||||
const processRowUpdate = useCallback((rowNew: GridRowModel, rowOld: GridRowModel) => {
|
||||
for(var j = 0; j < columns.length; ++j) if(rowNew[j] != null) rows[rowNew.id][j] = isNaN(+rowNew[j]) ? rowNew[j] : +rowNew[j];
|
||||
setRows(rows);
|
||||
return rowNew;
|
||||
}, [columns, rows]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3>SheetJS × MUI Data Grid Demo</h3>
|
||||
@ -99,7 +105,7 @@ export default function App() {
|
||||
</p>
|
||||
<div className="flex-cont"><b>Current Sheet: {current}</b></div>
|
||||
<div style={{width:"100%", height:400}}>
|
||||
<DataGrid columns={columns} rows={rows} experimentalFeatures={{ newEditingApi: true }} />
|
||||
<DataGrid columns={columns} rows={rows} processRowUpdate={processRowUpdate} />
|
||||
</div>
|
||||
<p>Click one of the buttons to create a new file with the modified data</p>
|
||||
<div className="flex-cont">{["xlsx", "xlsb", "xls"].map((ext) => (
|
66
docz/static/mui/table/App.tsx
Normal file
66
docz/static/mui/table/App.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import React, { useRef } from "react";
|
||||
import { utils, writeFileXLSX } from 'xlsx';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Paper from '@mui/material/Paper';
|
||||
|
||||
function createData(
|
||||
name: string,
|
||||
calories: number,
|
||||
fat: number,
|
||||
carbs: number,
|
||||
protein: number,
|
||||
) {
|
||||
return { name, calories, fat, carbs, protein };
|
||||
}
|
||||
|
||||
const rows = [
|
||||
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
|
||||
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
|
||||
createData('Eclair', 262, 16.0, 24, 6.0),
|
||||
createData('Cupcake', 305, 3.7, 67, 4.3),
|
||||
createData('Gingerbread', 356, 16.0, 49, 3.9),
|
||||
];
|
||||
|
||||
export default function BasicTable() {
|
||||
const tbl = useRef<HTMLTableElement>(null);
|
||||
return ( <>
|
||||
<button onClick={() => {
|
||||
const wb = utils.table_to_book(tbl.current);
|
||||
writeFileXLSX(wb, "SheetJSMaterialUI.xlsx");
|
||||
}}>Export</button>
|
||||
<TableContainer component={Paper}>
|
||||
<Table sx={{ minWidth: 650 }} aria-label="simple table" ref={tbl}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Dessert (100g serving)</TableCell>
|
||||
<TableCell align="right">Calories</TableCell>
|
||||
<TableCell align="right">Fat (g)</TableCell>
|
||||
<TableCell align="right">Carbs (g)</TableCell>
|
||||
<TableCell align="right">Protein (g)</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.name}
|
||||
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
|
||||
>
|
||||
<TableCell component="th" scope="row">
|
||||
{row.name}
|
||||
</TableCell>
|
||||
<TableCell align="right">{row.calories}</TableCell>
|
||||
<TableCell align="right">{row.fat}</TableCell>
|
||||
<TableCell align="right">{row.carbs}</TableCell>
|
||||
<TableCell align="right">{row.protein}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</> );
|
||||
}
|
Loading…
Reference in New Issue
Block a user