forked from sheetjs/docs.sheetjs.com
		
	gdg-sa
This commit is contained in:
		
							parent
							
								
									04b4124414
								
							
						
					
					
						commit
						ef06aba826
					
				| @ -16,7 +16,7 @@ Other demos cover general React deployments, including: | ||||
| - [iOS and Android applications powered by React Native](/docs/demos/mobile/reactnative) | ||||
| - [Desktop application powered by React Native Windows + macOS](/docs/demos/desktop/reactnative) | ||||
| - [React Data Grid UI component](/docs/demos/grid#react-data-grid) | ||||
| - [Glide Data Grid UI component](/docs/demos/grid#glide-data-grid) | ||||
| - [Glide Data Grid UI component](/docs/demos/grid/gdg) | ||||
| 
 | ||||
| 
 | ||||
| ## Installation | ||||
|  | ||||
| @ -118,8 +118,8 @@ function exportFile() { | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last run on 2022 November 11 using `vue@3.2.41`.  When running | ||||
| `npm init`, the package `create-vue@3.4.0` was installed. | ||||
| This demo was last run on 2023 April 06 using `vue@3.2.47`.  When running | ||||
| `npm init`, the package `create-vue@3.6.1` was installed. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -194,8 +194,8 @@ function exportFile() { | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last run on 2022 November 11 using `vue@3.2.41`.  When running | ||||
| `npm init`, the package `create-vue@3.4.0` was installed. | ||||
| This demo was last run on 2023 April 06 using `vue@3.2.47`.  When running | ||||
| `npm init`, the package `create-vue@3.6.1` was installed. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										305
									
								
								docz/docs/03-demos/02-grid/17-gdg.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										305
									
								
								docz/docs/03-demos/02-grid/17-gdg.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,305 @@ | ||||
| --- | ||||
| title: Glide Datagrid | ||||
| pagination_prev: demos/frontend/index | ||||
| pagination_next: demos/net/index | ||||
| --- | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 February 07 with the ViteJS+React+TypeScript | ||||
| starter (Vite `4.1.1`, React `18.2.0`) and `@glideapps/glide-data-grid@5.2.1`. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Integration Details | ||||
| 
 | ||||
| #### Backing Store | ||||
| 
 | ||||
| Under the hood, the `DataEditor` component is designed to call methods and | ||||
| request data to display in the grid. It is typical to store data *outside* of | ||||
| component state.  A `getCellContent` callback will pull data from the external | ||||
| backing store, while SheetJS operations will directly act on the store: | ||||
| 
 | ||||
| ```js | ||||
| // !! THESE OBJECTS ARE DEFINED OUTSIDE OF THE COMPONENT FUNCTION !! | ||||
| 
 | ||||
| // this will store the raw data objects | ||||
| let data: any[] = []; | ||||
| // this will store the header names | ||||
| let header: string[] = []; | ||||
| ``` | ||||
| 
 | ||||
| #### Props | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This is a high-level overview. The official documentation should be consulted. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| _Columns_ | ||||
| 
 | ||||
| `DataEditor` expects column metadata to be passed through a `columns` prop. This | ||||
| should be managed in the component state: | ||||
| 
 | ||||
| ```js | ||||
| import { useState } from 'react'; | ||||
| import { DataEditor, GridColumn } from '@glideapps/glide-data-grid'; | ||||
| 
 | ||||
| function App() { | ||||
|   // highlight-next-line | ||||
|   const [cols, setCols] = useState<GridColumn[]>([]); // gdg column objects | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       columns={cols} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| 
 | ||||
| Each `GridColumn` object expects a `title` representing the display name and an | ||||
| `id` representing the key to index within the data object. | ||||
| 
 | ||||
| _Data_ | ||||
| 
 | ||||
| The `DataEditor` component expects a `getCellContent` callback for supplying | ||||
| data. The callback accepts column and row indices.  The column index should be | ||||
| used to find the header key: | ||||
| 
 | ||||
| ```js | ||||
| import { useCallback } from 'react'; | ||||
| import { DataEditor, GridCellKind, GridCell, Item } from '@glideapps/glide-data-grid'; | ||||
| 
 | ||||
| // ... | ||||
| 
 | ||||
| function App() { | ||||
|   // ... | ||||
|   // backing data store -> gdg | ||||
|   // highlight-start | ||||
|   const getContent = useCallback((cell: Item): GridCell => { | ||||
|     const [col, row] = cell; | ||||
|     return { | ||||
|       kind: GridCellKind.Text, | ||||
|       // header[col] is the name of the field | ||||
|       displayData: String(data[row]?.[header[col]]??""), | ||||
|       data: data[row]?.[header[col]], | ||||
|     }; | ||||
|   }, []); | ||||
|   // highlight-end | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       getCellContent={getContent} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| _Row Count_ | ||||
| 
 | ||||
| `DataEditor` also accepts a `rows` property indicating the number of rows. This | ||||
| is best managed in state: | ||||
| 
 | ||||
| ```js | ||||
| import { useState } from 'react'; | ||||
| import { DataEditor } from '@glideapps/glide-data-grid'; | ||||
| 
 | ||||
| function App() { | ||||
|   // highlight-next-line | ||||
|   const [rows, setRows] = useState<number>(0); // number of rows | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       rows={rows} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| 
 | ||||
| _Editing Data_ | ||||
| 
 | ||||
| The demo uses the `onCellEdited` callback to write back to the data store. | ||||
| 
 | ||||
| ### Parsing Data | ||||
| 
 | ||||
| _SheetJS to Data Store_ | ||||
| 
 | ||||
| The raw data objects are readily generated with `sheet_to_json`. The headers | ||||
| can be pulled by extracting the first row of the worksheet: | ||||
| 
 | ||||
| ```js | ||||
| import { utils, WorkBook } from 'xlsx'; | ||||
| 
 | ||||
| // ... | ||||
| 
 | ||||
| const update_backing_store = (wb: WorkBook) => { | ||||
|   // get first worksheet | ||||
|   const sheet = wb.Sheets[wb.SheetNames[0]]; | ||||
| 
 | ||||
|   // set data | ||||
|   // highlight-next-line | ||||
|   data = utils.sheet_to_json<any>(sheet); | ||||
| 
 | ||||
|   // create a range consisting of the first row | ||||
|   const range = utils.decode_range(sheet["!ref"]??"A1"); // original range | ||||
|   range.e.r = range.s.r; // set ending row to starting row (select first row) | ||||
| 
 | ||||
|   // pull headers | ||||
|   // highlight-next-line | ||||
|   header = utils.sheet_to_json<string[]>(sheet, {header: 1, range})[0]; | ||||
| }; | ||||
| 
 | ||||
| // ... | ||||
| ``` | ||||
| 
 | ||||
| _Data Store to GDG_ | ||||
| 
 | ||||
| Scheduling a refresh for the `DataEditor` involves updating the grid column | ||||
| metadata and row count through the standard state.  It also requires a special | ||||
| `updateCells` call to instruct the grid to mark the cached data as stale: | ||||
| 
 | ||||
| ```js | ||||
| import { useRef } from 'react' | ||||
| import { WorkBook } from 'xlsx' | ||||
| import { DataEditor, GridColumn, Item, DataEditorRef } from '@glideapps/glide-data-grid' | ||||
| 
 | ||||
| function App() { | ||||
|   const ref = useRef<DataEditorRef>(null); // gdg ref | ||||
|   // ... | ||||
|   const parse_wb = (wb: WorkBook) => { | ||||
|     update_backing_store(wb); | ||||
| 
 | ||||
|     // highlight-start | ||||
|     // update column metadata by pulling from external header keys | ||||
|     setCols(header.map(h => ({title: h, id: h} as GridColumn))); | ||||
| 
 | ||||
|     // update number of rows | ||||
|     setRows(data.length); | ||||
| 
 | ||||
|     if(data.length > 0) { | ||||
|       // create an array of the cells that must be updated | ||||
|       let cells = data.map( | ||||
|         (_,R) => Array.from({length:header.length}, (_,C) => ({cell: ([C,R] as Item)})) | ||||
|       ).flat(); | ||||
|       // initiate update using the `ref` attached to the DataEditor | ||||
|       ref.current?.updateCells(cells) | ||||
|     } | ||||
|     // highlight-end | ||||
|   }; | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       ref={ref} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| 
 | ||||
| ### Writing Data | ||||
| 
 | ||||
| `json_to_sheet` works directly on the `data` array: | ||||
| 
 | ||||
| ```js | ||||
| const ws = utils.json_to_sheet(data); // easy :) | ||||
| ``` | ||||
| 
 | ||||
| Since the editor can change the header titles, it is strongly recommended to | ||||
| pull column data from the state and rewrite the header row: | ||||
| 
 | ||||
| ```js | ||||
| import { utils, writeFileXLSX } from 'xlsx'; | ||||
| 
 | ||||
| function App() { | ||||
|   // ... | ||||
|   const exportXLSX = useCallback(() => { | ||||
|     // highlight-start | ||||
|     // generate worksheet using data with the order specified in the columns array | ||||
|     const ws = utils.json_to_sheet(data, {header: cols.map(c => c.id ?? c.title)}); | ||||
| 
 | ||||
|     // rewrite header row with titles | ||||
|     utils.sheet_add_aoa(ws, [cols.map(c => c.title ?? c.id)], {origin: "A1"}); | ||||
|     // highlight-end | ||||
| 
 | ||||
|     // create workbook | ||||
|     const wb = utils.book_new(); | ||||
|     utils.book_append_sheet(wb, ws, "Export"); // replace with sheet name | ||||
|     // download file | ||||
|     writeFileXLSX(wb, "sheetjs-gdg.xlsx"); | ||||
|   }, []); | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     // highlight-next-line | ||||
|     <button onClick={exportXLSX}><b>Export XLSX!</b></button> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| 
 | ||||
| ## Demo | ||||
| 
 | ||||
| 1) Create a new project: | ||||
| 
 | ||||
| ```bash | ||||
| npm create vite@latest -- sheetjs-gdg --template react-ts | ||||
| cd sheetjs-gdg | ||||
| npm i | ||||
| ``` | ||||
| 
 | ||||
| Install SheetJS and Glide Data Grid required dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz | ||||
| npm i --save @glideapps/glide-data-grid lodash marked | ||||
| ``` | ||||
| 
 | ||||
| Start dev server: | ||||
| 
 | ||||
| ```bash | ||||
| npm run dev | ||||
| ``` | ||||
| 
 | ||||
| The terminal window will display a URL (typically `http://localhost:5173`). | ||||
| Open the URL with a web browser. | ||||
| 
 | ||||
| 2) Download [`App.tsx`](pathname:///gdg/App.tsx) and replace `src/App.tsx`: | ||||
| 
 | ||||
| ```bash | ||||
| curl -L -o src/App.tsx https://docs.sheetjs.com/gdg/App.tsx | ||||
| ``` | ||||
| 
 | ||||
| Refresh the browser window and a grid should be displayed: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 3) To test the export functionality, make some changes to the grid data. | ||||
| 
 | ||||
| Suppose you believe that President Grover Cleveland should be counted once. | ||||
| That would imply President Clinton should be index 41 and the indices of the | ||||
| other presidents should be decremented. By double-clicking on each cell in the | ||||
| Index column, a cell editor should appear. Decrement each index: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| Click on the "Export" button to create a file!  Open the file and verify. | ||||
| @ -217,307 +217,7 @@ function rdg_to_ws(rows: Row[]): WorkSheet { | ||||
| 
 | ||||
| ### Glide Data Grid | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 February 07 with the ViteJS+React+TypeScript | ||||
| starter (Vite `4.1.1`, React `18.2.0`) and `@glideapps/glide-data-grid@5.2.1`. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| #### GDG Demo | ||||
| 
 | ||||
| <details><summary><b>Complete Example</b> (click to show)</summary> | ||||
| 
 | ||||
| 1) Create a new project: | ||||
| 
 | ||||
| ```bash | ||||
| npm create vite@latest -- sheetjs-gdg --template react-ts | ||||
| cd sheetjs-gdg | ||||
| npm i | ||||
| ``` | ||||
| 
 | ||||
| Install SheetJS and Glide Data Grid required dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz | ||||
| npm i --save @glideapps/glide-data-grid lodash marked | ||||
| ``` | ||||
| 
 | ||||
| Start dev server: | ||||
| 
 | ||||
| ```bash | ||||
| npm run dev | ||||
| ``` | ||||
| 
 | ||||
| The terminal window will display a URL (typically `http://localhost:5173`). | ||||
| Open the URL with a web browser. | ||||
| 
 | ||||
| 2) Download [`App.tsx`](pathname:///gdg/App.tsx) and replace `src/App.tsx`: | ||||
| 
 | ||||
| ```bash | ||||
| curl -L -o src/App.tsx https://docs.sheetjs.com/gdg/App.tsx | ||||
| ``` | ||||
| 
 | ||||
| Refresh the browser window and a grid should be displayed: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 3) To test the export functionality, make some changes to the grid data. | ||||
| 
 | ||||
| Suppose you believe that President Grover Cleveland should be counted once. | ||||
| That would imply President Clinton should be index 41 and the indices of the | ||||
| other presidents should be decremented. By double-clicking on each cell in the | ||||
| Index column, a cell editor should appear. Decrement each index: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| Click on the "Export" button to create a file!  Open the file and verify. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| #### Backing Store | ||||
| 
 | ||||
| Under the hood, the `DataEditor` component is designed to call methods and | ||||
| request data to display in the grid. It is typical to store data *outside* of | ||||
| component state.  A `getCellContent` callback will pull data from the external | ||||
| backing store, while SheetJS operations will directly act on the store: | ||||
| 
 | ||||
| ```js | ||||
| // !! THESE OBJECTS ARE DEFINED OUTSIDE OF THE COMPONENT FUNCTION !! | ||||
| 
 | ||||
| // this will store the raw data objects | ||||
| let data: any[] = []; | ||||
| // this will store the header names | ||||
| let header: string[] = []; | ||||
| ``` | ||||
| 
 | ||||
| #### GDG Props | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This is a high-level overview. The official documentation should be consulted. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| _Columns_ | ||||
| 
 | ||||
| `DataEditor` expects column metadata to be passed through a `columns` prop. This | ||||
| should be managed in the component state: | ||||
| 
 | ||||
| ```js | ||||
| import { useState } from 'react'; | ||||
| import { DataEditor, GridColumn } from '@glideapps/glide-data-grid'; | ||||
| 
 | ||||
| function App() { | ||||
|   // highlight-next-line | ||||
|   const [cols, setCols] = useState<GridColumn[]>([]); // gdg column objects | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       columns={cols} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| 
 | ||||
| Each `GridColumn` object expects a `title` representing the display name and an | ||||
| `id` representing the key to index within the data object. | ||||
| 
 | ||||
| _Data_ | ||||
| 
 | ||||
| The `DataEditor` component expects a `getCellContent` callback for supplying | ||||
| data. The callback accepts column and row indices.  The column index should be | ||||
| used to find the header key: | ||||
| 
 | ||||
| ```js | ||||
| import { useCallback } from 'react'; | ||||
| import { DataEditor, GridCellKind, GridCell, Item } from '@glideapps/glide-data-grid'; | ||||
| 
 | ||||
| // ... | ||||
| 
 | ||||
| function App() { | ||||
|   // ... | ||||
|   // backing data store -> gdg | ||||
|   // highlight-start | ||||
|   const getContent = useCallback((cell: Item): GridCell => { | ||||
|     const [col, row] = cell; | ||||
|     return { | ||||
|       kind: GridCellKind.Text, | ||||
|       // header[col] is the name of the field | ||||
|       displayData: String(data[row]?.[header[col]]??""), | ||||
|       data: data[row]?.[header[col]], | ||||
|     }; | ||||
|   }, []); | ||||
|   // highlight-end | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       getCellContent={getContent} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| _Row Count_ | ||||
| 
 | ||||
| `DataEditor` also accepts a `rows` property indicating the number of rows. This | ||||
| is best managed in state: | ||||
| 
 | ||||
| ```js | ||||
| import { useState } from 'react'; | ||||
| import { DataEditor } from '@glideapps/glide-data-grid'; | ||||
| 
 | ||||
| function App() { | ||||
|   // highlight-next-line | ||||
|   const [rows, setRows] = useState<number>(0); // number of rows | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       rows={rows} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| 
 | ||||
| _Editing Data_ | ||||
| 
 | ||||
| The demo uses the `onCellEdited` callback to write back to the data store. | ||||
| 
 | ||||
| #### Parsing Data | ||||
| 
 | ||||
| _SheetJS to Data Store_ | ||||
| 
 | ||||
| The raw data objects are readily generated with `sheet_to_json`. The headers | ||||
| can be pulled by extracting the first row of the worksheet: | ||||
| 
 | ||||
| ```js | ||||
| import { utils, WorkBook } from 'xlsx'; | ||||
| 
 | ||||
| // ... | ||||
| 
 | ||||
| const update_backing_store = (wb: WorkBook) => { | ||||
|   // get first worksheet | ||||
|   const sheet = wb.Sheets[wb.SheetNames[0]]; | ||||
| 
 | ||||
|   // set data | ||||
|   // highlight-next-line | ||||
|   data = utils.sheet_to_json<any>(sheet); | ||||
| 
 | ||||
|   // create a range consisting of the first row | ||||
|   const range = utils.decode_range(sheet["!ref"]??"A1"); // original range | ||||
|   range.e.r = range.s.r; // set ending row to starting row (select first row) | ||||
| 
 | ||||
|   // pull headers | ||||
|   // highlight-next-line | ||||
|   header = utils.sheet_to_json<string[]>(sheet, {header: 1, range})[0]; | ||||
| }; | ||||
| 
 | ||||
| // ... | ||||
| ``` | ||||
| 
 | ||||
| _Data Store to GDG_ | ||||
| 
 | ||||
| Scheduling a refresh for the `DataEditor` involves updating the grid column | ||||
| metadata and row count through the standard state.  It also requires a special | ||||
| `updateCells` call to instruct the grid to mark the cached data as stale: | ||||
| 
 | ||||
| ```js | ||||
| import { useRef } from 'react' | ||||
| import { WorkBook } from 'xlsx' | ||||
| import { DataEditor, GridColumn, Item, DataEditorRef } from '@glideapps/glide-data-grid' | ||||
| 
 | ||||
| function App() { | ||||
|   const ref = useRef<DataEditorRef>(null); // gdg ref | ||||
|   // ... | ||||
|   const parse_wb = (wb: WorkBook) => { | ||||
|     update_backing_store(wb); | ||||
| 
 | ||||
|     // highlight-start | ||||
|     // update column metadata by pulling from external header keys | ||||
|     setCols(header.map(h => ({title: h, id: h} as GridColumn))); | ||||
| 
 | ||||
|     // update number of rows | ||||
|     setRows(data.length); | ||||
| 
 | ||||
|     if(data.length > 0) { | ||||
|       // create an array of the cells that must be updated | ||||
|       let cells = data.map( | ||||
|         (_,R) => Array.from({length:header.length}, (_,C) => ({cell: ([C,R] as Item)})) | ||||
|       ).flat(); | ||||
|       // initiate update using the `ref` attached to the DataEditor | ||||
|       ref.current?.updateCells(cells) | ||||
|     } | ||||
|     // highlight-end | ||||
|   }; | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     <DataEditor | ||||
|       // ... props | ||||
|       // highlight-next-line | ||||
|       ref={ref} | ||||
|     /> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| 
 | ||||
| #### Writing Data | ||||
| 
 | ||||
| `json_to_sheet` works directly on the `data` array: | ||||
| 
 | ||||
| ```js | ||||
| const ws = utils.json_to_sheet(data); // easy :) | ||||
| ``` | ||||
| 
 | ||||
| Since the editor can change the header titles, it is strongly recommended to | ||||
| pull column data from the state and rewrite the header row: | ||||
| 
 | ||||
| ```js | ||||
| import { utils, writeFileXLSX } from 'xlsx'; | ||||
| 
 | ||||
| function App() { | ||||
|   // ... | ||||
|   const exportXLSX = useCallback(() => { | ||||
|     // highlight-start | ||||
|     // generate worksheet using data with the order specified in the columns array | ||||
|     const ws = utils.json_to_sheet(data, {header: cols.map(c => c.id ?? c.title)}); | ||||
| 
 | ||||
|     // rewrite header row with titles | ||||
|     utils.sheet_add_aoa(ws, [cols.map(c => c.title ?? c.id)], {origin: "A1"}); | ||||
|     // highlight-end | ||||
| 
 | ||||
|     // create workbook | ||||
|     const wb = utils.book_new(); | ||||
|     utils.book_append_sheet(wb, ws, "Export"); // replace with sheet name | ||||
|     // download file | ||||
|     writeFileXLSX(wb, "sheetjs-gdg.xlsx"); | ||||
|   }, []); | ||||
|   // ... | ||||
|   return ( <> | ||||
|     // ... | ||||
|     // highlight-next-line | ||||
|     <button onClick={exportXLSX}><b>Export XLSX!</b></button> | ||||
|     // ... | ||||
|   </> ); | ||||
| } | ||||
| export default App; | ||||
| ``` | ||||
| **[The exposition has been moved to a separate page.](/docs/demos/grid/gdg)** | ||||
| 
 | ||||
| ### Material UI Data Grid | ||||
| 
 | ||||
|  | ||||
| @ -425,7 +425,7 @@ It should prompt to download `SheetJSNest.xlsx` | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was verified on 2022 August 24 using `fastify@4.5.2` | ||||
| This demo was verified on 2023 April 06 using `fastify@4.15.0` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -498,7 +498,7 @@ fastify.get('/', (req, reply) => { | ||||
| 
 | ||||
| 0) Save the following snippet to `SheetJSFastify.js`: | ||||
| 
 | ||||
| ```js | ||||
| ```js title="SheetJSFastify.js" | ||||
| /* load SheetJS Library */ | ||||
| const XLSX = require("xlsx"); | ||||
| /* load fastify and enable body parsing */ | ||||
|  | ||||
| @ -81,8 +81,8 @@ The following query pulls the `Name` and `Index` fields from each row: | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was tested on 2022 November 11 against `create-gatsby@3.0.0`. The | ||||
| generated project used `gatsby@5.0.0` and `react@18.2.0`. | ||||
| This demo was tested on 2023 April 06 against `create-gatsby@3.8.0`. The | ||||
| generated project used `gatsby@5.8.1` and `react@18.2.0`. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -121,9 +121,23 @@ npm i --save gatsby-transformer-excel gatsby-source-filesystem | ||||
| `} | ||||
| </code></pre> | ||||
| 
 | ||||
| 5) Edit `gatsby-config.js` and add the following lines to the `plugins` array: | ||||
| 5) Make a `src/data` directory, download <https://sheetjs.com/pres.xlsx>, and | ||||
| move the downloaded file into the new folder: | ||||
| 
 | ||||
| ```js | ||||
| ```bash | ||||
| mkdir -p src/data | ||||
| curl -L -o src/data/pres.xlsx https://sheetjs.com/pres.xlsx | ||||
| ``` | ||||
| 
 | ||||
| 6) Edit `gatsby-config.js` and add the following lines to the `plugins` array: | ||||
| 
 | ||||
| ```js title="gatsby-config.js" | ||||
| module.exports = { | ||||
|   siteMetadata: { | ||||
|     title: `sheetjs-gatsby`, | ||||
|     siteUrl: `https://www.yourdomain.tld`, | ||||
|   }, | ||||
| // highlight-start | ||||
|   plugins: [ | ||||
|     { | ||||
|       resolve: `gatsby-source-filesystem`, | ||||
| @ -134,18 +148,12 @@ npm i --save gatsby-transformer-excel gatsby-source-filesystem | ||||
|     }, | ||||
|     `gatsby-transformer-excel`, | ||||
|   ], | ||||
| // highlight-end | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Stop and restart the development server process (`npm run develop`). | ||||
| 
 | ||||
| 6) Make a `src/data` directory, download <https://sheetjs.com/pres.xlsx>, and | ||||
| move the downloaded file into the new folder: | ||||
| 
 | ||||
| ```bash | ||||
| mkdir -p src/data | ||||
| curl -L -o src/data/pres.xlsx https://sheetjs.com/pres.xlsx | ||||
| ``` | ||||
| 
 | ||||
| ### GraphiQL test | ||||
| 
 | ||||
| 7) Open the GraphiQL editor at `http://localhost:8000/___graphql`. | ||||
|  | ||||
| @ -11,7 +11,7 @@ and on-demand server rendering powered by spreadsheets. | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was tested on 2022 November 18 against Nuxt Content `v1.15.1`. | ||||
| This demo was tested on 2023 April 06 against Nuxt Content `v1.15.1`. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -87,7 +87,7 @@ neatly with nested `v-for`: | ||||
| :::note | ||||
| 
 | ||||
| The project was generated using `create-nuxt-app v4.0.0`.  The generated project | ||||
| used Nuxt `v2.15.8` and Nuxt Content `v1.15.1`. | ||||
| used Nuxt `v2.16.3` and Nuxt Content `v1.15.1`. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
|  | ||||
| @ -153,7 +153,7 @@ Deno.writeFileSync(out_file, new TextEncoder().encode(csv)); | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This was tested on 2023 February 11 using the GitHub UI. | ||||
| This was last tested on 2023 April 06 using the GitHub UI. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -240,7 +240,13 @@ jobs: | ||||
| 
 | ||||
| 6) Click the `☰` icon and click "Go to Repository" to return to the repo page. | ||||
| 
 | ||||
| 7) Click "Actions" to see the workflows. In the left column, click `flatsheet`. | ||||
| 7) Click "Settings" to see the repository settings. In the left column, click | ||||
|    "Actions" to expand the submenu and click "General". | ||||
| 
 | ||||
