forked from sheetjs/docs.sheetjs.com
209 lines
6.1 KiB
Markdown
209 lines
6.1 KiB
Markdown
|
---
|
||
|
title: Modern Spreadsheets in Maple
|
||
|
sidebar_label: Maple
|
||
|
pagination_prev: demos/cloud/index
|
||
|
pagination_next: demos/bigdata/index
|
||
|
---
|
||
|
|
||
|
import current from '/version.js';
|
||
|
import CodeBlock from '@theme/CodeBlock';
|
||
|
|
||
|
[Maple](https://www.maplesoft.com/products/Maple/) is a numeric computing
|
||
|
platform. It offers a robust C-based extension system.
|
||
|
|
||
|
[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 Maple. We'll create a Maple native extension that loads the
|
||
|
[Duktape](/docs/demos/engines/duktape) JavaScript engine and uses the SheetJS
|
||
|
library to read data from spreadsheets and converts to a Maple-friendly format.
|
||
|
|
||
|
```mermaid
|
||
|
flowchart LR
|
||
|
ofile[(workbook\nXLSB file)]
|
||
|
nfile[(clean file\nXLSX)]
|
||
|
data[[Maple\nTable]]
|
||
|
ofile --> |Maple Extension\nSheetJS + Duktape| nfile
|
||
|
nfile --> |ExcelTools\nImport|data
|
||
|
```
|
||
|
|
||
|
:::note
|
||
|
|
||
|
This demo was last tested by SheetJS users on 2023 October 3 in Maple 2023.
|
||
|
|
||
|
:::
|
||
|
|
||
|
:::info pass
|
||
|
|
||
|
Maple has limited support for processing spreadsheets through the `ExcelTools`
|
||
|
package[^1]. At the time of writing, it lacked support for XLSB, NUMBERS, and
|
||
|
other common spreadsheet formats.
|
||
|
|
||
|
SheetJS libraries help fill the gap by normalizing spreadsheets to a form that
|
||
|
Maple can understand.
|
||
|
|
||
|
:::
|
||
|
|
||
|
## Integration Details
|
||
|
|
||
|
The current recommendation involves a native plugin that reads arbitrary files
|
||
|
and generates clean XLSX files that Maple can import.
|
||
|
|
||
|
The extension function ultimately pairs the SheetJS `read`[^2] and `write`[^3]
|
||
|
methods to read data from the old file and write a new file:
|
||
|
|
||
|
```js
|
||
|
var wb = XLSX.read(original_file_data, {type: "buffer"});
|
||
|
var new_file_data = XLSX.write(wb, {type: "array", bookType: "xlsx"});
|
||
|
```
|
||
|
|
||
|
The extension function will receive a file name and perform the following steps:
|
||
|
|
||
|
```mermaid
|
||
|
flowchart LR
|
||
|
ofile{{File\nName}}
|
||
|
subgraph JS Operations
|
||
|
ojbuf[(Buffer\nFile Bytes)]
|
||
|
wb(((SheetJS\nWorkbook)))
|
||
|
njbuf[(Buffer\nXLSX bytes)]
|
||
|
end
|
||
|
obuf[(File\nbytes)]
|
||
|
nbuf[(New file\nbytes)]
|
||
|
nfile[(XLSX\nFile)]
|
||
|
ofile --> |C\nRead File| obuf
|
||
|
obuf --> |Duktape\nBuffer Ops| ojbuf
|
||
|
ojbuf --> |SheetJS\n`read`| wb
|
||
|
wb --> |SheetJS\n`write`| njbuf
|
||
|
njbuf --> |Duktape\nBuffer Ops| nbuf
|
||
|
nbuf --> |C\nWrite File| nfile
|
||
|
```
|
||
|
|
||
|
### C Extensions
|
||
|
|
||
|
Maple C extensions are shared libraries or DLLs that use special Maple methods
|
||
|
for parsing arguments and returning values.
|
||
|
|
||
|
To simplify the flow, the new function will take one argument (the original file
|
||
|
name) and return one value (the new file name).
|
||
|
|
||
|
The official documentation has a comprehensive list[^4] of methods. For this
|
||
|
demo, the following methods are used:
|
||
|
|
||
|
- `MapleNumArgs` and `IsMapleString` are used in argument validation. The demo
|
||
|
function will raise a Maple exception if no file name is specified.
|
||
|
|
||
|
- `MapleRaiseError` and `MapleRaiseError2` programmatically raise errors.
|
||
|
|
||
|
- `MapleToString` and `ToMapleString` convert between Maple and C strings.
|
||
|
|
||
|
### Duktape JS Engine
|
||
|
|
||
|
This demo uses the [Duktape JavaScript engine](/docs/demos/engines/duktape). The
|
||
|
SheetJS + Duktape demo covers engine integration details in more detail.
|
||
|
|
||
|
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
|
||
|
can be loaded in Duktape by reading the source from the filesystem.
|
||
|
|
||
|
## Complete Demo
|
||
|
|
||
|
:::info pass
|
||
|
|
||
|
This demo was tested in Windows x64. The path names and build commands will
|
||
|
differ in other platforms and operating systems.
|
||
|
|
||
|
:::
|
||
|
|
||
|
The [`sheetjs-maple.c`](pathname:///maple/sheetjs-maple.c) extension exports the
|
||
|
`SheetToXLSX` Maple method. It takes a file name argument, parses the specified
|
||
|
file, exports data to `sheetjsw.xlsx` and returns the string `"sheetjsw.xlsx"`.
|
||
|
|
||
|
This can be chained with `Import` from `ExcelTools`:
|
||
|
|
||
|
```maple
|
||
|
with(ExcelTools);
|
||
|
Import(SheetToXLSX("pres.numbers"))
|
||
|
```
|
||
|
|
||
|
0) Ensure "Windows Subsystem for Linux" (WSL) and Visual Studio are installed.
|
||
|
|
||
|
1) Open a new "x64 Native Tools Command Prompt" window and create a project
|
||
|
folder `c:\sheetjs-maple`:
|
||
|
|
||
|
```powershell
|
||
|
cd c:\
|
||
|
mkdir sheetjs-maple
|
||
|
cd sheetjs-maple
|
||
|
```
|
||
|
|
||
|
2) Copy the headers and `lib` files from the Maple folder to the project folder.
|
||
|
For example, using Maple 2023 on Windows x64:
|
||
|
|
||
|
```powershell
|
||
|
copy "C:\Program Files\Maple 2023\extern\include\"*.h .
|
||
|
copy "c:\Program Files\Maple 2023\bin.x86_64_WINDOWS"\*.lib .
|
||
|
```
|
||
|
|
||
|
3) Run `bash` to enter WSL
|
||
|
|
||
|
4) Within WSL, install Duktape:
|
||
|
|
||
|
```bash
|
||
|
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
|
||
|
tar -xJf duktape-2.7.0.tar.xz
|
||
|
mv duktape-2.7.0/src/*.{c,h} .
|
||
|
```
|
||
|
|
||
|
5) Still within WSL, download SheetJS scripts and the test file.
|
||
|
|
||
|
<CodeBlock language="bash">{`\
|
||
|
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
|
||
|
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||
|
curl -LO https://sheetjs.com/pres.numbers`}
|
||
|
</CodeBlock>
|
||
|
|
||
|
6) Still within WSL, download the extension C code
|
||
|
|
||
|
```bash
|
||
|
curl -LO https://docs.sheetjs.com/maple/sheetjs-maple.c
|
||
|
```
|
||
|
|
||
|
7) Exit WSL by running `exit`. The window will return to the command prompt.
|
||
|
|
||
|
8) Build the extension DLL:
|
||
|
|
||
|
```powershell
|
||
|
cl -Gz sheetjs-maple.c duktape.c /EHsc -link -dll -out:sheetjs-maple.dll maplec.lib
|
||
|
```
|
||
|
|
||
|
9) Close and re-open Maple, then create a new Maple Worksheet or Document
|
||
|
|
||
|
10) Run the following command in Maple to change the working directory:
|
||
|
|
||
|
```maple
|
||
|
currentdir("c:\\sheetjs-maple");
|
||
|
```
|
||
|
|
||
|
11) Load the `SheetToXLSX` method from the extension:
|
||
|
|
||
|
```maple
|
||
|
with(ExternalCalling):
|
||
|
dll:=ExternalLibraryName("sheetjs-maple"):
|
||
|
SheetToXLSX:=DefineExternal("SheetToXLSX",dll):
|
||
|
```
|
||
|
|
||
|
12) Read the `pres.numbers` test file:
|
||
|
|
||
|
```maple
|
||
|
with(ExcelTools);
|
||
|
Import(SheetToXLSX("pres.numbers"))
|
||
|
```
|
||
|
|
||
|
The result will show the data from `pres.numbers`
|
||
|
|
||
|
![Maple Screenshot](pathname:///maple/maple.png)
|
||
|
|
||
|
[^1]: See ["ExcelTools"](https://www.maplesoft.com/support/help/Maple/view.aspx?path=ExcelTools) in the Maple documentation.
|
||
|
[^2]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||
|
[^3]: See [`write` in "Writing Files"](/docs/api/write-options)
|
||
|
[^4]: See ["C OpenMaple and ExternalCalling Application Program Interface (API)"](https://www.maplesoft.com/support/help/maple/view.aspx?path=OpenMaple%2FC%2FAPI) in the Maple documentation.
|