forked from sheetjs/docs.sheetjs.com
		
	n_xt
This commit is contained in:
		
							parent
							
								
									481b147e97
								
							
						
					
					
						commit
						4c191dcc59
					
				| @ -1,5 +1,5 @@ | ||||
| --- | ||||
| title: ReactJS | ||||
| title: Sheets in ReactJS Sites | ||||
| sidebar_label: ReactJS | ||||
| description: Build interactive websites with ReactJS. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web. | ||||
| pagination_prev: demos/index | ||||
| @ -7,8 +7,6 @@ pagination_next: demos/grid/index | ||||
| sidebar_position: 1 | ||||
| --- | ||||
| 
 | ||||
| # Sheets in ReactJS Sites | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| @ -81,7 +79,7 @@ each row, using the values in the first rows as keys: | ||||
| 
 | ||||
| </td></tr></tbody></table> | ||||
| 
 | ||||
| The ReactJS `useState` hook can configure the state: | ||||
| The ReactJS `useState`[^1] hook can configure the state: | ||||
| 
 | ||||
| <Tabs groupId="lang"> | ||||
|   <TabItem name="JS" value="JavaScript"> | ||||
| @ -131,9 +129,9 @@ When the file header is not known in advance, `any` should be used. | ||||
| 
 | ||||
| #### Updating State | ||||
| 
 | ||||