|    Scroll down to "Workflow permissions" and select "Read and write permissions" | ||||
|    if it is not selected.  Click "Save". | ||||
| 
 | ||||
| 8) Click "Actions" to see the workflows. In the left column, click `flatsheet`. | ||||
| 
 | ||||
|    This is the page for the action.  Every time the action is run, a new entry | ||||
|    will be added to the list. | ||||
| @ -249,12 +255,12 @@ jobs: | ||||
|    This will start a new run.  After about 30 seconds, a new row should show up | ||||
|    in the main area.  The icon should be a white `✓` in a green circle. | ||||
| 
 | ||||
| 8) Click "Code" to return to the main view.  It should have a file listing that | ||||
| 9) Click "Code" to return to the main view.  It should have a file listing that | ||||
|    includes `data.xlsx` (downloaded file) and `data.csv` (generated data) | ||||
| 
 | ||||
|    Now repeat step 7 to run the action a second time.  Click "Code" again. | ||||
| 
 | ||||
| 9) Go to the URL bar and change "github.com" to "flatgithub.com".  For example, | ||||
| 10) Go to the URL bar and change "github.com" to "flatgithub.com".  For example, | ||||
|    if the URL was originally `https://github.com/SheetJS/flat-sheet` , the new | ||||
|    URL should be `https://flatgithub.com/SheetJS/flat-sheet` . Press Enter. | ||||
| 
 | ||||
|  | ||||
| @ -35,7 +35,7 @@ run in the web browser, demos will include interactive examples. | ||||
| - [`canvas-datagrid`](/docs/demos/grid/cdg) | ||||
| - [`x-spreadsheet`](/docs/demos/grid/xs) | ||||
| - [`react-data-grid`](/docs/demos/grid#react-data-grid) | ||||
| - [`glide-data-grid`](/docs/demos/grid#glide-data-grid) | ||||
| - [`glide-data-grid`](/docs/demos/grid/gdg) | ||||
| - [`vue3-table-lite`](/docs/demos/grid#vue3-table-lite) | ||||
| - [`angular-ui-grid`](/docs/demos/grid#angular-ui-grid) | ||||
| - [`material ui`](/docs/demos/grid#material-ui-table) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user