engines
This commit is contained in:
parent
6e3b91f9e5
commit
4258609879
|
@ -0,0 +1,21 @@
|
|||
import { read, utils } from 'xlsx';
|
||||
import url from './engines.xls';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
const EngineData = () => {
|
||||
const [engines, setEngines] = useState("");
|
||||
const [binding, setBinding] = useState("");
|
||||
|
||||
useEffect(() => { (async() => {
|
||||
const wb = read(await (await fetch(url)).arrayBuffer(), { dense: true });
|
||||
setEngines(utils.sheet_to_html(wb.Sheets["Engines"]));
|
||||
setBinding(utils.sheet_to_html(wb.Sheets["Bindings"]));
|
||||
})(); }, []);
|
||||
return ( <>
|
||||
<p>The following engines have been tested in their native languages:</p>
|
||||
<div dangerouslySetInnerHTML={{__html: engines}}/>
|
||||
<p>The following bindings have been tested:</p>
|
||||
<div dangerouslySetInnerHTML={{__html: binding}}/>
|
||||
</> );
|
||||
};
|
||||
export default EngineData;
|
|
@ -0,0 +1,321 @@
|
|||
<?xml version="1.0"?>
|
||||
<?mso-application progid="Excel.Sheet"?>
|
||||
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:html="http://www.w3.org/TR/REC-html40">
|
||||
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<WindowHeight>10620</WindowHeight>
|
||||
<WindowWidth>11020</WindowWidth>
|
||||
<WindowTopX>2260</WindowTopX>
|
||||
<WindowTopY>19600</WindowTopY>
|
||||
<ActiveSheet>1</ActiveSheet>
|
||||
<ProtectStructure>False</ProtectStructure>
|
||||
<ProtectWindows>False</ProtectWindows>
|
||||
</ExcelWorkbook>
|
||||
<Styles>
|
||||
<Style ss:ID="Default" ss:Name="Normal">
|
||||
<Alignment ss:Vertical="Bottom"/>
|
||||
<Borders/>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#000000"/>
|
||||
<Interior/>
|
||||
<NumberFormat/>
|
||||
<Protection/>
|
||||
</Style>
|
||||
<Style ss:ID="s16">
|
||||
<Font ss:FontName="Arial" x:Family="Swiss" ss:Size="12" ss:Color="#1C1E21"/>
|
||||
</Style>
|
||||
<Style ss:ID="s17">
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#000000"
|
||||
ss:Bold="1"/>
|
||||
</Style>
|
||||
<Style ss:ID="s19">
|
||||
<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#000000"
|
||||
ss:Bold="1"/>
|
||||
</Style>
|
||||
</Styles>
|
||||
<Worksheet ss:Name="Engines">
|
||||
<Table ss:ExpandedColumnCount="8" ss:ExpandedRowCount="14" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="16">
|
||||
<Column ss:Index="3" ss:Width="24"/>
|
||||
<Column ss:Width="31"/>
|
||||
<Column ss:Width="24"/>
|
||||
<Column ss:Width="31"/>
|
||||
<Column ss:Width="24"/>
|
||||
<Column ss:Width="31"/>
|
||||
<Row>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s17"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s19"><Data ss:Type="String">MacOS</Data></Cell>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s19"><Data ss:Type="String">Windows</Data></Cell>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s19"><Data ss:Type="String">Linux</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">Engine</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">Lang</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">x64</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">ARM</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">x64</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">ARM</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">x64</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">ARM</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Duktape</Data></Cell>
|
||||
<Cell><Data ss:Type="String">C</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">V8</Data></Cell>
|
||||
<Cell><Data ss:Type="String">C++</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Rhino</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Java</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Jint</Data></Cell>
|
||||
<Cell><Data ss:Type="String">C#</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Goja</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Go</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Nashorn</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Java</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">QuickJS</Data></Cell>
|
||||
<Cell><Data ss:Type="String">C</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Hermes</Data></Cell>
|
||||
<Cell><Data ss:Type="String">C++</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">ChakraCore</Data></Cell>
|
||||
<Cell><Data ss:Type="String">C++</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Boa</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Rust</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">JE</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Perl</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">JerryScript</Data></Cell>
|
||||
<Cell><Data ss:Type="String">C</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<FreezePanes/>
|
||||
<FrozenNoSplit/>
|
||||
<SplitHorizontal>2</SplitHorizontal>
|
||||
<TopRowBottomPane>2</TopRowBottomPane>
|
||||
<ActivePane>2</ActivePane>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
</Pane>
|
||||
<Pane>
|
||||
<Number>2</Number>
|
||||
<ActiveRow>12</ActiveRow>
|
||||
<ActiveCol>5</ActiveCol>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
<Worksheet ss:Name="Bindings">
|
||||
<Table ss:ExpandedColumnCount="8" ss:ExpandedRowCount="7" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="16">
|
||||
<Column ss:Index="3" ss:Width="24"/>
|
||||
<Column ss:Width="31"/>
|
||||
<Column ss:Width="24"/>
|
||||
<Column ss:Width="31"/>
|
||||
<Column ss:Width="24"/>
|
||||
<Column ss:Width="31"/>
|
||||
<Row>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s17"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s19"><Data ss:Type="String">MacOS</Data></Cell>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s19"><Data ss:Type="String">Windows</Data></Cell>
|
||||
<Cell ss:MergeAcross="1" ss:StyleID="s19"><Data ss:Type="String">Linux</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">Engine</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">Binding</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">x64</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">ARM</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">x64</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">ARM</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">x64</Data></Cell>
|
||||
<Cell ss:StyleID="s17"><Data ss:Type="String">ARM</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Duktape</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Perl</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">Duktape</Data></Cell>
|
||||
<Cell><Data ss:Type="String">PHP</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">V8</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Rust</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:Index="7" ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">V8</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Python</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">JSC</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Swift</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">ExecJS</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Ruby</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<Selected/>
|
||||
<FreezePanes/>
|
||||
<FrozenNoSplit/>
|
||||
<SplitHorizontal>2</SplitHorizontal>
|
||||
<TopRowBottomPane>2</TopRowBottomPane>
|
||||
<ActivePane>2</ActivePane>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
</Pane>
|
||||
<Pane>
|
||||
<Number>2</Number>
|
||||
<ActiveRow>3</ActiveRow>
|
||||
<ActiveCol>1</ActiveCol>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
</Workbook>
|
|
@ -76,8 +76,8 @@ the automation context is more efficient and strongly recommended.
|
|||
|
||||
## Puppeteer
|
||||
|
||||
Puppeteer enables headless Chromium automation for NodeJS. Releases ship with
|
||||
an installer script that prepares a compatible browser version.
|
||||
[Puppeteer](https://pptr.dev/) enables headless Chromium automation for NodeJS.
|
||||
Releases ship with an installer script that installs a headless browser.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="nodejs" label="NodeJS">
|
||||
|
@ -127,16 +127,16 @@ const puppeteer = require('puppeteer');
|
|||
|
||||
**Demo**
|
||||
|
||||
:::note
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 September 14 against Puppeteer 21.2.1.
|
||||
This demo was last tested on 2024 January 27 against Puppeteer 21.9.0.
|
||||
|
||||
:::
|
||||
|
||||
1) Install SheetJS and Puppeteer:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz puppeteer@21.2.1`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz puppeteer@21.9.0`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Save the `SheetJSPuppeteer.js` code snippet to `SheetJSPuppeteer.js`.
|
||||
|
@ -202,9 +202,9 @@ await browser.close();`}
|
|||
|
||||
**Demo**
|
||||
|
||||
:::note
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 September 14 against deno-puppeteer 16.2.0.
|
||||
This demo was last tested on 2024 January 27 against deno-puppeteer 16.2.0.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -242,9 +242,9 @@ This file can be opened with Excel.
|
|||
|
||||
## Playwright
|
||||
|
||||
Playwright presents a unified scripting framework for Chromium, WebKit, and
|
||||
other browsers. It draws inspiration from Puppeteer. In fact, the example
|
||||
code is almost identical!
|
||||
[Playwright](https://playwright.dev/) presents a unified scripting framework for
|
||||
Chromium, WebKit, and other browsers. It draws inspiration from Puppeteer. In
|
||||
fact, the example code is almost identical!
|
||||
|
||||
Differences from the Puppeteer example are highlighted below:
|
||||
|
||||
|
@ -290,16 +290,16 @@ const { webkit } = require('playwright'); // import desired browser
|
|||
|
||||
**Demo**
|
||||
|
||||
:::note
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 September 14 against Playwright 1.38.0.
|
||||
This demo was last tested on 2024 January 27 against Playwright 1.41.1.
|
||||
|
||||
:::
|
||||
|
||||
1) Install SheetJS and Playwright:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz playwright@1.33.0`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz playwright@1.41.1`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Save the `SheetJSPlaywright.js` code snippet to `SheetJSPlaywright.js`.
|
||||
|
@ -315,7 +315,7 @@ This file can be opened with Excel.
|
|||
|
||||
:::caution pass
|
||||
|
||||
In the latest Windows 10 test, the commmand failed with a clear error message:
|
||||
The commmand may fail with a message such as:
|
||||
|
||||
```
|
||||
╔═════════════════════════════════════════════════════════════════════════╗
|
||||
|
@ -328,13 +328,13 @@ In the latest Windows 10 test, the commmand failed with a clear error message:
|
|||
╚═════════════════════════════════════════════════════════════════════════╝
|
||||
```
|
||||
|
||||
As recommended, the command
|
||||
Running the recommended command will download and install browser engines:
|
||||
|
||||
```bash
|
||||
npx playwright install
|
||||
```
|
||||
|
||||
will download and install the browsers.
|
||||
After installing engines, re-run the script.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -398,13 +398,13 @@ strongly recommended to add verbose logging and to lint scripts before use.
|
|||
|
||||
**Demo**
|
||||
|
||||
:::note
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 September 14 against PhantomJS 2.1.1
|
||||
|
||||
:::
|
||||
|
||||
1) Download and unzip the PhantomJS release from the official website[^1].
|
||||
1) [Download and extract PhantomJS](https://phantomjs.org/download.html)
|
||||
|
||||
2) Save the `SheetJSPhantom.js` code snippet to `SheetJSPhantom.js`.
|
||||
|
||||
|
@ -421,5 +421,3 @@ When the script finishes, the file `SheetJSPhantomJS.xlsb` will be created.
|
|||
This file can be opened with Excel.
|
||||
|
||||
</details>
|
||||
|
||||
[^1]: Downloads available at <https://phantomjs.org/download.html>
|
|
@ -30,6 +30,27 @@ web browser. ["Browser Automation"](/docs/demos/net/headless) includes demos.
|
|||
|
||||
## Integration Details
|
||||
|
||||
Synthetic DOM implementations typically provide a function that accept a HTML
|
||||
string and return an object that represents `document`. An API method such as
|
||||
`getElementsByTagName` or `querySelector` can pull TABLE elements.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Synthetic DOM Operations
|
||||
html(HTML\nstring)
|
||||
doc{{`document`\nDOM Object}}
|
||||
end
|
||||
subgraph SheetJS Operations
|
||||
table{{DOM\nTable}}
|
||||
wb(((SheetJS\nWorkbook)))
|
||||
file(workbook\nfile)
|
||||
end
|
||||
html --> |Library\n\n| doc
|
||||
doc --> |DOM\nAPI| table
|
||||
table --> |`table_to_book`\n\n| wb
|
||||
wb --> |`writeFile`\n\n| file
|
||||
```
|
||||
|
||||
SheetJS methods use features that may be missing from some DOM implementations.
|
||||
|
||||
### Table rows
|
||||
|
@ -37,8 +58,8 @@ SheetJS methods use features that may be missing from some DOM implementations.
|
|||
The `rows` property of TABLE elements is a list of TR row children. This list
|
||||
automatically updates when rows are added and deleted.
|
||||
|
||||
SheetJS does not mutate `rows`. Assuming there are no nested tables, the `rows`
|
||||
property can be created using `getElementsByTagName`:
|
||||
SheetJS methods do not mutate `rows`. Assuming there are no nested tables, the
|
||||
`rows` property can be created using `getElementsByTagName`:
|
||||
|
||||
```js
|
||||
tbl.rows = Array.from(tbl.getElementsByTagName("tr"));
|
||||
|
@ -49,7 +70,7 @@ tbl.rows = Array.from(tbl.getElementsByTagName("tr"));
|
|||
The `cells` property of TR elements is a list of TD cell children. This list
|
||||
automatically updates when cells are added and deleted.
|
||||
|
||||
SheetJS does not mutate `cells`. Assuming there are no nested tables, the
|
||||
SheetJS methods do not mutate `cells`. Assuming there are no nested tables, the
|
||||
`cells` property can be created using `getElementsByTagName`:
|
||||
|
||||
```js
|
||||
|
@ -89,14 +110,14 @@ XLSX.writeFile(workbook, "SheetJSDOM.xlsx");
|
|||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 September 10 against JSDOM `22.1.0`
|
||||
This demo was last tested on 2024 January 27 against JSDOM `24.0.0`
|
||||
|
||||
:::
|
||||
|
||||
1) Install SheetJS and JSDOM libraries:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz jsdom@22.0.0`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz jsdom@24.0.0`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Save the previous codeblock to `SheetJSDOM.js`.
|
||||
|
@ -119,7 +140,7 @@ The script will create a file `SheetJSDOM.xlsx` that can be opened.
|
|||
|
||||
### HappyDOM
|
||||
|
||||
HappyDOM provides a DOM framework for NodeJS. For the tested version (`11.0.2`),
|
||||
HappyDOM provides a DOM framework for NodeJS. For the tested version (`13.3.1`),
|
||||
the following patches were needed:
|
||||
|
||||
- TABLE `rows` property (explained above)
|
||||
|
@ -129,14 +150,14 @@ the following patches were needed:
|
|||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 September 10 against HappyDOM `11.0.2`
|
||||
This demo was last tested on 2024 January 27 against HappyDOM `13.3.1`
|
||||
|
||||
:::
|
||||
|
||||
1) Install SheetJS and HappyDOM libraries:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz happy-dom@11.0.2`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz happy-dom@13.3.1`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Download [the sample script `SheetJSHappyDOM.js`](pathname:///dom/SheetJSHappyDOM.js):
|
||||
|
@ -145,7 +166,13 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz happy-d
|
|||
curl -LO https://docs.sheetjs.com/dom/SheetJSHappyDOM.js
|
||||
```
|
||||
|
||||
3) Run the script:
|
||||
3) Download [the sample `SheetJSTable.html`](pathname:///dom/SheetJSTable.html):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/dom/SheetJSTable.html
|
||||
```
|
||||
|
||||
4) Run the script:
|
||||
|
||||
```bash
|
||||
node SheetJSHappyDOM.js
|
||||
|
@ -256,7 +283,7 @@ The script will create a file `SheetJSCheerio.xlsx` that can be opened.
|
|||
### DenoDOM
|
||||
|
||||
[DenoDOM](https://deno.land/x/deno_dom) provides a DOM framework for Deno. For
|
||||
the tested version (`0.1.38`), the following patches were needed:
|
||||
the tested version (`0.1.43`), the following patches were needed:
|
||||
|
||||
- TABLE `rows` property (explained above)
|
||||
- TR `cells` property (explained above)
|
||||
|
@ -267,7 +294,7 @@ This example fetches [a sample table](pathname:///dom/SheetJSTable.html):
|
|||
// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
|
||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';
|
||||
\n\
|
||||
import { DOMParser } from 'https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts';
|
||||
import { DOMParser } from 'https://deno.land/x/deno_dom@v0.1.43/deno-dom-wasm.ts';
|
||||
\n\
|
||||
const doc = new DOMParser().parseFromString(
|
||||
await (await fetch('https://docs.sheetjs.com/dom/SheetJSTable.html')).text(),
|
||||
|
@ -290,7 +317,7 @@ XLSX.writeFile(workbook, "SheetJSDenoDOM.xlsx");`}
|
|||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 September 10 against DenoDOM `0.1.38`
|
||||
This demo was last tested on 2024 January 27 against DenoDOM `0.1.43`
|
||||
|
||||
:::
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ async function importFile() {
|
|||
|
||||
:::note pass
|
||||
|
||||
In older versions of Electron, `showOpenDialog` returned the path directly:
|
||||
`showOpenDialog` originally returned an array of paths:
|
||||
|
||||
```js
|
||||
var dialog = require('electron').remote.dialog;
|
||||
|
@ -134,6 +134,8 @@ function importFile(workbook) {
|
|||
}
|
||||
```
|
||||
|
||||
This method was renamed to `showOpenDialogSync` in Electron 6.
|
||||
|
||||
:::
|
||||
|
||||
### Writing Files
|
||||
|
@ -163,7 +165,7 @@ async function exportFile(workbook) {
|
|||
|
||||
:::note pass
|
||||
|
||||
In older versions of Electron, `showSaveDialog` returned the path directly:
|
||||
`showSaveDialog` originally returned the selected path:
|
||||
|
||||
```js
|
||||
var dialog = require('electron').remote.dialog;
|
||||
|
@ -174,6 +176,8 @@ function exportFile(workbook) {
|
|||
}
|
||||
```
|
||||
|
||||
This method was renamed to `showSaveDialogSync` in Electron 6.
|
||||
|
||||
:::
|
||||
|
||||
## Complete Example
|
||||
|
@ -188,7 +192,7 @@ This demo was tested in the following environments:
|
|||
| macOS 14.1.2 | `darwin-arm` | `27.1.3` | 2023-12-01 |
|
||||
| Windows 10 | `win10-x64` | `27.1.3` | 2023-12-09 |
|
||||
| Windows 11 | `win11-arm` | `27.1.3` | 2023-12-01 |
|
||||
| Linux (HoloOS) | `linux-x64` | `27.1.3` | 2023-12-09 |
|
||||
| Linux (HoloOS) | `linux-x64` | `28.2.0` | 2024-01-26 |
|
||||
| Linux (Debian) | `linux-arm` | `27.1.3` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
|
@ -315,25 +319,30 @@ and select `pres.numbers`.
|
|||
## Electron Breaking Changes
|
||||
|
||||
The first version of this demo used Electron 1.7.5. The current demo includes
|
||||
the required changes for Electron 27.1.3.
|
||||
the required changes for Electron 28.2.0.
|
||||
|
||||
There are no Electron-specific workarounds in the library, but Electron broke
|
||||
backwards compatibility multiple times. A summary of changes is noted below.
|
||||
|
||||
:::caution pass
|
||||
|
||||
Electron 6.x changed the `dialog` API. Methods like `showSaveDialog` originally
|
||||
returned an array of strings, but now returns a `Promise`. This change was not
|
||||
documented.
|
||||
Electron 6 changed the return types of `dialog` API methods. The old `dialog`
|
||||
methods have been renamed:
|
||||
|
||||
Electron 9.0.0 and later require the preference `nodeIntegration: true` in order
|
||||
to `require('xlsx')` in the renderer process.
|
||||
| Electron 1 - 5 | Electron 6 |
|
||||
|:-----------------|:---------------------|
|
||||
| `showOpenDialog` | `showOpenDialogSync` |
|
||||
| `showSaveDialog` | `showSaveDialogSync` |
|
||||
**This change was not properly documented!**
|
||||
|
||||
Electron 12.0.0 and later also require `worldSafeExecuteJavascript: true` and
|
||||
Electron 9 and later require the preference `nodeIntegration: true` in order to
|
||||
`require('xlsx')` in the renderer process.
|
||||
|
||||
Electron 12 and later also require `worldSafeExecuteJavascript: true` and
|
||||
`contextIsolation: true`.
|
||||
|
||||
Electron 14+ must use `@electron/remote` instead of `remote`. An `initialize`
|
||||
call is required to enable Developer Tools in the window.
|
||||
Electron 14 and later must use `@electron/remote` instead of `remote`. An
|
||||
`initialize` call is required to enable Developer Tools in the window.
|
||||
|
||||
:::
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ This demo was tested in the following environments:
|
|||
| macOS 14.1.2 | `darwin-arm` | `0.82.0` | 2023-12-01 |
|
||||
| Windows 10 | `win10-x64` | `0.82.0` | 2023-12-09 |
|
||||
| Windows 11 | `win11-arm` | `0.82.0` | 2023-12-01 |
|
||||
| Linux (HoloOS) | `linux-x64` | `0.82.0` | 2023-12-07 |
|
||||
| Linux (HoloOS) | `linux-x64` | `0.83.0` | 2024-01-26 |
|
||||
|
||||
There is no official Linux ARM64 release. The community release[^1] was tested
|
||||
and verified on 2023-09-27.
|
||||
|
@ -140,7 +140,7 @@ cd sheetjs-nwjs
|
|||
"version": "0.0.0",
|
||||
"main": "index.html",
|
||||
"dependencies": {
|
||||
"nw": "0.82.0",
|
||||
"nw": "0.83.0",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
|
||||
}
|
||||
}`}
|
||||
|
@ -179,7 +179,7 @@ the file input element to select a spreadsheet and clicking the export button.
|
|||
5) To build a standalone app, run the builder:
|
||||
|
||||
```bash
|
||||
npx -p nw-builder nwbuild --mode=build --version=0.82.0 --glob=false --outDir=../out ./
|
||||
npx -p nw-builder nwbuild --mode=build --version=0.83.0 --glob=false --outDir=../out ./
|
||||
```
|
||||
|
||||
This will generate the standalone app in the `..\out\` folder.
|
||||
|
|
|
@ -196,7 +196,7 @@ This demo was tested in the following environments:
|
|||
| macOS 14.0 | `darwin-arm` | `v4.14.1` | `v3.12.0` | 2023-10-18 |
|
||||
| Windows 10 | `win10-x64` | `v4.14.1` | `v3.12.0` | 2023-12-09 |
|
||||
| Windows 11 | `win11-arm` | `v4.14.1` | `v3.12.0` | 2023-12-01 |
|
||||
| Linux (HoloOS) | `linux-x64` | `v4.14.1` | `v3.12.0` | 2023-12-09 |
|
||||
| Linux (HoloOS) | `linux-x64` | `v4.14.1` | `v3.12.0` | 2024-01-26 |
|
||||
| Linux (Debian) | `linux-arm` | `v4.14.1` | `v3.12.0` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
|
@ -238,7 +238,7 @@ curl -L -o resources/js/xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}
|
|||
|
||||
3) Add the highlighted line to `neutralino.config.json` in `nativeAllowList`:
|
||||
|
||||
```json title="neutralino.config.json"
|
||||
```json title="neutralino.config.json (add highlighted line)"
|
||||
"nativeAllowList": [
|
||||
"app.*",
|
||||
"os.*",
|
||||
|
|
|
@ -49,37 +49,37 @@ This demo was tested in the following deployments:
|
|||
<Tabs groupId="njs">
|
||||
<TabItem value="nexe" label="Nexe">
|
||||
|
||||
| Architecture | Version | Node Target | Date |
|
||||
|:-------------|:-------------|:------------|:-----------|
|
||||
| `darwin-x64` | `4.0.0-rc.2` | `14.15.3` | 2023-10-10 |
|
||||
| `darwin-arm` | `4.0.0-rc.2` | `18.18.0` | 2023-12-01 |
|
||||
| `win10-x64` | `4.0.0-rc.2` | `14.15.3` | 2023-10-09 |
|
||||
| `win11-arm` | `4.0.0-rc.2` | `20.10.0` | 2023-12-01 |
|
||||
| `linux-x64` | `4.0.0-rc.2` | `14.15.3` | 2023-12-07 |
|
||||
| `linux-arm` | `4.0.0-rc.2` | `20.10.0` | 2023-12-01 |
|
||||
| Architecture | Version | NodeJS | Source | Date |
|
||||
|:-------------|:-------------|:----------|:----------|:-----------|
|
||||
| `darwin-x64` | `4.0.0-rc.2` | `14.15.3` | Pre-built | 2023-10-10 |
|
||||
| `darwin-arm` | `4.0.0-rc.2` | `18.18.0` | Compiled | 2023-12-01 |
|
||||
| `win10-x64` | `4.0.0-rc.2` | `14.15.3` | Pre-built | 2023-10-09 |
|
||||
| `win11-arm` | `4.0.0-rc.2` | `20.10.0` | Compiled | 2023-12-01 |
|
||||
| `linux-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-01-26 |
|
||||
| `linux-arm` | `4.0.0-rc.2` | `20.10.0` | Compiled | 2023-12-01 |
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="pkg" label="pkg">
|
||||
|
||||
| Architecture | Version | Node Target | Date |
|
||||
|:-------------|:--------|:------------|:-----------|
|
||||
| `darwin-x64` | `5.8.1` | `18.5.0` | 2023-10-11 |
|
||||
| `darwin-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
| `win10-x64` | `5.8.1` | `18.5.0` | 2023-10-09 |
|
||||
| `win11-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
| `linux-x64` | `5.8.1` | `18.5.0` | 2023-12-07 |
|
||||
| `linux-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
| Architecture | Version | NodeJS | Date |
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `5.8.1` | `18.5.0` | 2023-10-11 |
|
||||
| `darwin-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
| `win10-x64` | `5.8.1` | `18.5.0` | 2023-10-09 |
|
||||
| `win11-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
| `linux-x64` | `5.8.1` | `18.5.0` | 2024-01-26 |
|
||||
| `linux-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="boxednode" label="boxednode">
|
||||
|
||||
| Architecture | Version | Node Target | Date |
|
||||
|:-------------|:--------|:------------|:-----------|
|
||||
| `darwin-x64` | `2.1.2` | `20.8.0` | 2023-10-12 |
|
||||
| `darwin-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
|
||||
| `win10-x64` | `2.1.2` | `16.20.2` | 2023-10-09 |
|
||||
| `linux-x64` | `2.3.0` | `21.4.0` | 2023-12-07 |
|
||||
| `linux-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
|
||||
| Architecture | Version | NodeJS | Date |
|
||||
|:-------------|:--------|:----------|:-----------|
|
||||
| `darwin-x64` | `2.1.2` | `20.8.0` | 2023-10-12 |
|
||||
| `darwin-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
|
||||
| `win10-x64` | `2.1.2` | `16.20.2` | 2023-10-09 |
|
||||
| `linux-x64` | `2.3.0` | `21.6.1` | 2024-01-26 |
|
||||
| `linux-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
@ -309,7 +309,7 @@ This demo was last tested in the following deployments:
|
|||
| `darwin-arm` | `11.8.172.13` | `0.79.2` | 2023-10-18 |
|
||||
| `win10-x64` | `11.8.172.13` | `0.79.2` | 2023-10-09 |
|
||||
| `win11-x64` | `11.8.172.13` | `0.79.2` | 2023-10-14 |
|
||||
| `linux-x64` | `11.8.172.13` | `0.79.2` | 2023-10-11 |
|
||||
| `linux-x64` | `12.0.267.8` | `0.83.1` | 2024-01-26 |
|
||||
| `linux-arm` | `12.0.267.8` | `0.82.0` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
|
|
|
@ -26,11 +26,18 @@ This demo was verified by NetSuite consultants in the following deployments:
|
|||
|:----------------|:---------------|:-----------|
|
||||
| ScheduledScript | 2.1 | 2023-12-13 |
|
||||
| Restlet | 2.1 | 2023-10-05 |
|
||||
| Suitelet | 2.1 | 2024-01-17 |
|
||||
| Suitelet | 2.1 | 2024-01-26 |
|
||||
| MapReduceScript | 2.1 | 2023-12-07 |
|
||||
|
||||
:::
|
||||
|
||||
:::info pass
|
||||
|
||||
[See issue #3058](https://git.sheetjs.com/sheetjs/sheetjs/issues/3058) in the
|
||||
issue tracker for more examples submitted by NetSuite consultants.
|
||||
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
In SuiteScript parlance, third-party scripts are "Custom Modules"[^2].
|
||||
|
@ -126,6 +133,19 @@ define(
|
|||
|
||||
### Reading Files
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph NetSuite Operations
|
||||
cab[(File\nCabinet)]
|
||||
file(File)
|
||||
base64{{Base64\nString}}
|
||||
end
|
||||
wb(((SheetJS\nWorkbook)))
|
||||
cab --> |`load`\nN/file| file
|
||||
file --> |`getContents`\nFile method| base64
|
||||
base64 --> |`read`\nSheetJS| wb
|
||||
```
|
||||
|
||||
There are three steps to reading files:
|
||||
|
||||
1) Pull files from the file cabinet using `file.load`[^7]. The method returns a
|
||||
|
@ -156,6 +176,19 @@ workbook object.
|
|||
|
||||
### Writing Files
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
wb(((SheetJS\nWorkbook)))
|
||||
subgraph NetSuite Operations
|
||||
base64{{Base64\nString}}
|
||||
file(File)
|
||||
cab[(File\nCabinet)]
|
||||
end
|
||||
wb --> |`write`\nSheetJS| base64
|
||||
base64 --> |`create`\nN/file| file
|
||||
file --> |`save`\nFile method| cab
|
||||
```
|
||||
|
||||
There are three steps to writing files:
|
||||
|
||||
1) Write the data with the SheetJS `write` method[^11]. Using the `base64` output
|
||||
|
@ -171,7 +204,7 @@ There are three steps to writing files:
|
|||
var out = XLSX.write(workbook, { bookType: "xlsx", type: "base64" });
|
||||
/* create file */
|
||||
var newfile = file.create({
|
||||
name: 'test.xlsx', // replace with desired name
|
||||
name: 'SheetJSCabinetExport.xlsx', // replace with desired name
|
||||
fileType: file.Type.EXCEL,
|
||||
contents: out
|
||||
});
|
||||
|
@ -179,6 +212,137 @@ var newfile = file.create({
|
|||
newfile.save();
|
||||
```
|
||||
|
||||
## Sheets in Suitelet Requests
|
||||
|
||||
Suitelets are driven by an exported `onRequest` method[^15].
|
||||
|
||||
The `request` property of the argument is a `ServerRequest` object[^16]. The
|
||||
`files` property of the request[^17] is an object whose values are `file` objects.
|
||||
|
||||
The `response` property of the argument is a `ServerResponse` object[^18]. The
|
||||
`writeFile` method[^19] of the response can respond with a `file` object.
|
||||
For the examples in this section, the argument will be named `context`:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @NApiVersion 2.1
|
||||
* @NAmdConfig ./JsLibraryConfig.json
|
||||
* @NScriptType Suitelet
|
||||
*/
|
||||
define(['N/file', 'xlsx'], function (file, XLSX) {
|
||||
function onRequest(context) {
|
||||
/* ServerRequest object */
|
||||
var request = context.request;
|
||||
|
||||
/* ServerResponse object */
|
||||
var response = context.response;
|
||||
|
||||
// ... do work here ...
|
||||
}
|
||||
|
||||
return { onRequest: onRequest };
|
||||
});
|
||||
```
|
||||
|
||||
### Importing Sheet Data
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph NetSuite Operations
|
||||
req((Suitelet\nRequest))
|
||||
file(File)
|
||||
base64{{Base64\nString}}
|
||||
end
|
||||
wb(((SheetJS\nWorkbook)))
|
||||
req --> |`files`\nrequest data| file
|
||||
file --> |`getContents`\nFile method| base64
|
||||
base64 --> |`read`\nSheetJS| wb
|
||||
```
|
||||
|
||||
There are three steps to importing data from Suitelet requests:
|
||||
|
||||
1) Pull files from the `request.files` object.[^20]. Each value in the object is
|
||||
a `file.File` object which represents the file metadata.
|
||||
|
||||
2) Read raw data from the file using `File#getContents`[^21]. The method returns
|
||||
the data as a Base64-encoded string.
|
||||
|
||||
3) Parse the data with the SheetJS `read` method[^22]. This method returns a
|
||||
SheetJS workbook object.
|
||||
|
||||
```js
|
||||
/* form element ID or field name */
|
||||
var id_of_file = "uploaded_file"
|
||||
/* get file from request */
|
||||
var f = context.request.files[id_of_file];
|
||||
/* read file */
|
||||
var b64 = f.getContents();
|
||||
/* parse */
|
||||
var workbook = XLSX.read(b64, { type: "base64" });
|
||||
```
|
||||
|
||||
At this point, standard SheetJS utility functions[^23] can extract data from the
|
||||
workbook object.
|
||||
|
||||
:::note pass
|
||||
|
||||
When programmatically creating a form with `N/ui/serverWidget`, the keys of the
|
||||
`files` object are determined by the `id` properties of the field.
|
||||
|
||||
```js
|
||||
var form = serverWidget.createForm({ title: "Upload Spreadsheet" });
|
||||
var field = form.addField({
|
||||
// highlight-next-line
|
||||
id: "uploaded_file",
|
||||
label: "Choose Spreadsheet",
|
||||
type: serverWidget.FieldType.FILE
|
||||
});
|
||||
```
|
||||
|
||||
Since the `id` of the file field is `uploaded_file`, the request handler can
|
||||
access the file at at `context.request.files["uploaded_file"]`
|
||||
|
||||
:::
|
||||
|
||||
### Exporting Files
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
wb(((SheetJS\nWorkbook)))
|
||||
subgraph NetSuite Operations
|
||||
base64{{Base64\nString}}
|
||||
file(File)
|
||||
res[(Suitelet\nResponse)]
|
||||
end
|
||||
wb --> |`write`\nSheetJS| base64
|
||||
base64 --> |`create`\nN/file| file
|
||||
file --> |`writeFile`\nResponse method| res
|
||||
```
|
||||
|
||||
There are three steps to generating downloadable files:
|
||||
|
||||
1) Write the data with the SheetJS `write` method[^24]. Using the `base64` output
|
||||
type[^25], the method will return a Base64 string.
|
||||
|
||||
2) Create a new file using `file.create`[^26]. The recommended file type is
|
||||
`file.Type.EXCEL`. The method returns a `file.File` object.
|
||||
|
||||
3) Initiate download with `response.writeFile`[^27].
|
||||
|
||||
```js
|
||||
/* write XLSX workbook as Base64 string */
|
||||
var out = XLSX.write(workbook, { bookType: "xlsx", type: "base64" });
|
||||
/* create file */
|
||||
var newfile = file.create({
|
||||
name: 'SheetJSSuiteletExport.xlsx', // replace with desired name
|
||||
fileType: file.Type.EXCEL,
|
||||
contents: out
|
||||
});
|
||||
/* initiate download */
|
||||
context.response.writeFile(newfile);
|
||||
```
|
||||
|
||||
|
||||
[^1]: See ["SuiteScript 2.x API Introduction"](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_4387172221.html) in the NetSuite documentation.
|
||||
[^2]: See ["SuiteScript 2.x Custom Modules"](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_4704097697.html) in the NetSuite documentation.
|
||||
[^3]: See ["Java + Rhino" demo](/docs/demos/engines/rhino)
|
||||
|
@ -191,5 +355,18 @@ newfile.save();
|
|||
[^10]: See ["Utility Functions"](/docs/api/utilities/)
|
||||
[^11]: See [`write` in "Writing Files"](/docs/api/write-options)
|
||||
[^12]: See ["Supported Output Formats"](/docs/api/write-options#supported-output-formats)
|
||||
[^13]: See [`file.create`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4223861820.html) in the NetSuite documentation.
|
||||
[^14]: See [`File.save()`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4229271179.html) in the NetSuite documentation.
|
||||
[^13]: See [`file.create(options)`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4223861820.html) in the NetSuite documentation.
|
||||
[^14]: See [`File.save()`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4229271179.html) in the NetSuite documentation.
|
||||
[^15]: See [`onRequest(params)`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4407987288.html) in the NetSuite documentation.
|
||||
[^16]: See [`http.ServerRequest`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4314608702.html) in the NetSuite documentation.
|
||||
[^17]: See [`ServerRequest.files`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4314805947.html) in the NetSuite documentation.
|
||||
[^18]: See [`http.ServerResponse`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4314609319.html) in the NetSuite documentation.
|
||||
[^19]: See [`ServerResponse.writeFile(options)`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4426015540.html) in the NetSuite documentation.
|
||||
[^20]: See [`ServerRequest.files`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4314805947.html) in the NetSuite documentation.
|
||||
[^21]: See [`File.getContents()`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4229269811.html) in the NetSuite documentation.
|
||||
[^22]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^23]: See ["Utility Functions"](/docs/api/utilities/)
|
||||
[^24]: See [`write` in "Writing Files"](/docs/api/write-options)
|
||||
[^25]: See ["Supported Output Formats"](/docs/api/write-options#supported-output-formats)
|
||||
[^26]: See [`file.create(options)`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4223861820.html) in the NetSuite documentation.
|
||||
[^27]: See [`ServerResponse.writeFile(options)`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4426015540.html) in the NetSuite documentation.
|
||||
|
|
|
@ -134,7 +134,7 @@ This demo was tested in the following deployments:
|
|||
| `darwin-arm` | `2.7.0` | 2023-10-18 |
|
||||
| `win10-x64` | `2.7.0` | 2023-10-27 |
|
||||
| `win11-arm` | `2.7.0` | 2023-12-01 |
|
||||
| `linux-x64` | `2.7.0` | 2023-12-07 |
|
||||
| `linux-x64` | `2.7.0` | 2024-01-26 |
|
||||
| `linux-arm` | `2.7.0` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
|
@ -347,9 +347,75 @@ sequenceDiagram
|
|||
Bindings exist for many languages. As these bindings require "native" code, they
|
||||
may not work on every platform.
|
||||
|
||||
### PHP
|
||||
|
||||
There is no official PHP binding to the Duktape library. Instead, this demo uses
|
||||
the raw `FFI` interface[^1] to the Duktape shared library.
|
||||
|
||||
#### PHP Demo
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | PHP Version | Date |
|
||||
|:-------------|:--------|:------------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | `8.3.2` | 2024-01-26 |
|
||||
|
||||
:::
|
||||
|
||||
0) Ensure `php` is installed and available on the system path.
|
||||
|
||||
1) Build the Duktape shared library:
|
||||
|
||||
```bash
|
||||
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
|
||||
tar -xJf duktape-2.7.0.tar.xz
|
||||
cd duktape-2.7.0
|
||||
make -f Makefile.sharedlibrary
|
||||
cd ..
|
||||
```
|
||||
|
||||
2) Copy the shared library to the current folder. When the demo was last tested,
|
||||
the file name was `libduktape.207.20700.so`:
|
||||
|
||||
```bash
|
||||
cp duktape-*/libduktape.*.so .
|
||||
```
|
||||
|
||||
3) Download the SheetJS Standalone script, shim script and test file. Move all
|
||||
three files to the project directory:
|
||||
|
||||
<ul>
|
||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
|
||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
|
||||
<li><a href="https://sheetjs.com/pres.numbers">pres.numbers</a></li>
|
||||
</ul>
|
||||
|
||||
<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>
|
||||
|
||||
4) Download [`SheetJSDuk.php`](pathname:///duk/SheetJSDuk.php):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/duk/SheetJSDuk.php
|
||||
```
|
||||
|
||||
5) Run the script:
|
||||
|
||||
```bash
|
||||
php SheetJSDuk.php pres.numbers
|
||||
```
|
||||
|
||||
If the program succeeded, the CSV contents will be printed to console and the
|
||||
file `sheetjsw.xlsb` will be created. That file can be opened with Excel.
|
||||
|
||||
### Perl
|
||||
|
||||
The Perl binding for Duktape is available as `JavaScript::Duktape` on CPAN.
|
||||
The Perl binding for Duktape is available as `JavaScript::Duktape::XS` on CPAN.
|
||||
|
||||
The Perl binding does not have raw `Buffer` ops, so Base64 strings are used.
|
||||
|
||||
|
@ -361,17 +427,17 @@ This demo was tested in the following deployments:
|
|||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `2.5.0` | 2023-10-26 |
|
||||
| `linux-arm` | `2.5.0` | 2023-12-01 |
|
||||
| `darwin-x64` | `2.2.0` | 2024-01-26 |
|
||||
| `linux-x64` | `2.2.0` | 2024-01-26 |
|
||||
|
||||
:::
|
||||
|
||||
0) Ensure `perl` and `cpan` are installed and available on the system path.
|
||||
|
||||
1) Install the `JavaScript::Duktape` library:
|
||||
1) Install the `JavaScript::Duktape::XS` library:
|
||||
|
||||
```bash
|
||||
cpan install JavaScript::Duktape
|
||||
cpan install JavaScript::Duktape::XS
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
@ -379,7 +445,7 @@ cpan install JavaScript::Duktape
|
|||
On some systems, the command must be run as the root user:
|
||||
|
||||
```bash
|
||||
sudo cpan install JavaScript::Duktape
|
||||
sudo cpan install JavaScript::Duktape::XS
|
||||
```
|
||||
|
||||
:::
|
||||
|
@ -388,12 +454,12 @@ sudo cpan install JavaScript::Duktape
|
|||
|
||||
```perl title="SheetJSDuk.pl"
|
||||
# usage: perl SheetJSDuk.pl path/to/file
|
||||
use JavaScript::Duktape;
|
||||
use JavaScript::Duktape::XS;
|
||||
use File::Slurp;
|
||||
use MIME::Base64 qw( encode_base64 decode_base64 );
|
||||
|
||||
# Initialize
|
||||
my $js = JavaScript::Duktape->new( max_memory => 256 * 1024 * 1024 );
|
||||
my $js = JavaScript::Duktape::XS->new({ max_memory_bytes => 256 * 1024 * 1024 });
|
||||
$js->eval("var global = (function(){ return this; }).call(null);");
|
||||
|
||||
# Load the ExtendScript build
|
||||
|
@ -452,4 +518,6 @@ The fix is to install `File::Slurp` with `cpan`:
|
|||
sudo cpan install File::Slurp
|
||||
```
|
||||
|
||||
:::
|
||||
:::
|
||||
|
||||
[^1]: See [Foreign Function Interface](https://www.php.net/manual/en/book.ffi.php) in the PHP documentation.
|
|
@ -30,7 +30,7 @@ covers V8 engine bindings for other programming languages.
|
|||
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
|
||||
can be parsed and evaluated in a V8 context.
|
||||
|
||||
_Initialize V8_
|
||||
### Initialize V8
|
||||
|
||||
The official V8 `hello-world` example covers initialization and cleanup. For the
|
||||
purposes of this demo, the key variables are noted below:
|
||||
|
@ -50,7 +50,7 @@ v8::Local<v8::Value> eval_code(v8::Isolate *isolate, v8::Local<v8::Context> cont
|
|||
}
|
||||
```
|
||||
|
||||
_Load SheetJS Scripts_
|
||||
### Load SheetJS Scripts
|
||||
|
||||
The main library can be loaded by reading the scripts from the file system and
|
||||
evaluating in the V8 context:
|
||||
|
@ -127,7 +127,7 @@ This demo was tested in the following deployments:
|
|||
| `12.1.131` | `darwin-x64` | macOS 14.1 | `clang 15.0.0` | 2023-11-15 |
|
||||
| `12.1.283` | `darwin-arm` | macOS 14.1.2 | `clang 15.0.0` | 2023-12-01 |
|
||||
| `12.0.265` | `win10-x64` | Windows 10 | `CL 19.37.32822` | 2023-10-28 |
|
||||
| `12.1.222` | `linux-x64` | HoloOS 3.5.7 | `gcc 13.1.1` | 2023-11-27 |
|
||||
| `12.3.50` | `linux-x64` | HoloOS 3.5.7 | `gcc 13.1.1` | 2024-01-26 |
|
||||
| `11.8.82` | `linux-arm` | Debian 12 | `gcc 12.2.0` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
|
@ -406,11 +406,11 @@ The recommended fix is to delete the referenced folder and re-run `gclient sync`
|
|||
</Tabs>
|
||||
|
||||
|
||||
5) Checkout the desired version. The following command pulls `12.1.283`:
|
||||
5) Checkout the desired version. The following command pulls `12.3.50`:
|
||||
|
||||
|
||||
```bash
|
||||
git checkout tags/12.1.283 -b sample
|
||||
git checkout tags/12.3.50 -b sample
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
@ -418,14 +418,14 @@ git checkout tags/12.1.283 -b sample
|
|||
The official documentation recommends:
|
||||
|
||||
```bash
|
||||
git checkout refs/tags/12.1.283 -b sample -t
|
||||
git checkout refs/tags/12.3.50 -b sample -t
|
||||
```
|
||||
|
||||
This command failed in local testing:
|
||||
|
||||
```
|
||||
E:\v8\v8>git checkout refs/tags/12.1.283 -b sample -t
|
||||
fatal: cannot set up tracking information; starting point 'refs/tags/12.1.283' is not a branch
|
||||
E:\v8\v8>git checkout refs/tags/12.3.50 -b sample -t
|
||||
fatal: cannot set up tracking information; starting point 'refs/tags/12.3.50' is not a branch
|
||||
```
|
||||
|
||||
:::
|
||||
|
@ -473,7 +473,8 @@ warnings. The error messages included the tag `-Werror`:
|
|||
1 error generated.
|
||||
```
|
||||
|
||||
This was resolved by manually editing `out.gn/x64.release.sample/args.gn`:
|
||||
This was resolved by manually editing `out.gn/x64.release.sample/args.gn`. The
|
||||
option `treat_warnings_as_errors` should be set to `false`:
|
||||
|
||||
```ninja title="out.gn/x64.release.sample/args.gn (add to file)"
|
||||
treat_warnings_as_errors = false
|
||||
|
@ -815,7 +816,7 @@ This demo was last tested in the following deployments:
|
|||
| `darwin-x64` | `0.81.0` | 2023-11-14 |
|
||||
| `darwin-arm` | `0.82.0` | 2023-12-01 |
|
||||
| `win10-x64` | `0.81.0` | 2023-11-14 |
|
||||
| `linux-x64` | `0.81.0` | 2023-11-27 |
|
||||
| `linux-x64` | `0.83.1` | 2024-01-26 |
|
||||
| `linux-arm` | `0.82.0` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
|
|
|
@ -98,7 +98,7 @@ This demo was tested in the following deployments:
|
|||
| `darwin-arm` | `873a149` | `1.21.3` | 2023-10-18 |
|
||||
| `win10-x64` | `b396bb4` | `1.21.3` | 2023-10-28 |
|
||||
| `win11-arm` | `b396bb4` | `1.21.1` | 2023-12-01 |
|
||||
| `linux-x64` | `fc55792` | `1.21.3` | 2023-10-11 |
|
||||
| `linux-x64` | `b396bb4` | `1.21.6` | 2024-01-26 |
|
||||
| `linux-arm` | `b396bb4` | `1.21.4` | 2023-12-01 |
|
||||
|
||||
At the time of writing, Goja did not have proper version numbers. Versions are
|
||||
|
|
|
@ -7,6 +7,8 @@ pagination_next: solutions/input
|
|||
---
|
||||
|
||||
import current from '/version.js';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[Hermes](https://hermesengine.dev/) is an embeddable JS engine written in C++.
|
||||
|
@ -26,7 +28,7 @@ command-line tool for reading data from files.
|
|||
:::info pass
|
||||
|
||||
Many Hermes functions are not documented. The explanation was verified against
|
||||
commit `49e1930`.
|
||||
commit `90e2b47`.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -106,7 +108,7 @@ be parsed and evaluated in a Hermes context.
|
|||
The main library can be loaded by reading the script from the file system and
|
||||
evaluating in the Hermes context.
|
||||
|
||||
:::tip pass
|
||||
:::note pass
|
||||
|
||||
There are nonstandard tricks to embed the entire script in the binary. There are
|
||||
language proposals such as `#embed` (mirroring the same feature in C23).
|
||||
|
@ -364,7 +366,7 @@ This demo was tested in the following deployments:
|
|||
|:-------------|:-----------|:-----------|
|
||||
| `darwin-x64` | `84732b3` | 2023-11-14 |
|
||||
| `darwin-arm` | `2b4f949` | 2023-10-18 |
|
||||
| `linux-x64` | `2b4f949` | 2023-10-11 |
|
||||
| `linux-x64` | `90e2b47` | 2024-01-26 |
|
||||
| `linux-arm` | `84732b3` | 2023-12-01 |
|
||||
|
||||
The main Hermes source tree does not have Windows support. The `hermes-windows`
|
||||
|
@ -480,7 +482,28 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
|||
curl -LO https://sheetjs.com/pres.numbers`}
|
||||
</CodeBlock>
|
||||
|
||||
7) Run the application:
|
||||
7) Copy the `libhermes` and `libjsi` libraries into the current folder:
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="linux" label="Linux">
|
||||
|
||||
```bash
|
||||
cp ./build_release/API/hermes/libhermes.so .
|
||||
cp ./build_release/jsi/libjsi.so .
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="darwin" label="MacOS">
|
||||
|
||||
```bash
|
||||
cp ./build_release/API/hermes/libhermes.dylib .
|
||||
cp ./build_release/jsi/libjsi.dylib .
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
8) Run the application:
|
||||
|
||||
```bash
|
||||
./sheetjs-hermes pres.numbers
|
||||
|
@ -663,7 +686,7 @@ contents of the first sheet as CSV rows.
|
|||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2023 November 04 against Hermes version `0.11.0`.
|
||||
This demo was last tested on 2023 November 04 against Hermes version `0.12.0`.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -675,7 +698,7 @@ as a Base64 string and directly add it to an amalgamated script.
|
|||
0) Install the Hermes command line tools:
|
||||
|
||||
```bash
|
||||
npx jsvu install hermes@0.11.0
|
||||
npx jsvu hermes@0.12.0
|
||||
```
|
||||
|
||||
When prompted, select the appropriate operating system.
|
||||
|
@ -685,10 +708,10 @@ When prompted, select the appropriate operating system.
|
|||
```text pass
|
||||
❯ Extracting…
|
||||
// highlight-next-line
|
||||
Installing binary to ~/.jsvu/engines/hermes-0.11.0/hermes-0.11.0…
|
||||
Installing symlink at ~/.jsvu/bin/hermes-0.11.0 pointing to ~/.jsvu/engines/hermes-0.11.0/hermes-0.11.0…
|
||||
Installing binary to ~/.jsvu/engines/hermes-0.11.0/hermes-0.11.0-compiler…
|
||||
Installing symlink at ~/.jsvu/bin/hermes-0.11.0-compiler pointing to ~/.jsvu/engines/hermes-0.11.0/hermes-0.11.0-compiler…
|
||||
Installing binary to ~/.jsvu/engines/hermes-0.12.0/hermes-0.12.0…
|
||||
Installing symlink at ~/.jsvu/bin/hermes-0.12.0 pointing to ~/.jsvu/engines/hermes-0.12.0/hermes-0.12.0…
|
||||
Installing binary to ~/.jsvu/engines/hermes-0.12.0/hermes-0.12.0-compiler…
|
||||
Installing symlink at ~/.jsvu/bin/hermes-0.12.0-compiler pointing to ~/.jsvu/engines/hermes-0.12.0/hermes-0.12.0-compiler…
|
||||
```
|
||||
|
||||
The first "Installing binary" line mentions the path to the `hermes` tool.
|
||||
|
@ -705,7 +728,7 @@ cd sheetjs-hermes-cli
|
|||
3) Copy the binary from Step 1 into the current folder. For example, on macOS:
|
||||
|
||||
```bash
|
||||
cp ~/.jsvu/engines/hermes-0.11.0/hermes-0.11.0 .
|
||||
cp ~/.jsvu/engines/hermes-0.12.0/hermes-0.12.0 .
|
||||
```
|
||||
|
||||
#### Create Script
|
||||
|
@ -759,7 +782,7 @@ ready, it will read the bundled test data and print the contents as CSV.
|
|||
8) Run the script using the Hermes standalone binary:
|
||||
|
||||
```bash
|
||||
./hermes-0.11.0 sheetjs.hermes.js
|
||||
./hermes-0.12.0 sheetjs.hermes.js
|
||||
```
|
||||
|
||||
If successful, the script will print CSV data from the test file.
|
||||
|
|
|
@ -74,7 +74,7 @@ This demo was tested in the following deployments:
|
|||
| `darwin-arm` | `2.6.10` | `2.9.1` | 2023-12-01 |
|
||||
| `win10-x64` | `3.2.2` | `2.9.1` | 2023-10-28 |
|
||||
| `win11-arm` | `3.0.2` | `2.9.1` | 2023-12-01 |
|
||||
| `linux-x64` | `3.0.4` | `2.9.1` | 2023-10-11 |
|
||||
| `linux-x64` | `3.0.5` | `2.9.1` | 2024-01-26 |
|
||||
| `linux-arm` | `2.7.4` | `2.9.1` | 2023-12-01 |
|
||||
|
||||
**Note: The Windows 11 ARM64 test used the Ruby version that ships with WSL.**
|
||||
|
|
|
@ -135,7 +135,7 @@ This demo was tested in the following deployments:
|
|||
| `darwin-x64` | `c3ead3f` | 2023-11-04 |
|
||||
| `darwin-arm` | `c3ead3f` | 2023-10-19 |
|
||||
| `win10-x64` | `c3ead3f` | 2023-10-28 |
|
||||
| `linux-x64` | `c3ead3f` | 2023-12-09 |
|
||||
| `linux-x64` | `c3ead3f` | 2024-01-26 |
|
||||
|
||||
:::
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ This demo was tested in the following deployments:
|
|||
| `darwin-arm` | 2023-10-20 |
|
||||
| `win10-x64` | 2023-10-28 |
|
||||
| `win11-arm` | 2023-12-01 |
|
||||
| `linux-x64` | 2023-12-07 |
|
||||
| `linux-x64` | 2024-01-26 |
|
||||
| `linux-arm` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
|
|
|
@ -40,13 +40,11 @@ This demo was tested in the following environments:
|
|||
| `darwin-arm` | `ef4cb2b` | 2023-12-08 |
|
||||
| `win11-x64` | `ef4cb2b` | 2023-12-08 |
|
||||
| `win11-arm` | `ef4cb2b` | 2023-12-08 |
|
||||
| `linux-x64` | `ef4cb2b` | 2023-12-08 |
|
||||
| `linux-x64` | `514fa67` | 2024-01-26 |
|
||||
| `linux-arm` | `ef4cb2b` | 2023-12-08 |
|
||||
|
||||
The Windows tests were run in WSL.
|
||||
|
||||
Debian and WSL require the `cmake`, `python3` and `python-is-python3` packages.
|
||||
|
||||
:::
|
||||
|
||||
## Integration Details
|
||||
|
@ -343,6 +341,14 @@ while the "CLI Test" demonstrates other concepts using the `jerry` CLI tool.
|
|||
|
||||
### Integration Example
|
||||
|
||||
<details><summary><b>Build Dependencies</b> (click to show)</summary>
|
||||
|
||||
The JerryScript build system requires `cmake`.
|
||||
|
||||
Debian and WSL additionally require `python3` and `python-is-python3` packages.
|
||||
|
||||
</details>
|
||||
|
||||
1) Create a project folder:
|
||||
|
||||
```bash
|
||||
|
@ -384,7 +390,7 @@ curl -LO https://docs.sheetjs.com/jerryscript/sheetjs.jerry.c
|
|||
5) Build the sample application:
|
||||
|
||||
```bash
|
||||
gcc -o sheetjs.jerry -Ijerryscript/jerry-ext/include -Ijerryscript/jerry-math/include -Ijerryscript/jerry-core/include -ljerry-ext -ljerry-port -ljerry-core -Ljerryscript/build/lib sheetjs.jerry.c -Wno-pointer-sign
|
||||
gcc -o sheetjs.jerry -Ijerryscript/jerry-ext/include -Ijerryscript/jerry-math/include -Ijerryscript/jerry-core/include sheetjs.jerry.c -ljerry-core -ljerry-ext -ljerry-port -lm -Ljerryscript/build/lib -Wno-pointer-sign
|
||||
```
|
||||
|
||||
6) Run the test program:
|
||||
|
|
|
@ -8,22 +8,28 @@ import current from '/version.js';
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import EngineData from '/data/engines.js'
|
||||
|
||||
Browser vendors and other organizations have built "JavaScript engines". They
|
||||
are independent software libraries that are capable of running JS scripts.
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
The most popular JavaScript engine is V8. Designed for embedding in software,
|
||||
it powers Chrome, NodeJS, UXP, Deno and many other platforms.
|
||||
JavaScript code cannot be directly executed on most modern computers. A software
|
||||
component ("JavaScript engine") executes code. There are many engines designed
|
||||
for embedding in other applications. After embedding a JS engine in software,
|
||||
programs can leverage SheetJS libraries to process spreadsheets and data.
|
||||
|
||||
There are many other JS engines with different design goals. Some are designed
|
||||
for low-power or low-memory environments. Others aim for interoperability with
|
||||
specific programming languages or environments. Typically they support ES3 and
|
||||
are capable of running SheetJS code.
|
||||
The demos in this section showcase a number of JS engines and language bindings.
|
||||
In each case, we will build a sample application that embeds a JS engine, loads
|
||||
SheetJS library scripts, and reads and writes spreadsheet files.
|
||||
|
||||
This demo showcases a number of JS engines and language bindings.
|
||||
|
||||
## General Caveats
|
||||
|
||||
There are many other JS engines with different design goals. Some are designed
|
||||
for low-power or low-memory environments. Others aim for interoperability with
|
||||
specific programming languages or environments. Typically they support ES3 and
|
||||
are capable of running SheetJS code.
|
||||
|
||||
Common browser and NodeJS APIs are often missing from light-weight JS engines.
|
||||
|
||||
#### Global
|
||||
|
@ -76,21 +82,28 @@ for(var i = 0; i < signed_data.length; ++i) fixed_data[i] = signed_data[i] & 0xF
|
|||
|
||||
## Engines
|
||||
|
||||
This list is sorted in alphabetical order.
|
||||
:::info pass
|
||||
|
||||
### Boa
|
||||
Demos are tested across multiple operating systems (Windows, MacOS and Linux)
|
||||
across multiple architectures (x64 and ARM64).
|
||||
|
||||
:::
|
||||
|
||||
<EngineData/>
|
||||
|
||||
#### Boa
|
||||
|
||||
Boa is an embeddable JS engine written in Rust.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/boa).
|
||||
|
||||
### ChakraCore
|
||||
#### ChakraCore
|
||||
|
||||
ChakraCore is an embeddable JS engine written in C++.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/chakra).
|
||||
|
||||
### Duktape
|
||||
#### Duktape
|
||||
|
||||
Duktape is an embeddable JS engine written in C. It has been ported to a number
|
||||
of exotic architectures and operating systems.
|
||||
|
@ -98,45 +111,45 @@ of exotic architectures and operating systems.
|
|||
This demo has been moved [to a dedicated page](/docs/demos/engines/duktape).
|
||||
The demo includes examples in C and Perl.
|
||||
|
||||
### Goja
|
||||
#### Goja
|
||||
|
||||
Goja is a pure Go implementation of ECMAScript 5.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/goja).
|
||||
|
||||
### Hermes
|
||||
#### Hermes
|
||||
|
||||
Hermes is an embeddable JS engine written in C++.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/hermes).
|
||||
|
||||
### JavaScriptCore
|
||||
#### JavaScriptCore
|
||||
|
||||
iOS and MacOS ship with the JavaScriptCore framework for running JS code from
|
||||
Swift and Objective-C.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/jsc).
|
||||
|
||||
### JerryScript
|
||||
#### JerryScript
|
||||
|
||||
JerryScript is a lightweight JavaScript engine designed for use in low-memory
|
||||
environments including microcontrollers.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/jerryscript).
|
||||
|
||||
### Jint
|
||||
#### Jint
|
||||
|
||||
Jint is an embeddable JS engine for .NET written in C#.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/jint).
|
||||
|
||||
### Nashorn
|
||||
#### Nashorn
|
||||
|
||||
Nashorn shipped with some versions of Java. It is now a standalone library.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/nashorn).
|
||||
|
||||
### QuickJS
|
||||
#### QuickJS
|
||||
|
||||
QuickJS is an embeddable JS engine written in C. It provides a separate set of
|
||||
functions for interacting with the filesystem and the global object. It can run
|
||||
|
@ -144,13 +157,13 @@ the standalone browser scripts.
|
|||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/quickjs).
|
||||
|
||||
### Rhino
|
||||
#### Rhino
|
||||
|
||||
Rhino is an ES3+ engine in Java.
|
||||
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/rhino).
|
||||
|
||||
### V8
|
||||
#### V8
|
||||
|
||||
V8 is an embeddable JS engine written in C++. It powers Chromium and Chrome,
|
||||
NodeJS and Deno, Adobe UXP and other platforms.
|
||||
|
|
|
@ -39,7 +39,7 @@ These instructions were tested on the following platforms:
|
|||
|
||||
| Platform | Architecture | Test Date |
|
||||
|:------------------------------|:-------------|:-----------|
|
||||
| Linux (Steam Deck Holo x64) | `linux-x64` | 2023-11-27 |
|
||||
| Linux (Steam Deck Holo x64) | `linux-x64` | 2024-01-26 |
|
||||
| Linux (Ubuntu 18 AArch64) | `linux-arm` | 2023-12-01 |
|
||||
| MacOS 10.13.6 (x64) | `darwin-x64` | 2023-09-30 |
|
||||
| MacOS 14.1.2 (ARM64) | `darwin-arm` | 2023-12-01 |
|
||||
|
|
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
v8 = "0.82.0"
|
||||
v8 = "0.83.1"
|
||||
|
||||
[[bin]]
|
||||
name = "sheet2csv"
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
$ffi = FFI::cdef('
|
||||
typedef int duk_int_t;
|
||||
typedef unsigned int duk_uint_t;
|
||||
typedef unsigned int duk_small_uint_t;
|
||||
typedef size_t duk_size_t;
|
||||
typedef duk_int_t duk_idx_t;
|
||||
typedef duk_small_uint_t duk_bool_t;
|
||||
|
||||
typedef struct duk_hthread duk_context;
|
||||
|
||||
void duk_push_undefined(duk_context *ctx);
|
||||
const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len);
|
||||
duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);
|
||||
void duk_pop(duk_context *ctx);
|
||||
void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len);
|
||||
void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags);
|
||||
duk_bool_t duk_put_global_string(duk_context *ctx, const char *key);
|
||||
duk_bool_t duk_get_global_string(duk_context *ctx, const char *key);
|
||||
void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);
|
||||
const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);
|
||||
void duk_destroy_heap(duk_context *ctx);
|
||||
duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);
|
||||
duk_context *duk_create_heap(void* alloc_func, void* realloc_func, void* free_func, void *heap_udata, void *fatal_handler);
|
||||
const char *duk_get_string(duk_context *ctx, duk_idx_t idx);
|
||||
', './libduktape.207.20700.so' );
|
||||
|
||||
function duk_create_heap_default() { global $ffi; return $ffi->duk_create_heap(null, null, null, null, null); }
|
||||
function duk_eval_string_noresult($context, $cmd) { global $ffi; return $ffi->duk_eval_raw($context, $cmd, 0, 1 | (1<<3) | (1<<9) | (1<<10) | (1<<8) | (1<<11) ); }
|
||||
function duk_eval_string($context, $cmd) { global $ffi; return $ffi->duk_eval_raw($context, $cmd, 0, 0 | (1<<3) | (1<<9) | (1<<10) | (1<<11) ); }
|
||||
function duk_peval($context) { global $ffi; return $ffi->duk_eval_raw($context, null, 0, 1 | (1<<3) | (1<<7) | (1<<11) ); }
|
||||
function duk_get_string($context, $idx) { global $ffi; return $ffi->duk_get_string($context, $idx); }
|
||||
function duk_pop($context) { global $ffi; return $ffi->duk_pop($context); }
|
||||
|
||||
function eval_file($context, $path) {
|
||||
global $ffi;
|
||||
$script = file_get_contents($path);
|
||||
$ffi->duk_push_lstring($context, $script, strlen($script));
|
||||
$retval = duk_peval($context);
|
||||
$ffi->duk_pop($context);
|
||||
return $retval;
|
||||
}
|
||||
function load_file($context, $path, $var) {
|
||||
global $ffi;
|
||||
$data = file_get_contents($path);
|
||||
|
||||
$ffi->duk_push_buffer_raw($context, 0, 1 | 2);
|
||||
$ffi->duk_config_buffer($context, -1, $data, strlen($data));
|
||||
$ffi->duk_put_global_string($context, $var);
|
||||
return 0;
|
||||
}
|
||||
function save_file($context, $path, $var) {
|
||||
global $ffi;
|
||||
$ffi->duk_get_global_string($context, $var);
|
||||
|
||||
$sz = $ffi->new("duk_size_t");
|
||||
$ptr = $ffi->duk_get_buffer_data($context, -1, FFI::addr($sz));
|
||||
$buf = FFI::string($ptr, strval($sz));
|
||||
|
||||
$fh = fopen($path, "wb");
|
||||
fwrite($fh, $buf, strval($sz));
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
|
||||
function DOIT($cmd) { global $context; return duk_eval_string_noresult($context, $cmd); }
|
||||
|
||||
/* initialize */
|
||||
$context = duk_create_heap_default();
|
||||
/* duktape does not expose a standard "global" by default */
|
||||
DOIT("var global = (function(){ return this; }).call(null);");
|
||||
|
||||
/* load library */
|
||||
eval_file($context, "shim.min.js");
|
||||
eval_file($context, "xlsx.full.min.js");
|
||||
|
||||
/* get version string */
|
||||
duk_eval_string($context, "XLSX.version");
|
||||
printf("SheetJS Library Version %s\n", duk_get_string($context, -1));
|
||||
duk_pop($context);
|
||||
|
||||
/* read file */
|
||||
$res = load_file($context, $argv[1], "buf");
|
||||
printf("Loaded file %s\n", $argv[1]);
|
||||
|
||||
/* parse workbook */
|
||||
DOIT("wb = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});");
|
||||
DOIT("ws = wb.Sheets[wb.SheetNames[0]]");
|
||||
|
||||
/* print CSV */
|
||||
duk_eval_string($context, "XLSX.utils.sheet_to_csv(ws)");
|
||||
printf("%s\n", duk_get_string($context, -1));
|
||||
duk_pop($context);
|
||||
|
||||
/* write file */
|
||||
DOIT("newbuf = (XLSX.write(wb, {type:'array', bookType:'xlsb'}));");
|
||||
save_file($context, "sheetjsw.xlsb", "newbuf");
|
||||
|
||||
/* cleanup */
|
||||
$ffi->duk_destroy_heap($context);
|
||||
return 0;
|
|
@ -6,7 +6,7 @@
|
|||
"version": "0.0.0",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
"@electron/remote": "2.0.11",
|
||||
"@electron/remote": "2.1.2",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -20,7 +20,7 @@
|
|||
"@electron-forge/maker-rpm": "7.2.0",
|
||||
"@electron-forge/maker-squirrel": "7.2.0",
|
||||
"@electron-forge/maker-zip": "7.2.0",
|
||||
"electron": "27.1.3"
|
||||
"electron": "28.2.0"
|
||||
},
|
||||
"config": {
|
||||
"forge": {
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
# Note: The official Hermes documentation includes zero guidance on embedding.
|
||||
# Tested against commit 84732b3ce6a859cbc6a20112437c81154f111fe7
|
||||
# Tested against commit 90e2b470b5f8ee8f64fd928ab0b75ee14190e6bb
|
||||
|
||||
MYCC=llvm-g++
|
||||
POSTAMBLE=-framework CoreFoundation
|
||||
|
||||
POSTAMBLE=-framework CoreFoundation -Wl,-rpath .
|
||||
UNAME__S := $(shell uname -s)
|
||||
ifeq ($(UNAME__S),Linux)
|
||||
MYCC=g++
|
||||
POSTAMBLE=-pthread -licuuc -licudata -licuio -licutu -licui18n
|
||||
POSTAMBLE=-pthread -licuuc -licudata -licuio -licutu -licui18n -Wl,-rpath=./
|
||||
endif
|
||||
|
||||
.PHONY: doit
|
||||
doit: sheetjs-hermes
|
||||
if [ ! -e xlsx.full.min.js ]; then curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js; fi
|
||||
if [ ! -e pres.numbers ]; then curl -LO https://sheetjs.com/pres.numbers; fi
|
||||
if [ -e ./build_release/API/hermes/libhermes.so ]; then cp ./build_release/API/hermes/libhermes.so .; fi
|
||||
if [ -e ./build_release/API/hermes/libhermes.dylib ]; then cp ./build_release/API/hermes/libhermes.dylib .; fi
|
||||
if [ -e ./build_release/jsi/libjsi.so ]; then cp ./build_release/jsi/libjsi.so .; fi
|
||||
if [ -e ./build_release/jsi/libjsi.dylib ]; then cp ./build_release/jsi/libjsi.dylib .; fi
|
||||
./sheetjs-hermes pres.numbers
|
||||
|
||||
.PHONY: clean
|
||||
|
@ -30,7 +33,7 @@ sheetjs-hermes: sheetjs-hermes.cpp init
|
|||
$(MYCC) $< -o $@ -std=gnu++17 \
|
||||
-Ihermes/include/ -Ihermes/API/ -Ihermes/API/jsi -Ihermes/public \
|
||||
-Lbuild_release/API/hermes/ -lsynthTrace -lsynthTraceParser \
|
||||
-lhermesapi \
|
||||
-lhermes \
|
||||
-Lbuild_release/lib/VM/ -lhermesVMRuntime \
|
||||
-Lbuild_release/lib/BCGen/HBC/ -lhermesHBCBackend \
|
||||
-Lbuild_release/lib/BCGen/ -lhermesBackend \
|
||||
|
@ -62,7 +65,10 @@ sheetjs-hermes: sheetjs-hermes.cpp init
|
|||
-Lbuild_release/external/dtoa/ -ldtoa \
|
||||
$(POSTAMBLE)
|
||||
|
||||
sheetjs-hermes.cpp:
|
||||
curl -LO https://docs.sheetjs.com/hermes/sheetjs-hermes.cpp
|
||||
|
||||
.PHONY: init
|
||||
init:
|
||||
if [ ! -e hermes ]; then git clone https://github.com/facebook/hermes.git; cd hermes; git checkout 84732b3ce6a859cbc6a20112437c81154f111fe7; cd ..; fi
|
||||
if [ ! -e build_release ]; then cmake -S hermes -B build_release -G Ninja -DCMAKE_BUILD_TYPE=Release; cmake --build ./build_release; fi
|
||||
if [ ! -e hermes ]; then git clone https://github.com/facebook/hermes.git; cd hermes; git checkout 90e2b470b5f8ee8f64fd928ab0b75ee14190e6bb; cd ..; fi
|
||||
if [ ! -e build_release ]; then cmake -S hermes -B build_release -G Ninja -DCMAKE_BUILD_TYPE=Release -DHERMES_BUILD_APPLE_FRAMEWORK=OFF; cmake --build ./build_release; fi
|
Loading…
Reference in New Issue