Mathematica Extension demo refresh
This commit is contained in:
parent
5f443931f8
commit
67294eeeae
@ -25,7 +25,12 @@ data from opaque spreadsheets and parse the data from Mathematica.
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested by SheetJS users on 2023 November 04 in Mathematica 13.
|
||||
This demo was tested by SheetJS users in the following deployments:
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `14.0` | 2024-06-05 |
|
||||
| `win10-x64` | `14.0` | 2024-06-05 |
|
||||
|
||||
:::
|
||||
|
||||
@ -81,7 +86,7 @@ Dataset object assuming one header row.
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```mathematica title="Complete Function"
|
||||
```mathematica title="SheetJSImportFileEE"
|
||||
(* Import file stored in the Documents folder (e.g. C:\Users\Me\Documents) *)
|
||||
SheetJSImportFileEE[filename_]:=Module[{csv}, (
|
||||
(* This was required in local testing *)
|
||||
@ -107,7 +112,7 @@ SheetJSImportFileEE[filename_]:=Module[{csv}, (
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
```mathematica title="Complete Function"
|
||||
```mathematica title="SheetJSImportFileEE"
|
||||
(* Import file stored in the Documents folder (e.g. C:\Users\Me\Documents) *)
|
||||
SheetJSImportFileEE[filename_]:=Module[{csv}, (
|
||||
(* This was required in local testing *)
|
||||
@ -133,70 +138,6 @@ SheetJSImportFileEE[filename_]:=Module[{csv}, (
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<details open>
|
||||
<summary><b>How to run the example</b> (click to hide)</summary>
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This example was last tested on 2023 November 04 with Mathematica 13.3.
|
||||
|
||||
:::
|
||||
|
||||
0) Install NodeJS. When the demo was tested, version `20.9.0` was installed.
|
||||
|
||||
1) Install dependencies in the Home folder (`~` or `$HOME` or `%HOMEPATH%`):
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz zeromq@6.0.0-beta.17`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Open a new Mathematica Notebook and register NodeJS. When the example was
|
||||
tested in Windows, the commands were:
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```mathematica
|
||||
RegisterExternalEvaluator["NodeJS","/usr/local/bin/node"]
|
||||
FindExternalEvaluators["NodeJS"]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
```mathematica
|
||||
RegisterExternalEvaluator["NodeJS","C:\\Program Files\\nodejs\\node.exe"]
|
||||
FindExternalEvaluators["NodeJS"]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The second argument to `RegisterExternalEvaluator` should be the path to the
|
||||
`node` or `node.exe` binary.
|
||||
|
||||
If NodeJS is registered, the value in the "Registered" column will be "True".
|
||||
|
||||
4) To determine the base folder, run `require("process").cwd()` from NodeJS:
|
||||
|
||||
```mathematica
|
||||
ExternalEvaluate["NodeJS", "require('process').cwd()"]
|
||||
```
|
||||
|
||||
5) Download [`pres.numbers`](https://docs.sheetjs.com/pres.numbers) and move
|
||||
the file to the base folder as shown in the previous step.
|
||||
|
||||
6) Copy and evaluate the "Complete Function" in the previous codeblock.
|
||||
|
||||
7) Run the function and confirm the result is a proper Dataset:
|
||||
|
||||
```mathematica
|
||||
SheetJSImportFileEE["pres.numbers"]
|
||||
```
|
||||
|
||||
![SheetJSImportFileEE result](pathname:///mathematica/SheetJSImportFileEE.png)
|
||||
|
||||
</details>
|
||||
|
||||
### Command-Line Tools
|
||||
|
||||
@ -236,31 +177,177 @@ flowchart LR
|
||||
|
||||
## Complete Demo
|
||||
|
||||
1) Create the standalone `xlsx-cli` binary[^14]:
|
||||
This demo tests the NodeJS external engine and dedicated command line tools.
|
||||
|
||||
### NodeJS Engine
|
||||
|
||||
0) Install NodeJS. When the demo was tested, version `20.14.0` was installed.
|
||||
|
||||
1) Install dependencies in the Home folder (`~` or `$HOME` or `%HOMEPATH%`):
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz zeromq@6.0.0-beta.19`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Open a new Mathematica Notebook and register NodeJS. When the example was
|
||||
tested in Windows, the commands were:
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```mathematica
|
||||
RegisterExternalEvaluator["NodeJS","/usr/local/bin/node"]
|
||||
FindExternalEvaluators["NodeJS"]
|
||||
```
|
||||
|
||||
The second argument to `RegisterExternalEvaluator` should be the path to the
|
||||
`node` program, which can be found by running the following command in a new
|
||||
terminal window:
|
||||
|
||||
```bash
|
||||
which node
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
```mathematica
|
||||
RegisterExternalEvaluator["NodeJS","C:\\Program Files\\nodejs\\node.exe"]
|
||||
FindExternalEvaluators["NodeJS"]
|
||||
```
|
||||
|
||||
The second argument to `RegisterExternalEvaluator` should be the path to the
|
||||
`node.exe` program, which can be found by running the following command in a new
|
||||
PowerShell window:
|
||||
|
||||
```powershell
|
||||
Get-Command node.exe
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If NodeJS is registered, the value in the "Registered" column will be "True".
|
||||
|
||||
4) To determine the base folder, run `require("process").cwd()` from NodeJS:
|
||||
|
||||
```mathematica
|
||||
ExternalEvaluate["NodeJS", "require('process').cwd()"]
|
||||
```
|
||||
|
||||
5) Download [`pres.numbers`](https://docs.sheetjs.com/pres.numbers) and move
|
||||
the file to the base folder as shown in the previous step.
|
||||
|
||||
3) Copy, but do not run, the following snippet into the running notebook:
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```mathematica title="SheetJSImportFileEE"
|
||||
(* Import file stored in the Documents folder (e.g. C:\Users\Me\Documents) *)
|
||||
SheetJSImportFileEE[filename_]:=Module[{csv}, (
|
||||
(* This was required in local testing *)
|
||||
/* highlight-next-line */
|
||||
RegisterExternalEvaluator["NodeJS","/usr/local/bin/node"];
|
||||
|
||||
(* Generate CSV from first sheet *)
|
||||
csv:=ExternalEvaluate["NodeJS", StringJoin[
|
||||
(* module installed in home directory *)
|
||||
"var XLSX = require('xlsx');",
|
||||
(* read specified filename *)
|
||||
"var wb = XLSX.readFile('",filename,"');",
|
||||
(* grab first worksheet *)
|
||||
"var ws = wb.Sheets[wb.SheetNames[0]];",
|
||||
(* convert to CSV *)
|
||||
"XLSX.utils.sheet_to_csv(ws)"
|
||||
]];
|
||||
|
||||
(* Parse CSV into a dataset *)
|
||||
Return[ImportString[csv, "Dataset", "HeaderLines"->1]];
|
||||
)]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
```mathematica title="SheetJSImportFileEE"
|
||||
(* Import file stored in the Documents folder (e.g. C:\Users\Me\Documents) *)
|
||||
SheetJSImportFileEE[filename_]:=Module[{csv}, (
|
||||
(* This was required in local testing *)
|
||||
/* highlight-next-line */
|
||||
RegisterExternalEvaluator["NodeJS","C:\\Program Files\\nodejs\\node.exe"];
|
||||
|
||||
(* Generate CSV from first sheet *)
|
||||
csv:=ExternalEvaluate["NodeJS", StringJoin[
|
||||
(* module installed in home directory *)
|
||||
"var XLSX = require('xlsx');",
|
||||
(* read specified filename *)
|
||||
"var wb = XLSX.readFile('",filename,"');",
|
||||
(* grab first worksheet *)
|
||||
"var ws = wb.Sheets[wb.SheetNames[0]];",
|
||||
(* convert to CSV *)
|
||||
"XLSX.utils.sheet_to_csv(ws)"
|
||||
]];
|
||||
|
||||
(* Parse CSV into a dataset *)
|
||||
Return[ImportString[csv, "Dataset", "HeaderLines"->1]];
|
||||
)]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
After pasting, edit the highlighted line to reflect the path of the `node` or
|
||||
`node.exe` binary. This path was discovered in Step 2.
|
||||
|
||||
After editing the snippet, run the expression.
|
||||
|
||||
7) Run the function and confirm the result is a proper Dataset:
|
||||
|
||||
```mathematica
|
||||
SheetJSImportFileEE["pres.numbers"]
|
||||
```
|
||||
|
||||
![SheetJSImportFileEE result](pathname:///mathematica/SheetJSImportFileEE.png)
|
||||
|
||||
### Standalone Binary
|
||||
|
||||
8) Create the standalone `xlsx-cli` binary[^14]. The commands should be run in a
|
||||
Terminal or PowerShell window:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2
|
||||
curl -LO https://docs.sheetjs.com/cli/xlsx-cli.js
|
||||
npx nexe -t 14.15.3 xlsx-cli.js`}
|
||||
npx -y nexe -t 14.15.3 xlsx-cli.js`}
|
||||
</CodeBlock>
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
2) Move the generated `xlsx-cli` to a fixed location in `/usr/local/bin`:
|
||||
9) Move the generated `xlsx-cli` to a fixed location in `/usr/local/bin`:
|
||||
|
||||
```bash
|
||||
mkdir -p /usr/local/bin
|
||||
mv xlsx-cli /usr/local/bin/
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
If there are permission errors, the command should be run with the root user:
|
||||
|
||||
```bash
|
||||
sudo mv xlsx-cli /usr/local/bin/
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
2) Find the current directory:
|
||||
9) Find the current directory:
|
||||
|
||||
```bash
|
||||
cd
|
||||
pwd
|
||||
```
|
||||
|
||||
The generated binary will be `xlsx-cli.exe` in the displayed path.
|
||||
@ -270,9 +357,12 @@ The generated binary will be `xlsx-cli.exe` in the displayed path.
|
||||
|
||||
### Reading a Local File
|
||||
|
||||
3) In a new Mathematica notebook, run the following snippet:
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```mathematica
|
||||
10) In a new Mathematica notebook, run the following snippet:
|
||||
|
||||
```mathematica title="SheetJSImportFile"
|
||||
SheetJSImportFile[x_] := ImportString[Block[{Print}, ExternalEvaluate[
|
||||
"Shell" -> "StandardOutput",
|
||||
// highlight-next-line
|
||||
@ -280,17 +370,24 @@ SheetJSImportFile[x_] := ImportString[Block[{Print}, ExternalEvaluate[
|
||||
]], "Dataset", "HeaderLines" -> 1]
|
||||
```
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
10) In a new Mathematica notebook, copy but do not run the following snippet:
|
||||
|
||||
```mathematica title="SheetJSImportFile"
|
||||
SheetJSImportFile[x_] := ImportString[Block[{Print}, ExternalEvaluate[
|
||||
"Shell" -> "StandardOutput",
|
||||
// highlight-next-line
|
||||
"/usr/local/bin/xlsx-cli " <> x
|
||||
]], "Dataset", "HeaderLines" -> 1]
|
||||
```
|
||||
|
||||
Change `/usr/local/bin/xlsx-cli` in the string to the path to the generated
|
||||
`xlsx-cli.exe` binary. For example, if the path in step 2 was
|
||||
`C:\Users\Me\Documents\`, then the code should be:
|
||||
|
||||
```mathematica
|
||||
```mathematica title="SheetJSImportFile"
|
||||
SheetJSImportFile[x_] := ImportString[Block[{Print}, ExternalEvaluate[
|
||||
"Shell" -> "StandardOutput",
|
||||
// highlight-next-line
|
||||
@ -298,25 +395,58 @@ SheetJSImportFile[x_] := ImportString[Block[{Print}, ExternalEvaluate[
|
||||
]], "Dataset", "HeaderLines" -> 1]
|
||||
```
|
||||
|
||||
The `\` characters must be doubled.
|
||||
:::info pass
|
||||
|
||||
Mathematica requires the `\` characters must be doubled.
|
||||
|
||||
:::
|
||||
|
||||
After making the change, run the snippet.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
4) Download https://docs.sheetjs.com/pres.numbers and save to Downloads folder:
|
||||
11) Download https://docs.sheetjs.com/pres.numbers and save to Downloads folder:
|
||||
|
||||
```bash
|
||||
cd ~/Downloads/
|
||||
curl -LO https://docs.sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
5) In the Mathematica notebook, run the new function. If the file was saved to
|
||||
12) In the Mathematica notebook, run the new function. If the file was saved to
|
||||
the Downloads folder, the path will be `"~/Downloads/pres.numbers"` in macOS:
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```mathematica
|
||||
data = SheetJSImportFile["~/Downloads/pres.numbers"]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
On Windows, the absolute path to the file must be used. To find this path, run
|
||||
the following commands in PowerShell:
|
||||
|
||||
```powershell
|
||||
cd $HOME\Downloads
|
||||
pwd
|
||||
```
|
||||
|
||||
Append `\\pres.numbers` to the displayed path. For example, if the path was
|
||||
`C:\Users\Me\Downloads`, the command will be
|
||||
|
||||
```mathematica
|
||||
data = SheetJSImportFile["C:\\Users\\Me\\Downloads\\pres.numbers"]
|
||||
```
|
||||
|
||||
The `\` characters must be doubled.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
The result should be displayed in a concise table.
|
||||
|
||||
![SheetJSImportFile result](pathname:///mathematica/SheetJSImportFile.png)
|
||||
@ -326,9 +456,9 @@ The result should be displayed in a concise table.
|
||||
`FetchURL`[^15] 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:
|
||||
13) In the same notebook, run the following:
|
||||
|
||||
```mathematica
|
||||
```mathematica title="SheetJSImportURL"
|
||||
Needs["Utilities`URLTools`"];
|
||||
SheetJSImportURL[x_] := Module[{path},(
|
||||
path = FetchURL[x];
|
||||
@ -336,7 +466,7 @@ SheetJSImportURL[x_] := Module[{path},(
|
||||
)];
|
||||
```
|
||||
|
||||
7) Test by downloading the test file in the notebook:
|
||||
14) Test by downloading the test file in the notebook:
|
||||
|
||||
```mathematica
|
||||
data = SheetJSImportURL["https://docs.sheetjs.com/pres.numbers"]
|
||||
|
Loading…
Reference in New Issue
Block a user