diff --git a/README.md b/README.md index bbc5fb8..6d77d98 100644 --- a/README.md +++ b/README.md @@ -577,6 +577,7 @@ The [`demos` directory](demos/) includes sample projects for: - [`Headless Browsers`](demos/headless/) - [`canvas-datagrid`](demos/datagrid/) - [`x-spreadsheet`](demos/xspreadsheet/) +- [`react-data-grid`](demos/react/modify/) - [`Swift JSC and other engines`](demos/altjs/) - [`"serverless" functions`](demos/function/) - [`internet explorer`](demos/oldie/) diff --git a/demos/README.md b/demos/README.md index 78f2963..eca6fd0 100644 --- a/demos/README.md +++ b/demos/README.md @@ -49,6 +49,7 @@ can be installed with Bash on Windows or with `cygwin`. - [`Headless Browsers`](headless/) - [`canvas-datagrid`](datagrid/) - [`x-spreadsheet`](xspreadsheet/) +- [`react-data-grid`](react/modify/) - [`Swift JSC and other engines`](altjs/) - [`"serverless" functions`](function/) - [`internet explorer`](oldie/) diff --git a/demos/react/README.md b/demos/react/README.md index 5320a8b..df18f2f 100644 --- a/demos/react/README.md +++ b/demos/react/README.md @@ -10,16 +10,18 @@ into web pages with script tags: The library can also be imported directly from JSX code with: ```js -import XLSX from 'xlsx'; +import { read, utils, writeFileXLSX } from 'xlsx'; ``` This demo shows a simple React component transpiled in the browser using Babel standalone library. Since there is no standard React table model, this demo settles on the array of arrays approach. + Other scripts in this demo show: - server-rendered React component (with `next.js`) - `react-native` deployment for iOS and android +- [`react-data-grid` reading, modifying, and writing files](modify/) ## How to run diff --git a/demos/react/modify/.gitignore b/demos/react/modify/.gitignore new file mode 100644 index 0000000..4d29575 --- /dev/null +++ b/demos/react/modify/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/demos/react/modify/README.md b/demos/react/modify/README.md new file mode 100644 index 0000000..97180e0 --- /dev/null +++ b/demos/react/modify/README.md @@ -0,0 +1,10 @@ +# react-modify + +This demo shows import and export with the `react-data-grid` table component. + +In the project directory, you can run: + +```bash +$ npm install +$ npm start +``` diff --git a/demos/react/modify/package.json b/demos/react/modify/package.json new file mode 100644 index 0000000..c25d145 --- /dev/null +++ b/demos/react/modify/package.json @@ -0,0 +1,36 @@ +{ + "name": "react-modify-demo", + "dependencies": { + "@types/react": "^17.0.0", + "@types/react-dom": "^17.0.0", + "react": "^17.0.2", + "react-data-grid": "^7.0.0-beta.11", + "react-dom": "^17.0.2", + "react-scripts": "4.0.3", + "typescript": "^4.1.2", + "xlsx": "^0.18.3" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/demos/react/modify/src/components/App.tsx b/demos/react/modify/src/components/App.tsx new file mode 100644 index 0000000..7e979d5 --- /dev/null +++ b/demos/react/modify/src/components/App.tsx @@ -0,0 +1,107 @@ +import React, { useState, ChangeEvent } from "react"; +import DataGrid, { TextEditor } from "react-data-grid"; +import { read, utils, WorkSheet, writeFile } from "xlsx"; + +import "../styles/App.css"; + +type Row = any[]; /*{ + [index: string]: string | number; +};*/ + +type Column = { + key: string; + name: string; + editor: typeof TextEditor; +}; + +type DataSet = { + [index: string]: WorkSheet; +}; + +function getRowsCols( + data: DataSet, + sheetName: string +): { + rows: Row[]; + columns: Column[]; +} { + const rows: Row[] = utils.sheet_to_json(data[sheetName], {header:1}); + let columns: Column[] = []; + + for (let row of rows) { + const keys: string[] = Object.keys(row); + + if (keys.length > columns.length) { + columns = keys.map((key) => { + return { key, name: utils.encode_col(+key), editor: TextEditor }; + }); + } + } + + return { rows, columns }; +} + +export default function App() { + const [rows, setRows] = useState([]); + const [columns, setColumns] = useState([]); + const [workBook, setWorkBook] = useState({} as DataSet); + const [sheets, setSheets] = useState([]); + const [current, setCurrent] = useState(""); + + const exportTypes = ["xlsx", "xlsb", "csv", "html"]; + + function selectSheet(name: string, reset = true) { + if(reset) workBook[current] = utils.json_to_sheet(rows, { + header: columns.map((col: Column) => col.key), + skipHeader: true + }); + + const { rows: new_rows, columns: new_columns } = getRowsCols(workBook, name); + + setRows(new_rows); + setColumns(new_columns); + setCurrent(name); + } + + async function handleFile(ev: ChangeEvent): Promise { + const file = await ev.target.files?.[0]?.arrayBuffer(); + const data = read(file); + + setWorkBook(data.Sheets); + setSheets(data.SheetNames); + } + + function saveFile(ext: string): void { + const wb = utils.book_new(); + + sheets.forEach((n) => { + utils.book_append_sheet(wb, workBook[n], n); + }); + + writeFile(wb, "sheet." + ext); + } + + return ( + <> + +
+ {sheets.map((sheet) => ( + + ))} +
+
+ Current Sheet: {current} +
+ +
+ {exportTypes.map((ext) => ( + + ))} +
+ + ); +} diff --git a/demos/react/modify/src/index.tsx b/demos/react/modify/src/index.tsx new file mode 100644 index 0000000..270ed1a --- /dev/null +++ b/demos/react/modify/src/index.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './components/App'; + +import './styles/index.css'; + +ReactDOM.render( + + + , + document.getElementById('root') +); diff --git a/demos/react/modify/src/react-app-env.d.ts b/demos/react/modify/src/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/demos/react/modify/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/demos/react/modify/src/styles/App.css b/demos/react/modify/src/styles/App.css new file mode 100644 index 0000000..28b9df9 --- /dev/null +++ b/demos/react/modify/src/styles/App.css @@ -0,0 +1,14 @@ +input { + margin: 0.5rem; +} + +.flex-cont { + display: flex; + margin: 0.5rem; + justify-content: center; +} + +.flex-cont button { + margin: 0.3rem; + padding: 0.2rem; +} diff --git a/demos/react/modify/src/styles/index.css b/demos/react/modify/src/styles/index.css new file mode 100644 index 0000000..1532074 --- /dev/null +++ b/demos/react/modify/src/styles/index.css @@ -0,0 +1,8 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/demos/react/modify/tsconfig.json b/demos/react/modify/tsconfig.json new file mode 100644 index 0000000..5136b52 --- /dev/null +++ b/demos/react/modify/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": [ + "src" + ] +} diff --git a/docbits/16_demos.md b/docbits/16_demos.md index b06eb08..b9b5629 100644 --- a/docbits/16_demos.md +++ b/docbits/16_demos.md @@ -34,6 +34,7 @@ The [`demos` directory](demos/) includes sample projects for: - [`Headless Browsers`](demos/headless/) - [`canvas-datagrid`](demos/datagrid/) - [`x-spreadsheet`](demos/xspreadsheet/) +- [`react-data-grid`](demos/react/modify/) - [`Swift JSC and other engines`](demos/altjs/) - [`"serverless" functions`](demos/function/) - [`internet explorer`](demos/oldie/)