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:
|
||||
|
||||
![`pres.xlsx` data](pathname:///pres.png)
|
||||
|
||||
@ -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