| The [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/utilities/array#array-output) | ||||
| The SheetJS [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/utilities/array#array-output) | ||||
| functions simplify state updates. They are best used in the function bodies of | ||||
| `useEffect` and `useCallback` hooks. | ||||
| `useEffect`[^2] and `useCallback`[^3] hooks. | ||||
| 
 | ||||
| A `useEffect` hook can download and update state when a person loads the site: | ||||
| 
 | ||||
| @ -225,7 +223,7 @@ in the example JSX code: | ||||
| 
 | ||||
| The [`writeFile`](/docs/api/write-options) and [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input) | ||||
| functions simplify exporting data. They are best used in the function bodies of | ||||
| `useCallback` hooks attached to button or other elements. | ||||
| `useCallback`[^4] hooks attached to button or other elements. | ||||
| 
 | ||||
| A callback can generate a local file when a user clicks a button: | ||||
| 
 | ||||
| @ -347,12 +345,13 @@ The main disadvantage of the Array of Objects approach is the specific nature | ||||
| of the columns.  For more general use, passing around an Array of Arrays works. | ||||
| However, this does not handle merge cells well! | ||||
| 
 | ||||
| The `sheet_to_html` function generates HTML that is aware of merges and other | ||||
| worksheet features.  ReactJS `dangerouslySetInnerHTML` attribute allows code to | ||||
| set the `innerHTML` attribute, effectively inserting the code into the page. | ||||
| The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function | ||||
| generates HTML that is aware of merges and other worksheet features.  ReactJS | ||||
| `dangerouslySetInnerHTML`[^5] prop allows code to 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 | ||||
| export, the first `TABLE` child element can be parsed with [`table_to_book`](/docs/api/utilities/html#html-table-input) to | ||||
| generate a workbook object. | ||||
| 
 | ||||
| ```jsx title="src/SheetJSReactHTML.js" | ||||
| @ -438,8 +437,8 @@ generate column headings and for indexing into the row objects. | ||||
| The safest approach is to use an array of arrays for state and to generate | ||||
| column objects that map to A1-Style column headers. | ||||
| 
 | ||||
| The [React Data Grid demo](/docs/demos/grid#rows-and-columns-state) uses this approach | ||||
| with the following column and row structure: | ||||
| The [React Data Grid demo](/docs/demos/grid/rdg#rows-and-columns-state) uses | ||||
| this approach with the following column and row structure: | ||||
| 
 | ||||
| ```js | ||||
| /* rows are generated with a simple array of arrays */ | ||||
| @ -465,4 +464,10 @@ const columns = Array.from({ length: range.e.c + 1 }, (_, i) => ({ | ||||
| with legacy deployments that do not use a bundler. | ||||
| 
 | ||||
| [The legacy demo](pathname:///react/index.html) shows a simple ReactJS component | ||||
| transpiled in the browser using Babel standalone library. | ||||
| transpiled in the browser using Babel standalone library. | ||||
| 
 | ||||
| [^1]: See [`useState`](https://react.dev/reference/react/useState) in the ReactJS documentation. | ||||
| [^2]: See [`useEffect`](https://react.dev/reference/react/useEffect) in the ReactJS documentation. | ||||
| [^3]: See [`useCallback`](https://react.dev/reference/react/useCallback) in the ReactJS documentation. | ||||
| [^4]: See [`useCallback`](https://react.dev/reference/react/useCallback) in the ReactJS documentation. | ||||
| [^5]: [`dangerouslySetInnerHTML`](https://react.dev/reference/react-dom/components/common#common-props) is a ReactJS prop supported for all built-in components. | ||||
| @ -1,25 +1,36 @@ | ||||
| --- | ||||
| title: VueJS | ||||
| title: Sheets in VueJS Sites | ||||
| sidebar_label: VueJS | ||||
| description: Build interactive websites with VueJS. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web. | ||||
| pagination_prev: demos/index | ||||
| pagination_next: demos/grid/index | ||||
| sidebar_position: 2 | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| VueJS is a JS library for building user interfaces. | ||||
| [VueJS](https://vuejs.org/) is a JavaScript library for building user interfaces. | ||||
| 
 | ||||
| This demo covers common VueJS data flow ideas and strategies.  Single-File | ||||
| Components (SFC) and VueJS familiarity is assumed. | ||||
| [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing | ||||
| data from spreadsheets. | ||||
| 
 | ||||
| Other demos cover general VueJS deployments, including: | ||||
| This demo uses VueJS and SheetJS to process and generate spreadsheets. We'll | ||||
| explore how to load SheetJS in a VueJS SFC (single-file component) and compare | ||||
| common state models and data flow strategies. | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| This demo focuses on VueJS concepts. Other demos cover general deployments: | ||||
| 
 | ||||
| - [Static Site Generation powered by NuxtJS](/docs/demos/static/nuxtjs) | ||||
| - [iOS and Android applications powered by Quasar](/docs/demos/mobile/quasar) | ||||
| - [Desktop application powered by Tauri](/docs/demos/desktop/tauri) | ||||
| - [`vue3-table-lite` UI component](/docs/demos/grid/vtl) | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Installation | ||||
| 
 | ||||
| @ -41,8 +52,9 @@ depends on the application. | ||||
| ### Array of Objects | ||||
| 
 | ||||
| Typically, some users will create a spreadsheet with source data that should be | ||||
| loaded into the site.  This sheet will have known columns.  For example, our | ||||
| [presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" / "Index" columns: | ||||
| loaded into the site.  This sheet will have known columns. | ||||
| 
 | ||||
| For example, our [presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" and "Index" columns: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| @ -266,7 +278,7 @@ The pages are not minified and "View Source" should be used to inspect. | ||||
| 
 | ||||
| There is a shared component [`SheetJS-vue.js`](pathname:///vue/SheetJS-vue.js) | ||||
| 
 | ||||
| :::caution | ||||
| :::caution pass | ||||
| 
 | ||||
| The entire demo is designed to run in Internet Explorer and does not reflect | ||||
| modern design patterns. | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| --- | ||||
| title: NextJS | ||||
| title: Sheets in ReactJS Sites with NextJS | ||||
| sidebar_label: NextJS | ||||
| description: Make static websites from spreadsheets using NextJS. Seamlessly integrate data into the data layer using SheetJS. Create content without leaving the comfort of Excel. | ||||
| pagination_prev: demos/net/index | ||||
| pagination_next: demos/mobile/index | ||||
| --- | ||||
| @ -9,23 +11,13 @@ import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| NextJS is a server-side framework for building static and dynamic sites. For | ||||
| pure static sites, [Webpack loaders](/docs/demos/static/webpack) can preprocess | ||||
| files and NextJS can build static pages from spreadsheets. For dynamic sites, | ||||
| NextJS lifecycle methods can read files on the server side. | ||||
| [NextJS](https://nextjs.org/) is a server-side framework for building static | ||||
| and dynamic sites using the ReactJS framework. | ||||
| 
 | ||||
| The [NodeJS module](/docs/getting-started/installation/nodejs) can be imported | ||||
| from pages or loaded in Webpack loaders. | ||||
| [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing | ||||
| data from spreadsheets. | ||||
| 
 | ||||
| :::warning | ||||
| 
 | ||||
| [`import`](/docs/getting-started/installation/nodejs#esm-import) does not load | ||||
| NodeJS native modules. The Installation section includes a note on dynamic | ||||
| import of `fs` within lifecycle methods. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| NextJS best practices have evolved over time, but there are three key parts: | ||||
| This discussion covers three key SheetJS + NextJS operations: | ||||
| 
 | ||||
| 1) [Loading Data](#loading-data): NextJS can read files in lifecycle methods OR | ||||
| custom Webpack loaders can create asset modules. | ||||
| @ -35,6 +27,26 @@ static pages (`getStaticProps`) as well as dynamic pages (`getServerSideProps`). | ||||
| 
 | ||||
| 3) [Data Presentation](#data-presentation): Pages use React and JSX. | ||||
| 
 | ||||
| The ["Demo"](#demo) uses NextJS and SheetJS to pull data from a spreadsheet. | ||||
| We'll explore how to create asset modules that process spreadsheet data at build | ||||
| time and how to read files on the server in NextJS lifecycle methods. | ||||
| 
 | ||||
| :::warning Telemetry | ||||
| 
 | ||||
| NextJS collects telemetry by default. The `telemetry` subcommand can disable it: | ||||
| 
 | ||||
| ```js | ||||
| npx next@13.4.19 telemetry disable | ||||
| ``` | ||||
| 
 | ||||
| The setting can be verified by running | ||||
| 
 | ||||
| ```js | ||||
| npx next@13.4.19 telemetry status | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::caution Next 13+ and SWC | ||||
| 
 | ||||
| Next 13 switched to the SWC minifier. There are known issues with the minifier. | ||||
| @ -49,31 +61,17 @@ module.exports = { | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::warning Telemetry | ||||
| 
 | ||||
| NextJS collects telemetry by default. The `telemetry` subcommand can disable it: | ||||
| 
 | ||||
| ```js | ||||
| npx next@13.4.12 telemetry disable | ||||
| ``` | ||||
| 
 | ||||
| The setting can be verified by running | ||||
| 
 | ||||
| ```js | ||||
| npx next@13.4.12 telemetry status | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| The following deployments were tested: | ||||
| 
 | ||||
| | NextJS  | NodeJS    | Date       | | ||||
| |:--------|:----------|:-----------| | ||||
| | 11.1.4  | `16.20.1` | 2023-07-23 | | ||||
| | 12.3.4  | `18.17.0` | 2023-07-23 | | ||||
| | 13.4.12 | `18.17.0` | 2023-07-23 | | ||||
| | NextJS    | NodeJS    | Date       | | ||||
| |:----------|:----------|:-----------| | ||||
| | ` 9.5.5`  | `16.20.2` | 2023-08-20 | | ||||
| | `10.2.3`  | `16.20.2` | 2023-08-20 | | ||||
| | `11.1.4`  | `16.20.2` | 2023-08-20 | | ||||
| | `12.3.4`  | `18.17.1` | 2023-08-20 | | ||||
| | `13.4.19` | `18.17.1` | 2023-08-20 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -89,13 +87,16 @@ but does not support live reloading. | ||||
| 
 | ||||
| ### Asset Module | ||||
| 
 | ||||
| :::caution | ||||
| :::caution pass | ||||
| 
 | ||||
| When the demo was last tested, Turbopack did not support true raw loaders. For | ||||
| development use, the normal `npx next dev` should be used. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be | ||||
| imported in Webpack asset modules[^1]. | ||||
| 
 | ||||
| The following diagram depicts the workbook waltz: | ||||
| 
 | ||||
| ```mermaid | ||||
| @ -157,7 +158,13 @@ Module alias directories can be defined in `jsconfig.json` or `tsconfig.json`: | ||||
| ``` | ||||
| 
 | ||||
| Pages can import the files directly. It is strongly recommended to store files | ||||
| in a `data` folder. This example uses `getStaticProps` to parse `sheetjs.xlsx`: | ||||
| in a `data` folder. | ||||
| 
 | ||||
| In this example, the import statement pulls the `sheetjs.xlsx` file as a Base64 | ||||
| string. The SheetJS `read` method[^2] parses the string and returns a workbook | ||||
| object[^3]. The `sheet_to_json`[^4] utility function generates an array of | ||||
| objects based on the data. As long as the `base64` variable is only used in | ||||
| `getStaticProps`, the library and file will be processed at build time. | ||||
| 
 | ||||
| ```jsx title="index.js" | ||||
| import { read, utils } from 'xlsx'; | ||||
| @ -177,8 +184,19 @@ export async function getStaticProps() { | ||||
| 
 | ||||
| ### Raw Operations | ||||
| 
 | ||||
| Files can be read using `readFile` in lifecycle methods. The `cwd` method from | ||||
| the `process` module will point to the root of the project. | ||||
| The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be | ||||
| imported from page scripts. | ||||
| 
 | ||||
| :::warning pass | ||||
| 
 | ||||
| [`import`](/docs/getting-started/installation/nodejs#esm-import) does not load | ||||
| NodeJS native modules. The Installation section includes a note on dynamic | ||||
| import of `fs` within lifecycle methods. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Files can be read using the SheetJS `readFile`[^5] method in lifecycle methods. | ||||
| The `cwd` method in the `process` module will point to the root of the project. | ||||
| 
 | ||||
| The following diagram depicts the workbook waltz: | ||||
| 
 | ||||
| @ -195,7 +213,8 @@ flowchart LR | ||||
|   aoo --> |page\nIndex method| html | ||||
| ``` | ||||
| 
 | ||||
| This example reads the file `sheetjs.xlsx` in the `data` folder in the project: | ||||
| This example reads the file `sheetjs.xlsx` in the `data` folder in the project | ||||
| and uses `sheet_to_json`[^6] to generate data rows. | ||||
| 
 | ||||
| ```js | ||||
| import { readFile, utils, set_fs } from 'xlsx'; | ||||
| @ -229,9 +248,9 @@ dynamic import must happen within a lifecycle function. | ||||
| 
 | ||||
| NextJS currently provides 3 strategies: | ||||
| 
 | ||||
| - "Static Site Generation" using `getStaticProps` | ||||
| - "SSG with Dynamic Routes" using `getStaticPaths` | ||||
| - "Server-Side Rendering" using `getServerSideProps` | ||||
| - "Static Site Generation" using `getStaticProps`[^7] | ||||
| - "SSG with Dynamic Routes" using `getStaticPaths`[^8] | ||||
| - "Server-Side Rendering" using `getServerSideProps`[^9] | ||||
| 
 | ||||
| ### Static Site Generation | ||||
| 
 | ||||
| @ -323,9 +342,9 @@ export async function getStaticPaths() { | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| :::note | ||||
| :::note pass | ||||
| 
 | ||||
| For a pure static site, `fallback` must be set to `false`! | ||||
| For a pure static site, `fallback` must be set to `false`![^10] | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -413,7 +432,6 @@ export async function getServerSideProps() { | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="raw" label="Raw Operations"> | ||||
| 
 | ||||
| @ -439,12 +457,12 @@ export async function getServerSideProps() { | ||||
| 
 | ||||
| ## Data Presentation | ||||
| 
 | ||||
| [The React demo](/docs/demos/frontend/react) compares common approaches. | ||||
| [The ReactJS demo](/docs/demos/frontend/react) compares common approaches. | ||||
| 
 | ||||
| ### HTML | ||||
| 
 | ||||
| HTML output can be generated using `XLSX.utils.sheet_to_html` and inserted into | ||||
| the document using the `dangerouslySetInnerHTML` attribute: | ||||
| HTML output can be generated using the SheetJS `sheet_to_html`[^11] method and | ||||
| inserted into the document using the `dangerouslySetInnerHTML`[^12] attribute: | ||||
| 
 | ||||
| ```mermaid | ||||
| flowchart LR | ||||
| @ -465,8 +483,8 @@ export default function Index({html, type}) { return ( | ||||
| 
 | ||||
| ### Arrays of Objects | ||||
| 
 | ||||
| Arrays of objects can be generated using `XLSX.utils.sheet_to_json` and inserted | ||||
| into the document using standard JSX: | ||||
| Arrays of objects can be generated using the SheetJS `sheet_to_json`[^13] method | ||||
| and inserted into the document using standard JSX[^14]: | ||||
| 
 | ||||
| ```mermaid | ||||
| flowchart LR | ||||
| @ -494,7 +512,7 @@ export default function Index({aoo, type}) { return ( | ||||
| 
 | ||||
| ## Demo | ||||
| 
 | ||||
| :::note | ||||
| :::note pass | ||||
| 
 | ||||
| This demo showcases the following SheetJS + NextJS flows: | ||||
| 
 | ||||
| @ -504,23 +522,36 @@ This demo showcases the following SheetJS + NextJS flows: | ||||
| | `/sheets/[id]`        | asset module | `getStaticPaths`     | `sheet_to_html` | | ||||
| | `/getServerSideProps` | lifecycle    | `getServerSideProps` | `sheet_to_html` | | ||||
| 
 | ||||
| The commands in this demo use `next@13.4.12`. Other versions were tested by | ||||
| The commands in this demo use `next@13.4.19`. Other versions were tested by | ||||
| replacing the version number in the relevant commands. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| Older versions of NextJS will refuse to run in newer versions of NodeJS. The | ||||
| error message points to an issue with OpenSSL: | ||||
| 
 | ||||
| ``` | ||||
| Error: error:0308010C:digital envelope routines::unsupported | ||||
| ``` | ||||
| 
 | ||||
| When upgrading NextJS is not an option, NodeJS should be downgraded to v16. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Initial Setup | ||||
| 
 | ||||
| 0) Disable NextJS telemetry: | ||||
| 
 | ||||
| ```js | ||||
| npx next@13.4.12 telemetry disable | ||||
| npx next@13.4.19 telemetry disable | ||||
| ``` | ||||
| 
 | ||||
| Confirm it is disabled by running | ||||
| 
 | ||||
| ```js | ||||
| npx next@13.4.12 telemetry status | ||||
| npx next@13.4.19 telemetry status | ||||
| ``` | ||||
| 
 | ||||
| 1) Set up folder structure.  At the end, a `pages` folder with a `sheets` | ||||
| @ -542,7 +573,7 @@ curl -LO https://docs.sheetjs.com/next/sheetjs.xlsx | ||||
| 3) Install dependencies: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz next@13.4.12`} | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz next@13.4.19`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 4) Download NextJS config scripts and place in the root folder: | ||||
| @ -600,7 +631,7 @@ cd ../.. | ||||
| 6) Test the deployment: | ||||
| 
 | ||||
| ```bash | ||||
| npx next@13.4.12 | ||||
| npx next@13.4.19 | ||||
| ``` | ||||
| 
 | ||||
| Open a web browser and access: | ||||
| @ -626,7 +657,7 @@ After saving the file, the website should refresh with the new row. | ||||
| 8) Stop the server and run a production build: | ||||
| 
 | ||||
| ```bash | ||||
| npx next@13.4.12 build | ||||
| npx next@13.4.19 build | ||||
| ``` | ||||
| 
 | ||||
| The final output will show a list of the routes and types: | ||||
| @ -651,7 +682,7 @@ worksheets in the file.  `/getServerSideProps` is server-rendered. | ||||
| 9) Try to build a static site: | ||||
| 
 | ||||
| ```bash | ||||
| npx next@13.4.12 export | ||||
| npx next@13.4.19 export | ||||
| ``` | ||||
| 
 | ||||
| :::note The static export will fail! | ||||
| @ -667,7 +698,7 @@ is still server-rendered. | ||||
| 
 | ||||
| ```bash | ||||
| rm -f pages/getServerSideProps.js | ||||
| npx next@13.4.12 build | ||||
| npx next@13.4.19 build | ||||
| ``` | ||||
| 
 | ||||
| Inspecting the output, there should be no lines with the `λ` symbol: | ||||
| @ -687,7 +718,7 @@ Route (pages)                              Size     First Load JS | ||||
| 11) Generate the static site: | ||||
| 
 | ||||
| ```bash | ||||
| npx next@13.4.12 export | ||||
| npx next@13.4.19 export | ||||
| ``` | ||||
| 
 | ||||
| The static site will be written to the `out` subfolder | ||||
| @ -701,3 +732,18 @@ npx http-server out | ||||
| The command will start a local HTTP server at `http://localhost:8080/` for | ||||
| testing the generated site. Note that `/getServerSideProps` will 404 since the | ||||
| page was removed. | ||||
| 
 | ||||
| [^1]: See the ["Webpack" asset module demo](/docs/demos/static/webpack) for more details. | ||||
| [^2]: See [`read` in "Reading Files"](/docs/api/parse-options) | ||||
| [^3]: See ["SheetJS Data Model"](/docs/csf/) for more details. | ||||
| [^4]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) | ||||
| [^5]: See [`readFile` in "Reading Files"](/docs/api/parse-options) | ||||
| [^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) | ||||
| [^7]: See [`getStaticProps`](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-props) in the NextJS documentation. | ||||
| [^8]: See [`getStaticPaths`](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths) in the NextJS documentation. | ||||
| [^9]: See [`getServerSideProps`](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props) in the NextJS documentation. | ||||
| [^10]: See [`fallback` in getStaticPaths](https://nextjs.org/docs/pages/api-reference/functions/get-static-paths#fallback-false) in the NextJS documentation. | ||||
| [^11]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output) | ||||
| [^12]: [`dangerouslySetInnerHTML`](https://react.dev/reference/react-dom/components/common#common-props) is a ReactJS prop supported for all built-in components. | ||||
| [^13]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) | ||||
| [^14]: See ["Array of Objects" in the ReactJS demo](/docs/demos/frontend/react#rendering-data) | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| --- | ||||
| title: Spreadsheets in VueJS Sites with NuxtJS | ||||
| title: Sheets in VueJS Sites with NuxtJS | ||||
| sidebar_label: NuxtJS | ||||
| description: Make static websites from spreadsheets using NuxtJS. Seamlessly integrate data into the data layer using SheetJS. Create content without leaving the comfort of Excel. | ||||
| pagination_prev: demos/net/index | ||||
| @ -396,8 +396,6 @@ the library hard-codes UTF-8 interpretations, the `_id` field currently uses | ||||
| the pattern `content:` followed by the filename (if files are placed in the | ||||
| `content` folder directly).  This enables a transformer to re-read the file. | ||||
| 
 | ||||
| <details><summary><b>Transformer Details</b> (click to show)</summary> | ||||
| 
 | ||||
| For example, if the file `pres.xlsx` is stored in the `content` folder, NuxtJS | ||||
| Content will use ID `"content:pres.xlsx"`. `"./content/" + _id.slice(8)` will | ||||
| be the original path `"./content/pres.xlsx"`. | ||||
| @ -407,9 +405,6 @@ read the file and return a NodeJS `Buffer`. That `Buffer` object can be parsed | ||||
| with the SheetJS `read`[^7] method. The `sheet_to_json`[^8] utility function can | ||||
| generate arrays of row objects for use in NuxtJS pages. | ||||
| 
 | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ```ts title="sheetformer.ts (Transformer)" | ||||
| // @ts-ignore | ||||
| import { defineTransformer } from "@nuxt/content/transformers/utils"; | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| --- | ||||
| title: Mathematica | ||||
| title: Spreadsheet Processing in Mathematica | ||||
| sidebar_label: Mathematica | ||||
| description: Build complex data pipelines in Mathematica Notebooks. Seamlessly create datasets with SheetJS. Leverage the Mathematica ecosystem to analyze data from Excel workbooks. | ||||
| pagination_prev: demos/cloud/index | ||||
| pagination_next: demos/bigdata/index | ||||
| --- | ||||
| @ -7,55 +9,86 @@ pagination_next: demos/bigdata/index | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| [Mathematica](https://mathematica.com) is a software system for mathematics and | ||||
| scientific computing. It supports command-line tools and JavaScript extensions. | ||||
| 
 | ||||
| [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing | ||||
| data from spreadsheets. | ||||
| 
 | ||||
| This demo uses SheetJS to pull data from a spreadsheet for further analysis | ||||
| within Mathematica. We'll explore how to run an external tool to generate CSV | ||||
| data from opaque spreadsheets and parse the data from Mathematica. | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested in 2023 April 22 in Mathematica 13.2.1 | ||||
| This demo was last tested in 2023 August 21 in Mathematica 13.2.1. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| [The "NodeJS" instructions](/docs/getting-started/installation/frameworks) | ||||
| describe installation steps for NodeJS projects.  Mathematica has built-in | ||||
| features for external scripting with NodeJS. Helper functions can translate | ||||
| between CSV text and Mathematica datasets or arrays. | ||||
| 
 | ||||
| Mathematica can also use [command-line tools](/docs/demos/desktop/cli) | ||||
| 
 | ||||
| ## Integration Details | ||||
| 
 | ||||
| :::caution | ||||
| The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be | ||||
| loaded in NodeJS scripts, including scripts invoked using the `"NodeJS"` mode | ||||
| of the `ExternalEvaluate`[^1] Mathematica function. | ||||
| 
 | ||||
| Mathematica includes `ExternalEvaluate` for running scripts in an external | ||||
| engine.  In local testing, there were incompatibilities with recent NodeJS | ||||
| versions.  This demo uses the shell integration to call a command-line tool. | ||||
| :::caution pass | ||||
| 
 | ||||
| In local testing, there were incompatibilities with recent NodeJS versions. | ||||
| 
 | ||||
| **This is a Mathematica bug.** | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| The current recommendation involves a dedicated command-line tool that leverages | ||||
| SheetJS libraries to to perform spreadsheet processing. | ||||
| 
 | ||||
| ### Command-Line Tools | ||||
| 
 | ||||
| `ExternalEvaluate` can run command-line tools and capture standard output: | ||||
| The ["Command-Line Tools" demo](/docs/demos/desktop/cli) creates `xlsx-cli`, a | ||||
| command-line tool that reads a spreadsheet file and generates CSV rows from the | ||||
| first worksheet. | ||||
| 
 | ||||
| `ExternalEvaluate`[^2] can run command-line tools and capture standard output. | ||||
| The following snippet processes `~/Downloads.pres.numbers` and pulls CSV data | ||||
| into a variable in Mathematica: | ||||
| 
 | ||||
| ```mathematica | ||||
| cmd = "/usr/local/bin/xlsx-cli ~/Downloads/pres.numbers" | ||||
| csvdata = ExternalEvaluate["Shell" -> "StandardOutput", cmd]; | ||||
| ``` | ||||
| 
 | ||||
| Once evaluated, `ImportString` can interpret the data as a dataset.  Typically | ||||
| the first row of the CSV output is the header row.  The `HeaderLines` option | ||||
| `ImportString`[^3] can interpret the CSV data as a `Dataset`[^4]. Typically the | ||||
| first row of the CSV output is the header row. The `HeaderLines`[^5] option | ||||
| controls how Mathematica parses the data: | ||||
| 
 | ||||
| ```mathematica | ||||
| data = ImportString[csvdata, "Dataset", "HeaderLines" -> 1] | ||||
| ``` | ||||
| 
 | ||||
| The following diagram depicts the workbook waltz: | ||||
| 
 | ||||
| ```mermaid | ||||
| flowchart LR | ||||
|   subgraph SheetJS operations | ||||
|     file[(workbook\nfile)] | ||||
|     csv(CSV) | ||||
|   end | ||||
|   csvstr(CSV\nString) | ||||
|   data[(Dataset)] | ||||
|   file --> |`xlsx-cli`\nSheetJS Ops| csv | ||||
|   csv --> |ExternalEvaluate\nMathematica| csvstr | ||||
|   csvstr --> |ImportString\nMathematica| data | ||||
| ``` | ||||
| 
 | ||||
| ## Complete Demo | ||||
| 
 | ||||
| :::note | ||||
| :::info pass | ||||
| 
 | ||||
| This demo was tested in macOS.  The path names will differ in other platforms. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Create the standalone `xlsx-cli` binary: | ||||
| 1) Create the standalone `xlsx-cli` binary[^6]: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| cd /tmp | ||||
| @ -64,8 +97,6 @@ curl -LO https://docs.sheetjs.com/cli/xlsx-cli.js | ||||
| npx nexe -t 14.15.3 xlsx-cli.js`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| This is discussed in ["Command-line Tools"](/docs/demos/desktop/cli) | ||||
| 
 | ||||
| 2) Move the generated `xlsx-cli` to a fixed location in `/usr/local/bin`: | ||||
| 
 | ||||
| ```bash | ||||
| @ -97,15 +128,15 @@ The result should be displayed in a concise table. | ||||
| 
 | ||||
| ### Reading from a URL | ||||
| 
 | ||||
| `FetchURL` downloads a file from a specified URL. This function will be wrapped | ||||
| in a new function called `SheetJSImportURL`. | ||||
| `FetchURL`[^7] downloads a file from a specified URL and returns a path to the | ||||
| file. This function will be wrapped in a new function called `SheetJSImportURL`. | ||||
| 
 | ||||
| 6) In the same notebook, run the following: | ||||
| 
 | ||||
| ```mathematica | ||||
| Needs["Utilities`URLTools`"]; | ||||
| SheetJSImportURL[x_] := Module[{path},( | ||||
|   path = FetchURL["https://sheetjs.com/pres.numbers"]; | ||||
|   path = FetchURL[x]; | ||||
|   SheetJSImportFile[path] | ||||
| )]; | ||||
| ``` | ||||
| @ -115,3 +146,11 @@ SheetJSImportURL[x_] := Module[{path},( | ||||
| ```mathematica | ||||
| data = SheetJSImportURL["https://sheetjs.com/pres.numbers"] | ||||
| ``` | ||||
| 
 | ||||
| [^1]: See [the `ExternalEvaluate` Node.js example](https://reference.wolfram.com/language/ref/ExternalEvaluate.html#:~:text=Evaluate%20a%20basic%20math%20function%20in%20JavaScript%20using%20Node.js%3A) in the Mathematica documentation. | ||||
| [^2]: See [`ExternalEvaluate`](https://reference.wolfram.com/language/ref/ExternalEvaluate.html) in the Mathematica documentation. | ||||
| [^3]: See [`ImportString`](https://reference.wolfram.com/language/ref/ImportString.html) in the Mathematica documentation. | ||||
| [^4]: A [`Dataset`](https://reference.wolfram.com/language/ref/Dataset.html) will be created when using the [`"Dataset"` element in `ImportString`](https://reference.wolfram.com/language/ref/format/CSV.html) | ||||
| [^5]: See [`HeaderLines`](https://reference.wolfram.com/language/ref/HeaderLines.html) in the Mathematica documentation. | ||||
| [^6]: See ["Command-line Tools"](/docs/demos/desktop/cli) for more details. | ||||
| [^7]: Mathematica 11 introduced new methods including [`URLRead`](https://reference.wolfram.com/language/ref/URLRead.html). | ||||
| @ -4,11 +4,27 @@ hide_table_of_contents: true | ||||
| title: Reading Files | ||||
| --- | ||||
| 
 | ||||
| # Parsing Options | ||||
| **`XLSX.read(data, options)`** | ||||
| 
 | ||||
| `XLSX.read(data, read_opts)` attempts to parse `data`. | ||||
| `read` attempts to parse `data` and return [a workbook object](/docs/csf/book) | ||||
| 
 | ||||
| `XLSX.readFile(filename, read_opts)` attempts to read `filename` and parse. | ||||
| The [`type`](#input-type) of the `options` object determines how `data` is | ||||
| interpreted. For string data, the default interpretation is Base64. | ||||
| 
 | ||||
| **`XLSX.readFile(filename, options)`** | ||||
| 
 | ||||
| `readFile` attempts to read a local file with specified `filename`. | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| This method only works in specific environments. It does not work in browsers! | ||||
| 
 | ||||
| The [NodeJS installation note](/docs/getting-started/installation/nodejs#usage) | ||||
| includes additional instructions for non-standard use cases. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Parsing Options | ||||
| 
 | ||||
| The read functions accept an options argument: | ||||
| 
 | ||||
| @ -151,8 +167,8 @@ Plain text format guessing follows the priority order: | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Why are random text files valid?</b> (click to show)</summary> | ||||
| <details open> | ||||
|   <summary><b>Why are random text files valid?</b> (click to hide)</summary> | ||||
| 
 | ||||
| Excel is extremely aggressive in reading files.  Adding an XLS extension to any | ||||
| display text file  (where the only characters are ANSI display chars) tricks | ||||
|  | ||||
| @ -150,7 +150,7 @@ const config = { | ||||
|       prism: { | ||||
|         theme: lightCodeTheme, | ||||
|         darkTheme: darkCodeTheme, | ||||
|         additionalLanguages: [ "visual-basic", "swift", "java", "csharp", "perl", "ruby", "cpp", "applescript", "liquid", "rust", "dart" ], | ||||
|         additionalLanguages: [ "visual-basic", "swift", "java", "csharp", "perl", "ruby", "cpp", "applescript", "liquid", "rust", "dart", "wolfram" ], | ||||
|       }, | ||||
|       liveCodeBlock: { | ||||
|         playgroundPosition: 'top' | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user