| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | # React
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | into web pages with script tags: | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```html | 
					
						
							|  |  |  | <script src="xlsx.full.min.js"></script> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The library can also be imported directly from JSX code with: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2022-03-11 13:38:20 +00:00
										 |  |  | import { read, utils, writeFileXLSX } from 'xlsx'; | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | This demo shows a simple React component transpiled in the browser using Babel | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | standalone library.  Since there is no standard React table model, this demo | 
					
						
							|  |  |  | settles on the array of arrays approach. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 13:38:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | Other scripts in this demo show: | 
					
						
							|  |  |  | - server-rendered React component (with `next.js`) | 
					
						
							|  |  |  | - `react-native` deployment for iOS and android | 
					
						
							| 
									
										
										
										
											2022-03-11 13:38:20 +00:00
										 |  |  | - [`react-data-grid` reading, modifying, and writing files](modify/) | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-30 22:28:10 +00:00
										 |  |  | ## How to run
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-11 23:20:51 +00:00
										 |  |  | Run `make react` to run the browser demo for React, or run `make next` to run | 
					
						
							|  |  |  | the server-rendered demo using `next.js`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | ## Internal State
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The simplest state representation is an array of arrays.  To avoid having the | 
					
						
							|  |  |  | table component depend on the library, the column labels are precomputed.  The | 
					
						
							|  |  |  | state in this demo is shaped like the following object: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  |   cols: [{ name: "A", key: 0 }, { name: "B", key: 1 }, { name: "C", key: 2 }], | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  |   data: [ | 
					
						
							|  |  |  |     [ "id",    "name", "value" ], | 
					
						
							| 
									
										
										
										
											2017-11-15 12:35:16 +00:00
										 |  |  |     [    1, "sheetjs",    7262 ], | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  |     [    2, "js-xlsx",    6969 ] | 
					
						
							|  |  |  |   ] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | `sheet_to_json` and `aoa_to_sheet` utility functions can convert between arrays | 
					
						
							|  |  |  | of arrays and worksheets: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* convert from workbook to array of arrays */ | 
					
						
							|  |  |  | var first_worksheet = workbook.Sheets[workbook.SheetNames[0]]; | 
					
						
							|  |  |  | var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* convert from array of arrays to workbook */ | 
					
						
							|  |  |  | var worksheet = XLSX.utils.aoa_to_sheet(data); | 
					
						
							|  |  |  | var new_workbook = XLSX.utils.book_new(); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(new_workbook, worksheet, "SheetJS"); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The column objects can be generated with the `encode_col` utility function: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function make_cols(refstr/*:string*/) { | 
					
						
							|  |  |  |   var o = []; | 
					
						
							|  |  |  |   var range = XLSX.utils.decode_range(refstr); | 
					
						
							|  |  |  |   for(var i = 0; i <= range.e.c; ++i) { | 
					
						
							|  |  |  |     o.push({name: XLSX.utils.encode_col(i), key:i}); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return o; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## React Native
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <img src="screen.png" width="400px"/> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Reproducing the full project is straightforward: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | $ make native     # build the project | 
					
						
							|  |  |  | $ make ios        # build and run the iOS demo | 
					
						
							|  |  |  | $ make android    # build and run the android demo | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | The app will prompt before reading and after writing data.  The printed location | 
					
						
							|  |  |  | depends on the environment: | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | - android: path in the device filesystem | 
					
						
							|  |  |  | - iOS simulator: local path to file | 
					
						
							|  |  |  | - iOS device: a path accessible from iTunes App Documents view | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | Components used in the demo: | 
					
						
							|  |  |  | - [`react-native-table-component`](https://npm.im/react-native-table-component) | 
					
						
							|  |  |  | - [`react-native-file-access`](https://npm.im/react-native-file-access) | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | React Native does not provide a native component for reading and writing files. | 
					
						
							| 
									
										
										
										
											2022-04-12 11:59:15 +00:00
										 |  |  | The sample script `react-native.js` uses `react-native-file-access` and has | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | notes for integrations with `react-native-fetch-blob` and `react-native-fs`. | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-13 02:51:54 +00:00
										 |  |  | Note: for real app deployments, the `UIFileSharingEnabled` flag must be manually | 
					
						
							|  |  |  | set in the iOS project `Info.plist` file. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 11:59:15 +00:00
										 |  |  | ## Server-Rendered React Components with Next.js
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 11:59:15 +00:00
										 |  |  | The demo reads from `public/sheetjs.xlsx`.  HTML output is generated using | 
					
						
							|  |  |  | `XLSX.utils.sheet_to_html` and inserted with `dangerouslySetInnerHTML`: | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 11:59:15 +00:00
										 |  |  | ```jsx | 
					
						
							|  |  |  | export default function Index({html, type}) { return ( | 
					
						
							|  |  |  |   // ... | 
					
						
							|  |  |  |   <div dangerouslySetInnerHTML={{ __html: html }} /> | 
					
						
							|  |  |  |   // ... | 
					
						
							|  |  |  | ); } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Next currently offers 3 general strategies for server-side data fetching: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### "Server-Side Rendering" using `getServerSideProps`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `/getServerSideProps` reads the file on each request.  The first worksheet is | 
					
						
							|  |  |  | converted to HTML: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | export async function getServerSideProps() { | 
					
						
							|  |  |  |   const wb = XLSX.readFile(path); | 
					
						
							|  |  |  |   return { props: { | 
					
						
							|  |  |  |     html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]) | 
					
						
							|  |  |  |   }}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### "Static Site Generation" using `getStaticProps`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `/getServerSideProps` reads the file at build time.  The first worksheet is | 
					
						
							|  |  |  | converted to HTML: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | export async function getStaticProps() { | 
					
						
							|  |  |  |   const wb = XLSX.readFile(path); | 
					
						
							|  |  |  |   return { props: { | 
					
						
							|  |  |  |     html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]) | 
					
						
							|  |  |  |   }}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### "Static Site Generation with Dynamic Routes" using `getStaticPaths`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `/getStaticPaths` reads the file at build time and generates a list of sheets. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `/sheets/[id]` uses `getStaticPaths` to generate a path per sheet index: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | export async function getStaticPaths() { | 
					
						
							|  |  |  |   const wb = XLSX.readFile(path); | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     paths: wb.SheetNames.map((name, idx) => ({ params: { id: idx.toString()  } })), | 
					
						
							|  |  |  |     fallback: false | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It also uses `getStaticProps` for the actual HTML generation: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | export async function getStaticProps(ctx) { | 
					
						
							|  |  |  |   const wb = XLSX.readFile(path); | 
					
						
							|  |  |  |   return { props: { | 
					
						
							|  |  |  |     html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[ctx.params.id]]), | 
					
						
							|  |  |  |   }}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2020-06-11 23:20:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Additional Notes
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-29 08:07:23 +00:00
										 |  |  | Some additional notes can be found in [`NOTES.md`](NOTES.md). | 
					
						
							| 
									
										
										
										
											2022-04-12 11:59:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | [](https://github.com/SheetJS/js-xlsx) |