forked from sheetjs/docs.sheetjs.com
		
	engines
This commit is contained in:
		
							parent
							
								
									6e3b91f9e5
								
							
						
					
					
						commit
						4258609879
					
				
							
								
								
									
										21
									
								
								docz/data/engines.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								docz/data/engines.js
									
									
									
									
									
										Normal file
									
								
							| @ -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; | ||||
							
								
								
									
										321
									
								
								docz/data/engines.xls
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										321
									
								
								docz/data/engines.xls
									
									
									
									
									
										Normal file
									
								
							| @ -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" | ||||
|  | ||||
							
								
								
									
										102
									
								
								docz/static/duk/SheetJSDuk.php
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										102
									
								
								docz/static/duk/SheetJSDuk.php
									
									
									
									
									
										Normal file
									
								
							| @ -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
	
	Block a user