forked from sheetjs/docs.sheetjs.com
Compare commits
18 Commits
rasmus-pat
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 20a52fe655 | |||
| f77d0bd788 | |||
| f9dbcc069b | |||
| 38b268d40c | |||
| fc5a19d6cd | |||
| f5aabe0c29 | |||
| 7bb2ddcaea | |||
| a0e35dd7e1 | |||
| d922ad6246 | |||
| 5633b2387a | |||
| ef89abda1f | |||
| 6532f9fea8 | |||
| 67d7c1f993 | |||
| def11cf796 | |||
| b205f3f6a1 | |||
| f1a4f192d3 | |||
| 1327b2f98c | |||
| f39d01eb84 |
@ -1,417 +1,417 @@
|
||||
<?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="Calibri" 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>
|
||||
<Style ss:ID="s20">
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#467886" ss:Underline="Single"/>
|
||||
</Style>
|
||||
</Styles>
|
||||
<Worksheet ss:Name="Engines">
|
||||
<Table ss:ExpandedColumnCount="8" ss:ExpandedRowCount="18" 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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#complete-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#complete-example"><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"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/rhino#complete-example"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jsc#complete-example"><Data ss:Type="String">JSC</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jint#integration-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/goja#complete-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/nashorn#complete-example"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/quickjs#integration-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/hermes#integration-example"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/chakra#integration-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/boa#complete-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/perl#complete-example"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jerryscript#integration-example"><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>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/graaljs#complete-example"><Data ss:Type="String">GraalJS</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Java</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/mujs#integration-example"><Data ss:Type="String">MuJS</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jurassic#integration-example"><Data ss:Type="String">Jurassic.NET</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="20" 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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#perl"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#php"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#python"><Data ss:Type="String">Duktape</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Python</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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#rust"><Data ss:Type="String">Duktape</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#zig"><Data ss:Type="String">Duktape</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Zig</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#rust"><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: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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#java"><Data ss:Type="String">V8</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Java</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#c"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#python"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jsc#swift"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/jsc#rust"><Data ss:Type="String">JSC</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"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/rb#complete-example"><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>
|
||||
<?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="Calibri" 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>
|
||||
<Style ss:ID="s20">
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#467886" ss:Underline="Single"/>
|
||||
</Style>
|
||||
</Styles>
|
||||
<Worksheet ss:Name="Engines">
|
||||
<Table ss:ExpandedColumnCount="8" ss:ExpandedRowCount="18" 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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#complete-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#complete-example"><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"/>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/rhino#complete-example"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jsc#complete-example"><Data ss:Type="String">JSC</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jint#integration-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/goja#complete-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/nashorn#complete-example"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/quickjs#integration-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/hermes#integration-example"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/chakra#integration-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/boa#complete-example"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/perl#complete-example"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jerryscript#integration-example"><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>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/graaljs#complete-example"><Data ss:Type="String">GraalJS</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Java</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/mujs#integration-example"><Data ss:Type="String">MuJS</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jurassic#integration-example"><Data ss:Type="String">Jurassic.NET</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="20" 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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#perl"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#php"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"/>
|
||||
<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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#python"><Data ss:Type="String">Duktape</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Python</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#rust"><Data ss:Type="String">Duktape</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/duktape#zig"><Data ss:Type="String">Duktape</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Zig</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#rust"><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: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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#java"><Data ss:Type="String">V8</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Java</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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#c"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/v8#python"><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"><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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/jsc#swift"><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"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/engines/jsc#rust"><Data ss:Type="String">JSC</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"/>
|
||||
<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 ss:StyleID="s20" ss:HRef="/docs/demos/engines/rb#complete-example"><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>
|
||||
|
||||
@ -121,12 +121,12 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | BunJS | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `1.2.8` | 2025-03-31 |
|
||||
| `darwin-arm` | `1.2.7` | 2025-03-30 |
|
||||
| `win11-x64` | `1.2.8` | 2025-04-17 |
|
||||
| `win11-arm` | `1.2.3` | 2025-02-23 |
|
||||
| `linux-x64` | `1.2.10` | 2025-04-21 |
|
||||
| `linux-arm` | `1.2.2` | 2025-02-16 |
|
||||
| `darwin-x64` | `1.3.6` | 2026-01-20 |
|
||||
| `darwin-arm` | `1.3.6` | 2026-01-19 |
|
||||
| `win11-x64` | `1.3.6` | 2026-01-28 |
|
||||
| `win11-arm` | `1.3.10` | 2026-03-07 |
|
||||
| `linux-x64` | `1.3.6` | 2026-01-18 |
|
||||
| `linux-arm` | `1.3.10` | 2026-03-07 |
|
||||
|
||||
BunJS on Windows on ARM uses the X64 compatibility layer.
|
||||
|
||||
@ -137,42 +137,9 @@ BunJS on Windows on ARM uses the X64 compatibility layer.
|
||||
```bash
|
||||
mkdir sheetjs-bun-dle
|
||||
cd sheetjs-bun-dle
|
||||
echo "{}" > package.json
|
||||
bun init -y
|
||||
```
|
||||
|
||||
:::caution PowerShell Encoding Errors
|
||||
|
||||
The PowerShell file redirect will use the `UTF-16 LE` encoding. Bun does not
|
||||
support the encoding and will fail to install the package:
|
||||
|
||||
```
|
||||
bun add v1.1.42 (50eec002)
|
||||
1 | <20><>
|
||||
^
|
||||
error: Unexpected <20><>
|
||||
at <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:1:1
|
||||
```
|
||||
|
||||
The file must be resaved in UTF8 (without BOM) or ASCII.
|
||||
|
||||
0) Open `package.json` in VSCodium.
|
||||
|
||||
The current encoding is displayed in the lower-right corner:
|
||||
|
||||

|
||||
|
||||
1) Click the displayed encoding.
|
||||
|
||||
2) In the "Select Action" popup, select "Save with Encoding"
|
||||
|
||||
3) In the new list, select `UTF-8 utf8`:
|
||||
|
||||

|
||||
|
||||
VSCodium will automatically re-save the file.
|
||||
|
||||
:::
|
||||
|
||||
1) Install the SheetJS package tarball:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
|
||||
@ -469,14 +469,16 @@ The result is an array of "simple" objects with no nesting:
|
||||
|
||||
## Create a Workbook
|
||||
|
||||
With the cleaned dataset, `XLSX.utils.json_to_sheet`[^3] generates a worksheet:
|
||||
The [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input) method
|
||||
can generate a SheetJS worksheet from the cleaned dataset:
|
||||
|
||||
```js
|
||||
const worksheet = XLSX.utils.json_to_sheet(rows);
|
||||
```
|
||||
|
||||
`XLSX.utils.book_new`[^4] creates a new workbook and `XLSX.utils.book_append_sheet`[^5]
|
||||
appends a worksheet to the workbook. The new worksheet will be called "Dates":
|
||||
[`XLSX.utils.book_new`](/docs/api/utilities/wb) creates a new workbook and
|
||||
[`XLSX.utils.book_append_sheet`](/docs/api/utilities/wb) appends a worksheet to
|
||||
the workbook. The new worksheet will be called "Dates":
|
||||
|
||||
```js
|
||||
const workbook = XLSX.utils.book_new();
|
||||
@ -503,10 +505,12 @@ cell styling and frozen rows.
|
||||
<summary><b>Changing Header Names</b> (click to show)</summary>
|
||||
|
||||
By default, `json_to_sheet` creates a worksheet with a header row. In this case,
|
||||
the headers come from the JS object keys: "name" and "birthday".
|
||||
the headers come from the JS object keys: "name" and "birthday". The headers are
|
||||
written to the first row.
|
||||
|
||||
The headers are in cells `A1` and `B1`. `XLSX.utils.sheet_add_aoa`[^6] can write
|
||||
text values to the existing worksheet starting at cell `A1`:
|
||||
[`XLSX.utils.sheet_add_aoa`](/docs/api/utilities/array#array-of-arrays-input)
|
||||
can overwrite data in the worksheet. The following line will set `A1` to "Name"
|
||||
and set `B1` to "Birthday":
|
||||
|
||||
```js
|
||||
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
|
||||
@ -518,7 +522,7 @@ XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
|
||||
<summary><b>Changing Column Widths</b> (click to show)</summary>
|
||||
|
||||
Some of the names are longer than the default column width. Column widths are
|
||||
set by setting the `"!cols"` worksheet property.[^7]
|
||||
stored in the [`"!cols"` worksheet property](/docs/csf/features/colprops).
|
||||
|
||||
The following line sets the width of column A to approximately 10 characters:
|
||||
|
||||
@ -541,9 +545,9 @@ After cleanup, the generated workbook looks like the screenshot below:
|
||||
|
||||
## Export a File
|
||||
|
||||
`XLSX.writeFile`[^8] creates a spreadsheet file and tries to write it to the
|
||||
system. In the browser, it will try to prompt the user to download the file. In
|
||||
NodeJS, it will write to the local directory.
|
||||
[`XLSX.writeFile`](/docs/api/write-options) creates a spreadsheet file and tries
|
||||
to write it to the system. In the browser, it will try to prompt the user to
|
||||
download the file. In NodeJS, it will write to the local directory.
|
||||
|
||||
```js
|
||||
XLSX.writeFile(workbook, "Presidents.xlsx", { compression: true });
|
||||
@ -1165,14 +1169,8 @@ see a preview of the data. The Numbers app can open the file.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
[^1]: https://theunitedstates.io/congress-legislators/executive.json is the
|
||||
[^1]: `https://theunitedstates.io/congress-legislators/executive.json` is the
|
||||
original location of the example dataset. The contributors to the dataset
|
||||
dedicated the content to the public domain.
|
||||
dedicated the content to the public domain. When this demo was last tested,
|
||||
[^2]: See ["The Executive Branch"](https://github.com/unitedstates/congress-legislators#the-executive-branch)
|
||||
in the dataset documentation.
|
||||
[^3]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^4]: See [`book_new` in "Utilities"](/docs/api/utilities/wb)
|
||||
[^5]: See [`book_append_sheet` in "Utilities"](/docs/api/utilities/wb)
|
||||
[^6]: See [`sheet_add_aoa` in "Utilities"](/docs/api/utilities/array#array-of-arrays-input)
|
||||
[^7]: See ["Column Properties"](/docs/csf/features/colprops)
|
||||
[^8]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
@ -148,14 +148,15 @@ The file data is stored in an `ArrayBuffer`.
|
||||
|
||||
## Parse File
|
||||
|
||||
With the file data in hand, `XLSX.read`[^2] parses the workbook:
|
||||
With the file data in hand, [`XLSX.read`](/docs/api/parse-options) parses the
|
||||
file and generates a SheetJS workbook object:
|
||||
|
||||
```js
|
||||
const workbook = XLSX.read(file);
|
||||
```
|
||||
|
||||
The `workbook` object follows the "Common Spreadsheet Format"[^3], an in-memory
|
||||
format for representing workbooks, worksheets, cells, and spreadsheet features.
|
||||
The `workbook` object follows the ["Common Spreadsheet Format"](/docs/csf/), an
|
||||
in-memory schema for workbooks, worksheets, cells, and spreadsheet features.
|
||||
|
||||
|
||||
## Explore Dataset
|
||||
@ -170,8 +171,8 @@ To determine how to process the data, it is best to inspect the file first.
|
||||
|
||||
### List Sheet Names
|
||||
|
||||
As explained in the "Workbook Object"[^4] section, the `SheetNames` property is
|
||||
a ordered list of the sheet names in the workbook.
|
||||
As explained in the ["Workbook Object"](/docs/csf/book) page, the `SheetNames`
|
||||
property is a list of the sheet names in the workbook.
|
||||
|
||||
The following live code block displays an ordered list of the sheet names:
|
||||
|
||||
@ -195,21 +196,25 @@ function SheetJSheetNames() {
|
||||
|
||||
### Inspect Worksheet Data
|
||||
|
||||
The `Sheets` property of the workbook object[^5] is an object whose keys are
|
||||
sheet names and whose values are sheet objects. For example, the first worksheet
|
||||
is pulled by indexing `SheetNames` and using the name to index `Sheets`:
|
||||
The [`Sheets` property of the workbook object](/docs/csf/book) is an object
|
||||
whose keys are sheet names and whose values are sheet objects.
|
||||
|
||||
For example, the first worksheet can be pulled by indexing `SheetNames` and
|
||||
using the name to index `Sheets`:
|
||||
|
||||
```js
|
||||
var first_sheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
```
|
||||
|
||||
The actual worksheet object can be inspected directly[^6], but it is strongly
|
||||
recommended to use utility functions to present JS-friendly data structures.
|
||||
The [worksheet object](/docs/csf/sheet) can be inspected directly, but it is
|
||||
strongly recommended to use utility functions to extract relevant data.
|
||||
|
||||
### Preview HTML
|
||||
|
||||
The `sheet_to_html` utility function[^7] generates an HTML table from worksheet
|
||||
objects. The following live example shows the first 20 rows of data in a table:
|
||||
The [`sheet_to_html` function](/docs/api/utilities/html#html-table-output)
|
||||
generates an HTML table from worksheet objects.
|
||||
|
||||
The following live example shows the first 20 rows of data in a table:
|
||||
|
||||
<details>
|
||||
<summary><b>Live example</b> (click to show)</summary>
|
||||
@ -254,7 +259,8 @@ The key points from looking at the table are:
|
||||
|
||||
### Extract Raw Data
|
||||
|
||||
`XLSX.utils.sheet_to_json`[^8] generates arrays of data from worksheet objects.
|
||||
The [`sheet_to_json` function](/docs/api/utilities/array#array-output) generates
|
||||
arrays of data from worksheet objects.
|
||||
|
||||
For a complex layout like this, it is easiest to generate an "array of arrays"
|
||||
where each row is an array of cell values. The screenshot shows rows 5-8:
|
||||
@ -277,7 +283,7 @@ Row 7 includes the data for FY2007:
|
||||
```
|
||||
|
||||
`XLSX.utils.sheet_to_json` will generate an array of arrays if the option
|
||||
`header: 1` is specified[^9]:
|
||||
[`header: 1`](/docs/api/utilities/array#array-output) is specified:
|
||||
|
||||
```js
|
||||
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
@ -332,7 +338,9 @@ function SheetJSAoAHoles() {
|
||||
|
||||
</details>
|
||||
|
||||
The worksheet `!merges` property[^10] includes every merge range in the sheet.
|
||||
The [worksheet `!merges` property](/docs/csf/features/merges) includes every
|
||||
merge range in the sheet.
|
||||
|
||||
It is possible to loop through every merge block and fill cells, but in this
|
||||
case it is easier to post-process the raw data:
|
||||
|
||||
@ -539,7 +547,7 @@ Looking at the headers:
|
||||

|
||||
|
||||
The desired data is in column `I`. The column index can be calculated using
|
||||
`XLSX.utils.decode_col`[^11].
|
||||
the [`decode_col` utility function](/docs/csf/general#column-names).
|
||||
|
||||
<details>
|
||||
<summary><b>Column Index calculation</b> (click to show)</summary>
|
||||
@ -617,7 +625,7 @@ At this point, `objects` is an array of objects.
|
||||
### ReactJS
|
||||
|
||||
The live demos in this example use ReactJS. In ReactJS, arrays of objects are
|
||||
best presented in simple HTML tables[^12]:
|
||||
best presented in [simple tables](/docs/demos/frontend/react#array-of-objects):
|
||||
|
||||
```jsx
|
||||
<table>
|
||||
@ -1053,7 +1061,7 @@ Press `a` to run on Android.
|
||||
|
||||
:::info Device Testing
|
||||
|
||||
The demo also runs on real Android devices! After enabling USB debugging[^13],
|
||||
The demo also runs on real Android devices! After enabling USB debugging[^2],
|
||||
the Android device can be connected to the computer with a USB cable.
|
||||
|
||||
:::
|
||||
@ -1088,15 +1096,4 @@ When the app is loaded, the data will be displayed in rows.
|
||||
</Tabs>
|
||||
|
||||
[^1]: The dataset URL has changed many times over the years. The current location for the CC0-licensed dataset can be found by [searching for "National Student Loan Data System" on `data.gov`](https://catalog.data.gov/dataset/?q=national+student+loan+data+system&publisher=Office+of+Federal+Student+Aid+%28FSA%29&organization=ed-gov). `PortfolioSummary.xls` is the file name within the dataset.
|
||||
[^2]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^3]: See ["SheetJS Data Model"](/docs/csf/)
|
||||
[^4]: See ["Workbook Object"](/docs/csf/book)
|
||||
[^5]: See ["Workbook Object"](/docs/csf/book)
|
||||
[^6]: See ["Sheet Objects"](/docs/csf/sheet)
|
||||
[^7]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output)
|
||||
[^8]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^9]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^10]: See ["Merged Cells" in "SheetJS Data Model"](/docs/csf/features/merges)
|
||||
[^11]: See ["Column Names" in "Addresses and Ranges"](/docs/csf/general#column-names)
|
||||
[^12]: See ["Array of Objects" in "ReactJS"](/docs/demos/frontend/react#array-of-objects)
|
||||
[^13]: See ["Running on Device"](https://reactnative.dev/docs/running-on-device) in the React Native documentation for more details.
|
||||
[^2]: See ["Running on Device"](https://reactnative.dev/docs/running-on-device) in the React Native documentation for more details.
|
||||
@ -35,17 +35,21 @@ This demo was tested in the following configurations:
|
||||
|
||||
| Platform | Architecture | Date |
|
||||
|:------------------------------------------------------------------|:-------------|:-----------|
|
||||
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-06-17 |
|
||||
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-06-20 |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-04-17 |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-06-20 |
|
||||
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-06-20 |
|
||||
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-06-21 |
|
||||
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-06-20 |
|
||||
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-06-21 |
|
||||
| Apple M4 Max 16-Core CPU + 40-Core GPU (48 GB unified memory) | `darwin-arm` | 2025-03-06 |
|
||||
| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | 2025-06-24 |
|
||||
| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2025-03-25 |
|
||||
| NVIDIA RTX PRO 6000 (96 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2025-11-15 |
|
||||
| NVIDIA RTX PRO 6000 (96 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 |
|
||||
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 (32 GB RAM) | `win11-x64` | 2026-01-25 |
|
||||
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 |
|
||||
| AMD AI PRO R9700 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2026-01-17 |
|
||||
| AMD AI PRO R9700 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2026-01-17 |
|
||||
| AMD RX 9070 XT (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2026-01-17 |
|
||||
| AMD RX 9070 XT (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2026-01-17 |
|
||||
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-11-15 |
|
||||
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 |
|
||||
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-11-15 |
|
||||
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 |
|
||||
| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `linux-x64` | 2025-11-15 |
|
||||
| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `win11-x64` | 2025-11-15 |
|
||||
| Apple M4 Max 16-Core CPU + 40-Core GPU (48 GB unified memory) | `darwin-arm` | 2025-11-15 |
|
||||
|
||||
SheetJS users have verified this demo in other configurations:
|
||||
|
||||
@ -55,6 +59,8 @@ SheetJS users have verified this demo in other configurations:
|
||||
| Platform | Architecture | Demo |
|
||||
|:---------------------------------------------------------------------|:-------------|:------------|
|
||||
| NVIDIA L40 (48 GB VRAM) + i9-13900K (32 GB RAM) | `linux-x64` | LangChainJS |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | LangChainJS |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | LangChainJS |
|
||||
| NVIDIA RTX 4080 SUPER (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | LangChainJS |
|
||||
| NVIDIA RTX 4080 SUPER (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | LangChainJS |
|
||||
| NVIDIA RTX 4070 Ti SUPER (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | LangChainJS |
|
||||
@ -71,6 +77,8 @@ SheetJS users have verified this demo in other configurations:
|
||||
| NVIDIA GTX 1070 (8 GB VRAM) + Ryzen 7 7700x (32 GB RAM) | `win11-x64` | LangChainJS |
|
||||
| AMD RX 6800 XT (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | LangChainJS |
|
||||
| Apple M4 10-Core CPU + 10-Core GPU (24 GB unified memory) | `darwin-arm` | LangChainJS |
|
||||
| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | LangChainJS |
|
||||
| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | LangChainJS |
|
||||
|
||||
</details>
|
||||
|
||||
@ -382,7 +390,7 @@ includes one header row and a number of data rows.
|
||||
|
||||
```js title="loadofsheet.mjs"
|
||||
import { Document } from "@langchain/core/documents";
|
||||
import { BufferLoader } from "langchain/document_loaders/fs/buffer";
|
||||
import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
|
||||
import { read, utils } from "xlsx";
|
||||
|
||||
/**
|
||||
@ -521,7 +529,7 @@ export class CSVLoader extends TextLoader {
|
||||
The SheetJS `read` method supports NodeJS Buffer objects directly[^6]:
|
||||
|
||||
```js title="Parsing a workbook in a BufferLoader"
|
||||
import { BufferLoader } from "langchain/document_loaders/fs/buffer";
|
||||
import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
|
||||
import { read, utils } from "xlsx";
|
||||
|
||||
export default class LoadOfSheet extends BufferLoader {
|
||||
@ -832,6 +840,62 @@ D) Run the `start-ollama.sh` script from the extracted folder.
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
AMD GPUs may require special ROCm / HIP libraries.
|
||||
|
||||
<details>
|
||||
<summary><b>AMD Instructions on Windows</b> (click to show)</summary>
|
||||
|
||||
[`ollama-for-amd`](https://github.com/likelovewant/ollama-for-amd) is a
|
||||
community fork that provides support for many AMD GPUs.
|
||||
|
||||
[Installers](https://github.com/ByronLeeeee/Ollama-For-AMD-Installer/releases)
|
||||
are also provided by the community.
|
||||
|
||||
There are separate drivers for each GPU family. The following GPUs were tested:
|
||||
|
||||
| Name | GPU | Identifier |
|
||||
|:-----------------|:--------|:-----------|
|
||||
| AMD AI PRO R9700 | Navi 48 | `gfx1200` |
|
||||
| AMD RX 9070 XT | Navi 48 | `gfx1201` |
|
||||
| AND RX 7900 XTX | Navi 31 | `gfx1100` |
|
||||
|
||||
When this demo was last tested, the installer claimed `gfx1200` corresponded to
|
||||
Navi 48. `gfx1200` should be used for the PRO R9700, while `gfx1201` should be
|
||||
used for the 9070 XT.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>AMD Instructions on Linux</b> (click to show)</summary>
|
||||
|
||||
The official Ollama release is compatible with AMD cards. However, in some test
|
||||
runs, Ollama will try to use the CPU. Some environment variables were required:
|
||||
|
||||
```bash
|
||||
export OLLAMA_USE_ROCM=1
|
||||
export OLLAMA_GPU_LAYERS=999
|
||||
export OLLAMA_VULKAN=1
|
||||
```
|
||||
|
||||
In addition, `HSA_OVERRIDE_GFX_VERSION` must be set to a specific version based
|
||||
on the card, which may not match the official version:
|
||||
|
||||
| Name | Value | Command |
|
||||
|:-----------------|:---------|:-------------------------------------------|
|
||||
| AMD AI PRO R9700 | `12.0.0` | `export HSA_OVERRIDE_GFX_VERSION="12.0.0"` |
|
||||
| AMD RX 9070 XT | `12.0.0` | `export HSA_OVERRIDE_GFX_VERSION="12.0.0"` |
|
||||
| AND RX 7900 XTX | `11.0.0` | `export HSA_OVERRIDE_GFX_VERSION="11.0.0"` |
|
||||
|
||||
These environment variables may not be used by the Ollama service, so it is
|
||||
strongly recommended to stop the default service and run `ollama serve` in a
|
||||
separate terminal window.
|
||||
|
||||
</details>
|
||||
|
||||
:::
|
||||
|
||||
After installing dependencies, start a new terminal session.
|
||||
|
||||
1) Create a new project:
|
||||
@ -878,7 +942,7 @@ npm i --save https://sheet.lol/balls/xlsx-${current}.tgz`}
|
||||
4) Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i --save @langchain/core@0.3.59 langchain@0.3.28 @langchain/ollama@0.2.2 peggy@3.0.2
|
||||
npm i --save @langchain/core@1.1.15 langchain@1.2.10 @langchain/classic@1.0.9 @langchain/ollama@1.2.0 peggy@5.0.6
|
||||
```
|
||||
|
||||
:::note pass
|
||||
@ -887,7 +951,7 @@ In some test runs, there were error messages relating to dependency and peer
|
||||
dependency versions. The `--force` flag will suppress version mismatch errors:
|
||||
|
||||
```bash
|
||||
npm i --save @langchain/core@0.3.59 langchain@0.3.28 @langchain/ollama@0.2.2 peggy@3.0.2 --force
|
||||
npm i --save @langchain/core@1.1.15 langchain@1.2.10 @langchain/classic@1.0.9 @langchain/ollama@1.2.0 peggy@5.0.6 --force
|
||||
```
|
||||
|
||||
:::
|
||||
@ -921,7 +985,7 @@ ollama pull phi4:14b
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Additional steps for Intel GPUs</b> (click to show)</summary>
|
||||
<summary><b>Additional steps for Intel GPUs and AMD Strix Halo</b> (click to show)</summary>
|
||||
|
||||
A different embedding model must be used on Intel GPUs:
|
||||
|
||||
|
||||
@ -44,14 +44,15 @@ The NodeJS demo was tested in the following environments:
|
||||
|
||||
| NodeJS | TF.js | Date |
|
||||
|:------------|:----------|:-----------|
|
||||
| `22.14.0` | `4.22.0` | 2025-04-21 |
|
||||
| `20.18.0` | `4.22.0` | 2025-04-21 |
|
||||
| `24.13.0` | `4.22.0` | 2026-01-28 |
|
||||
| `22.22.0` | `4.22.0` | 2026-01-28 |
|
||||
| `20.20.0` | `4.22.0` | 2026-01-28 |
|
||||
|
||||
The Kaioken demo was tested in the following environments:
|
||||
|
||||
| Kaioken | TF.js | Date |
|
||||
|:------------|:----------|:-----------|
|
||||
| `0.37.0` | `4.22.0` | 2025-04-21 |
|
||||
| `0.44.3` | `4.22.0` | 2025-11-15 |
|
||||
|
||||
:::
|
||||
|
||||
@ -417,7 +418,7 @@ The SheetJS team strongly recommends using Kaioken in projects using TF.js.
|
||||
1) Create a new site.
|
||||
|
||||
```bash
|
||||
npm create vite sheetjs-tfjs-kaioken -- --template vanilla-ts
|
||||
npm create vite sheetjs-tfjs-kaioken -- --template vanilla-ts --no-rolldown --no-interactive
|
||||
cd sheetjs-tfjs-kaioken
|
||||
npm add --save kaioken
|
||||
npm add --save vite-plugin-kaioken -D
|
||||
@ -443,7 +444,14 @@ export default defineConfig({
|
||||
"jsx": "preserve",
|
||||
```
|
||||
|
||||
4) Replace `src/main.ts` with the following codeblock:
|
||||
4) Edit `tsconfig.json` and remove any lines referencing `verbatimModuleSyntax`.
|
||||
When the demo was last tested, the file had the following line:
|
||||
|
||||
```js title="tsconfig.json (remove this line if present)"
|
||||
"verbatimModuleSyntax": true,
|
||||
```
|
||||
|
||||
5) Replace `src/main.ts` with the following codeblock:
|
||||
|
||||
```js title="src/main.ts"
|
||||
import { mount } from "kaioken";
|
||||
@ -453,19 +461,19 @@ const root = document.getElementById("app");
|
||||
mount(App, root!);
|
||||
```
|
||||
|
||||
5) Download [`SheetJSTF.tsx`](pathname:///tfjs/SheetJSTF.tsx) to the `src` directory:
|
||||
6) Download [`SheetJSTF.tsx`](pathname:///tfjs/SheetJSTF.tsx) to the `src` directory:
|
||||
|
||||
```bash
|
||||
curl -L -o src/SheetJSTF.tsx https://docs.sheetjs.com/tfjs/SheetJSTF.tsx
|
||||
```
|
||||
|
||||
6) Install SheetJS and TF.js dependencies:
|
||||
7) Install SheetJS and TF.js dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @tensorflow/tfjs`}
|
||||
</CodeBlock>
|
||||
|
||||
7) Start the development server:
|
||||
8) Start the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
@ -40,12 +40,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | JS Engine | Pandas | Python | Date |
|
||||
|:-------------|:----------------|:-------|:-------|:-----------|
|
||||
| `darwin-x64` | Duktape `2.7.0` | 2.2.3 | 3.13.1 | 2025-03-31 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 2.2.3 | 3.13.2 | 2025-03-30 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 2.2.3 | 3.11.9 | 2025-04-28 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 2.2.3 | 3.13.2 | 2025-02-23 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 2.1.4 | 3.12.3 | 2025-06-16 |
|
||||
| `linux-arm` | Duktape `2.7.0` | 1.5.3 | 3.11.2 | 2025-02-16 |
|
||||
| `darwin-x64` | Duktape `2.7.0` | 3.0.1 | 3.13.7 | 2026-03-07 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 2.3.3 | 3.9.6 | 2026-01-25 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 3.0.1 | 3.11.9 | 2026-03-08 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 2.2.3 | 3.11.5 | 2026-03-07 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 3.0.1 | 3.13.9 | 2026-03-07 |
|
||||
| `linux-arm` | Duktape `2.7.0` | 2.2.3 | 3.13.5 | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -542,14 +542,14 @@ The Pandas example requires a few slight changes to work with Polars:
|
||||
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | JS Engine | Polars | Python | Date |
|
||||
|:-------------|:----------------|:--------|:-------|:-----------|
|
||||
| `darwin-x64` | Duktape `2.7.0` | 1.26.0 | 3.13.1 | 2025-03-31 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 1.26.0 | 3.13.2 | 2025-03-30 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 1.28.1 | 3.11.9 | 2025-04-28 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 1.23.0 | 3.13.2 | 2025-02-23 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 1.30.0 | 3.12.3 | 2025-06-16 |
|
||||
| `linux-arm` | Duktape `2.7.0` | 1.22.0 | 3.11.2 | 2025-02-16 |
|
||||
| Architecture | JS Engine | Polars | Python | Date |
|
||||
|:-------------|:----------------|:-------|:-------|:-----------|
|
||||
| `darwin-x64` | Duktape `2.7.0` | 1.38.1 | 3.13.7 | 2026-03-07 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 1.36.1 | 3.9.6 | 2026-01-25 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 1.38.1 | 3.11.9 | 2026-03-08 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 1.23.0 | 3.11.5 | 2026-03-07 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 1.38.1 | 3.13.9 | 2026-03-07 |
|
||||
| `linux-arm` | Duktape `2.7.0` | 1.38.1 | 3.13.5 | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -360,9 +360,9 @@ export default function SheetJSKaiokenAoO() {
|
||||
{ /* error message */
|
||||
!pres && !loading && ( <tr><td colSpan="2">{error.message}</td></tr> )
|
||||
}
|
||||
</tbody><tfoot><td colSpan={2}>
|
||||
</tbody><tfoot><tr><td colSpan={2}>
|
||||
<button onclick={exportFile}>Export XLSX</button>
|
||||
</td></tfoot></table>);
|
||||
</td></tr></tfoot></table>);
|
||||
}
|
||||
```
|
||||
|
||||
@ -429,9 +429,9 @@ export default function SheetJSKaiokenAoO() {
|
||||
<td>{pres.Index}</td>
|
||||
</tr>))
|
||||
}
|
||||
</tbody><tfoot><td colSpan={2}>
|
||||
</tbody><tfoot><tr><td colSpan={2}>
|
||||
<button onclick={exportFile}>Export XLSX</button>
|
||||
</td></tfoot></table>);
|
||||
</td></tr></tfoot></table>);
|
||||
}
|
||||
```
|
||||
|
||||
@ -450,14 +450,14 @@ This demo was tested in the following environments:
|
||||
|
||||
| Kaioken | ViteJS | Date |
|
||||
|:----------|:--------|:-----------|
|
||||
| `0.35.10` | `6.1.0` | 2025-02-11 |
|
||||
| `0.44.3` | `6.4.1` | 2026-03-14 |
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new site.
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-kaioken -- --template vanilla-ts
|
||||
npm create vite@latest sheetjs-kaioken -- --template vanilla-ts --no-rolldown --no-interactive
|
||||
cd sheetjs-kaioken
|
||||
npm add --save kaioken
|
||||
npm add --save vite-plugin-kaioken -D
|
||||
@ -597,14 +597,14 @@ This demo was tested in the following environments:
|
||||
|
||||
| Kaioken | ViteJS | Date |
|
||||
|:----------|:--------|:-----------|
|
||||
| `0.35.10` | `6.1.0` | 2025-02-11 |
|
||||
| `0.44.3` | `6.4.1` | 2026-03-14 |
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new site.
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-kaioken -- --template vanilla-ts
|
||||
npm create vite@latest sheetjs-kaioken -- --template vanilla-ts --no-rolldown --no-interactive
|
||||
cd sheetjs-kaioken
|
||||
npm add --save kaioken
|
||||
npm add --save vite-plugin-kaioken -D
|
||||
|
||||
@ -341,7 +341,7 @@ This demo was tested in the following environments:
|
||||
1) Create a new site:
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-react -- --template react
|
||||
npm create vite@latest sheetjs-react -- --template react --no-rolldown --no-interactive
|
||||
```
|
||||
|
||||
2) Install the SheetJS dependency and start the dev server:
|
||||
@ -845,7 +845,7 @@ This demo was tested in the following environments:
|
||||
1) Create a new site:
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-react -- --template react
|
||||
npm create vite@latest sheetjs-react -- --template react --no-rolldown --no-interactive
|
||||
```
|
||||
|
||||
2) Install the SheetJS dependency and start the dev server:
|
||||
|
||||
@ -425,11 +425,11 @@ This demo was tested in the following environments:
|
||||
|
||||
| Angular | Date |
|
||||
|:----------|:-----------|
|
||||
| `20.2.3` | 2025-09-03 |
|
||||
| `19.0.5` | 2025-01-03 |
|
||||
| `18.2.13` | 2025-01-03 |
|
||||
| `17.3.12` | 2025-01-03 |
|
||||
| `16.2.12` | 2025-01-03 |
|
||||
| `20.3.1` | 2026-03-12 |
|
||||
| `19.2.17` | 2026-03-12 |
|
||||
| `18.2.14` | 2026-03-12 |
|
||||
| `17.3.12` | 2026-03-12 |
|
||||
| `16.2.16` | 2026-03-12 |
|
||||
|
||||
:::
|
||||
|
||||
@ -634,10 +634,11 @@ This demo was tested in the following environments:
|
||||
|
||||
| Angular | Date |
|
||||
|:----------|:-----------|
|
||||
| `19.0.5` | 2025-01-03 |
|
||||
| `18.2.13` | 2025-01-03 |
|
||||
| `17.3.12` | 2025-01-03 |
|
||||
| `16.2.12` | 2025-01-03 |
|
||||
| `20.3.1` | 2026-03-12 |
|
||||
| `19.2.17` | 2026-03-12 |
|
||||
| `18.2.14` | 2026-03-12 |
|
||||
| `17.3.12` | 2026-03-12 |
|
||||
| `16.2.16` | 2026-03-12 |
|
||||
|
||||
:::
|
||||
|
||||
@ -650,7 +651,7 @@ npx @angular/cli analytics disable -g
|
||||
1) Create a new project:
|
||||
|
||||
```bash
|
||||
npx @angular/cli@19 new --minimal --defaults --no-interactive sheetjs-angular
|
||||
npx @angular/cli@20 new --minimal --defaults --no-interactive sheetjs-angular
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
@ -59,14 +59,15 @@ depends on the application.
|
||||
|
||||
### Array of Objects
|
||||
|
||||
Typically, some users will create a spreadsheet with source data that should be
|
||||
loaded into the site. This sheet will have known columns.
|
||||
Typically, users will create a spreadsheet with data that should be imported to
|
||||
the site. The data sheets will typically store headers in the first row. In some
|
||||
applications, the data will follow a standardized template.
|
||||
|
||||
#### State
|
||||
|
||||
The example [presidents sheet](https://docs.sheetjs.com/pres.xlsx) has one
|
||||
header row with "Name" and "Index" columns. The natural JS representation is an
|
||||
object for each row, where the keys are specified in the first row:
|
||||
object for each data row, where the values in the first row are used as keys:
|
||||
|
||||
<table>
|
||||
<thead><tr><th>Spreadsheet</th><th>State</th></tr></thead>
|
||||
@ -114,7 +115,8 @@ const pres = ref<any[]>([]);
|
||||
</script>
|
||||
```
|
||||
|
||||
When the spreadsheet header row is known ahead of time, row typing is possible:
|
||||
`ref` is a generic method in TypeScript. If the spreadsheet header row is known
|
||||
ahead of time, each row object can be typed:
|
||||
|
||||
```html
|
||||
<script setup lang="ts">
|
||||
@ -461,18 +463,19 @@ and test the page.
|
||||
|
||||
### HTML
|
||||
|
||||
The main disadvantage of the Array of Objects approach is the specific nature
|
||||
The main disadvantage of the "Array of Objects" approach is the specific nature
|
||||
of the columns. For more general use, passing around an Array of Arrays works.
|
||||
However, this does not handle merge cells[^5] well!
|
||||
However, this does not handle merged cells[^5] well!
|
||||
|
||||
The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function
|
||||
generates HTML that is aware of merges and other worksheet features. VueJS
|
||||
`v-html`[^6] attribute allows code to set the `innerHTML` attribute, effectively
|
||||
inserting the code into the page.
|
||||
|
||||
In this example, the component attaches a `ref` to the `DIV` container. During
|
||||
export, the first `TABLE` child element can be parsed with [`table_to_book`](/docs/api/utilities/html#html-table-input) to
|
||||
generate a workbook object.
|
||||
In this example, the component attaches a `ref` to the `DIV` container. When the
|
||||
"Export XLSX" button is clicked, the first `TABLE` child element will be parsed
|
||||
with the [`table_to_book`](/docs/api/utilities/html#html-table-input) method.
|
||||
The generated workbook object will be exported to XLSX using `writeFile`.
|
||||
|
||||
```html title="src/SheetJSVueHTML.vue"
|
||||
<script setup>
|
||||
|
||||
@ -143,14 +143,14 @@ This demo was tested in the following environments:
|
||||
|
||||
| SvelteJS | ViteJS | Date |
|
||||
|:---------|:---------|:-----------|
|
||||
| `5.38.6` | `7.1.1` | 2025-09-03 |
|
||||
| `5.43.7` | `7.2.2` | 2025-11-15 |
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new project:
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-svelte -- --template svelte-ts
|
||||
npm create vite@latest sheetjs-svelte -- --template svelte-ts --no-rolldown --no-interactive
|
||||
```
|
||||
|
||||
2) Install the SheetJS dependency and start the dev server:
|
||||
@ -245,14 +245,14 @@ This demo was tested in the following environments:
|
||||
|
||||
| SvelteJS | ViteJS | Date |
|
||||
|:---------|:---------|:-----------|
|
||||
| `5.25.3` | `6.2.3` | 2025-03-30 |
|
||||
| `5.43.7` | `7.2.2` | 2025-11-15 |
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new project:
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-svelte -- --template svelte-ts
|
||||
npm create vite@latest sheetjs-svelte -- --template svelte-ts --no-rolldown --no-interactive
|
||||
```
|
||||
|
||||
2) Install the SheetJS dependency and start the dev server:
|
||||
|
||||
@ -295,8 +295,8 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Date |
|
||||
|:-------------|:-----------|
|
||||
| `darwin-x64` | 2025-04-17 |
|
||||
| `darwin-arm` | 2025-04-24 |
|
||||
| `darwin-x64` | 2026-03-07 |
|
||||
| `darwin-arm` | 2026-03-07 |
|
||||
| `win11-x64` | 2025-04-17 |
|
||||
| `win11-arm` | 2025-04-24 |
|
||||
|
||||
|
||||
@ -365,7 +365,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| OpenUI5 | Date |
|
||||
|:----------|------------|
|
||||
| `1.132.1` | 2025-01-24 |
|
||||
| `1.145.0` | 2026-03-13 |
|
||||
|
||||
:::
|
||||
|
||||
@ -535,7 +535,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| OpenUI5 | Date |
|
||||
|:----------|------------|
|
||||
| `1.132.1` | 2025-01-24 |
|
||||
| `1.145.0` | 2026-03-13 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -211,8 +211,8 @@ This demo was tested in the following environments:
|
||||
|
||||
| KnockoutJS | Date | Live Demo |
|
||||
|:-----------|:-----------|:-----------------------------------------------|
|
||||
| `3.5.0` | 2025-01-08 | [**KO3**](pathname:///knockout/knockout3.html) |
|
||||
| `2.3.0` | 2025-01-08 | [**KO2**](pathname:///knockout/knockout2.html) |
|
||||
| `3.5.0` | 2026-03-06 | [**KO3**](pathname:///knockout/knockout3.html) |
|
||||
| `2.3.0` | 2026-03-06 | [**KO2**](pathname:///knockout/knockout2.html) |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -41,10 +41,11 @@ This demo was tested in the following environments:
|
||||
|
||||
| ViteJS | Date |
|
||||
|:---------|:-----------|
|
||||
| `6.2.3` | 2025-03-30 |
|
||||
| `5.4.15` | 2025-03-30 |
|
||||
| `4.5.10` | 2025-03-30 |
|
||||
| `3.2.11` | 2025-03-30 |
|
||||
| `7.3.1` | 2026-01-28 |
|
||||
| `6.4.1` | 2026-01-28 |
|
||||
| `5.4.21` | 2026-01-28 |
|
||||
| `4.5.14` | 2026-01-28 |
|
||||
| `3.2.11` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -74,7 +75,7 @@ It is strongly recommended to [upgrade to the latest version](/docs/getting-star
|
||||
1) Create a new ViteJS project:
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-vite -- --template vue-ts
|
||||
npm create vite@latest sheetjs-vite -- --template vue-ts --no-rolldown --no-interactive
|
||||
cd sheetjs-vite
|
||||
npm i
|
||||
```
|
||||
|
||||
@ -47,23 +47,25 @@ This demo was tested in the following environments:
|
||||
|
||||
| ESBuild | Date |
|
||||
|:----------|:-----------|
|
||||
| `0.25.5` | 2025-06-02 |
|
||||
| `0.24.2` | 2025-06-02 |
|
||||
| `0.23.1` | 2025-06-02 |
|
||||
| `0.22.0` | 2025-06-02 |
|
||||
| `0.21.5` | 2025-06-02 |
|
||||
| `0.20.2` | 2025-06-02 |
|
||||
| `0.19.12` | 2025-06-02 |
|
||||
| `0.18.20` | 2025-06-02 |
|
||||
| `0.17.19` | 2025-06-02 |
|
||||
| `0.16.17` | 2025-06-02 |
|
||||
| `0.15.18` | 2025-06-02 |
|
||||
| `0.14.54` | 2025-06-02 |
|
||||
| `0.13.15` | 2025-06-02 |
|
||||
| `0.12.29` | 2025-06-02 |
|
||||
| `0.11.23` | 2025-06-02 |
|
||||
| `0.10.2` | 2025-06-02 |
|
||||
| `0.9.7` | 2025-06-02 |
|
||||
| `0.27.2` | 2026-01-28 |
|
||||
| `0.26.0` | 2026-01-28 |
|
||||
| `0.25.12` | 2026-01-28 |
|
||||
| `0.24.2` | 2026-01-28 |
|
||||
| `0.23.1` | 2026-01-28 |
|
||||
| `0.22.0` | 2026-01-28 |
|
||||
| `0.21.5` | 2026-01-28 |
|
||||
| `0.20.2` | 2026-01-28 |
|
||||
| `0.19.12` | 2026-01-28 |
|
||||
| `0.18.20` | 2026-01-28 |
|
||||
| `0.17.19` | 2026-01-28 |
|
||||
| `0.16.17` | 2026-01-28 |
|
||||
| `0.15.18` | 2026-01-28 |
|
||||
| `0.14.54` | 2026-01-28 |
|
||||
| `0.13.15` | 2026-01-28 |
|
||||
| `0.12.29` | 2026-01-28 |
|
||||
| `0.11.23` | 2026-01-28 |
|
||||
| `0.10.2` | 2026-01-28 |
|
||||
| `0.9.7` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -91,7 +93,7 @@ Assuming the primary source file is `in.js`, the following command will bundle
|
||||
the script and generate `out.js`:
|
||||
|
||||
```bash
|
||||
npx -y esbuild@0.25.5 in.js --bundle --outfile=out.js
|
||||
npx -y esbuild@0.25.9 in.js --bundle --outfile=out.js
|
||||
```
|
||||
|
||||
### Browser Demo
|
||||
@ -140,7 +142,7 @@ curl -LO https://docs.sheetjs.com/esbuild/esbrowser.js
|
||||
4) Create bundle:
|
||||
|
||||
```bash
|
||||
npx -y esbuild@0.25.5 esbrowser.js --bundle --outfile=esb.browser.js
|
||||
npx -y esbuild@0.25.9 esbrowser.js --bundle --outfile=esb.browser.js
|
||||
```
|
||||
|
||||
5) Start a local HTTP server:
|
||||
@ -180,7 +182,7 @@ Assuming the primary source file is `in.js`, the following command will bundle
|
||||
the script for NodeJS and generate `out.js`:
|
||||
|
||||
```bash
|
||||
npx -y esbuild@0.25.5 in.js --bundle --platform=node --outfile=out.js
|
||||
npx -y esbuild@0.25.9 in.js --bundle --platform=node --outfile=out.js
|
||||
```
|
||||
|
||||
### NodeJS Demo
|
||||
@ -229,7 +231,7 @@ curl -LO https://docs.sheetjs.com/esbuild/esbnode.js
|
||||
3) Create bundle:
|
||||
|
||||
```bash
|
||||
npx -y esbuild@0.25.5 esbnode.js --bundle --platform=node --outfile=esb.node.js
|
||||
npx -y esbuild@0.25.9 esbnode.js --bundle --platform=node --outfile=esb.node.js
|
||||
```
|
||||
|
||||
4) Run the bundle:
|
||||
|
||||
@ -39,12 +39,12 @@ which covers SheetJS library usage in more detail.
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| Version | Date | Required Workarounds |
|
||||
|:---------|:-----------|:------------------------------------|
|
||||
| `5.97.1` | 2025-01-03 | |
|
||||
| `4.47.0` | 2025-01-03 | |
|
||||
| `3.12.0` | 2025-01-03 | Import `xlsx/dist/xlsx.full.min.js` |
|
||||
| `2.7.0` | 2025-01-03 | Import `xlsx/dist/xlsx.full.min.js` |
|
||||
| Version | Date | Required Workarounds |
|
||||
|:----------|:-----------|:------------------------------------|
|
||||
| `5.104.1` | 2026-01-28 | |
|
||||
| `4.47.0` | 2026-01-28 | |
|
||||
| `3.12.0` | 2026-01-28 | Import `xlsx/dist/xlsx.full.min.js` |
|
||||
| `2.7.0` | 2026-01-28 | Import `xlsx/dist/xlsx.full.min.js` |
|
||||
|
||||
:::
|
||||
|
||||
@ -329,8 +329,6 @@ npx -y http-server .
|
||||
|
||||
Click on "Click here to export" to generate a file.
|
||||
|
||||
## Miscellany
|
||||
|
||||
[^1]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^2]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^3]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
|
||||
@ -34,21 +34,21 @@ This demo was tested in the following environments:
|
||||
|
||||
| Browserify | Date |
|
||||
|:-----------|:-----------|
|
||||
| `17.0.1` | 2025-06-18 |
|
||||
| `16.5.2` | 2025-06-18 |
|
||||
| `15.2.0` | 2025-06-18 |
|
||||
| `14.5.0` | 2025-06-18 |
|
||||
| `13.3.0` | 2025-06-18 |
|
||||
| `12.0.2` | 2025-06-18 |
|
||||
| `11.2.0` | 2025-06-18 |
|
||||
| `10.2.6` | 2025-06-18 |
|
||||
| `9.0.8` | 2025-06-18 |
|
||||
| `8.1.3` | 2025-06-18 |
|
||||
| `7.1.0` | 2025-06-18 |
|
||||
| `6.3.4` | 2025-06-18 |
|
||||
| `5.13.1` | 2025-06-18 |
|
||||
| `4.2.3` | 2025-06-18 |
|
||||
| `3.46.1` | 2025-06-18 |
|
||||
| `17.0.1` | 2026-01-28 |
|
||||
| `16.5.2` | 2026-01-28 |
|
||||
| `15.2.0` | 2026-01-28 |
|
||||
| `14.5.0` | 2026-01-28 |
|
||||
| `13.3.0` | 2026-01-28 |
|
||||
| `12.0.2` | 2026-01-28 |
|
||||
| `11.2.0` | 2026-01-28 |
|
||||
| `10.2.6` | 2026-01-28 |
|
||||
| `9.0.8` | 2026-01-28 |
|
||||
| `8.1.3` | 2026-01-28 |
|
||||
| `7.1.0` | 2026-01-28 |
|
||||
| `6.3.4` | 2026-01-28 |
|
||||
| `5.13.1` | 2026-01-28 |
|
||||
| `4.2.3` | 2026-01-28 |
|
||||
| `3.46.1` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -40,8 +40,8 @@ This demo was tested in the following environments:
|
||||
|
||||
| RequireJS | Date |
|
||||
|:----------|:-----------|
|
||||
| `2.3.7` | 2025-01-07 |
|
||||
| `2.1.22` | 2025-01-07 |
|
||||
| `2.3.7` | 2026-01-25 |
|
||||
| `2.1.22` | 2026-01-25 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -46,11 +46,11 @@ This demo was tested in the following environments:
|
||||
|
||||
| Version | Platform | Date |
|
||||
|:----------|:---------|:-----------|
|
||||
| `0.19.47` | NodeJS | 2025-01-03 |
|
||||
| `0.20.16` | Browser | 2025-01-03 |
|
||||
| `0.20.19` | NodeJS | 2025-03-03 |
|
||||
| `0.21.6` | NodeJS | 2025-03-03 |
|
||||
| `6.15.1` | NodeJS | 2025-01-03 |
|
||||
| `6.15.1` | NodeJS | 2026-01-28 |
|
||||
| `0.21.6` | NodeJS | 2026-01-28 |
|
||||
| `0.20.19` | NodeJS | 2026-01-28 |
|
||||
| `0.19.47` | NodeJS | 2026-01-28 |
|
||||
| `0.20.16` | Browser | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -34,10 +34,10 @@ This demo was tested in the following environments:
|
||||
|
||||
| Version | Date |
|
||||
|:---------|:-----------|
|
||||
| `4.29.1` | 2025-01-03 |
|
||||
| `3.29.5` | 2025-01-03 |
|
||||
| `2.79.1` | 2025-01-03 |
|
||||
| `1.32.1` | 2025-01-03 |
|
||||
| `4.57.0` | 2026-01-28 |
|
||||
| `3.29.5` | 2026-01-28 |
|
||||
| `2.79.2` | 2026-01-28 |
|
||||
| `1.32.1` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
195
docz/docs/03-demos/02-frontend/19-bundler/18-rspack.md
Normal file
195
docz/docs/03-demos/02-frontend/19-bundler/18-rspack.md
Normal file
@ -0,0 +1,195 @@
|
||||
---
|
||||
title: Packing Sheets with Rspack
|
||||
sidebar_label: Rspack
|
||||
pagination_prev: demos/index
|
||||
pagination_next: demos/grid/index
|
||||
sidebar_position: 18
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[Rspack](https://rspack.rs/) is a fast module bundler for JavaScript.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
This demo uses Rspack and SheetJS to export data. We'll explore how to add
|
||||
SheetJS to a site using Rspack and how to export data to spreadsheets.
|
||||
|
||||
:::note pass
|
||||
|
||||
This demo focuses on integration details with the Rspack bundler.
|
||||
|
||||
The demos follow the ["Export Tutorial"](/docs/getting-started/examples/export),
|
||||
which covers SheetJS library usage in more detail.
|
||||
|
||||
:::
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| Rspack | Date |
|
||||
|:--------|:-----------|
|
||||
| `1.7.4` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
## Integration Details
|
||||
|
||||
[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers
|
||||
installation with Yarn and other package managers.
|
||||
|
||||
After installing the SheetJS module in a Rspack project, `import` statements can
|
||||
load relevant parts of the library.
|
||||
|
||||
Projects that import data will use methods such as `read`[^1] to parse workbooks
|
||||
and `sheet_to_json`[^2] to generate usable data from files. As `sheet_to_json`
|
||||
is part of the `utils` object, the required import is:
|
||||
|
||||
```js
|
||||
import { read, utils } from 'xlsx';
|
||||
```
|
||||
|
||||
Projects that export data will use methods such as `json_to_sheet`[^3] to
|
||||
generate worksheets and `writeFile`[^4] to export files. As `json_to_sheet` is
|
||||
part of the `utils` object, the required import is:
|
||||
|
||||
```js
|
||||
import { utils, writeFile } from 'xlsx';
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
This demo follows the [Export Example](/docs/getting-started/examples/export).
|
||||
|
||||
0) Initialize a new project:
|
||||
|
||||
```bash
|
||||
mkdir sheetjs-rspack
|
||||
cd sheetjs-rspack
|
||||
npm init -y
|
||||
```
|
||||
|
||||
1) Install the dependencies using a package manager:
|
||||
|
||||
<Tabs groupId="pm">
|
||||
<TabItem value="npm" label="npm">
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @rspack/core @rspack/cli`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
<CodeBlock language="bash">{`\
|
||||
pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @rspack/core @rspack/cli`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn" default>
|
||||
<CodeBlock language="bash">{`\
|
||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @rspack/core @rspack/cli`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
2) Save the following to `src/index.js`:
|
||||
|
||||
```js title="src/index.js"
|
||||
import { utils, writeFileXLSX } from 'xlsx';
|
||||
|
||||
document.getElementById("xport").addEventListener("click", async() => {
|
||||
/* fetch JSON data and parse */
|
||||
const url = "https://docs.sheetjs.com/executive.json";
|
||||
const raw_data = await (await fetch(url)).json();
|
||||
|
||||
/* filter for the Presidents */
|
||||
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
|
||||
|
||||
/* sort by first presidential term */
|
||||
prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start);
|
||||
prez.sort((l,r) => l.start.localeCompare(r.start));
|
||||
|
||||
/* flatten objects */
|
||||
const rows = prez.map(row => ({
|
||||
name: row.name.first + " " + row.name.last,
|
||||
birthday: row.bio.birthday
|
||||
}));
|
||||
|
||||
/* generate worksheet and workbook */
|
||||
const worksheet = utils.json_to_sheet(rows);
|
||||
const workbook = utils.book_new();
|
||||
utils.book_append_sheet(workbook, worksheet, "Dates");
|
||||
|
||||
/* fix headers */
|
||||
utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
|
||||
|
||||
/* calculate column width */
|
||||
const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
|
||||
worksheet["!cols"] = [ { wch: max_width } ];
|
||||
|
||||
/* create an XLSX file and try to save to Presidents.xlsx */
|
||||
writeFileXLSX(workbook, "Presidents.xlsx");
|
||||
});
|
||||
```
|
||||
|
||||
3) Create bundle:
|
||||
|
||||
```bash
|
||||
npx -p @rspack/cli rspack build
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
This build may fail with a module error:
|
||||
|
||||
```
|
||||
ERROR in ./src/index.js
|
||||
× Module parse failed:
|
||||
╰─▶ × JavaScript parse error: 'import', and 'export' cannot be used outside of module code
|
||||
```
|
||||
|
||||
Some versions of the `npm` tool create `package.json` files with the option
|
||||
`"type": "commonjs"`. Rspack will fail if that option is specified. Edit
|
||||
`package.json` and remove the property:
|
||||
|
||||
```js title="package.json (remove highlighted line)"
|
||||
"license": "ISC",
|
||||
// highlight-next-line
|
||||
"type": "commonjs",
|
||||
"dependencies": {
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
This command will create the script `dist/main.js`
|
||||
|
||||
4) Create a small HTML page that loads the generated script:
|
||||
|
||||
```html title="index.html"
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head></head>
|
||||
<body>
|
||||
<h1>SheetJS Presidents Demo</h1>
|
||||
<button id="xport">Click here to export</button>
|
||||
<script src="dist/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
5) Start a local HTTP server:
|
||||
|
||||
```bash
|
||||
npx -y http-server .
|
||||
```
|
||||
|
||||
Access the displayed URL (typically `http://localhost:8080`) with a web browser.
|
||||
|
||||
Click the "Click here to export" button to generate `Presidents.xlsx`
|
||||
|
||||
[^1]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^2]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^3]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^4]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
@ -34,8 +34,8 @@ This demo was tested in the following environments:
|
||||
|
||||
| Version | Date |
|
||||
|:---------|:-----------|
|
||||
| `2.14.4` | 2025-05-07 |
|
||||
| `1.12.3` | 2025-05-07 |
|
||||
| `2.16.1` | 2026-01-28 |
|
||||
| `1.12.3` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -44,7 +44,7 @@ This demo was tested in the following environments:
|
||||
[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers
|
||||
installation with Yarn and other package managers.
|
||||
|
||||
After installing the SheetJS module in a RollupJS project, `import` statements
|
||||
After installing the SheetJS module in a ParcelJS project, `import` statements
|
||||
can load relevant parts of the library:
|
||||
|
||||
```js
|
||||
|
||||
@ -35,7 +35,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| Version | Date |
|
||||
|:----------|:-----------|
|
||||
| `1.21.1` | 2025-06-18 |
|
||||
| `1.15.11` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -75,8 +75,8 @@ thread '<unnamed>' panicked at 'cannot access a scoped thread local variable wit
|
||||
|
||||
This bug is known to affect versions `1.3.100`, `1.4.17`, and `1.10.6`.
|
||||
|
||||
This bug was fixed in version `1.21.1`. It is strongly recommended to upgrade
|
||||
existing projects to use `1.21.1` or to downgrade to `1.2.246`.
|
||||
This bug was fixed in version `1.12.1`. It is strongly recommended to upgrade
|
||||
existing projects to use `1.12.1` or to downgrade to `1.2.246`.
|
||||
|
||||
:::
|
||||
|
||||
@ -95,17 +95,17 @@ npm init -y
|
||||
<Tabs groupId="pm">
|
||||
<TabItem value="npm" label="npm">
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.21.1`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.13.5`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
<CodeBlock language="bash">{`\
|
||||
pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.21.1`}
|
||||
pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.13.5`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn" default>
|
||||
<CodeBlock language="bash">{`\
|
||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.21.1`}
|
||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.13.5`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@ -62,7 +62,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| Version | Date |
|
||||
|:--------|:-----------|
|
||||
| `3.8.8` | 2025-01-07 |
|
||||
| `3.8.8` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -149,7 +149,7 @@ writeFileXLSX(workbook, "Presidents.xlsx");
|
||||
</html>
|
||||
```
|
||||
|
||||
:::note pass
|
||||
:::danger pass
|
||||
|
||||
Unlike other bundlers, Snowpack requires a full page including `HEAD` element.
|
||||
|
||||
@ -194,7 +194,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| Version | Date |
|
||||
|:--------|:-----------|
|
||||
| `3.8.0` | 2025-01-07 |
|
||||
| `3.8.0` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -98,11 +98,40 @@ Each browser demo was tested in the following environments:
|
||||
|
||||
### XMLHttpRequest
|
||||
|
||||
For downloading data, the `arraybuffer` response type generates an `ArrayBuffer`
|
||||
that can be viewed as an `Uint8Array` and fed to the SheetJS `read` method. For
|
||||
legacy browsers, the option `type: "array"` should be specified:
|
||||
`XMLHttpRequest` is a browser API for performing network requests. Files can be
|
||||
downloaded from external sources in `GET` and `POST` requests.
|
||||
|
||||
The `responseType` property controls how `XMLHttpRequest` processes data. The
|
||||
SheetJS [`read`](/docs/api/parse-options/) method accepts a `type` option that
|
||||
specifies the data representation. SheetJS and `XMLHttpRequest` options must be
|
||||
set in tandem.
|
||||
|
||||
In modern browsers, when the response type is `"arraybuffer"`, `XMLHttpRequest`
|
||||
will generate an `ArrayBuffer` of raw data. The SheetJS `read` method directly
|
||||
processes `ArrayBuffer` objects.
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: XMLHttpRequest + SheetJS in modern browsers
|
||||
---
|
||||
flowchart LR
|
||||
file[(workbook\nfile)]
|
||||
ab[(file bytes\nArrayBuffer)]
|
||||
wb(((SheetJS\nWorkbook)))
|
||||
file --> |XMLHttpRequest\nresponseType="arraybuffer"| ab
|
||||
ab --> |SheetJS read\n\n|wb
|
||||
```
|
||||
|
||||
The following example fetches a file, generates an HTML `TABLE` from the first
|
||||
sheet using the [`sheet_to_html`](/docs/api/utilities/html#html-table-output)
|
||||
method, and inserts the `TABLE` in a `DIV` container:
|
||||
|
||||
```html title="Download and parse files with XMLHttpRequest and SheetJS"
|
||||
<div id="sheetjs-tbl"></div>
|
||||
<script>
|
||||
/* This file will be downloaded and processed */
|
||||
var url = "https://docs.sheetjs.com/pres.numbers";
|
||||
|
||||
```js
|
||||
/* set up an async GET request */
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", url, true);
|
||||
@ -110,11 +139,19 @@ req.responseType = "arraybuffer";
|
||||
|
||||
req.onload = function(e) {
|
||||
/* parse the data when it is received */
|
||||
var data = new Uint8Array(req.response);
|
||||
var workbook = XLSX.read(data, {type:"array"});
|
||||
var workbook = XLSX.read(req.response);
|
||||
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
|
||||
/* generate HTML from the first worksheet */
|
||||
var first_sheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
var table_html = XLSX.utils.sheet_to_html(first_sheet);
|
||||
|
||||
/* add to page */
|
||||
document.getElementById("sheetjs-tbl").innerHTML = table_html;
|
||||
};
|
||||
req.send();
|
||||
</script>
|
||||
```
|
||||
|
||||
<details>
|
||||
@ -135,7 +172,7 @@ function SheetJSXHRDL() {
|
||||
req.responseType = "arraybuffer";
|
||||
req.onload = e => {
|
||||
/* Parse file */
|
||||
const wb = XLSX.read(new Uint8Array(req.response));
|
||||
const wb = XLSX.read(req.response);
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
|
||||
/* Generate HTML */
|
||||
@ -150,6 +187,35 @@ function SheetJSXHRDL() {
|
||||
|
||||
</details>
|
||||
|
||||
In browsers that do not support `ArrayBuffer`, including Internet Explorer and
|
||||
older versions of Firefox, `XMLHttpRequest` will return an array of unsigned
|
||||
bytes. In this case, the `read` method requires the option `type: "array"`:
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: XMLHttpRequest + SheetJS in browsers lacking ArrayBuffer support
|
||||
---
|
||||
flowchart LR
|
||||
file[(workbook\nfile)]
|
||||
ab[(file bytes\nArray)]
|
||||
wb(((SheetJS\nWorkbook)))
|
||||
file --> |XMLHttpRequest\nresponseType="arraybuffer"| ab
|
||||
ab --> |SheetJS read\ntype="array"|wb
|
||||
```
|
||||
|
||||
```js title="Download and parse files in legacy browsers (snippet)"
|
||||
/* set up an async GET request */
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", url, true);
|
||||
req.responseType = "arraybuffer";
|
||||
|
||||
req.onload = function(e) {
|
||||
/* parse the data when it is received */
|
||||
var workbook = XLSX.read(req.response, {type: "array"});
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
};
|
||||
req.send();
|
||||
```
|
||||
|
||||
### fetch
|
||||
|
||||
|
||||
@ -589,10 +589,11 @@ NodeJS `fetch`, available in version 20, mirrors the [browser `fetch`](#fetch).
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| NodeJS | Date |
|
||||
|:-----------|:-----------|
|
||||
| `22.13.0` | 2025-01-08 |
|
||||
| `20.18.1` | 2025-01-08 |
|
||||
| NodeJS | Date |
|
||||
|:-----------|:------------|
|
||||
| `24.11.1` | 2026-03-22 |
|
||||
| `22.22.1` | 2026-03-22 |
|
||||
| `20.18.0` | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -705,18 +706,19 @@ This demo was tested in the following environments:
|
||||
|
||||
| NodeJS | `request` | Date |
|
||||
|:-----------|:----------|:-----------|
|
||||
| `22.13.0` | `2.88.2` | 2025-01-08 |
|
||||
| `20.18.1` | `2.88.2` | 2025-01-08 |
|
||||
| `18.20.5` | `2.88.2` | 2025-01-08 |
|
||||
| `16.20.2` | `2.88.2` | 2025-01-08 |
|
||||
| `14.21.3` | `2.88.2` | 2025-01-08 |
|
||||
| `12.22.12` | `2.88.2` | 2025-01-08 |
|
||||
| `10.24.1` | `2.88.2` | 2025-01-08 |
|
||||
| `8.17.0` | `2.88.2` | 2025-01-08 |
|
||||
| `6.17.1` | `2.88.2` | 2025-01-08 |
|
||||
| `4.9.1` | `2.81.0` | 2025-01-08 |
|
||||
| `0.12.18` | `2.81.0` | 2025-01-08 |
|
||||
| `0.10.48` | `2.81.0` | 2025-01-08 |
|
||||
| `24.11.1` | `2.88.2` | 2026-03-22 |
|
||||
| `22.22.1` | `2.88.2` | 2026-03-22 |
|
||||
| `20.18.0` | `2.88.2` | 2026-03-22 |
|
||||
| `18.20.8` | `2.88.2` | 2026-03-22 |
|
||||
| `16.20.2` | `2.88.2` | 2026-03-22 |
|
||||
| `14.21.3` | `2.88.2` | 2026-03-22 |
|
||||
| `12.22.12` | `2.88.2` | 2026-03-22 |
|
||||
| `10.24.1` | `2.88.2` | 2026-03-22 |
|
||||
| `8.17.0` | `2.88.2` | 2026-03-22 |
|
||||
| `6.17.1` | `2.88.2` | 2026-03-22 |
|
||||
| `4.9.1` | `2.88.2` | 2026-03-22 |
|
||||
| `0.12.18` | `2.81.0` | 2026-03-22 |
|
||||
| `0.10.48` | `2.81.0` | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -735,9 +737,13 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz request
|
||||
|
||||
:::note pass
|
||||
|
||||
The current version of `request` requires NodeJS 6 or later. For older versions
|
||||
The current version of `request` requires NodeJS 4 or later. For older versions
|
||||
of NodeJS, `request` version `2.81.0` should be installed.
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz request@2.81.0`}
|
||||
</CodeBlock>
|
||||
|
||||
:::
|
||||
|
||||
2) Save the following to `SheetJSRequest.js`:
|
||||
|
||||
@ -26,8 +26,8 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Version | Date |
|
||||
|:---------|:-----------|
|
||||
| `4.21.2` | 2025-01-03 |
|
||||
| `5.0.1` | 2025-01-03 |
|
||||
| `4.21.2` | 2026-03-12 |
|
||||
| `5.2.1` | 2026-03-12 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -130,13 +130,13 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Puppeteer | Date |
|
||||
|:----------|:-----------|
|
||||
| `24.9.0` | 2025-05-21 |
|
||||
| `23.11.1` | 2025-05-21 |
|
||||
| `22.15.0` | 2025-05-21 |
|
||||
| `21.11.0` | 2025-05-21 |
|
||||
| `20.9.0` | 2025-05-21 |
|
||||
| `15.5.0` | 2025-05-21 |
|
||||
| `10.4.0` | 2025-05-21 |
|
||||
| `24.35.0` | 2026-01-21 |
|
||||
| `23.11.1` | 2026-01-21 |
|
||||
| `22.15.0` | 2026-01-21 |
|
||||
| `21.11.0` | 2026-01-21 |
|
||||
| `20.9.0` | 2026-01-21 |
|
||||
| `15.5.0` | 2026-01-21 |
|
||||
| `10.4.0` | 2026-01-21 |
|
||||
|
||||
:::
|
||||
|
||||
@ -333,9 +333,9 @@ This demo was tested in the following environments:
|
||||
|
||||
| Architecture | PhantomJS | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `2.1.1` | 2025-03-31 |
|
||||
| `win11-x64` | `2.1.1` | 2025-06-18 |
|
||||
| `linux-x64` | `2.1.1` | 2025-06-16 |
|
||||
| `darwin-x64` | `2.1.1` | 2026-03-07 |
|
||||
| `win11-x64` | `2.1.1` | 2026-03-07 |
|
||||
| `linux-x64` | `2.1.1` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -430,4 +430,4 @@ env OPENSSL_CONF=/dev/null QT_QPA_PLATFORM=phantom ./phantomjs-2.1.1-linux-x86_6
|
||||
|
||||
[^1]: See ["Workbook Object"](/docs/csf/book) for more details about the SheetJS workbook object.
|
||||
[^2]: See [`table_to_book` in "HTML" Utilities](/docs/api/utilities/html#create-new-sheet)
|
||||
[^3]: See [`write` in "Writing Files"](/docs/api/write-options)
|
||||
[^3]: See [`write` in "Writing Files"](/docs/api/write-options)
|
||||
|
||||
@ -296,10 +296,9 @@ features to ensure that SheetJS DOM methods can process TABLE elements.
|
||||
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| CheerioJS | Date |
|
||||
|:--------------|:-----------|
|
||||
| `1.0.0` | 2025-04-24 |
|
||||
| `1.0.0-rc.12` | 2025-04-24 |
|
||||
| CheerioJS | Date |
|
||||
|:----------|:-----------|
|
||||
| `1.2.0` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -309,7 +308,7 @@ This demo was tested in the following deployments:
|
||||
1) Install SheetJS and CheerioJS libraries:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz cheerio@1.0.0`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz cheerio@1.1.2`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Download [the sample script `SheetJSCheerio.js`](pathname:///dom/SheetJSCheerio.js):
|
||||
@ -375,12 +374,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | DenoDOM | Deno | Date |
|
||||
|:-------------|:--------|:-------|:-----------|
|
||||
| `darwin-x64` | 0.1.48 | 2.2.6 | 2025-03-31 |
|
||||
| `darwin-arm` | 0.1.48 | 2.2.12 | 2025-04-24 |
|
||||
| `darwin-x64` | 0.1.48 | 2.7.4 | 2026-03-07 |
|
||||
| `darwin-arm` | 0.1.48 | 2.7.4 | 2026-03-12 |
|
||||
| `win11-x64` | 0.1.48 | 2.2.12 | 2025-04-28 |
|
||||
| `win11-arm` | 0.1.48 | 2.2.1 | 2025-02-23 |
|
||||
| `linux-x64` | 0.1.48 | 2.3.6 | 2025-06-16 |
|
||||
| `linux-arm` | 0.1.48 | 2.1.10 | 2025-02-16 |
|
||||
| `win11-arm` | 0.1.48 | 2.7.7 | 2026-03-22 |
|
||||
| `linux-x64` | 0.1.48 | 2.7.4 | 2026-03-07 |
|
||||
| `linux-arm` | 0.1.48 | 2.7.4 | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -204,24 +204,26 @@ This demo was tested in the following environments:
|
||||
|
||||
| `esbuild` | Date |
|
||||
|:----------|:-----------|
|
||||
| `0.25.5` | 2025-06-20 |
|
||||
| `0.24.2` | 2025-06-20 |
|
||||
| `0.23.1` | 2025-06-20 |
|
||||
| `0.22.0` | 2025-06-20 |
|
||||
| `0.21.5` | 2025-06-20 |
|
||||
| `0.20.2` | 2025-06-20 |
|
||||
| `0.19.12` | 2025-06-20 |
|
||||
| `0.18.20` | 2025-06-20 |
|
||||
| `0.17.19` | 2025-06-20 |
|
||||
| `0.16.17` | 2025-06-20 |
|
||||
| `0.15.18` | 2025-06-20 |
|
||||
| `0.14.54` | 2025-06-20 |
|
||||
| `0.13.15` | 2025-06-20 |
|
||||
| `0.12.29` | 2025-06-20 |
|
||||
| `0.11.23` | 2025-06-20 |
|
||||
| `0.10.2` | 2025-06-20 |
|
||||
| `0.9.7` | 2025-06-20 |
|
||||
| `0.9.1` | 2025-06-20 |
|
||||
| `0.27.2` | 2026-01-28 |
|
||||
| `0.26.0` | 2026-01-28 |
|
||||
| `0.25.5` | 2026-01-28 |
|
||||
| `0.24.2` | 2026-01-28 |
|
||||
| `0.23.1` | 2026-01-28 |
|
||||
| `0.22.0` | 2026-01-28 |
|
||||
| `0.21.5` | 2026-01-28 |
|
||||
| `0.20.2` | 2026-01-28 |
|
||||
| `0.19.12` | 2026-01-28 |
|
||||
| `0.18.20` | 2026-01-28 |
|
||||
| `0.17.19` | 2026-01-28 |
|
||||
| `0.16.17` | 2026-01-28 |
|
||||
| `0.15.18` | 2026-01-28 |
|
||||
| `0.14.54` | 2026-01-28 |
|
||||
| `0.13.15` | 2026-01-28 |
|
||||
| `0.12.29` | 2026-01-28 |
|
||||
| `0.11.23` | 2026-01-28 |
|
||||
| `0.10.2` | 2026-01-28 |
|
||||
| `0.9.7` | 2026-01-28 |
|
||||
| `0.9.1` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -356,11 +356,12 @@ This demo was tested in the following environments:
|
||||
|
||||
| ViteJS | Date |
|
||||
|:---------|:-----------|
|
||||
| `6.2.3` | 2025-03-30 |
|
||||
| `5.4.15` | 2025-03-30 |
|
||||
| `4.5.10` | 2025-03-30 |
|
||||
| `3.2.11` | 2025-03-30 |
|
||||
| `2.9.18` | 2025-03-30 |
|
||||
| `7.2.2` | 2025-11-15 |
|
||||
| `6.4.1` | 2025-11-15 |
|
||||
| `5.4.21` | 2025-11-15 |
|
||||
| `4.5.14` | 2025-11-15 |
|
||||
| `3.2.11` | 2025-11-15 |
|
||||
| `2.9.18` | 2025-11-15 |
|
||||
|
||||
:::
|
||||
|
||||
@ -376,7 +377,7 @@ major version. For example, `npm create vite@3` will use ViteJS major version 3.
|
||||
:::
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm create vite@5 sheetjs-vite -- --template vue-ts
|
||||
npm create vite@5 sheetjs-vite -- --template vue-ts --no-rolldown --no-interactive
|
||||
cd sheetjs-vite
|
||||
npm i
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
|
||||
@ -186,9 +186,9 @@ document.body.appendChild(elt);
|
||||
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| Version | Date |
|
||||
|:---------|:-----------|
|
||||
| `5.97.1` | 2025-01-08 |
|
||||
| Version | Date |
|
||||
|:----------|:-----------|
|
||||
| `5.105.2` | 2026-03-12 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -115,11 +115,11 @@ accessed using the variable `pres` in a template:
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| Eleventy | Date |
|
||||
|:---------------|:-----------|
|
||||
| `2.0.1` | 2025-05-07 |
|
||||
| `3.0.0` | 2025-05-07 |
|
||||
| `3.1.0-beta.1` | 2025-05-07 |
|
||||
| Eleventy | Date |
|
||||
|:----------------|:-----------|
|
||||
| `4.0.0-alpha.6` | 2026-01-28 |
|
||||
| `3.1.2` | 2026-01-28 |
|
||||
| `2.0.1` | 2026-01-28 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -52,13 +52,14 @@ This demo was tested in the following environments:
|
||||
|
||||
| AstroJS | Template | Date |
|
||||
|:--------|:-----------------|:-----------|
|
||||
| `4.6.1` | Starlight 0.22.4 | 2025-01-07 |
|
||||
| `5.1.3` | Starlight 0.30.5 | 2025-01-07 |
|
||||
| `6.0.6` | Starlight 0.38.1 | 2026-03-22 |
|
||||
|
||||
In previous test runs, this demo successfully ran using older AstroJS versions:
|
||||
|
||||
| AstroJS | Template |
|
||||
|:--------|:-----------------|
|
||||
| `5.1.3` | Starlight 0.30.5 |
|
||||
| `4.6.1` | Starlight 0.22.4 |
|
||||
| `3.6.5` | Starlight 0.14.0 |
|
||||
|
||||
:::
|
||||
|
||||
@ -242,7 +242,7 @@ npx -y @capacitor/cli telemetry
|
||||
2) Create a new Svelte project:
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-cap -- --template svelte
|
||||
npm create vite@latest sheetjs-cap -- --template svelte --no-rolldown --no-interactive
|
||||
cd sheetjs-cap
|
||||
```
|
||||
|
||||
|
||||
@ -48,18 +48,18 @@ This demo was tested in the following environments:
|
||||
|
||||
**Real Devices**
|
||||
|
||||
| OS | Device | Dart | Flutter | Date |
|
||||
|:-----------|:------------------|:--------|:---------|:-----------|
|
||||
| Android 34 | NVIDIA Shield | `3.7.2` | `3.29.2` | 2025-03-31 |
|
||||
| iOS 15.6 | iPhone 13 Pro Max | `3.7.2` | `3.29.2` | 2025-03-31 |
|
||||
| OS | Device | Dart | Flutter | Date |
|
||||
|:-----------|:------------------|:---------|:---------|:-----------|
|
||||
| Android 34 | NVIDIA Shield | `3.7.2` | `3.29.2` | 2025-03-31 |
|
||||
| iOS 26.3 | iPhone 13 Pro Max | `3.11.1` | `3.41.4` | 2026-03-10 |
|
||||
|
||||
**Simulators**
|
||||
|
||||
| OS | Device | Dart | Flutter | Dev Platform | Date |
|
||||
|:-----------|:------------------|:--------|:---------|:-------------|:-----------|
|
||||
| Android 35 | Pixel 9 Pro XL | `3.7.2` | `3.29.2` | `darwin-x64` | 2025-03-31 |
|
||||
| iOS 18.3 | iPhone 16 Pro Max | `3.7.2` | `3.29.2` | `darwin-x64` | 2025-03-31 |
|
||||
| Android 36 | Pixel 9 Pro XL | `3.7.2` | `3.29.3` | `win11-x64` | 2054-04-28 |
|
||||
| OS | Device | Dart | Flutter | Dev Platform | Date |
|
||||
|:-----------|:------------------|:---------|:---------|:-------------|:-----------|
|
||||
| Android 36 | Pixel Tablet | `3.11.1` | `3.41.4` | `darwin-arm` | 2026-03-11 |
|
||||
| iOS 18.6 | iPhone 16 Pro Max | `3.11.1` | `3.41.4` | `darwin-arm` | 2026-03-11 |
|
||||
| Android 36 | Pixel 9 Pro XL | `3.7.2` | `3.29.3` | `win11-x64` | 2054-04-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -297,6 +297,21 @@ error: Android sdkmanager not found. Update to the latest Android SDK and ensure
|
||||
Android Studio does not install `Android SDK Command-Line Tools` by default. It
|
||||
must be installed manually.
|
||||
|
||||
---
|
||||
To enable Android SDK Command-Line Tools via Android Studio follow this:
|
||||
|
||||
Find SDK manager by searching it in *Search Everywhere*
|
||||

|
||||
|
||||
Select **SDK Tools** from the top tab in the middle panel, then check **Android SDK Command-line Tools (latest)** and
|
||||
click **OK**.
|
||||
|
||||

|
||||
|
||||
A dialog will appear asking to download and install the tools. Click **OK** to continue.
|
||||
|
||||
---
|
||||
|
||||
Assuming the command-line tools are installed
|
||||
|
||||
This was fixed by switching to Java 20, installing `Android SDK 33`, and rolling
|
||||
@ -531,7 +546,7 @@ Once the app loads, stop the terminal process and close the simulator.
|
||||
5) Install Flutter / Dart dependencies:
|
||||
|
||||
```bash
|
||||
flutter pub add http csv flutter_js
|
||||
flutter pub add http csv flutter_js collection
|
||||
```
|
||||
|
||||
:::info pass
|
||||
@ -555,7 +570,7 @@ As stated, "Developer Mode" must be enabled:
|
||||
3) Reinstall dependencies:
|
||||
|
||||
```bash
|
||||
flutter pub add http csv flutter_js
|
||||
flutter pub add http csv flutter_js collection
|
||||
```
|
||||
|
||||
:::
|
||||
@ -858,7 +873,7 @@ The app may take 30 seconds to load the content.
|
||||
|
||||
### iOS Device
|
||||
|
||||
19) Follow the official "Deploy to physical iOS devices" instructions[^10]
|
||||
19) **Follow the official ["Deploy to physical iOS devices"](https://docs.flutter.dev/platform-integration/ios/setup#set-up-devices) instructions**
|
||||
|
||||
20) Connect the iOS device and verify that `flutter` can find the device:
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import current from '/version.js';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import Link from '@docusaurus/Link';
|
||||
|
||||
export const r = {style: {color:"red"}};
|
||||
export const g = {style: {color:"green"}};
|
||||
@ -257,7 +258,8 @@ curl -o ./src/App.tsx https://docs.sheetjs.com/lynx/App.tsx
|
||||
```bash
|
||||
curl -o ./src/App.css https://docs.sheetjs.com/lynx/App.css
|
||||
```
|
||||
<a name="step5"></a>
|
||||
|
||||
<Link id="step5"/>
|
||||
|
||||
5) Start the development server:
|
||||
|
||||
|
||||
@ -238,7 +238,7 @@ This demo was tested in the following environments:
|
||||
|
||||
| OS and Version | Architecture | Electron | Date |
|
||||
|:---------------|:-------------|:---------|:-----------|
|
||||
| macOS 15.3 | `darwin-x64` | `35.1.2` | 2025-03-31 |
|
||||
| macOS 15.7.4 | `darwin-x64` | `40.8.0` | 2026-03-08 |
|
||||
| macOS 14.5 | `darwin-arm` | `35.1.2` | 2025-08-30 |
|
||||
| Windows 11 | `win11-x64` | `33.2.1` | 2025-02-11 |
|
||||
| Windows 11 | `win11-arm` | `33.2.1` | 2025-02-23 |
|
||||
|
||||
@ -37,12 +37,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | NodeJS | Source | Date |
|
||||
|:-------------|:---------------|:----------|:----------|:-----------|
|
||||
| `darwin-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-04-21 |
|
||||
| `darwin-arm` | `5.0.0-beta.4` | `22.14.0` | Compiled | 2025-06-18 |
|
||||
| `win11-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-05-07 |
|
||||
| `darwin-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2026-01-21 |
|
||||
| `darwin-arm` | `5.0.0-beta.4` | `20.18.0` | Compiled | 2026-03-07 |
|
||||
| `win11-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2026-03-08 |
|
||||
| `win11-arm` | `4.0.0-rc.6` | `22.14.0` | Compiled | 2025-02-23 |
|
||||
| `linux-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-04-21 |
|
||||
| `linux-arm` | `4.0.0-rc.6` | `22.13.0` | Compiled | 2025-02-15 |
|
||||
| `linux-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2026-01-18 |
|
||||
| `linux-arm` | `5.0.0-beta.4` | `24.14.0` | Compiled | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -37,12 +37,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | NodeJS | Date |
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `5.8.1` | `18.5.0` | 2025-04-21 |
|
||||
| `darwin-arm` | `5.8.1` | `18.5.0` | 2025-06-18 |
|
||||
| `win11-x64` | `5.8.1` | `18.5.0` | 2025-05-07 |
|
||||
| `darwin-x64` | `5.8.1` | `18.5.0` | 2026-01-21 |
|
||||
| `darwin-arm` | `5.8.1` | `18.5.0` | 2026-03-07 |
|
||||
| `win11-x64` | `5.8.1` | `18.5.0` | 2026-03-08 |
|
||||
| `win11-arm` | `5.8.1` | `18.5.0` | 2025-02-23 |
|
||||
| `linux-x64` | `5.8.1` | `18.5.0` | 2025-04-21 |
|
||||
| `linux-arm` | `5.8.1` | `18.5.0` | 2025-02-15 |
|
||||
| `linux-x64` | `5.8.1` | `18.5.0` | 2026-01-18 |
|
||||
| `linux-arm` | `5.8.1` | `18.5.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -30,10 +30,10 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | NodeJS | Date |
|
||||
|:-------------|:--------|:----------|:-----------|
|
||||
| `darwin-x64` | `2.4.4` | `23.11.0` | 2025-04-21 |
|
||||
| `darwin-arm` | `2.4.4` | `23.11.0` | 2025-06-18 |
|
||||
| `darwin-x64` | `3.0.0` | `25.8.0` | 2026-03-08 |
|
||||
| `darwin-arm` | `3.0.0` | `23.11.0` | 2026-03-13 |
|
||||
| `win11-x64` | `2.4.4` | `16.20.2` | 2025-05-07 |
|
||||
| `linux-x64` | `2.4.4` | `23.11.0` | 2025-04-21 |
|
||||
| `linux-x64` | `3.0.0` | `25.8.0` | 2026-03-08 |
|
||||
| `linux-arm` | `2.4.4` | `23.8.0` | 2025-02-15 |
|
||||
|
||||
:::
|
||||
@ -91,7 +91,7 @@ yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epi
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```bash
|
||||
npx -y boxednode@2.4.4 -s xlsx-cli.js -t xlsx-cli
|
||||
npx -y boxednode@3.0.0 -s xlsx-cli.js -t xlsx-cli
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
@ -158,12 +158,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | NodeJS | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `22.14.0` | 2025-04-21 |
|
||||
| `darwin-arm` | `24.2.0` | 2025-06-18 |
|
||||
| `win11-x64` | `24.2.0` | 2025-06-17 |
|
||||
| `darwin-x64` | `24.13.0` | 2026-01-21 |
|
||||
| `darwin-arm` | `20.18.0` | 2026-03-13 |
|
||||
| `win11-x64` | `24.13.0` | 2026-03-08 |
|
||||
| `win11-arm` | `22.14.0` | 2025-02-23 |
|
||||
| `linux-x64` | `24.2.0` | 2025-06-16 |
|
||||
| `linux-arm` | `22.13.0` | 2025-02-16 |
|
||||
| `linux-x64` | `24.11.0` | 2026-03-08 |
|
||||
| `linux-arm` | `24.14.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -79,12 +79,12 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | BunJS | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `1.2.10` | 2025-04-21 |
|
||||
| `darwin-arm` | `1.2.16` | 2025-06-18 |
|
||||
| `win11-x64` | `1.2.13` | 2025-05-07 |
|
||||
| `darwin-x64` | `1.3.6` | 2026-01-21 |
|
||||
| `darwin-arm` | `1.3.10` | 2026-03-07 |
|
||||
| `win11-x64` | `1.3.10` | 2026-03-08 |
|
||||
| `win11-arm` | `1.2.3` | 2025-02-23 |
|
||||
| `linux-x64` | `1.2.16` | 2025-06-16 |
|
||||
| `linux-arm` | `1.2.2` | 2025-02-16 |
|
||||
| `linux-x64` | `1.3.10` | 2026-03-08 |
|
||||
| `linux-arm` | `1.3.10` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -102,12 +102,12 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | Deno | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.2.11` | 2025-04-21 |
|
||||
| `darwin-arm` | `2.3.6` | 2025-06-18 |
|
||||
| `win11-x64` | `2.3.6` | 2025-06-17 |
|
||||
| `darwin-x64` | `2.6.5` | 2026-01-21 |
|
||||
| `darwin-arm` | `2.7.4` | 2026-03-07 |
|
||||
| `win11-x64` | `2.7.4` | 2026-03-08 |
|
||||
| `win11-arm` | `2.2.1` | 2025-02-23 |
|
||||
| `linux-x64` | `2.3.6` | 2025-06-16 |
|
||||
| `linux-arm` | `2.1.10` | 2025-02-15 |
|
||||
| `linux-x64` | `2.7.4` | 2026-03-08 |
|
||||
| `linux-arm` | `2.7.4` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -88,14 +88,14 @@ console.log(csv);
|
||||
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | TxikiJS | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `24.12.0` | 2025-04-19 |
|
||||
| `darwin-arm` | `24.12.0` | 2025-04-19 |
|
||||
| `win11-x64` | `24.12.0` | 2025-04-19 |
|
||||
| `win11-arm` | `24.12.0` | 2025-04-19 |
|
||||
| `linux-x64` | `24.12.0` | 2025-04-19 |
|
||||
| `linux-arm` | `24.12.0` | 2025-04-19 |
|
||||
| Architecture | Version | Commit | Date |
|
||||
|:-------------|:----------|:----------|:-----------|
|
||||
| `darwin-x64` | `24.12.0` | `793dd9d` | 2026-01-21 |
|
||||
| `darwin-arm` | `24.12.0` | `793dd9d` | 2026-01-18 |
|
||||
| `win11-x64` | `24.12.0` | | 2026-03-08 |
|
||||
| `win11-arm` | `24.12.0` | | 2025-04-19 |
|
||||
| `linux-x64` | `24.12.0` | `65e5595` | 2026-01-18 |
|
||||
| `linux-arm` | `24.12.0` | `65e5595` | 2026-01-21 |
|
||||
|
||||
:::
|
||||
|
||||
@ -133,6 +133,40 @@ cp build/tjs ../
|
||||
cd ..
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
In some `linux-x64` test runs, the `make` step failed:
|
||||
|
||||
```
|
||||
make[5]: *** No rule to make target 'all-configured'. Stop.
|
||||
```
|
||||
|
||||
After re-running `make`, the `[ 0%]` line identifies the root cause:
|
||||
|
||||
```text
|
||||
// highlight-next-line
|
||||
[ 0%] Performing build step for 'libffi'
|
||||
[ 1%] Built target sqlite3
|
||||
[ 2%] Built target ffi-test
|
||||
...
|
||||
[ 61%] Built target sqlite-test
|
||||
MAKE x86_64-pc-linux-gnu : 0 * all-configured
|
||||
// highlight-next-line
|
||||
make[5]: *** No rule to make target 'all-configured'. Stop.
|
||||
```
|
||||
|
||||
If the root cause is `libffi`, it is possible to use the system `libffi`. The
|
||||
following commands should be run in the `txiki.js` folder:
|
||||
|
||||
```bash
|
||||
rm -rf build
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -DUSE_EXTERNAL_FFI=ON
|
||||
cmake --build build -j 8
|
||||
cp build/tjs ../
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win11-x64" label="Windows">
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ sidebar_custom_props:
|
||||
---
|
||||
|
||||
<head>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.13.0/sql-wasm.js"></script>
|
||||
</head>
|
||||
|
||||
import current from '/version.js';
|
||||
@ -39,11 +39,11 @@ This demo was tested in the following environments:
|
||||
|
||||
| Platform | Connector Library | Date |
|
||||
|:-----------------|:----------------------------|:-----------|
|
||||
| Chromium 131 | `sql.js` (`1.8.0`) | 2025-01-08 |
|
||||
| Konqueror 22 | `sql.js` (`1.8.0`) | 2025-04-23 |
|
||||
| NodeJS `20.18.0` | `better-sqlite3` (`11.7.2`) | 2025-01-08 |
|
||||
| BunJS `1.1.43` | (built-in) | 2025-01-08 |
|
||||
| Deno `2.1.4` | `sqlite` (`3.9.1`) | 2025-01-09 |
|
||||
| Chromium 143 | `sql.js` (`1.13.0`) | 2026-03-22 |
|
||||
| Konqueror 25 | `sql.js` (`1.13.0`) | 2026-03-22 |
|
||||
| NodeJS `20.18.0` | `better-sqlite3` (`12.6.2`) | 2026-03-22 |
|
||||
| BunJS `1.3.11` | (built-in) | 2026-03-22 |
|
||||
| Deno `2.7.4` | `sqlite` (`3.9.1`) | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -143,7 +143,7 @@ exported to a XLSX file.
|
||||
function SheetJSQLJS() { return (<button onClick={async() => {
|
||||
/* Load sql.js library */
|
||||
const config = {
|
||||
locateFile: filename => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/${filename}`
|
||||
locateFile: filename => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.13.0/${filename}`
|
||||
}
|
||||
const SQL = await initSqlJs(config);
|
||||
|
||||
@ -211,7 +211,7 @@ sqlite3 chinook.db ".read chinook.sql"
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm init -y
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz better-sqlite3@9.2.0`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz better-sqlite3@12.6.2`}
|
||||
</CodeBlock>
|
||||
|
||||
2) Download [`SheetJSQLiteNode.mjs`](pathname:///sqlite/SheetJSQLiteNode.mjs):
|
||||
@ -288,7 +288,8 @@ import * as XLSX from "https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs"
|
||||
var db = new DB("chinook.db");
|
||||
\n\
|
||||
/* get data from the \`Invoice\` table */
|
||||
var aoa = db.prepareQuery("SELECT * FROM 'Invoice' LIMIT 100000").all();
|
||||
var query = db.prepareQuery("SELECT * FROM 'Invoice' LIMIT 100000");
|
||||
var aoa = query.all();
|
||||
\n\
|
||||
/* create worksheet from the row objects */
|
||||
var data = [query.columns().map(x => x.name)].concat(aoa);
|
||||
|
||||
@ -25,10 +25,9 @@ This demo was tested in the following environments:
|
||||
|
||||
| Version | Database | Connector Module | Date |
|
||||
|:----------|:---------|:-----------------|:-----------|
|
||||
| `0.21.20` | SQLite | `sqlite3` | 2025-01-09 |
|
||||
| `2.4.2` | SQLite | `better-sqlite3` | 2025-01-09 |
|
||||
| `2.5.1` | SQLite | `better-sqlite3` | 2025-01-09 |
|
||||
| `3.1.0` | SQLite | `better-sqlite3` | 2025-01-09 |
|
||||
| `0.21.20` | SQLite | `sqlite3` | 2026-03-22 |
|
||||
| `2.5.1` | SQLite | `better-sqlite3` | 2026-03-22 |
|
||||
| `3.1.0` | SQLite | `better-sqlite3` | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -42,8 +41,8 @@ loaded in NodeJS scripts that use KnexJS.
|
||||
The KnexJS `select` method[^1] creates a `SELECT` query. The return value is a
|
||||
Promise that resolves to an array of objects.
|
||||
|
||||
The SheetJS `json_to_sheet` method[^2] can generate a worksheet object[^3] from
|
||||
the array of objects:
|
||||
The SheetJS [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
|
||||
method can generate a [worksheet object](/docs/csf/sheet) from the array:
|
||||
|
||||
```js
|
||||
const table_name = "Tabeller1"; // name of table
|
||||
@ -55,8 +54,9 @@ const aoo = await knex.select("*").from(table_name);
|
||||
const worksheet = XLSX.utils.json_to_sheet(aoo);
|
||||
```
|
||||
|
||||
A workbook object can be built from the worksheet using utility functions[^4].
|
||||
The workbook can be exported using the SheetJS `writeFile` method[^5]:
|
||||
Using [`book_new` and `book_append_sheet`](/docs/api/utilities/wb), a workbook
|
||||
object can be created. This workbook is typically exported to the filesystem
|
||||
with the [`writeFile`](/docs/api/write-options) method:
|
||||
|
||||
```js
|
||||
/* create a new workbook and add the worksheet */
|
||||
@ -69,10 +69,10 @@ XLSX.writeFile(wb, "SheetJSKnexJSExport.xlsx");
|
||||
|
||||
### Importing Data
|
||||
|
||||
The SheetJS `sheet_to_json` function[^6] takes a worksheet object and generates
|
||||
an array of objects.
|
||||
The SheetJS [`sheet_to_json` function](/docs/api/utilities/array#array-output)
|
||||
accepts a worksheet object and generates an array of objects.
|
||||
|
||||
The KnexJS `insert` method[^7] creates `INSERT` queries. The return value is a
|
||||
The KnexJS `insert` method[^2] creates `INSERT` queries. The return value is a
|
||||
Promise that resolves when the query is executed:
|
||||
|
||||
```js
|
||||
@ -87,8 +87,8 @@ await knex.insert(aoo).into(table_name);
|
||||
|
||||
### Creating a Table
|
||||
|
||||
The KnexJS Schema Builder supports creating tables with `createTable`[^8] and
|
||||
dropping tables with `dropTableIfExists`[^9].
|
||||
The KnexJS Schema Builder supports creating tables with `createTable`[^3] and
|
||||
dropping tables with `dropTableIfExists`[^4].
|
||||
|
||||
The array of objects can be scanned to determine column names and types.
|
||||
|
||||
@ -272,11 +272,6 @@ Older versions of KnexJS do not support the `better-sqlite3` module. The
|
||||
:::
|
||||
|
||||
[^1]: See [`select`](https://knexjs.org/guide/query-builder.html#select) in the KnexJS query builder documentation.
|
||||
[^2]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^3]: See ["Sheet Objects"](/docs/csf/sheet) in "SheetJS Data Model" for more details.
|
||||
[^4]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
|
||||
[^5]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
[^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^7]: See [`insert`](https://knexjs.org/guide/query-builder.html#insert) in the KnexJS query builder documentation.
|
||||
[^8]: See [`createTable`](https://knexjs.org/guide/schema-builder.html#createtable) in the KnexJS Schema Builder documentation.
|
||||
[^9]: See [`dropTableIfExists`](https://knexjs.org/guide/schema-builder.html#droptableifexists) in the KnexJS Schema Builder documentation.
|
||||
[^2]: See [`insert`](https://knexjs.org/guide/query-builder.html#insert) in the KnexJS query builder documentation.
|
||||
[^3]: See [`createTable`](https://knexjs.org/guide/schema-builder.html#createtable) in the KnexJS Schema Builder documentation.
|
||||
[^4]: See [`dropTableIfExists`](https://knexjs.org/guide/schema-builder.html#droptableifexists) in the KnexJS Schema Builder documentation.
|
||||
|
||||
@ -36,12 +36,13 @@ This demo was tested in the following environments:
|
||||
|
||||
| Postgres | Connector Library | Date |
|
||||
|:---------|:------------------|:-----------|
|
||||
| `17.2` | `pg` (`8.13.1`) | 2025-01-03 |
|
||||
| `16.6` | `pg` (`8.13.1`) | 2025-01-03 |
|
||||
| `15.10` | `pg` (`8.13.1`) | 2025-01-03 |
|
||||
| `14.15` | `pg` (`8.13.1`) | 2025-01-03 |
|
||||
| `13.18` | `pg` (`8.13.1`) | 2025-01-03 |
|
||||
| `12.22` | `pg` (`8.13.1`) | 2025-01-03 |
|
||||
| `18.3` | `pg` (`8.20.0`) | 2026-03-22 |
|
||||
| `17.2` | `pg` (`8.20.0`) | 2026-03-22 |
|
||||
| `16.6` | `pg` (`8.20.0`) | 2026-03-22 |
|
||||
| `15.10` | `pg` (`8.20.0`) | 2026-03-22 |
|
||||
| `14.15` | `pg` (`8.20.0`) | 2026-03-22 |
|
||||
| `13.18` | `pg` (`8.20.0`) | 2026-03-22 |
|
||||
| `12.22` | `pg` (`8.20.0`) | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -58,8 +59,8 @@ other PostgreSQL libraries.
|
||||
`Client#query` returns a Promise that resolves to a result set. The `rows`
|
||||
property of the result is an array of objects.
|
||||
|
||||
The SheetJS `json_to_sheet` method[^2] can generate a worksheet object[^3] from
|
||||
the array of objects:
|
||||
The SheetJS [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
|
||||
method can generate a [worksheet object](/docs/csf/sheet) from the array:
|
||||
|
||||
```js
|
||||
const table_name = "Tabeller1"; // name of table
|
||||
@ -71,8 +72,8 @@ const res = await client.query(`SELECT * FROM ${table_name}`);
|
||||
const worksheet = XLSX.utils.json_to_sheet(res.rows);
|
||||
```
|
||||
|
||||
A workbook object can be built from the worksheet using utility functions[^4].
|
||||
The workbook can be exported using the SheetJS `writeFile` method[^5]:
|
||||
[Utility functions](/docs/api/utilities/wb) can build a SheetJS workbook object.
|
||||
The workbook can be exported using the [`writeFile`](/docs/api/write-options):
|
||||
|
||||
```js
|
||||
/* create a new workbook and add the worksheet */
|
||||
@ -85,8 +86,8 @@ XLSX.writeFile(wb, "SheetJSPGExport.xlsx");
|
||||
|
||||
### Importing Data
|
||||
|
||||
The SheetJS `sheet_to_json` function[^6] takes a worksheet object and generates
|
||||
an array of objects.
|
||||
The SheetJS [`sheet_to_json` function](/docs/api/utilities/array#array-output)
|
||||
accepts a worksheet object and generates an array of objects.
|
||||
|
||||
Queries must be manually generated from the objects. Assuming the field names
|
||||
in the object match the column headers, a loop can generate `INSERT` queries.
|
||||
@ -101,7 +102,7 @@ INSERT INTO table_name (?) VALUES (?);
|
||||
```
|
||||
|
||||
Queries are generated manually. To help prevent SQL injection vulnerabilities,
|
||||
the `pg-format`[^7] module escapes identifiers and fields.
|
||||
the `pg-format`[^2] module escapes identifiers and fields.
|
||||
|
||||
:::
|
||||
|
||||
@ -308,7 +309,7 @@ sudo -u postgres createuser -P $USER
|
||||
sudo -u postgres psql -c "ALTER USER $USER WITH SUPERUSER;"
|
||||
```
|
||||
|
||||
If running the optional user creation steps above, a PostgreSQL password will be required. [^8]
|
||||
If running the optional user creation steps above, a PostgreSQL password will be required. [^3]
|
||||
|
||||
Run the command to start a local database instance.
|
||||
|
||||
@ -538,10 +539,5 @@ psql SheetJSPG -c 'SELECT * FROM "Presidents";'
|
||||
|
||||
|
||||
[^1]: See [the official `pg` website](https://node-postgres.com/) for more info.
|
||||
[^2]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^3]: See ["Sheet Objects"](/docs/csf/sheet) in "SheetJS Data Model" for more details.
|
||||
[^4]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
|
||||
[^5]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
[^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^7]: The [`pg-format`](https://npm.im/pg-format) package is available on the public NPM registry. Even though the project is marked as deprecated, the official [`pg` website still recommends `pg-format`](https://node-postgres.com/features/queries#parameterized-query:~:text=use%20pg%2Dformat%20package%20for%20handling%20escaping)
|
||||
[^8]: PostgreSQL on Linux uses [SCRAM authentication by default, which requires a password](https://www.postgresql.org/docs/current/auth-password.html)
|
||||
[^2]: The [`pg-format`](https://npm.im/pg-format) package is available on the public NPM registry. Even though the project is marked as deprecated, the official [`pg` website still recommends `pg-format`](https://node-postgres.com/features/queries#parameterized-query:~:text=use%20pg%2Dformat%20package%20for%20handling%20escaping)
|
||||
[^3]: PostgreSQL on Linux uses [SCRAM authentication by default, which requires a password](https://www.postgresql.org/docs/current/auth-password.html)
|
||||
@ -36,7 +36,8 @@ This demo was tested in the following environments:
|
||||
|
||||
| MariaDB | Connector Library | Date |
|
||||
|:---------|:--------------------|:-----------|
|
||||
| `11.6.2` | `mysql2` (`3.12.0`) | 2025-01-19 |
|
||||
| `11.8` | `mysql2` (`3.20.2`) | 2026-03-22 |
|
||||
| `10.6` | `mysql2` (`3.20.2`) | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -53,8 +54,8 @@ to other MariaDB and MySQL libraries.
|
||||
`Connection#execute` returns a Promise that resolves to a result array. The
|
||||
first entry of the result is an array of objects.
|
||||
|
||||
The SheetJS `json_to_sheet` method[^2] can generate a worksheet object[^3] from
|
||||
the array of objects:
|
||||
The SheetJS [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
|
||||
method can generate a [worksheet object](/docs/csf/sheet) from the array:
|
||||
|
||||
```js
|
||||
const mysql = require("mysql2/promise"), XLSX = require("xlsx");
|
||||
@ -72,8 +73,9 @@ const [rows, fields] = await conn.execute(`SELECT * FROM ${mysql.escapeId(table_
|
||||
const worksheet = XLSX.utils.json_to_sheet(rows);
|
||||
```
|
||||
|
||||
A workbook object can be built from the worksheet using utility functions[^4].
|
||||
The workbook can be exported using the SheetJS `writeFile` method[^5]:
|
||||
Using [`book_new` and `book_append_sheet`](/docs/api/utilities/wb), a workbook
|
||||
object can be created. This workbook is typically exported to the filesystem
|
||||
with the [`writeFile`](/docs/api/write-options) method:
|
||||
|
||||
```js
|
||||
/* create a new workbook and add the worksheet */
|
||||
@ -86,8 +88,8 @@ XLSX.writeFile(wb, "SheetJSMariaDBExport.xlsx");
|
||||
|
||||
### Importing Data
|
||||
|
||||
The SheetJS `sheet_to_json` function[^6] takes a worksheet object and generates
|
||||
an array of objects.
|
||||
The SheetJS [`sheet_to_json` function](/docs/api/utilities/array#array-output)
|
||||
accepts a worksheet object and generates an array of objects.
|
||||
|
||||
Queries must be manually generated from the objects. Assuming the field names
|
||||
in the object match the column headers, a loop can generate `INSERT` queries.
|
||||
@ -102,7 +104,7 @@ INSERT INTO table_name (?) VALUES (?);
|
||||
```
|
||||
|
||||
Queries are generated manually. To help prevent SQL injection vulnerabilities,
|
||||
the undocumented `escapeId` method [^7] escapes identifiers and fields.
|
||||
the undocumented `escapeId` method [^2] escapes identifiers and fields.
|
||||
|
||||
:::
|
||||
|
||||
@ -408,9 +410,4 @@ The output should be consistent with the following table:
|
||||
```
|
||||
|
||||
[^1]: See [the official `mysql2` website](https://sidorares.github.io/node-mysql2/docs) for more info.
|
||||
[^2]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^3]: See ["Sheet Objects"](/docs/csf/sheet) in "SheetJS Data Model" for more details.
|
||||
[^4]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
|
||||
[^5]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
[^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^7]: The `mysql2` connector library `escapeId` method is not mentioned in the documentation but is present in the TypeScript definitions.
|
||||
[^2]: The `mysql2` connector library `escapeId` method is not mentioned in the documentation but is present in the TypeScript definitions.
|
||||
|
||||
@ -10,27 +10,35 @@ sidebar_custom_props:
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[MongoDB](https://mongodb.github.io/node-mongodb-native/) is a document-oriented
|
||||
database engine. [FerretDB](https://www.ferretdb.com/) is a truly open source
|
||||
implementation of the MongoDB wire protocol.
|
||||
:::danger pass
|
||||
|
||||
**MongoDB is not open source!**
|
||||
|
||||
MongoDB uses the Server Side Public License (SSPL), which is not open source.
|
||||
|
||||
This demo has been tested with FerretDB and other servers that implement the
|
||||
MongoDB wire protocol.
|
||||
|
||||
:::
|
||||
|
||||
[FerretDB](https://www.ferretdb.com/) is an Apache 2.0-licensed document database
|
||||
that implements the MongoDB wire protocol using PostgreSQL or SQLite as the backend.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
This demo uses SheetJS to exchange data between spreadsheets and MongoDB. We'll
|
||||
explore how to use save tables from a MongoDB collection to spreadsheets and how
|
||||
to add data from spreadsheets into a collection.
|
||||
explore how to save tables from a database collection to spreadsheets and how to
|
||||
add data from spreadsheets into a collection.
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| Server | Connector Library | Date |
|
||||
|:--------------------|:---------------------|:-----------|
|
||||
| FerretDB `1.24.0` | `mongodb` (`6.12.0`) | 2025-01-03 |
|
||||
| MongoDB CE `8.0.4` | `mongodb` (`6.12.0`) | 2025-01-19 |
|
||||
| MongoDB CE `7.0.16` | `mongodb` (`6.12.0`) | 2025-01-19 |
|
||||
| MongoDB CE `6.0.20` | `mongodb` (`6.5.0`) | 2025-01-19 |
|
||||
| Server | Connector Library | Date |
|
||||
|:-------------------|:--------------------|:-----------|
|
||||
| FerretDB `1.24.0` | `mongodb` (`7.1.0`) | 2026-03-22 |
|
||||
| MongoDB CE `8.2.0` | `mongodb` (`7.1.0`) | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -45,8 +53,10 @@ a row in the table.
|
||||
#### Importing Data
|
||||
|
||||
Data stored in an array of objects can be added to MongoDB Collections using
|
||||
`Collection#insertMany`[^1]. The SheetJS `sheet_to_json` method[^2] can generate
|
||||
data from worksheets:
|
||||
`Collection#insertMany`[^1].
|
||||
|
||||
The SheetJS [`sheet_to_json` method](/docs/api/utilities/array#array-output) can
|
||||
generate data from worksheets:
|
||||
|
||||
```js
|
||||
/* import data from a worksheet to a collection */
|
||||
@ -54,15 +64,15 @@ const aoo = XLSX.utils.sheet_to_json(ws);
|
||||
await collection.insertMany(aoo, {ordered: true});
|
||||
```
|
||||
|
||||
Typically worksheet objects are extracted from workbook objects[^3] generated
|
||||
from the SheetJS `read` or `readFile` methods[^4].
|
||||
Typically worksheets are extracted from [workbook objects](/docs/csf/book) that
|
||||
are created by SheetJS [`read` or `readFile`](/docs/api/parse-options) methods.
|
||||
|
||||
#### Exporting Data
|
||||
|
||||
`Collection#find`[^5] can pull an array of objects from a MongoDB Collection.
|
||||
`Collection#find`[^2] can pull an array of objects from a MongoDB Collection.
|
||||
|
||||
The SheetJS `json_to_sheet` method[^6] can take the result and generate a
|
||||
worksheet object.
|
||||
The SheetJS [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
|
||||
method can take the result and generate a worksheet object.
|
||||
|
||||
:::info pass
|
||||
|
||||
@ -79,20 +89,18 @@ const aoo = await collection.find({}, {projection:{_id:0}}).toArray();
|
||||
const ws = utils.json_to_sheet(aoo);
|
||||
```
|
||||
|
||||
Using `book_new` and `book_append_sheet`[^7], a workbook object can be created.
|
||||
This workbook is typically exported to the filesystem with `writeFile`[^8].
|
||||
Using [`book_new` and `book_append_sheet`](/docs/api/utilities/wb), a workbook
|
||||
object can be created. This workbook is typically exported to the filesystem
|
||||
with the [`writeFile`](/docs/api/write-options) method.
|
||||
|
||||
## Complete Example
|
||||
|
||||
0) Install a MongoDB-compatible server. Options include MongoDB CE[^9] and
|
||||
FerretDB[^10]
|
||||
|
||||
1) Start a server on `localhost` (follow official instructions).
|
||||
1) Install and start a compatible database locally.
|
||||
|
||||
<details>
|
||||
<summary><b>MongoDB CE Setup</b> (click to show)</summary>
|
||||
<summary><b>MongoDB CE</b> (click to show)</summary>
|
||||
|
||||
For MongoDB 8.0 Community Edition, the macOS steps required `brew`:
|
||||
For MongoDB 8.2 Community Edition, the macOS steps required `brew`:
|
||||
|
||||
```bash
|
||||
brew tap mongodb/brew
|
||||
@ -116,7 +124,7 @@ $(brew --prefix)/opt/mongodb-community/bin/mongod --config $(brew --prefix)/etc/
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>FerretDB Setup</b> (click to show)</summary>
|
||||
<summary><b>FerretDB</b> (click to show)</summary>
|
||||
|
||||
The official documentation recommends Docker, but it is strongly recommended to
|
||||
use [`colima`](https://github.com/abiosoft/colima) on MacOS:
|
||||
@ -188,7 +196,7 @@ docker run -d --rm --name ferretdb -p 27017:27017 -e FERRETDB_HANDLER=sqlite ghc
|
||||
mkdir sheetjs-mongo
|
||||
cd sheetjs-mongo
|
||||
npm init -y
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz mongodb@6.12.0`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz mongodb@7.1.0`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Save the following to `SheetJSMongoCRUD.mjs` (the key step is highlighted):
|
||||
@ -247,12 +255,6 @@ There should be no errors in the terminal. The script will generate the file
|
||||
`SheetJSMongoCRUD.xlsx`. That file can be opened in a spreadsheet editor.
|
||||
|
||||
[^1]: See [`insertMany`](https://mongodb.github.io/node-mongodb-native/5.7/classes/Collection.html#insertMany) in the MongoDB documentation.
|
||||
[^2]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^3]: See ["Workbook Object"](/docs/csf/book)
|
||||
[^4]: See [`read` and `readFile` in "Reading Files"](/docs/api/parse-options)
|
||||
[^5]: See [`find`](https://mongodb.github.io/node-mongodb-native/5.7/classes/Collection.html#find) in the MongoDB documentation.
|
||||
[^6]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^7]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
|
||||
[^8]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
[^9]: See ["Install MongoDB Community Edition"](https://www.mongodb.com/docs/manual/administration/install-community/#std-label-install-mdb-community-edition) in the MongoDB documentation.
|
||||
[^10]: See ["SQLite Setup with Docker Compose"](https://docs.ferretdb.io/quickstart-guide/docker/#sqlite-setup-with-docker-compose) in the FerretDB documentation.
|
||||
[^2]: See [`find`](https://mongodb.github.io/node-mongodb-native/5.7/classes/Collection.html#find) in the MongoDB documentation.
|
||||
[^3]: See ["Install MongoDB Community Edition"](https://www.mongodb.com/docs/manual/administration/install-community/#std-label-install-mdb-community-edition) in the MongoDB documentation.
|
||||
[^4]: See ["SQLite Setup with Docker Compose"](https://docs.ferretdb.io/quickstart-guide/docker/#sqlite-setup-with-docker-compose) in the FerretDB documentation.
|
||||
@ -24,8 +24,9 @@ serialization protocol" (RESP).
|
||||
|
||||
:::
|
||||
|
||||
[KeyDB](https://docs.keydb.dev/) is a Redis-compatible in-memory data store. It
|
||||
is capable of storing sets, lists and other simple data structures.
|
||||
[KeyDB](https://docs.keydb.dev/) is a Redis-compatible in-memory data store
|
||||
licensed under BSD-3-Clause. It is capable of storing sets, lists and other
|
||||
simple data structures.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
@ -38,12 +39,12 @@ from XLSX files to a Redis database and to serialize a database to a workbook.
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| Server | Connector Module | Date |
|
||||
|:----------------|:------------------|:----------:|
|
||||
| KeyDB `6.3.4` | `redis` (`4.7.0`) | 2025-01-08 |
|
||||
| Redis `6.2.17` | `redis` (`4.7.0`) | 2025-01-08 |
|
||||
| Valkey `8.0.2` | `redis` (`4.7.0`) | 2025-01-08 |
|
||||
| Garnet `1.0.49` | `redis` (`4.7.0`) | 2025-01-08 |
|
||||
| Server | Connector Module | Date |
|
||||
|:---------------|:-------------------|:----------:|
|
||||
| KeyDB `6.3.4` | `redis` (`5.11.0`) | 2026-03-22 |
|
||||
| Redis `6.2.18` | `redis` (`5.11.0`) | 2026-03-22 |
|
||||
| Valkey `9.0.3` | `redis` (`5.11.0`) | 2026-03-22 |
|
||||
| Garnet `1.1.1` | `redis` (`5.11.0`) | 2026-03-22 |
|
||||
|
||||
:::
|
||||
|
||||
@ -249,12 +250,14 @@ this demo also requires NodeJS version 18 or later.
|
||||
|
||||
This demo was last tested on macOS.
|
||||
|
||||
---
|
||||
|
||||
_KeyDB_
|
||||
|
||||
KeyDB was installed with:
|
||||
KeyDB was installed from Homebrew:
|
||||
|
||||
```bash
|
||||
brew install keydb@6.3.4
|
||||
brew install keydb
|
||||
```
|
||||
|
||||
The following command started the server process:
|
||||
@ -263,6 +266,8 @@ The following command started the server process:
|
||||
keydb-server --protected-mode no
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
_Valkey_
|
||||
|
||||
Valkey was installed with:
|
||||
@ -278,7 +283,7 @@ This conflicts with the main `redis` package. `redis` must be unlinked:
|
||||
|
||||
```bash
|
||||
brew unlink redis
|
||||
brew link valkey
|
||||
brew link valkey || brew install valkey
|
||||
```
|
||||
|
||||
:::
|
||||
@ -286,9 +291,11 @@ brew link valkey
|
||||
The following command started the server process:
|
||||
|
||||
```bash
|
||||
redis-server $(brew config | grep HOMEBREW_PREFIX | awk '{print $2}')/etc/redis.conf
|
||||
redis-server $(brew --prefix)/etc/redis.conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
_Redis 6_
|
||||
|
||||
Redis 6 was installed with:
|
||||
@ -300,7 +307,7 @@ brew install redis@6.2
|
||||
The following command started the server process:
|
||||
|
||||
```bash
|
||||
redis-server $(brew config | grep HOMEBREW_PREFIX | awk '{print $2}')/etc/redis.conf
|
||||
redis-server $(brew --prefix)/etc/redis.conf
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
@ -310,6 +317,8 @@ version of Redis.
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
_Garnet_
|
||||
|
||||
After installing `dotnet` and .NET runtime, install the `garnet-server` tool:
|
||||
@ -335,7 +344,7 @@ curl -LO https://docs.sheetjs.com/nosql/SheetJSRedisTest.mjs
|
||||
2) Install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.13`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@5.11.0`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Run the test script:
|
||||
|
||||
@ -29,13 +29,13 @@ This demo was tested in the following environments:
|
||||
|
||||
| PouchDB | Date |
|
||||
|:--------|:----------:|
|
||||
| `9.0.0` | 2025-01-19 |
|
||||
| `8.0.1` | 2025-01-19 |
|
||||
| `7.3.1` | 2025-01-19 |
|
||||
| `6.4.3` | 2025-01-19 |
|
||||
| `5.4.5` | 2025-01-19 |
|
||||
| `4.0.3` | 2025-01-19 |
|
||||
| `3.6.0` | 2025-01-19 |
|
||||
| `9.0.0` | 2026-01-08 |
|
||||
| `8.0.1` | 2026-01-08 |
|
||||
| `7.3.1` | 2026-01-08 |
|
||||
| `6.4.3` | 2026-01-08 |
|
||||
| `5.4.5` | 2026-01-08 |
|
||||
| `4.0.3` | 2026-01-08 |
|
||||
| `3.6.0` | 2026-01-08 |
|
||||
|
||||
:::
|
||||
|
||||
@ -53,20 +53,18 @@ The `PouchDB` constructor returns a `Database` object.
|
||||
#### Importing Data
|
||||
|
||||
`Database#bulkDocs`[^2] is the standard approach for bulk data import. The method
|
||||
accepts "arrays of objects" that can be generated through the SheetJS
|
||||
`sheet_to_json`[^3] method.
|
||||
accepts "arrays of objects" that can be generated using the SheetJS
|
||||
[`sheet_to_json`](/docs/api/utilities/array#array-output) method.
|
||||
|
||||
If rows do not include the `_id` parameter, the database will automatically
|
||||
assign an ID per row. It is strongly recommended to generate the `_id` directly.
|
||||
|
||||
This method starts from a SheetJS workbook object[^4] and uses data from the
|
||||
first sheet. `read` and `readFile`[^5] can generate workbook objects from files.
|
||||
|
||||
```js
|
||||
async function push_first_sheet_to_pouchdb(db, wb, _id_) {
|
||||
/* get first worksheet */
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
This method starts from a SheetJS [worksheet object](/docs/csf/sheet) and uses
|
||||
data from the first sheet. [`read` and `readFile`](/docs/api/parse-options) can
|
||||
generate workbook objects from files.
|
||||
|
||||
```js title="Extract data from a SheetJS worksheet and push to PouchDB"
|
||||
async function push_sheet_to_pouchdb(db, ws, _id_) {
|
||||
/* generate array of objects */
|
||||
const aoo = XLSX.utils.sheet_to_json(ws);
|
||||
|
||||
@ -86,14 +84,15 @@ Existing data can be erased with `Database#destroy`.
|
||||
|
||||
#### Exporting Data
|
||||
|
||||
`Database#allDocs`[^6] is the standard approach for bulk data export. Generated
|
||||
`Database#allDocs`[^3] is the standard approach for bulk data export. Generated
|
||||
row objects have additional `_id` and `_rev` keys that should be removed.
|
||||
|
||||
After removing the PouchDB internal fields, the SheetJS `json_to_sheet`[^7]
|
||||
method can generate a worksheet. Other utility functions[^8] can construct a
|
||||
workbook. The workbook can be exported with the SheetJS `writeFile`[^9] method:
|
||||
The SheetJS [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
|
||||
method can generate a worksheet. [API functions](/docs/api/utilities/wb) can
|
||||
generate a workbook object. The [`writeFile`](/docs/api/write-options) method
|
||||
will attempt to download the generated workbook:
|
||||
|
||||
```js
|
||||
```js title="Extract data from PouchDB and export to XLSX using SheetJS"
|
||||
function export_pouchdb_to_xlsx(db) {
|
||||
/* fetch all rows, including the underlying data */
|
||||
db.allDocs({include_docs: true}, function(err, doc) {
|
||||
@ -171,8 +170,8 @@ cd getting-started-todo-master
|
||||
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>
|
||||
<button id="xport">Export!</button>
|
||||
<!-- highlight-end -->
|
||||
<section id="todoapp">`}
|
||||
</CodeBlock>
|
||||
<section id="todoapp">
|
||||
`}</CodeBlock>
|
||||
|
||||
3) Near the end of `index.html`, look for a script tag referencing a CDN:
|
||||
|
||||
@ -180,7 +179,7 @@ cd getting-started-todo-master
|
||||
<script src="//cdn.jsdelivr.net/pouchdb/3.2.0/pouchdb.min.js"></script>
|
||||
```
|
||||
|
||||
Upgrade PouchDB by changing the `src` attribute to the production build[^10]:
|
||||
Upgrade PouchDB by changing the `src` attribute to the production build[^4]:
|
||||
|
||||
```html title="index.html (replace line)"
|
||||
<script src="//cdn.jsdelivr.net/npm/pouchdb@8.0.1/dist/pouchdb.min.js"></script>
|
||||
@ -255,11 +254,5 @@ export named "SheetJSPouch.xlsx"
|
||||
|
||||
[^1]: See ["Setting up PouchDB"](https://pouchdb.com/guides/setup-pouchdb.html) in the PouchDB documentation.
|
||||
[^2]: See ["Create/update a batch of documents"](https://pouchdb.com/api.html#batch_create) in the PouchDB API documentation
|
||||
[^3]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^4]: See ["SheetJS Data Model"](/docs/csf)
|
||||
[^5]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
[^6]: See ["Fetch a batch of documents"](https://pouchdb.com/api.html#batch_fetch) in the PouchDB API documentation
|
||||
[^7]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
|
||||
[^8]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
|
||||
[^9]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
[^10]: The ["Quick Start" section of "Download"](https://pouchdb.com/download.html#file) in the PouchDB website describes the recommended CDN for PouchDB scripts.
|
||||
[^3]: See ["Fetch a batch of documents"](https://pouchdb.com/api.html#batch_fetch) in the PouchDB API documentation
|
||||
[^4]: The ["Quick Start" section of "Download"](https://pouchdb.com/download.html#file) in the PouchDB website describes the recommended CDN for PouchDB scripts.
|
||||
@ -291,7 +291,7 @@ following screenshot was taken in Chrome 126.0.6478.127:
|
||||
|
||||
This is a browser limitation and no pure JavaScript library can work around the
|
||||
issue. See [Issue #3145](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145) in
|
||||
the SheetJS bug tracker for more details.
|
||||
the SheetJS CE bug tracker for more details.
|
||||
|
||||
:::
|
||||
|
||||
@ -466,13 +466,13 @@ This browser demo was tested in the following environments:
|
||||
|
||||
| Browser | Date |
|
||||
|:-------------|:-----------|
|
||||
| Chromium 137 | 2025-06-20 |
|
||||
| Chromium 142 | 2025-11-15 |
|
||||
|
||||
Some lesser-used browsers do not support File System Access API:
|
||||
|
||||
| Browser | Date |
|
||||
|:-------------|:-----------|
|
||||
| Safari 18.5 | 2025-06-20 |
|
||||
| Safari 26.1 | 2025-11-15 |
|
||||
| Konqueror 22 | 2025-04-23 |
|
||||
| Firefox 139 | 2025-06-20 |
|
||||
|
||||
@ -836,4 +836,4 @@ Desktop and mobile apps have their own specific APIs covered in separate demos:
|
||||
[^1]: See ["Input Type" in "Reading Files"](/docs/api/parse-options#input-type)
|
||||
[^2]: See ["Supported Output Formats" type in "Writing Files"](/docs/api/write-options#supported-output-formats)
|
||||
[^3]: See ["Buffers and TypedArrays"](https://nodejs.org/api/buffer.html#buffers-and-typedarrays) in the NodeJS documentation.
|
||||
[^4]: See [issue 3145 in the SheetJS bug tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145#issuecomment-11074) for more details. Special thanks to `@sjoenH`!
|
||||
[^4]: See [issue 3145 in the SheetJS CE bug tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145#issuecomment-11074) for more details. Special thanks to `@sjoenH`!
|
||||
@ -8,7 +8,7 @@ pagination_next: demos/extensions/index
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[Deno Deploy](https://dash.deno.com/) offers distributed "Serverless Functions"
|
||||
[Deno Deploy](https://deno.com/deploy) offers distributed "Serverless Functions"
|
||||
powered by Deno.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
@ -22,7 +22,7 @@ types of spreadsheets to HTML tables and CSV rows.
|
||||
|
||||
:::caution pass
|
||||
|
||||
When the demo was last tested, Deno Deploy required a GitHub account.
|
||||
When the demo was last tested, Deno Deploy required a GitHub or Google account.
|
||||
|
||||
:::
|
||||
|
||||
@ -82,9 +82,9 @@ class SheetJSResource extends Drash.Resource {
|
||||
|
||||
## Demo
|
||||
|
||||
0) Create a new GitHub account or sign into an existing account.
|
||||
0) Create a new Github or Google account, or sign into an existing account.
|
||||
|
||||
1) Open the [main Deno Deploy portal](https://dash.deno.com/) in a browser.
|
||||
1) Open the [main Deno Deploy portal](https://console.deno.com/) in a browser.
|
||||
|
||||
2) If the account never signed into Deno Deploy, click "Continue with Github".
|
||||
|
||||
|
||||
@ -207,7 +207,7 @@ const wb = XLSX.readFile("SheetJSAirtableTest.xlsb");
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2025-04-21. In the most recent test, free accounts
|
||||
This demo was last tested on 2026-03-15. In the most recent test, free accounts
|
||||
included limited API access.
|
||||
|
||||
:::
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
---
|
||||
title: Visualizing Data in VS Code
|
||||
sidebar_label: Visual Studio Code
|
||||
description: View Excel files directly in VS Code. Seamlessly browse spreadsheet data without leaving your editor using SheetJS. Navigate between worksheets and pages of data with a responsive
|
||||
description: View Excel files directly in VS Code. Seamlessly browse spreadsheet data using SheetJS. Navigate between worksheets and pages of data with a responsive interface.
|
||||
pagination_prev: demos/cloud/index
|
||||
pagination_next: demos/bigdata/index
|
||||
sidebar_custom_props:
|
||||
summary: View Excel files directly within Visual Studio Code
|
||||
summary: View Excel spreadsheets directly within Visual Studio Code
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
@ -21,13 +21,14 @@ that supports JavaScript extensions for customizing and enhancing functionality.
|
||||
|
||||
The ["Complete Example"](#complete-example) uses SheetJS in a VS Code extension
|
||||
to view Excel files directly within the editor. The extension leverages the VS
|
||||
Code "Custom Editor API"[^2] and "WebView API"[^1] to display spreadsheet data
|
||||
Code "WebView API"[^1] and "Custom Editor API"[^2] to display spreadsheet data
|
||||
as HTML tables.
|
||||
|
||||
:::tip pass
|
||||
|
||||
["SheetJS Spreadsheet Viewer"](https://marketplace.visualstudio.com/items?itemName=asadbek.sheetjs-demo)
|
||||
is a sample extension based on this demo.
|
||||
"SheetJS Spreadsheet Viewer" is a sample extension based on this demo. It is
|
||||
available on [Open VSX](https://open-vsx.org/extension/asadbek/sheetjs-demo) and
|
||||
[VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=asadbek.sheetjs-demo)
|
||||
|
||||
[The source code](https://git.sheetjs.com/asadbek064/sheetjs-vscode-extension)
|
||||
is available on the SheetJS Git server. Feedback and contributions are welcome!
|
||||
@ -38,146 +39,217 @@ is available on the SheetJS Git server. Feedback and contributions are welcome!
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was verified in the following deployments:
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| Platform | Architecture | Date |
|
||||
|:-----------------|:-------------|:-----------|
|
||||
| VS Code 1.100.0 | `darwin-arm` | 2025-05-15 | TODO
|
||||
| VSCodium 1.100.0 | `darwin-arm` | 2025-05-15 | TODO
|
||||
| Cursor | `win11-arm` | 2025-05-15 | TODO
|
||||
| Windsurf | `win11-arm` | 2025-05-15 | TODO
|
||||
| Void | `win11-arm` | 2025-05-15 | TODO
|
||||
| Platform | Architecture | Date |
|
||||
|:--------------------------------------------------|:-------------|:-----------|
|
||||
| [VSCodium 1.109.51242](https://vscodium.com/) | `darwin-arm` | 2026-03-05 |
|
||||
| [VS Code 1.110.0](https://code.visualstudio.com/) | `win11-arm` | 2026-03-05 |
|
||||
| [Antigravity 1.19.6](https://antigravity.google/) | `linux-arm` | 2026-03-05 |
|
||||
|
||||
:::
|
||||
|
||||
:::danger Telemetry and Data Exfiltration
|
||||
|
||||
VSCode and many forks embed telemetry and send code to third-party servers.
|
||||
|
||||
For example, Antigravity includes AI features that are powered by Google Gemini
|
||||
and other cloud AI services. These features necessitate code exfiltration.
|
||||
|
||||
**[VSCodium](https://vscodium.com/) does not include AI features or telemetry!**
|
||||
|
||||
:::
|
||||
|
||||
## Integration Details
|
||||
|
||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
||||
imported from any component or script in the extension.
|
||||
imported from any script in the extension.
|
||||
|
||||
:::caution pass
|
||||
|
||||
The module must be installed as a development dependency. If the module is
|
||||
installed as a normal dependency, `vsce`[^5] (Visual Studio Code Extension
|
||||
Manager) will fail to package or publish your extension correctly.
|
||||
The SheetJS NodeJS module must be installed as a development dependency. If the
|
||||
module is installed as a normal dependency, the `vsce`[^3] command-line tool
|
||||
will fail to package or publish the extension.
|
||||
|
||||
<Tabs groupId="pm">
|
||||
<TabItem value="npm" label="npm">
|
||||
<CodeBlock language="bash">{`\
|
||||
<Tabs groupId="pm">
|
||||
<TabItem value="npm" label="npm">
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm rm --save xlsx
|
||||
npm i --save-dev https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
<CodeBlock language="bash">{`\
|
||||
</CodeBlock>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
pnpm rm xlsx
|
||||
pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn" default>
|
||||
<CodeBlock language="bash">{`\
|
||||
</CodeBlock>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn" default>
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
yarn remove xlsx
|
||||
yarn add -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
</CodeBlock>
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
</Tabs>
|
||||
|
||||
:::
|
||||
|
||||
## Extension Architecture
|
||||
The core extension APIs are available in the `vscode` package. A TypeScript
|
||||
extension typically uses "glob imports" to load SheetJS and VSCode features:
|
||||
|
||||
The VS Code Spreadsheet viewer extension has three main components:
|
||||
|
||||
- **Extension Entry Point:** Registers the extension with VS Code
|
||||
- **Custom Editor Provider:** Handles Excel files and converts them to web content
|
||||
- **WebView Content:** Displays Excel data as HTML tables
|
||||
|
||||
The extension uses VS Code's `Custom Editor API`[^2] to register as a handler for Excel files. When a file is opened,
|
||||
SheetJS parses it and displays the data in a WebView component.
|
||||
|
||||
### Extension Entry Point
|
||||
|
||||
The main entry point registers the custom editor provider:
|
||||
|
||||
```ts title="src/extension.ts"
|
||||
```ts title="Importing SheetJS and VSCode features"
|
||||
import * as vscode from 'vscode';
|
||||
// highlight-start
|
||||
import { ExcelEditorProvider } from './excelEditorProvider';
|
||||
// highlight-end
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// SheetJS Spreadsheet Viewer extension activating...
|
||||
// highlight-start
|
||||
const provider = ExcelEditorProvider.register(context);
|
||||
context.subscriptions.push(provider);
|
||||
// highlight-end
|
||||
}
|
||||
export function deactivate() {}`}
|
||||
import * as XLSX from 'xlsx';
|
||||
```
|
||||
|
||||
The `custom editor`[^3] is configured to support specific file types, giving us complete control over how each file is
|
||||
presented to the user. Additionally, `custom document`[^4] enables us to maintain and persist the state of each individual
|
||||
file that's opened.
|
||||
## Extension Architecture
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">
|
||||
{`import * as vscode from 'vscode';
|
||||
// highlight-start
|
||||
import * as XLSX from 'xlsx';
|
||||
import { ExcelDocument } from './excelDocument';
|
||||
// highlight-end
|
||||
VSCode Extensions for processing custom file types use the Custom Editor API[^2]
|
||||
for lifecycle events. This involves a number of moving parts:
|
||||
|
||||
// A simple class to store document state (one per opened file)
|
||||
class ExcelDocument implements vscode.CustomDocument {
|
||||
constructor(public readonly uri: vscode.Uri) {}
|
||||
dispose() {}
|
||||
1) "Custom Document" for managing file metadata
|
||||
|
||||
2) "Custom Editor Provider" for processing file data and generating previews
|
||||
|
||||
3) Registration during extension lifecycle events.
|
||||
|
||||
4) Advertisement of filetype support in extension metadata.
|
||||
|
||||
When a spreadsheet is opened, the extension will use SheetJS methods to parse
|
||||
the raw file and display the data in a HTML table.
|
||||
|
||||
### Custom Documents
|
||||
|
||||
Extensions must provide a class that implements `vscode.CustomDocument`[^4].
|
||||
|
||||
```ts title="Simple CustomDocument"
|
||||
class ExcelDocument implements vscode.CustomDocument {
|
||||
constructor(public readonly uri: vscode.Uri) { }
|
||||
dispose() { }
|
||||
}
|
||||
```
|
||||
|
||||
### Editor Provider
|
||||
|
||||
Extensions that read data should implement `vscode.CustomReadonlyEditorProvider`
|
||||
with a generic parameter for the custom document type.
|
||||
|
||||
The `openCustomDocument` method takes a `vscode.Uri` and is expected to return a
|
||||
new document:
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
|
||||
return new ExcelDocument(uri);
|
||||
}
|
||||
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
public static register(context: vscode.ExtensionContext): vscode.Disposable {
|
||||
return vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
}
|
||||
// ...
|
||||
}`}
|
||||
</CodeBlock>
|
||||
}
|
||||
```
|
||||
|
||||
### Reading Files
|
||||
|
||||
The extension reads Excel files using the VS Code filesystem API and passes
|
||||
the data to SheetJS for parsing:
|
||||
The `FileSystemProvider` API[^5], available at `vscode.workspace.fs`, exposes
|
||||
common filesystem operations including reading raw data from files and watching
|
||||
for changes.
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">
|
||||
{`export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
The `resolveCustomEditor`[^6] method of the `CustomEditorProvider` will be
|
||||
called when a file is opened. The first argument is a `CustomDocument` whose
|
||||
`uri` property points to the location of the file.
|
||||
|
||||
`vscode.workspace.fs.readFile`[^5] returns a promise that resolves to a
|
||||
`Uint8Array` containing the raw binary data. This `Uint8Array` can be passed to
|
||||
the SheetJS [`read`](/docs/api/parse-options) method:
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
// read the raw bytes from the file
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
|
||||
// parse the file data
|
||||
const wb: XLSX.WorkBook = XLSX.read(data);
|
||||
|
||||
// At this point, `wb` is a SheetJS Workbook Object
|
||||
// ...
|
||||
private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<XLSX.WorkBook> {
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
const options: XLSX.ParsingOptions = {
|
||||
type: 'array',
|
||||
cellStyles: true,
|
||||
cellDates: true,
|
||||
};
|
||||
### Previewing Data
|
||||
|
||||
return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
|
||||
}
|
||||
The `resolveCustomEditor`[^6] method of the `CustomEditorProvider` will be
|
||||
called when a file is opened. The second argument is a `WebviewPanel`[^7].
|
||||
|
||||
// This is called when the first time an editor for a given resource is opened
|
||||
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
|
||||
return new ExcelDocument(uri);
|
||||
}
|
||||
The `webview.html` nested property of the `WebviewPanel` controls the displayed
|
||||
HTML. Extensions can use SheetJS [API methods](/docs/api/).
|
||||
|
||||
// This is called whenever the user opens a new editor
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel);
|
||||
const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
webviewPanel.webview.html = \`<!DOCTYPE html><html><body>\${htmlTable}</body></html>\`;
|
||||
}
|
||||
}`}
|
||||
</CodeBlock>
|
||||
The SheetJS [`sheet_to_html`](/docs/api/utilities/html#html-table-output) method
|
||||
generates a simple HTML table. The following snippet displays the data of the
|
||||
first worksheet:
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
// ...
|
||||
// continuing from "Reading Files", `wb` is a SheetJS Workbook Object
|
||||
const first_sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
webviewPanel.webview.html = XLSX.utils.sheet_to_html(first_sheet);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Registration
|
||||
|
||||
The exported `activate` method registers the editor provider. The first argument
|
||||
to `registerCustomEditorProvider` is expected to be a unique name that will be
|
||||
referenced later.
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const provider = vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
context.subscriptions.push(provider);
|
||||
}
|
||||
```
|
||||
|
||||
### Filetype Support
|
||||
|
||||
Extensions must announce custom editor file type support in `package.json`.
|
||||
The `selector` property[^8] is expected to include "Glob Pattterns"[^9].
|
||||
|
||||
The demo uses the following `package.json` snippet to announce support for `xls`
|
||||
and `xlsx` spreadsheets:
|
||||
|
||||
```json title="package.json (snippet)"
|
||||
"contributes": {
|
||||
"customEditors": [
|
||||
{
|
||||
// ... other properties including displayName
|
||||
// highlight-start
|
||||
// The viewType must match the first argument of `registerCustomEditorProvider`
|
||||
"viewType": "excelViewer.spreadsheet",
|
||||
"selector": [
|
||||
{ "filenamePattern": "*.xlsx" },
|
||||
{ "filenamePattern": "*.xls" }
|
||||
]
|
||||
// highlight-end
|
||||
}
|
||||
],
|
||||
// ...
|
||||
},
|
||||
```
|
||||
|
||||
### Usage Flow
|
||||
|
||||
@ -205,7 +277,17 @@ sequenceDiagram
|
||||
|
||||
## Complete Example
|
||||
|
||||
1) Create a new VS Code extension
|
||||
:::caution pass
|
||||
|
||||
To avoid conflicts with existing extensions, it is strongly recommended to test
|
||||
with a different VSCode fork. For example, VSCode and Antigravity users should
|
||||
install and use VSCodium for extension development.
|
||||
|
||||
:::
|
||||
|
||||
1) Download the [`pres.xlsx`](https://docs.sheetjs.com/pres.xlsx) sample file.
|
||||
|
||||
2) Create a new VS Code extension
|
||||
|
||||
```bash
|
||||
npx --package yo --package generator-code -- yo code
|
||||
@ -215,17 +297,15 @@ When prompted, enter the following options:
|
||||
|
||||
- `What type of extension do you want to create?`: Select `New Extension (TypeScript)` and press <kbd>Enter</kbd>
|
||||
- `What's the name of your extension?`: Type `sheetjs-demo` and press <kbd>Enter</kbd>
|
||||
- `What's the identifier of your extension?`: Press <kbd>Enter</kbd>
|
||||
- `What's the description of your extension?`: Press <kbd>Enter</kbd>
|
||||
- `What's the identifier of your extension?`: Press <kbd>Enter</kbd> (use the default `sheetjs-demo`)
|
||||
- `What's the description of your extension?`: Press <kbd>Enter</kbd> (leave blank)
|
||||
- `Initialize a git repository?`: Type `n` and press <kbd>Enter</kbd>
|
||||
- `Which bundler to use?`: Select `webpack` and press <kbd>Enter</kbd>
|
||||
- `Which package manager to use?`: Select `pnpm` and press <kbd>Enter</kbd>
|
||||
|
||||

|
||||
|
||||
- `Do you want to open the new folder with Visual Studio Code?`: Press <kbd>Enter</kbd>
|
||||
|
||||
2) [Install the dependencies](#integration-details) and start the dev server:
|
||||
3) Install the SheetJS library and start the dev server:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
cd sheetjs-demo
|
||||
@ -234,9 +314,11 @@ pnpm run watch
|
||||
`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Save the following code snippet to `src/excelEditorProvider.ts`:
|
||||
4) Launch a new window with the VSCode fork and open the `sheetjs-demo` folder.
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">{`\
|
||||
5) Save the following codeblock to `src/extension.ts`:
|
||||
|
||||
```ts title="src/extension.ts (replace contents)"
|
||||
import * as vscode from 'vscode';
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
@ -245,27 +327,7 @@ class ExcelDocument implements vscode.CustomDocument {
|
||||
dispose() { }
|
||||
}
|
||||
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
public static register(context: vscode.ExtensionContext): vscode.Disposable {
|
||||
return vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
}
|
||||
|
||||
private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<XLSX.WorkBook> {
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
|
||||
const options: XLSX.ParsingOptions = {
|
||||
type: 'array',
|
||||
cellStyles: true,
|
||||
cellDates: true,
|
||||
};
|
||||
|
||||
return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
|
||||
}
|
||||
|
||||
class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// This is called when the first time an editor for a given resource is opened
|
||||
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
|
||||
return new ExcelDocument(uri);
|
||||
@ -273,31 +335,30 @@ export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<
|
||||
|
||||
// This is called whenever the user opens a new editor
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel);
|
||||
const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
webviewPanel.webview.html = \`<!DOCTYPE html><html><body>\${htmlTable}</body></html>\`;
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
|
||||
const options: XLSX.ParsingOptions = { cellStyles: true, cellDates: true };
|
||||
const wb: XLSX.WorkBook = XLSX.read(data, options);
|
||||
|
||||
const first_sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
webviewPanel.webview.html = XLSX.utils.sheet_to_html(first_sheet);
|
||||
}
|
||||
}`}
|
||||
</CodeBlock>
|
||||
|
||||
4) Register the custom editor provider in `src/extension.ts`:
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/extension.ts (replace contents)">{`\
|
||||
import * as vscode from 'vscode';
|
||||
import { ExcelEditorProvider } from './excelEditorProvider';
|
||||
}
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// SheetJS Spreadsheet Viewer extension activating...
|
||||
const provider = ExcelEditorProvider.register(context);
|
||||
const provider = vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
context.subscriptions.push(provider);
|
||||
}
|
||||
export function deactivate() {}`}
|
||||
</CodeBlock>
|
||||
export function deactivate() {}
|
||||
```
|
||||
|
||||
5) Register the custom editor in the `contributes` section of `package.json`:
|
||||
6) Add the highlighted lines to the `contributes` section of `package.json`:
|
||||
|
||||
<CodeBlock language="json" value="json" title="package.json (add highlighted lines)">{`\
|
||||
"main": "./dist/extension.js",
|
||||
```json title="package.json (add highlighted lines)"
|
||||
"contributes": {
|
||||
// highlight-start
|
||||
"customEditors": [
|
||||
@ -318,19 +379,42 @@ export function deactivate() {}`}
|
||||
}
|
||||
]
|
||||
},
|
||||
`}
|
||||
</CodeBlock>
|
||||
```
|
||||
|
||||
6. Inside the editor, open `src/extension.ts` and press <kbd>F5</kbd> or run the command **Debug: Start Debugging**
|
||||
from the Command Palette (<kbd>⇧⌘P</kbd>). This will compile and run the extension in a new Extension Development Host window.
|
||||
7) In the editor, open the Command Palette (Help > "Show All Commands" from the
|
||||
menu), type `Debug: Start` and select `Debug: Start Debugging`.
|
||||
|
||||
7. Select the new VSCode Window and open a `.xlsx` or `.xls` file.
|
||||
This will compile and run the extension in a new Extension Development Host window.
|
||||
|
||||
8) Drag and drop the `pres.xlsx` test file into the new window. If drag and drop
|
||||
is not available, click "Open..." in the Welcome screen and select the file.
|
||||
|
||||
---
|
||||
A new `pres.xlsx` tab will show the contents of the file.
|
||||
|
||||
[^1]: See [`Webview API`](https://code.visualstudio.com/api/extension-guides/webview) for more details.
|
||||
[^2]: See [`Custom Editor API`](https://code.visualstudio.com/api/extension-guides/custom-editors) documentation for more details.
|
||||
[^3]: See [`Custom Editor`](https://code.visualstudio.com/api/extension-guides/custom-editors#custom-editor) for more details.
|
||||
[^4]: See [`CustomDocument`](https://code.visualstudio.com/api/extension-guides/custom-editors#customdocument) for more details.
|
||||
[^5]: See [`Visual Studio Code Extension Manager`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) for more details.
|
||||
:::info pass
|
||||
|
||||
When this demo was last tested, the default project assumed VSCode version
|
||||
1.109.0 or later. Antigravity 1.19.6 is aligned to VSCode 1.107.0. The default
|
||||
extension will not run in Antigravity.
|
||||
|
||||
This can be fixed by changing the `vscode` field in `package.json`. When this
|
||||
demo was last tested, it was safe to set a minimum version of `^1.100.0`:
|
||||
|
||||
```json title="package.json (change highlighted line)"
|
||||
"engines": {
|
||||
// highlight-next-line
|
||||
"vscode": "^1.100.0"
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
[^1]: See [`Webview API`](https://code.visualstudio.com/api/extension-guides/webview) in the VSCode documentation for more details.
|
||||
[^2]: See [`Custom Editor API`](https://code.visualstudio.com/api/extension-guides/custom-editors) in the VSCode documentation for more details.
|
||||
[^3]: See [`vsce`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#vsce) in the VSCode documentation for more details.
|
||||
[^4]: See [`CustomDocument`](https://code.visualstudio.com/api/references/vscode-api#CustomDocument) in the VSCode API documentation for more details.
|
||||
[^5]: See [`FileSystemProvider`](https://code.visualstudio.com/api/references/vscode-api#FileSystemProvider) in the VSCode API documentation for more details.
|
||||
[^6]: See [`CustomEditorProvider<T>`](https://code.visualstudio.com/api/references/vscode-api#CustomEditorProvider<T>) in the VSCode API documentation for more details.
|
||||
[^7]: See [`WebviewPanel`](https://code.visualstudio.com/api/references/vscode-api#WebviewPanel) in the VSCode API documentation for more details.
|
||||
[^8]: See [`contributes.customEditors`](https://code.visualstudio.com/api/references/contribution-points#contributes.customEditors) in the VSCode API documentation for more details.
|
||||
[^9]: See ["Glob Patterns Reference"](https://code.visualstudio.com/docs/editor/glob-patterns) in the VSCode documentation for more details.
|
||||
@ -54,7 +54,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:------------------|:-----------|
|
||||
| `darwin-x64` | `18.5` (StataNow) | 2025-06-20 |
|
||||
| `darwin-arm` | `18.5` (StataNow) | 2025-04-24 |
|
||||
| `darwin-arm` | `19.5` (StataNow) | 2026-03-13 |
|
||||
| `win11-x64` | `18.5` (StataNow) | 2025-04-28 |
|
||||
| `win11-arm` | `18.5` (StataNow) | 2025-02-23 |
|
||||
| `linux-x64` | `19.5` (StataNow) | 2025-07-06 |
|
||||
@ -299,7 +299,7 @@ curl -LO https://docs.sheetjs.com/stata/cleanfile.c
|
||||
7) Build the plugin:
|
||||
|
||||
```bash title="Build plugin (run in terminal)"
|
||||
gcc -shared -fPIC -DSYSTEM=APPLEMAC stplugin.c duktape.c cleanfile.c -lm -std=c99 -Wall -ocleanfile.plugin
|
||||
gcc -shared -fPIC -DSYSTEM=APPLEMAC -fms-extensions stplugin.c duktape.c cleanfile.c -lm -std=c99 -Wall -o cleanfile.plugin
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
@ -28,7 +28,7 @@ This demo was tested by SheetJS users in the following deployments:
|
||||
| Architecture | Ghidra | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `11.13.1` | 2025-04-17 |
|
||||
| `darwin-arm` | `11.13.1` | 2025-03-17 |
|
||||
| `darwin-arm` | `11.13.1` | 2025-10-19 |
|
||||
|
||||
:::
|
||||
|
||||
@ -255,14 +255,15 @@ Rows will be generated for each block and the final dataset will be exported.
|
||||
|
||||
### System Setup
|
||||
|
||||
0) Install Ghidra, Xcode, and Apple Numbers.
|
||||
0) Install Java, Ghidra, Xcode, and Apple Numbers.
|
||||
|
||||
<details>
|
||||
<summary><b>Installation Notes</b> (click to show)</summary>
|
||||
|
||||
On macOS, Ghidra was installed using Homebrew:
|
||||
When this demo was last tested, Java and Ghidra were installed using Homebrew:
|
||||
|
||||
```bash
|
||||
brew install zulu@21
|
||||
brew install --cask ghidra
|
||||
```
|
||||
|
||||
|
||||
@ -180,25 +180,25 @@ be reported to the Bun project for further diagnosis.
|
||||
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| Node Version | Date | Node Status when tested |
|
||||
|:-------------|:-----------|:------------------------|
|
||||
| `0.12.18` | 2025-04-24 | End-of-Life |
|
||||
| `4.9.1` | 2025-04-24 | End-of-Life |
|
||||
| `6.17.1` | 2025-04-24 | End-of-Life |
|
||||
| `8.17.0` | 2025-04-24 | End-of-Life |
|
||||
| `10.24.1` | 2025-04-24 | End-of-Life |
|
||||
| `12.22.12` | 2025-04-24 | End-of-Life |
|
||||
| `14.15.5` | 2025-04-24 | End-of-Life |
|
||||
| `16.20.2` | 2025-04-24 | End-of-Life |
|
||||
| `18.20.8` | 2025-04-24 | Maintenance LTS |
|
||||
| `20.18.0` | 2025-04-24 | Active LTS |
|
||||
| `22.14.0` | 2025-04-24 | Current |
|
||||
| Platform | Date | Status when tested |
|
||||
|:------------------|:-----------|:-------------------|
|
||||
| NodeJS `0.12.18` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `4.9.1` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `6.17.1` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `8.17.0` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `10.24.1` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `12.22.12` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `14.21.3` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `16.20.2` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `18.20.8` | 2025-11-15 | End-of-Life |
|
||||
| NodeJS `20.18.0` | 2025-11-15 | Maintenance LTS |
|
||||
| NodeJS `22.21.1` | 2025-11-15 | Active LTS |
|
||||
| NodeJS `24.11.1` | 2025-11-15 | Current |
|
||||
| BunJS `1.3.2` | 2025-11-15 | Current |
|
||||
|
||||
While streaming methods work in End-of-Life versions of NodeJS, production
|
||||
deployments should upgrade to a Current or LTS version of NodeJS.
|
||||
|
||||
This demo was also tested against BunJS `1.2.10` on 2025-04-24.
|
||||
|
||||
:::
|
||||
|
||||
1) Install the [NodeJS module](/docs/getting-started/installation/nodejs)
|
||||
@ -399,11 +399,11 @@ includes a live example of CSV streaming write.
|
||||
|
||||
The demo has a URL input box. Feel free to change the URL. For example,
|
||||
|
||||
`https://raw.githubusercontent.com/SheetJS/test_files/master/large_strings.xls`
|
||||
is an XLS file over 50 MB
|
||||
`https://test-files.sheetjs.com/large_strings.xls` is a large XLS file with many
|
||||
large strings (approximately 56 MB).
|
||||
|
||||
`https://raw.githubusercontent.com/SheetJS/libreoffice_test-files/master/calc/xlsx-import/perf/8-by-300000-cells.xlsx`
|
||||
is an XLSX file with 300000 rows (approximately 20 MB)
|
||||
`https://test-files.sheetjs.com/8-by-300000-cells.xlsx` is an XLSX file with
|
||||
300000 rows (approximately 20 MB).
|
||||
|
||||
<CodeBlock language="jsx" live>{`\
|
||||
function SheetJSFetchCSVStreamWorker() {
|
||||
|
||||
@ -576,10 +576,10 @@ will try to commit each row as it is generated.
|
||||
|
||||
The demo also has a URL input box. Feel free to change the URL. For example:
|
||||
|
||||
`https://raw.githubusercontent.com/SheetJS/test_files/master/large_strings.xls`
|
||||
is an XLS file over 50 MB. The generated CSV file is about 55 MB.
|
||||
`https://test-files.sheetjs.com/large_strings.xls` is approximately 56 MB. The
|
||||
equivalent CSV is about 55 MB.
|
||||
|
||||
`https://raw.githubusercontent.com/SheetJS/libreoffice_test-files/master/calc/xlsx-import/perf/8-by-300000-cells.xlsx`
|
||||
`https://test-files.sheetjs.com/8-by-300000-cells.xlsx`
|
||||
is an XLSX file with 300000 rows (approximately 20 MB) yielding a CSV of 10 MB.
|
||||
|
||||
<CodeBlock language="jsx" live>{`\
|
||||
|
||||
@ -128,12 +128,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.7.0` | 2025-09-03 |
|
||||
| `darwin-x64` | `2.7.0` | 2026-01-21 |
|
||||
| `darwin-arm` | `2.7.0` | 2026-03-07 |
|
||||
| `win11-x64` | `2.7.0` | 2025-04-28 |
|
||||
| `win11-arm` | `2.7.0` | 2025-02-23 |
|
||||
| `linux-x64` | `2.7.0` | 2025-04-21 |
|
||||
| `linux-arm` | `2.7.0` | 2025-02-15 |
|
||||
| `linux-arm` | `2.7.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -145,7 +145,8 @@ The [flow diagram is displayed after the example steps](#flow-diagram)
|
||||
:::note pass
|
||||
|
||||
The Windows build requires Visual Studio with "Desktop development with C++".
|
||||
Commands must be run in a "Native Tools Command Prompt" session.
|
||||
|
||||
**Commands must be run in a "Native Tools Command Prompt" session.**
|
||||
|
||||
:::
|
||||
|
||||
@ -225,7 +226,7 @@ curl -LO https://docs.sheetjs.com/duk/sheetjs.duk.c
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```bash
|
||||
gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm
|
||||
gcc -std=c99 -Wall -o sheetjs.duk sheetjs.duk.c duktape.c -lm
|
||||
```
|
||||
|
||||
:::note pass
|
||||
@ -405,10 +406,10 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | PHP | Date |
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | `8.4.2` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.7.0` | `8.4.4` | 2025-02-25 |
|
||||
| `darwin-x64` | `2.7.0` | `8.4.11` | 2026-01-21 |
|
||||
| `darwin-arm` | `2.7.0` | `8.4.8` | 2026-01-23 |
|
||||
| `linux-x64` | `2.7.0` | `8.3.6` | 2025-04-21 |
|
||||
| `linux-arm` | `2.7.0` | `8.2.26` | 2025-02-15 |
|
||||
| `linux-arm` | `2.7.0` | `8.4.16` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -547,10 +548,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | Python | Date |
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | `3.13.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.7.0` | `3.12.3` | 2025-03-30 |
|
||||
| `darwin-x64` | `2.7.0` | `3.13.7` | 2026-01-21 |
|
||||
| `darwin-arm` | `2.7.0` | `3.12.3` | 2026-01-23 |
|
||||
| `win11-x64` | `2.7.0` | `3.11.9` | 2026-02-02 |
|
||||
| `win11-arm` | `2.7.0` | `3.11.9` | 2026-02-02 |
|
||||
| `linux-x64` | `2.7.0` | `3.12.3` | 2025-04-21 |
|
||||
| `linux-arm` | `2.7.0` | `3.11.2` | 2025-02-15 |
|
||||
| `linux-arm` | `2.7.0` | `3.13.5` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -558,6 +561,9 @@ This demo was tested in the following deployments:
|
||||
|
||||
1) Build the Duktape shared library:
|
||||
|
||||
<Tabs groupId="triple">
|
||||
<TabItem value="darwin-x64" label="MacOS">
|
||||
|
||||
```bash
|
||||
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
|
||||
tar -xJf duktape-2.7.0.tar.xz
|
||||
@ -566,18 +572,92 @@ make -f Makefile.sharedlibrary
|
||||
cd ..
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="linux-x64" label="Linux">
|
||||
|
||||
```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 ..
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win11-x64" label="Windows">
|
||||
|
||||
- Download and extract the source tarball:
|
||||
|
||||
```bash
|
||||
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
|
||||
tar -xJf duktape-2.7.0.tar.xz
|
||||
```
|
||||
|
||||
- Enter the source folder:
|
||||
|
||||
```bash
|
||||
cd duktape-2.7.0
|
||||
```
|
||||
|
||||
- Edit `src\duk_config.h` and add the highlighted lines to the end of the file:
|
||||
|
||||
```c title="src\duk_config.h (add highlighted lines to end of file)"
|
||||
#endif /* DUK_CONFIG_H_INCLUDED */
|
||||
|
||||
// highlight-start
|
||||
#define DUK_EXTERNAL_DECL extern __declspec(dllexport)
|
||||
#define DUK_EXTERNAL __declspec(dllexport)
|
||||
// highlight-end
|
||||
```
|
||||
|
||||
- Build the Duktape DLL:
|
||||
|
||||
```cmd
|
||||
cl /O2 /W3 /Isrc /LD /DDUK_SINGLE_FILE /DDUK_F_DLL_BUILD /DDUK_F_WINDOWS /DDUK_COMPILING_DUKTAPE src\\duktape.c
|
||||
```
|
||||
|
||||
- Move up to the parent directory:
|
||||
|
||||
```bash
|
||||
cd ..
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
2) Copy the shared library to the current folder. When the demo was last tested,
|
||||
the shared library file name differed by platform:
|
||||
|
||||
| OS | name |
|
||||
|:-------|:--------------------------|
|
||||
| Darwin | `libduktape.207.20700.so` |
|
||||
| Linux | `libduktape.so.207.20700` |
|
||||
| OS | name |
|
||||
|:--------|:--------------------------|
|
||||
| Darwin | `libduktape.207.20700.so` |
|
||||
| Linux | `libduktape.so.207.20700` |
|
||||
| Windows | `duktape.dll` |
|
||||
|
||||
<Tabs groupId="triple">
|
||||
<TabItem value="darwin-x64" label="MacOS">
|
||||
|
||||
```bash
|
||||
cp duktape-*/libduktape.* .
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="linux-x64" label="Linux">
|
||||
|
||||
```bash
|
||||
cp duktape-*/libduktape.* .
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win11-x64" label="Windows">
|
||||
|
||||
```cmd
|
||||
copy duktape-2.7.0\duktape.dll .
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
3) Download the SheetJS Standalone script, shim script and test file. Move all
|
||||
three files to the project directory:
|
||||
|
||||
@ -630,6 +710,38 @@ The name of the library is `libduktape.so.207.20700`:
|
||||
lib = "libduktape.so.207.20700"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win11-x64" label="Windows">
|
||||
|
||||
The name of the library is `duktape.dll`:
|
||||
|
||||
```python title="SheetJSDuk.py (change highlighted line)"
|
||||
# highlight-next-line
|
||||
lib = ".\\duktape.dll"
|
||||
```
|
||||
|
||||
In addition, the following changes must be made:
|
||||
|
||||
- `str_to_c` must be defined as follows:
|
||||
|
||||
```python title="SheetJSDuk.py (replace str_to_c function)"
|
||||
def str_to_c(s):
|
||||
if type(s) == bytes:
|
||||
b = s
|
||||
else:
|
||||
b = s.encode("utf8")
|
||||
return [c_char_p(b), len(b)]
|
||||
```
|
||||
|
||||
- `eval_file` must `open` with mode `rb`:
|
||||
|
||||
```python title="SheetJSDuk.py (edit highlighted line)"
|
||||
def eval_file(ctx, path):
|
||||
# highlight-next-line
|
||||
with open(path, "rb") as f:
|
||||
code = f.read()
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@ -670,6 +782,16 @@ The name of the library is `libduktape.so.207.20700`:
|
||||
```python title="SheetJSDuk.py (change highlighted line)"
|
||||
# highlight-next-line
|
||||
lib = "./libduktape.so.207.20700"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win11-x64" label="Windows">
|
||||
|
||||
The name of the library is `duktape.dll`:
|
||||
|
||||
```python title="SheetJSDuk.py (change highlighted line)"
|
||||
# highlight-next-line
|
||||
lib = ".\\duktape.dll"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -784,12 +906,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | Zig | Date |
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | `0.14.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.7.0` | `0.13.0` | 2025-02-13 |
|
||||
| `darwin-x64` | `2.7.0` | `0.15.2` | 2026-01-20 |
|
||||
| `darwin-arm` | `2.7.0` | `0.15.2` | 2026-01-20 |
|
||||
| `win11-x64` | `2.7.0` | `0.14.0` | 2025-04-28 |
|
||||
| `win11-arm` | `2.7.0` | `0.13.0` | 2025-02-23 |
|
||||
| `linux-x64` | `2.7.0` | `0.14.0` | 2025-04-21 |
|
||||
| `linux-arm` | `2.7.0` | `0.13.0` | 2025-02-15 |
|
||||
| `linux-arm` | `2.7.0` | `0.15.2` | 2026-03-07 |
|
||||
|
||||
On Windows, due to incompatibilities between WSL and PowerShell, some commands
|
||||
must be run in WSL Bash.
|
||||
@ -812,15 +934,15 @@ the project folder.
|
||||
For X64 Mac:
|
||||
|
||||
```bash
|
||||
curl -LO https://ziglang.org/download/0.14.0/zig-macos-x86_64-0.14.0.tar.xz
|
||||
tar -xzf zig-macos-*.tar.xz
|
||||
curl -LO https://ziglang.org/download/0.15.2/zig-x86_64-macos-0.15.2.tar.xz
|
||||
tar -xzf zig-*.tar.xz
|
||||
```
|
||||
|
||||
For ARM64 Mac:
|
||||
|
||||
```bash
|
||||
curl -LO https://ziglang.org/download/0.13.0/zig-macos-aarch64-0.13.0.tar.xz
|
||||
tar -xzf zig-macos-*.tar.xz
|
||||
curl -LO https://ziglang.org/download/0.15.2/zig-aarch64-macos-0.15.2.tar.xz
|
||||
tar -xzf zig-*.tar.xz
|
||||
```
|
||||
|
||||
|
||||
@ -838,9 +960,9 @@ tar -xf zig-linux-*.tar
|
||||
For AArch64 Linux:
|
||||
|
||||
```bash
|
||||
curl -LO https://ziglang.org/download/0.13.0/zig-linux-aarch64-0.13.0.tar.xz
|
||||
xz -d zig-linux-*.tar.xz
|
||||
tar -xf zig-linux-*.tar
|
||||
curl -LO https://ziglang.org/download/0.15.2/zig-aarch64-linux-0.15.2.tar.xz
|
||||
xz -d zig-*.tar.xz
|
||||
tar -xf zig-*.tar
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -1017,10 +1139,10 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `2.2.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.2.0` | 2025-03-30 |
|
||||
| `darwin-x64` | `2.2.0` | 2026-01-21 |
|
||||
| `darwin-arm` | `2.2.0` | 2026-03-07 |
|
||||
| `linux-x64` | `2.2.0` | 2025-04-21 |
|
||||
| `linux-arm` | `2.2.0` | 2025-02-15 |
|
||||
| `linux-arm` | `2.2.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -1112,11 +1234,39 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `2.2.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.2.1` | 2025-03-31 |
|
||||
| `win11-x64` | `2.2.1` | 2025-04-17 |
|
||||
| `linux-x64` | `2.2.1` | 2025-04-18 |
|
||||
| `linux-arm` | `2.2.1` | 2025-04-18 |
|
||||
| `darwin-x64` | `2.2.1` | 2026-01-21 |
|
||||
| `darwin-arm` | `2.2.1` | 2026-03-07 |
|
||||
| `win11-x64` | `2.2.1` | 2026-02-02 |
|
||||
| `win11-arm` | `2.2.1` | 2026-02-02 |
|
||||
| `linux-x64` | `2.2.1` | 2026-01-08 |
|
||||
| `linux-arm` | `2.2.1` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
The `ducc` crate cannot compile Duktape from source in Windows on ARM, so the
|
||||
x64 Rust toolchain must be used through the X64 compatibility layer.
|
||||
|
||||
<details>
|
||||
<summary><b>Windows on ARM steps</b> (click to show)</summary>
|
||||
|
||||
The following commands switch to the X64 toolchain:
|
||||
|
||||
```pwsh
|
||||
rustup toolchain install stable-x86_64-pc-windows-msvc --force-non-host
|
||||
rustup default stable-x86_64-pc-windows-msvc --force-non-host
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
The following command switches back to the native toolchain:
|
||||
|
||||
```pwsh
|
||||
rustup default stable
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
:::
|
||||
|
||||
@ -1181,7 +1331,7 @@ cargo add ducc base64
|
||||
6) Build and run the app:
|
||||
|
||||
```bash
|
||||
cargo run pres.numbers
|
||||
cargo run -- pres.numbers
|
||||
```
|
||||
|
||||
If the program succeeded, the CSV contents will be printed to console and the
|
||||
|
||||
@ -184,7 +184,7 @@ cd /usr/local/lib
|
||||
|
||||
:::note pass
|
||||
|
||||
If this step throws a permission error, run the following commands:
|
||||
If this step throws an error, run the following commands to fix permissions:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /usr/local/lib
|
||||
@ -489,7 +489,7 @@ ninja -C out.gn/x64.release.sample v8_monolith
|
||||
|
||||
**This may not work in newer Python releases due to a breaking change!**
|
||||
|
||||
Python 3.13 removed the `pipes` module from the standard library[^9]. `v8gen.py`
|
||||
Python 3.13 removed the `pipes` module from the standard library[^7]. `v8gen.py`
|
||||
will fail on newer Python releases with the following traceback:
|
||||
|
||||
```
|
||||
@ -1078,18 +1078,14 @@ may not work on every platform.
|
||||
The `v8` crate[^6] provides binary builds and straightforward bindings. The Rust
|
||||
code is similar to the C++ code.
|
||||
|
||||
Pulling data from an `ArrayBuffer` back into Rust involves an unsafe operation:
|
||||
Pulling data from an `ArrayBuffer` back into Rust involves an unsafe conversion
|
||||
from a raw pointer and byte length to `Vec<u8>`:
|
||||
|
||||
```rust
|
||||
/* assuming JS code returns an ArrayBuffer, copy result to a Vec<u8> */
|
||||
fn eval_code_ab(scope: &mut v8::HandleScope, code: &str) -> Vec<u8> {
|
||||
let source = v8::String::new(scope, code).unwrap();
|
||||
let script = v8::Script::compile(scope, source, None).unwrap();
|
||||
let result: v8::Local<v8::ArrayBuffer> = script.run(scope).unwrap().try_into().unwrap();
|
||||
/* In C++, `Data` returns a pointer. Collecting data into Vec<u8> is unsafe */
|
||||
```rust title="Pull ArrayBuffer data from V8 to Rust vector of bytes"
|
||||
fn pull_ab_to_vecu8(ab: v8::Local<v8::ArrayBuffer>) -> Vec<u8> {
|
||||
unsafe { return std::slice::from_raw_parts_mut(
|
||||
result.data().unwrap().cast::<u8>().as_ptr(),
|
||||
result.byte_length()
|
||||
ab.data().unwrap().cast::<u8>().as_ptr(),
|
||||
ab.byte_length()
|
||||
).to_vec(); }
|
||||
}
|
||||
```
|
||||
@ -1100,11 +1096,12 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | V8 Crate | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `136.0.0` | 2025-04-21 |
|
||||
| `darwin-x64` | `146.3.0` | 2026-03-08 |
|
||||
| `darwin-arm` | `134.3.0` | 2025-02-13 |
|
||||
| `win11-x64` | `137.1.0` | 2025-05-11 |
|
||||
| `linux-x64` | `137.2.0` | 2025-06-16 |
|
||||
| `linux-arm` | `134.4.0` | 2025-02-15 |
|
||||
| `win11-arm` | `145.0.0` | 2026-02-02 |
|
||||
| `linux-x64` | `142.2.0` | 2026-01-08 |
|
||||
| `linux-arm` | `146.3.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -1177,13 +1174,12 @@ curl.exe -L -o src/main.rs https://docs.sheetjs.com/v8/main.rs
|
||||
|
||||
:::info pass
|
||||
|
||||
There was a breaking change in version `0.102.0` affecting `v8::Context::new`.
|
||||
When targeting older versions of the crate, remove the second argument:
|
||||
There were multiple breaking changes in the `v8` crate. This example was tested
|
||||
against version `142.2.0`.
|
||||
|
||||
```rust title="src/main.rs"
|
||||
let context = v8::Context::new(handle_scope); // v8 <= 0.101.0
|
||||
//let context = v8::Context::new(handle_scope, Default::default()); // v8 >= 0.102.0
|
||||
```
|
||||
Older versions of this demo script were designed for older `v8` versions. They
|
||||
are available in the source repo for the documentation. Please reach out to the
|
||||
[SheetJS chat](https://sheetjs.com/chat) for more details.
|
||||
|
||||
:::
|
||||
|
||||
@ -1217,10 +1213,29 @@ This demo was last tested in the following deployments:
|
||||
| Architecture | V8 Version | Javet | Java | Date |
|
||||
|:-------------|:--------------|:--------|:----------|:-----------|
|
||||
| `darwin-x64` | `13.2.152.16` | `4.1.1` | `24.0.1` | 2025-04-21 |
|
||||
| `darwin-arm` | `13.2.152.16` | `4.1.1` | `17.0.14` | 2025-03-30 |
|
||||
| `win11-x64` | `13.2.152.16` | `4.1.1` | `17.0.13` | 2025-05-11 |
|
||||
| `linux-x64` | `13.2.152.16` | `4.1.1` | `21.0.6` | 2025-04-21 |
|
||||
| `linux-arm` | `13.2.152.16` | `4.1.1` | `17.0.14` | 2025-02-16 |
|
||||
| `darwin-arm` | `13.2.152.16` | `4.1.1` | `17.0.14` | 2026-03-04 |
|
||||
| `win11-x64` | `13.2.152.16` | `4.1.1` | `17.0.12` | 2026-03-04 |
|
||||
| `win11-arm` | `13.2.152.16` | `4.1.1` | `25.0.2` | 2026-03-04 |
|
||||
| `linux-x64` | `13.2.152.16` | `4.1.1` | `21.0.10` | 2026-02-04 |
|
||||
| `linux-arm` | `13.2.152.16` | `4.1.1` | `17.0.18` | 2026-02-04 |
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
Javet does not provide a pre-built JAR for Windows on ARM. This demo was tested
|
||||
using the X64 compatibility layer.
|
||||
|
||||
<details>
|
||||
<summary><b>Windows on ARM steps</b> (click to show)</summary>
|
||||
|
||||
Windows on ARM defaults to ARM64 JRE/JDK. A proper x64 JDK must be installed and
|
||||
`JAVA_HOME` must point to the x64 version.
|
||||
|
||||
[Direct downloads are available at `adoptium.net`](https://adoptium.net/temurin/releases/).
|
||||
The Windows x64 JDK release should be downloaded and installed.
|
||||
|
||||
</details>
|
||||
|
||||
:::
|
||||
|
||||
@ -1430,12 +1445,12 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | V8 Version | Date |
|
||||
|:-------------|:--------------|:-----------|
|
||||
| `darwin-x64` | `13.3.415.23` | 2025-03-31 |
|
||||
| `darwin-arm` | `13.3.415.23` | 2025-03-31 |
|
||||
| `darwin-x64` | `13.3.415.23` | 2026-03-06 |
|
||||
| `darwin-arm` | `13.3.415.23` | 2026-03-06 |
|
||||
| `win11-x64` | `13.3.415.23` | 2025-05-11 |
|
||||
| `win11-arm` | `12.3.219.12` | 2025-02-23 |
|
||||
| `linux-x64` | `12.3.219.12` | 2025-06-16 |
|
||||
| `linux-arm` | `12.3.219.12` | 2025-02-16 |
|
||||
| `linux-x64` | `12.3.219.12` | 2026-03-06 |
|
||||
| `linux-arm` | `13.3.415.23` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -1583,16 +1598,15 @@ opened in a spreadsheet editor.
|
||||
|
||||
### Python
|
||||
|
||||
[`pyv8`](https://code.google.com/archive/p/pyv8/) is a Python wrapper for V8.
|
||||
|
||||
The `stpyv8` package[^7] is an actively-maintained fork with binary wheels.
|
||||
The [`mini-racer`](https://bpcreech.com/PyMiniRacer/) V8 wrapper package has
|
||||
precompiled wheels for all major platforms.
|
||||
|
||||
:::caution pass
|
||||
|
||||
When this demo was last tested, there was no direct conversion between Python
|
||||
`bytes` and JavaScript `ArrayBuffer` data.
|
||||
|
||||
This is a known issue[^8]. The current recommendation is Base64 strings.
|
||||
This is a known issue. The current recommendation is Base64 strings.
|
||||
|
||||
:::
|
||||
|
||||
@ -1603,25 +1617,26 @@ the `base64` type[^5].
|
||||
|
||||
_Reading Files_
|
||||
|
||||
It is recommended to create a global context with a special method that handles
|
||||
file reading from Python. The `read_file` helper in the following snippet will
|
||||
read bytes from `sheetjs.xlsx` and generate a Base64 string:
|
||||
The file data can be read in Python and encoded as Base64. The `set_object_item`
|
||||
method on the internal context can assign to properties of the global object.
|
||||
|
||||
`mini-racer` does not expose a dedicated API to reference the global object.
|
||||
The standard approach is to evaluate `this` in the JavaScript engine:
|
||||
|
||||
```py
|
||||
from base64 import b64encode;
|
||||
from STPyV8 import JSContext, JSClass;
|
||||
from py_mini_racer import MiniRacer;
|
||||
|
||||
# Create context with methods for file i/o
|
||||
class Base64Context(JSClass):
|
||||
def read_file(self, path):
|
||||
with open(path, "rb") as f:
|
||||
data = f.read();
|
||||
return b64encode(data).decode("ascii");
|
||||
globals = Base64Context();
|
||||
with open("sheetjs.xlsx", "rb") as f:
|
||||
file_data = b64encode(f.read()).decode("ascii");
|
||||
|
||||
# The JSContext starts and cleans up the V8 engine
|
||||
with JSContext(globals) as ctxt:
|
||||
print(ctxt.eval("read_file('sheetjs.xlsx')")); # read base64 data and print
|
||||
# Create context and obtain a handle to `this`
|
||||
ctx = MiniRacer();
|
||||
global_scope = ctx.eval("this");
|
||||
|
||||
# assign to the `fileData` global property and parse
|
||||
ctx._ctx.set_object_item(global_scope, "fileData", file_data);
|
||||
ctx.eval("var wb = XLSX.read(fileData, {type:'base64'});");
|
||||
```
|
||||
|
||||
_Writing Files_
|
||||
@ -1631,14 +1646,14 @@ decoded and written to file from Python:
|
||||
|
||||
```py
|
||||
from base64 import b64decode;
|
||||
from STPyV8 import JSContext;
|
||||
from py_mini_racer import MiniRacer;
|
||||
|
||||
# The JSContext starts and cleans up the V8 engine
|
||||
with JSContext() as ctxt:
|
||||
# ... initialization and workbook creation ...
|
||||
xlsb = ctxt.eval("XLSX.write(wb, {type: 'base64', bookType: 'xlsb'})");
|
||||
with open("SheetJSSTPyV8.xlsb", "wb") as f:
|
||||
f.write(b64decode(xlsb));
|
||||
ctx = MiniRacer();
|
||||
# ... initialization and workbook creation ...
|
||||
xlsb = ctx.eval("XLSX.write(wb, {type: 'base64', bookType: 'xlsb'})");
|
||||
with open("SheetJSMiniRacer.xlsb", "wb") as f:
|
||||
f.write(b64decode(xlsb));
|
||||
ctx.close();
|
||||
```
|
||||
|
||||
#### Python Demo
|
||||
@ -1649,46 +1664,28 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | V8 Version | Python | Date |
|
||||
|:-------------|:--------------|:---------|:-----------|
|
||||
| `darwin-x64` | `13.1.201.22` | `3.13.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `13.1.201.22` | `3.13.2` | 2025-04-24 |
|
||||
| `win11-x64` | `13.1.201.22` | `3.11.9` | 2025-04-28 |
|
||||
| `linux-x64` | `13.1.201.22` | `3.12.3` | 2025-06-16 |
|
||||
| `darwin-x64` | `14.4` | `3.13.7` | 2026-03-04 |
|
||||
| `darwin-arm` | `14.4` | `3.14.3` | 2026-03-04 |
|
||||
| `win11-x64` | `14.4` | `3.11.9` | 2026-03-05 |
|
||||
| `win11-arm` | `14.4` | `3.11.9` | 2026-03-05 |
|
||||
| `linux-x64` | `14.4` | `3.13.9` | 2026-03-04 |
|
||||
| `linux-arm` | `14.4` | `3.13.5` | 2026-03-04 |
|
||||
|
||||
:::
|
||||
|
||||
0) Make a new folder for the project:
|
||||
|
||||
```bash
|
||||
mkdir sheetjs-stpyv8
|
||||
cd sheetjs-stpyv8
|
||||
mkdir sheetjs-miniracer
|
||||
cd sheetjs-miniracer
|
||||
```
|
||||
|
||||
1) Install `stpyv8`:
|
||||
1) Install `mini-racer`:
|
||||
|
||||
```bash
|
||||
pip install stpyv8
|
||||
pip install mini-racer
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
The install may fail with a `externally-managed-environment` error:
|
||||
|
||||
```
|
||||
error: externally-managed-environment
|
||||
|
||||
× This environment is externally managed
|
||||
```
|
||||
|
||||
The wheel can be downloaded and forcefully installed. The following commands
|
||||
download and install version `13.0.245.16` for Python `3.13` on `darwin-arm`:
|
||||
|
||||
```bash
|
||||
curl -LO https://github.com/cloudflare/stpyv8/releases/download/v13.1.201.22/stpyv8-13.1.201.22-cp313-cp313-macosx_14_0_arm64.whl
|
||||
sudo python -m pip install --break-system-packages --upgrade stpyv8-13.1.201.22-cp313-cp313-macosx_14_0_arm64.whl
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
2) Download the SheetJS standalone script and test file. Move both files to the
|
||||
project directory:
|
||||
|
||||
@ -1702,40 +1699,20 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -LO https://docs.sheetjs.com/pres.xlsx`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Download [`sheetjs-stpyv8.py`](pathname:///v8/sheetjs-stpyv8.py):
|
||||
3) Download [`sheetjs-mini-racer.py`](pathname:///v8/sheetjs-mini-racer.py):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/v8/sheetjs-stpyv8.py
|
||||
curl -LO https://docs.sheetjs.com/v8/sheetjs-mini-racer.py
|
||||
```
|
||||
|
||||
4) Run the script and pass `pres.xlsx` as the first argument:
|
||||
|
||||
```bash
|
||||
python sheetjs-stpyv8.py pres.xlsx
|
||||
python sheetjs-mini-racer.py pres.xlsx
|
||||
```
|
||||
|
||||
The script will display CSV rows from the first worksheet. It will also create
|
||||
`SheetJSSTPyV8.xlsb`, a workbook that can be opened with a spreadsheet editor.
|
||||
|
||||
:::caution pass
|
||||
|
||||
On Windows, this may fail with a `charmap` error:
|
||||
|
||||
```
|
||||
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 380: character maps to <undefined>
|
||||
```
|
||||
|
||||
`sheetjs-stpyv8.py` must be altered to read `xlsx.full.min.js` with mode `rb`:
|
||||
|
||||
```python title="sheetjs-stpyv8.py (edit highlighted line)"
|
||||
# Read xlsx.full.min.js
|
||||
# highlight-next-line
|
||||
with open("xlsx.full.min.js", "rb") as f:
|
||||
```
|
||||
|
||||
:::
|
||||
`SheetJSMiniRacer.xlsb`, a workbook that can be opened with a spreadsheet editor.
|
||||
|
||||
## Snapshots
|
||||
|
||||
@ -1761,11 +1738,11 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | V8 Version | Crate | Date |
|
||||
|:-------------|:--------------|:----------|:-----------|
|
||||
| `darwin-x64` | `13.5.212.10` | `136.0.0` | 2025-04-21 |
|
||||
| `darwin-x64` | `13.5.212.10` | `136.0.0` | 2026-03-08 |
|
||||
| `darwin-arm` | `13.5.212.10` | `136.0.0` | 2025-04-24 |
|
||||
| `win11-x64` | `13.5.212.10` | `136.0.0` | 2025-05-11 |
|
||||
| `linux-x64` | `13.5.212.10` | `136.0.0` | 2025-06-16 |
|
||||
| `linux-arm` | `13.4.114.9` | `134.4.0` | 2025-02-15 |
|
||||
| `linux-arm` | `13.5.212.10` | `136.0.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -1864,6 +1841,4 @@ mv target/release/sheet2csv.exe .
|
||||
[^4]: See [`write` in "Writing Files"](/docs/api/write-options)
|
||||
[^5]: See ["Supported Output Formats" type in "Writing Files"](/docs/api/write-options#supported-output-formats)
|
||||
[^6]: The project does not have an official website. The [official Rust crate](https://crates.io/crates/v8) is hosted on `crates.io`.
|
||||
[^7]: The project does not have a separate website. The source repository is hosted on [GitHub](https://github.com/cloudflare/stpyv8)
|
||||
[^8]: According to a maintainer, [typed arrays were not supported in the original `pyv8` project](https://github.com/cloudflare/stpyv8/issues/104#issuecomment-2059125389)
|
||||
[^9]: `pipes` and other modules were removed from the standard library in Python 3.13 as part of ["PEP 594"](https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-pep594).
|
||||
[^7]: `pipes` and other modules were removed from the standard library in Python 3.13 as part of ["PEP 594"](https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-pep594).
|
||||
@ -32,28 +32,28 @@ Swift on MacOS supports JavaScriptCore without additional dependencies.
|
||||
|
||||
| Architecture | Swift | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `6.1` | 2025-04-21 |
|
||||
| `darwin-arm` | `6.1` | 2025-04-21 |
|
||||
| `darwin-x64` | `6.1.2` | 2026-03-04 |
|
||||
| `darwin-arm` | `6.0.3` | 2026-03-04 |
|
||||
|
||||
[**C / C++ Compiled from Source**](#c)
|
||||
|
||||
JavaScriptCore can be built from source and linked in C / C++ programs.
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:-----------------|:-----------|
|
||||
| `darwin-x64` | `7620.2.4.111.7` | 2025-04-21 |
|
||||
| `darwin-arm` | `7620.2.4.111.7` | 2025-04-21 |
|
||||
| `linux-x64` | `7620.2.4.111.7` | 2025-04-21 |
|
||||
| `linux-arm` | `7620.2.4.111.7` | 2025-04-21 |
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:------------------|:-----------|
|
||||
| `darwin-x64` | `7623.1.14.14.11` | 2026-03-04 |
|
||||
| `darwin-arm` | `7623.1.14.14.11` | 2026-03-04 |
|
||||
| `linux-x64` | `7623.1.14.14.11` | 2026-03-04 |
|
||||
| `linux-arm` | `7623.1.14.14.11` | 2026-03-04 |
|
||||
|
||||
[**Swift Compiled from Source**](#swift-c)
|
||||
|
||||
Swift compiler can link against libraries built from the JavaScriptCore source.
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:-----------------|:-----------|
|
||||
| `linux-x64` | `7620.2.4.111.7` | 2025-04-21 |
|
||||
| `linux-arm` | `7620.2.4.111.7` | 2025-04-21 |
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:------------------|:-----------|
|
||||
| `linux-x64` | `7623.1.14.14.11` | 2026-03-04 |
|
||||
| `linux-arm` | `7623.1.14.14.11` | 2026-03-04 |
|
||||
|
||||
:::
|
||||
|
||||
@ -445,7 +445,7 @@ sudo pacman -Syu base-devel cmake ruby icu glibc linux-api-headers
|
||||
On Debian and Ubuntu, dependencies should be installed with `apt`:
|
||||
|
||||
```bash
|
||||
sudo apt-get install build-essential cmake ruby
|
||||
sudo apt-get install build-essential cmake ruby libicu-dev
|
||||
```
|
||||
|
||||
</details>
|
||||
@ -457,12 +457,12 @@ mkdir sheetjs-jsc
|
||||
cd sheetjs-jsc
|
||||
```
|
||||
|
||||
2) Clone the WebKit repository and switch to the `WebKit-7620.2.4.111.7` tag:
|
||||
2) Clone the WebKit repository and switch to the `WebKit-7623.1.14.14.11` tag:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/WebKit/WebKit.git WebKit
|
||||
cd WebKit
|
||||
git checkout WebKit-7620.2.4.111.7
|
||||
git checkout WebKit-7623.1.14.14.11
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -473,19 +473,36 @@ cd ..
|
||||
|
||||
```bash
|
||||
cd WebKit
|
||||
env CFLAGS="-Wno-error=all -Wno-deprecated-declarations" CXXFLAGS="-Wno-error=all -Wno-deprecated-declarations" LDFLAGS="-framework Foundation" Tools/Scripts/build-webkit --jsc-only --cmakeargs="-Wno-error=all -DENABLE_STATIC_JSC=ON -DCMAKE_C_FLAGS=\"-Wno-error=all -Wno-deprecated-declarations\" -DCMAKE_CXX_FLAGS=\"-Wno-error=all -Wno-deprecated-declarations\"" --make-args="-Wno-error=all -Wno-deprecated-declarations"
|
||||
env CFLAGS="-Wno-error=all -Wno-deprecated-declarations" CXXFLAGS="-Wno-error=all -Wno-deprecated-declarations" LDFLAGS="-framework Foundation" Tools/Scripts/build-webkit --jsc-only --cmakeargs="-Wno-error=all -DENABLE_STATIC_JSC=ON -DCMAKE_C_FLAGS=\"-Wno-error=all -Wno-deprecated-declarations\" -DCMAKE_CXX_FLAGS=\"-Wno-error=all -Wno-deprecated-declarations\"" --make-args="-Wno-error=all -Wno-deprecated-declarations" --no-jit --no-webassembly
|
||||
cd ..
|
||||
```
|
||||
|
||||
:::note pass
|
||||
:::caution pass
|
||||
|
||||
In some test runs on ARM64 macOS, JIT elicited runtime errors and WebAssembly
|
||||
elicited compile-time errors. WebAssembly and JIT should be disabled:
|
||||
In some test runs, there were test compile errors:
|
||||
|
||||
```
|
||||
WebKit/Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.cpp:42:10: fatal error: 'wtf/darwin/DispatchExtras.h' file not found
|
||||
42 | #include <wtf/darwin/DispatchExtras.h>
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
1 error generated.
|
||||
```
|
||||
|
||||
The referenced file must be patched to assume `MACH_EXCEPTIONS` is not defined.
|
||||
There are a number of pre-processor directives:
|
||||
|
||||
```c
|
||||
#if HAVE(MACH_EXCEPTIONS)
|
||||
#include <wtf/darwin/DispatchExtras.h>
|
||||
#endif
|
||||
```
|
||||
|
||||
Each pre-processor block must be removed.
|
||||
|
||||
This can be automated with a simple Perl command:
|
||||
|
||||
```bash
|
||||
cd WebKit
|
||||
env CFLAGS="-Wno-error=all -Wno-deprecated-declarations" CXXFLAGS="-Wno-error=all -Wno-deprecated-declarations" LDFLAGS="-framework Foundation" Tools/Scripts/build-webkit --jsc-only --cmakeargs="-Wno-error=all -DENABLE_STATIC_JSC=ON -DCMAKE_C_FLAGS=\"-Wno-error=all -Wno-deprecated-declarations\" -DCMAKE_CXX_FLAGS=\"-Wno-error=all -Wno-deprecated-declarations\"" --make-args="-Wno-error=all -Wno-deprecated-declarations" --no-jit --no-webassembly
|
||||
cd ..
|
||||
perl -0777 -i -pe 's/#if HAVE\(MACH_EXCEPTIONS\).*?#endif\n*/\n/gs' "Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.cpp"
|
||||
```
|
||||
|
||||
:::
|
||||
@ -545,7 +562,7 @@ The `#include` should be changed to a relative directive:
|
||||
|
||||
```bash
|
||||
cd WebKit
|
||||
env CFLAGS="-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference" CXXFLAGS="-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference" Tools/Scripts/build-webkit --jsc-only --cmakeargs="-Wno-error=all -Wno-error=volatile-register-var -DENABLE_STATIC_JSC=ON -DUSE_THIN_ARCHIVES=OFF -DCMAKE_C_FLAGS=\"-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference\" -DCMAKE_CXX_FLAGS=\"-Wno-error=all -Wno-error=volatile-register-var \"" --make-args="-j1 -Wno-error=all -Wno-error=volatile-register-var " -j1
|
||||
env CFLAGS="-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference" CXXFLAGS="-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference" Tools/Scripts/build-webkit --jsc-only --cmakeargs="-Wno-error=all -Wno-error=volatile-register-var -DENABLE_STATIC_JSC=ON -DUSE_THIN_ARCHIVES=OFF" --make-args="-j1 -Wno-error=all -Wno-error=volatile-register-var" -j1 --no-jit --no-webassembly
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -585,17 +602,10 @@ The error can be suppressed with preprocessor directives around the definition:
|
||||
T* prev() const { return static_cast<T*>(PtrTraits::unwrap(m_prev)); }
|
||||
```
|
||||
|
||||
After patching the header, JSC must be built without WebAssembly or JIT support:
|
||||
|
||||
```bash
|
||||
cd WebKit
|
||||
env CFLAGS="-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference" CXXFLAGS="-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference" Tools/Scripts/build-webkit --jsc-only --cmakeargs="-Wno-error=all -Wno-error=volatile-register-var -DENABLE_STATIC_JSC=ON -DUSE_THIN_ARCHIVES=OFF -DCMAKE_C_FLAGS=\"-Wno-error=all -Wno-error=volatile-register-var -Wno-dangling-reference\" -DCMAKE_CXX_FLAGS=\"-Wno-error=all -Wno-error=volatile-register-var \"" --make-args="-j1 -Wno-error=all -Wno-error=volatile-register-var " -j1 --no-jit --no-webassembly
|
||||
cd ..
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
:::note pass
|
||||
|
||||
In some test runs, there was a register error:
|
||||
|
||||
@ -884,7 +894,7 @@ pub struct JSString {
|
||||
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
|
||||
}
|
||||
// highlight-next-line
|
||||
type JSStringRef = *mut JSContext;
|
||||
type JSStringRef = *mut JSString;
|
||||
```
|
||||
|
||||
**Function Declaration**
|
||||
@ -898,9 +908,10 @@ JSStringRef JSStringCreateWithUTF8CString(const char * string);
|
||||
The equivalent Rust declaration must be defined in an `extern "C"` block:
|
||||
|
||||
```rust title="JSStringCreateWithUTF8CString Rust declaration"
|
||||
use libc::c_char;
|
||||
unsafe extern "C" {
|
||||
// JSStringRef JSStringCreateWithUTF8CString(const char * string);
|
||||
pub unsafe fn JSStringCreateWithUTF8CString(string: *const u8) -> JSStringRef;
|
||||
pub unsafe fn JSStringCreateWithUTF8CString(string: *const c_char) -> JSStringRef;
|
||||
}
|
||||
```
|
||||
|
||||
@ -940,8 +951,10 @@ The demo makes a safe wrapper to perform the unsafe waltz in one line:
|
||||
pub struct JSC;
|
||||
impl JSC {
|
||||
pub fn JSStringCreateWithUTF8CString(str: &str) -> JSStringRef { unsafe {
|
||||
// highlight-next-line
|
||||
JSStringCreateWithUTF8CString(std::ffi::CString::new(str.as_bytes()).unwrap().as_ptr() as *const u8)
|
||||
// highlight-start
|
||||
let cstr = std::ffi::CString::new(str).unwrap();
|
||||
JSStringCreateWithUTF8CString(cstr.as_ptr())
|
||||
// highlight-end
|
||||
} }
|
||||
}
|
||||
```
|
||||
@ -954,11 +967,24 @@ This demo was last tested in the following deployments:
|
||||
|
||||
| Architecture | Date |
|
||||
|:-------------|:-----------|
|
||||
| `darwin-x64` | 2025-03-31 |
|
||||
| `darwin-arm` | 2025-03-30 |
|
||||
| `darwin-x64` | 2026-03-04 |
|
||||
| `darwin-arm` | 2026-03-04 |
|
||||
| `linux-x64` | 2026-03-04 |
|
||||
| `linux-arm` | 2026-03-04 |
|
||||
|
||||
:::
|
||||
|
||||
<Tabs groupId="triple">
|
||||
<TabItem value="darwin-x64" label="MacOS">
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="linux-x64" label="Linux">
|
||||
|
||||
0) Follow the entire ["C" demo](#c). The library will be used in Rust.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
1) Create a new project:
|
||||
|
||||
```bash
|
||||
@ -999,7 +1025,13 @@ curl -L -o src/main.rs https://docs.sheetjs.com/jsc/main.rs
|
||||
curl -LO https://docs.sheetjs.com/jsc/build.rs
|
||||
```
|
||||
|
||||
6) Build and run the app:
|
||||
6) Install the `libc` crate:
|
||||
|
||||
```bash
|
||||
cargo add libc
|
||||
```
|
||||
|
||||
7) Build and run the app:
|
||||
|
||||
```bash
|
||||
cargo run pres.numbers
|
||||
|
||||
@ -163,12 +163,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Jint | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `4.2.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `4.2.0` | 2025-02-13 |
|
||||
| `darwin-x64` | `4.5.0` | 2026-01-21 |
|
||||
| `darwin-arm` | `4.6.3` | 2026-03-22 |
|
||||
| `win11-x64` | `4.2.2` | 2026-04-28 |
|
||||
| `win11-arm` | `4.2.0` | 2025-02-23 |
|
||||
| `win11-arm` | `4.6.3` | 2026-03-22 |
|
||||
| `linux-x64` | `4.2.2` | 2025-06-16 |
|
||||
| `linux-arm` | `4.2.0` | 2025-02-15 |
|
||||
| `linux-arm` | `4.5.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
@ -248,7 +248,7 @@ dotnet run
|
||||
|
||||
```bash
|
||||
dotnet nuget add source https://www.myget.org/F/jint/api/v3/index.json
|
||||
dotnet add package Jint --version 4.2.2
|
||||
dotnet add package Jint --version 4.6.3
|
||||
```
|
||||
|
||||
To verify Jint is installed, replace `Program.cs` with the following:
|
||||
|
||||
@ -105,12 +105,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Git Commit | Go version | Date |
|
||||
|:-------------|:-----------|:-----------|:-----------|
|
||||
| `darwin-x64` | `bcd7cc6` | `1.24.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `cb187b0` | `1.24.0` | 2025-06-18 |
|
||||
| `win11-x64` | `bcd7cc6` | `1.24.2` | 2025-04-28 |
|
||||
| `win11-arm` | `5ef83b8` | `1.24.0` | 2025-02-23 |
|
||||
| `darwin-x64` | `651366f` | `1.25.6` | 2026-01-21 |
|
||||
| `darwin-arm` | `6a7976c` | `1.24.0` | 2026-03-07 |
|
||||
| `win11-x64` | `6a7976c` | `1.24.2` | 2026-03-08 |
|
||||
| `win11-arm` | `065cd970` | `1.26.1` | 2026-03-22 |
|
||||
| `linux-x64` | `cb187b0` | `1.22.2` | 2025-06-16 |
|
||||
| `linux-arm` | `5ef83b8` | `1.19.8` | 2025-02-15 |
|
||||
| `linux-arm` | `6a7976c` | `1.24.4` | 2026-03-07 |
|
||||
|
||||
At the time of writing, Goja did not have proper version numbers. Versions are
|
||||
identified by Git commit hashes.
|
||||
|
||||
@ -27,7 +27,7 @@ command-line tool for reading data from files.
|
||||
:::note pass
|
||||
|
||||
Many QuickJS functions are not documented. The explanation was verified against
|
||||
commit `0d7aaed`.
|
||||
commit `f113949`.
|
||||
|
||||
:::
|
||||
|
||||
@ -263,14 +263,14 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Library | Git Commit | Date |
|
||||
|:-------------|:-----------|:-----------|:-----------|
|
||||
| `darwin-x64` | QuickJS | `0d7aaed` | 2025-03-31 |
|
||||
| `darwin-arm` | QuickJS | `3306254` | 2025-09-03 |
|
||||
| `win11-x64` | QuickJS-NG | `865ba1f` | 2025-04-18 |
|
||||
| `darwin-x64` | QuickJS | `f113949` | 2026-01-21 |
|
||||
| `darwin-arm` | QuickJS | `f113949` | 2026-03-07 |
|
||||
| `win11-x64` | QuickJS-NG | `4951c83` | 2025-04-18 |
|
||||
| `win11-arm` | QuickJS-NG | `865ba1f` | 2025-04-18 |
|
||||
| `linux-x64` | QuickJS | `3306254` | 2025-06-18 |
|
||||
| `linux-arm` | QuickJS | `6e2e68f` | 2025-02-15 |
|
||||
| `linux-x64` | QuickJS | `f113949` | 2026-03-08 |
|
||||
| `linux-arm` | QuickJS | `f113949` | 2026-03-07 |
|
||||
|
||||
When the demo was tested, `0d7aaed` was the HEAD commit on the `master` branch.
|
||||
When the demo was tested, `f113949` was the HEAD commit on the `master` branch.
|
||||
|
||||
:::
|
||||
|
||||
@ -281,7 +281,7 @@ When the demo was tested, `0d7aaed` was the HEAD commit on the `master` branch.
|
||||
```bash
|
||||
git clone https://github.com/bellard/quickjs
|
||||
cd quickjs
|
||||
git checkout 3306254
|
||||
git checkout f113949
|
||||
make
|
||||
cd ..
|
||||
```
|
||||
@ -369,7 +369,7 @@ cd sheetjs-quick
|
||||
```bash
|
||||
git clone https://github.com/quickjs-ng/quickjs
|
||||
cd quickjs
|
||||
git checkout 865ba1f1
|
||||
git checkout 4951c83
|
||||
cmake -B build -DQJS_BUILD_EXAMPLES=ON
|
||||
cmake --build build --config Release
|
||||
build\Release\qjs.exe amalgam.js
|
||||
@ -386,7 +386,7 @@ copy quickjs\quickjs.h .
|
||||
3) Download [`sheetjs.quick.c`](pathname:///quickjs/sheetjs.quick.c):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/quickjs/sheetjs.quick.c
|
||||
curl.exe -LO https://docs.sheetjs.com/quickjs/sheetjs.quick.c
|
||||
```
|
||||
|
||||
4) Build the sample application:
|
||||
@ -406,8 +406,8 @@ the project directory:
|
||||
</ul>
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -LO https://docs.sheetjs.com/pres.numbers`}
|
||||
curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl.exe -LO https://docs.sheetjs.com/pres.numbers`}
|
||||
</CodeBlock>
|
||||
|
||||
6) Run the test program:
|
||||
@ -428,9 +428,9 @@ This demo was tested in the following environments:
|
||||
|
||||
| Git Commit | Date |
|
||||
|:-----------|:-----------|
|
||||
| `0d7aaed` | 2025-03-31 |
|
||||
| `f113949` | 2026-01-21 |
|
||||
|
||||
When the demo was tested, `0d7aaed` was the HEAD commit on the `master` branch.
|
||||
When the demo was tested, `f113949` was the HEAD commit on the `master` branch.
|
||||
|
||||
:::
|
||||
|
||||
@ -440,7 +440,7 @@ and build the `quickjs` project:
|
||||
```bash
|
||||
git clone https://github.com/bellard/quickjs
|
||||
cd quickjs
|
||||
git checkout 0d7aaed
|
||||
git checkout f113949
|
||||
make
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -364,10 +364,10 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Git Commit | Date |
|
||||
|:-------------|:-----------|:-----------|
|
||||
| `darwin-x64` | `8ef11b4` | 2025-03-31 |
|
||||
| `darwin-arm` | `8ef11b4` | 2025-09-03 |
|
||||
| `darwin-x64` | `f45c6bc` | 2026-03-06 |
|
||||
| `darwin-arm` | `f45c6bc` | 2026-01-23 |
|
||||
| `linux-x64` | `8ef11b4` | 2025-04-21 |
|
||||
| `linux-arm` | `388376f` | 2025-02-15 |
|
||||
| `linux-arm` | `f45c6bc` | 2026-03-07 |
|
||||
|
||||
The main Hermes source tree does not have Windows support. The `hermes-windows`
|
||||
fork, which powers React Native for Windows, does have built-in support[^5]
|
||||
@ -586,9 +586,15 @@ cp ./build_release/jsi/libjsi.so .
|
||||
</TabItem>
|
||||
<TabItem value="darwin" label="MacOS">
|
||||
|
||||
:::note pass
|
||||
|
||||
Some Hermes releases build static libraries, rendering this step unnecessary.
|
||||
|
||||
:::
|
||||
|
||||
```bash
|
||||
cp ./build_release/API/hermes/libhermes.dylib .
|
||||
cp ./build_release/jsi/libjsi.dylib .
|
||||
if [ -e ./build_release/API/hermes/libhermes.dylib ]; then cp ./build_release/API/hermes/libhermes.dylib .; fi
|
||||
if [ -e ./build_release/jsi/libjsi.dylib ]; then cp ./build_release/jsi/libjsi.dylib .; fi
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -847,13 +853,16 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Hermes | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `0.13.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `0.13.0` | 2025-04-23 |
|
||||
| `darwin-x64` | `0.13.0` | 2026-03-06 |
|
||||
| `darwin-arm` | `0.13.0` | 2026-03-06 |
|
||||
| `win11-x64` | `0.13.0` | 2025-04-28 |
|
||||
| `win11-arm` | `0.13.0` | 2025-02-23 |
|
||||
| `linux-x64` | `0.13.0` | 2025-04-21 |
|
||||
| `linux-arm` | `0.13.0` | 2026-03-07 |
|
||||
|
||||
When this demo was last tested, `jsvu` did not support `linux-arm`.
|
||||
When this demo was last tested, `jsvu` did not install a native `linux-arm`
|
||||
binary. Nevertheless, the process was tested using `qemu-user` to simulate the
|
||||
`linux-x64` program.
|
||||
|
||||
:::
|
||||
|
||||
@ -870,13 +879,26 @@ npx -y jsvu hermes@0.13.0
|
||||
|
||||
When prompted, select the appropriate operating system.
|
||||
|
||||
:::info pass
|
||||
<details>
|
||||
<summary><b>Installation Notes</b> (click to show)</summary>
|
||||
|
||||
`jsvu` on Windows on ARM uses the X64 compatibility layer. When the demo was
|
||||
last tested, the engine binaries were not native ARM64 programs.
|
||||
|
||||
:::
|
||||
---
|
||||
|
||||
`jsvu` will fail on Linux on ARM since the `linux64` binary is X64. This error
|
||||
can be ignored.
|
||||
|
||||
On this platform, `qemu-user` must be installed by the root user:
|
||||
|
||||
```bash
|
||||
sudo apt install qemu-user
|
||||
```
|
||||
|
||||
In Debian, the package includes bindings to support the `binfmt_misc` system.
|
||||
|
||||
</details>
|
||||
|
||||
1) Inspect the output of the installer. Look for "Installing binary" lines:
|
||||
|
||||
|
||||
@ -87,12 +87,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Platform | Ruby | ExecJS | Date |
|
||||
|:-------------|:---------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.6.10` | `2.10.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.6.10` | `2.10.0` | 2025-09-03 |
|
||||
| `darwin-x64` | `2.6.10` | `2.10.0` | 2026-01-21 |
|
||||
| `darwin-arm` | `2.6.10` | `2.10.0` | 2026-03-07 |
|
||||
| `win11-x64` | `3.3.8` | `2.10.0` | 2025-04-28 |
|
||||
| `win11-arm` | `3.2.3` | `2.10.0` | 2025-02-23 |
|
||||
| `linux-x64` | `3.2.3` | `2.10.0` | 2025-04-21 |
|
||||
| `linux-arm` | `3.1.2` | `2.10.0` | 2025-02-15 |
|
||||
| `linux-x64` | `3.3.8` | `2.10.0` | 2026-03-08 |
|
||||
| `linux-arm` | `3.3.8` | `2.10.0` | 2026-03-07 |
|
||||
|
||||
When the demo was last tested, there was no official Ruby release for Windows
|
||||
on ARM. The `win11-arm` test was run in WSL.
|
||||
|
||||
@ -87,7 +87,6 @@ static char *read_file(const char *filename, size_t *sz) {
|
||||
|
||||
// ...
|
||||
/* load library */
|
||||
EVAL_FILE("shim.min.js")
|
||||
EVAL_FILE("xlsx.full.min.js")
|
||||
```
|
||||
|
||||
@ -132,11 +131,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Git Commit | Date |
|
||||
|:-------------|:-----------|:-----------|
|
||||
| `darwin-x64` | `36becec` | 2025-03-31 |
|
||||
| `darwin-arm` | `36becec` | 2025-09-03 |
|
||||
| `darwin-x64` | `792ee76` | 2026-01-20 |
|
||||
| `darwin-arm` | `792ee76` | 2026-03-08 |
|
||||
| `win11-x64` | `36becec` | 2025-04-28 |
|
||||
| `win11-arm` | `e26c81f` | 2025-02-23 |
|
||||
| `linux-x64` | `36becec` | 2025-06-18 |
|
||||
| `linux-x64` | `792ee76` | 2026-03-08 |
|
||||
| `linux-arm` | `792ee76` | 2026-01-10 |
|
||||
|
||||
:::
|
||||
|
||||
@ -204,7 +204,7 @@ The commands in this demo should be run in "ARM64 Native Tools Command Prompt".
|
||||
```bash
|
||||
git clone https://github.com/chakra-core/ChakraCore.git
|
||||
cd ChakraCore
|
||||
git checkout 36becec
|
||||
git checkout 792ee76
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -215,7 +215,7 @@ cd ..
|
||||
|
||||
```bash
|
||||
cd ChakraCore
|
||||
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --system-icu --no-jit
|
||||
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -233,6 +233,7 @@ This was fixed with a local symlink to the `icu4c` folder before the build step:
|
||||
cd ChakraCore
|
||||
mkdir -p usr/local/opt
|
||||
ln -s /opt/homebrew/opt/icu4c usr/local/opt/icu4c
|
||||
./build.sh --static --icu=usr/local/opt/icu4c/include --test-build -j=8 --system-icu --no-jit
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -291,12 +292,10 @@ When the demo was last tested, ChakraCore JIT was not supported.
|
||||
|
||||
```bash
|
||||
cd ChakraCore
|
||||
export PATH="$(brew --prefix cmake3)/bin:${PATH}"
|
||||
./build.sh --static --icu=$(brew --prefix)/opt/icu4c/include --test-build -j=8 --no-jit
|
||||
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
|
||||
cd ..
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::caution Troubleshooting
|
||||
|
||||
@ -568,18 +567,16 @@ cl sheetjs.ch.cpp ChakraCore.lib /I ChakraCore\lib\Jsrt /link /LIBPATH:ChakraCor
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
5) Download the SheetJS Standalone script, shim script and test file. Move all
|
||||
three files to the project directory:
|
||||
5) Download the SheetJS Standalone script and test file. Move all three files to
|
||||
the project directory:
|
||||
|
||||
<ul>
|
||||
<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://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
|
||||
<li><a href="https://docs.sheetjs.com/pres.numbers">pres.numbers</a></li>
|
||||
</ul>
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl -L -O https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -L -O https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
|
||||
curl -L -O https://docs.sheetjs.com/pres.numbers`}
|
||||
</CodeBlock>
|
||||
|
||||
@ -609,7 +606,7 @@ If successful, the program will print the contents of the first sheet as CSV.
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2025-06-20 against `ch` commit `36becec`.
|
||||
This demo was last tested on 2026-01-10 against `ch` commit `792ee76`.
|
||||
|
||||
:::
|
||||
|
||||
@ -627,18 +624,16 @@ or `ChakraCore\Build\VcBuild\bin\x64_debug\` on x64 Windows.
|
||||
|
||||
:::
|
||||
|
||||
1) Download the SheetJS Standalone script, shim script and test file. Move all
|
||||
three files to the project directory:
|
||||
1) Download the SheetJS Standalone script and test file. Move all three files to
|
||||
the project directory:
|
||||
|
||||
<ul>
|
||||
<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://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
|
||||
<li><a href="https://docs.sheetjs.com/pres.numbers">pres.numbers</a></li>
|
||||
</ul>
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl -L -O https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -L -O https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
|
||||
curl -L -O https://docs.sheetjs.com/pres.numbers`}
|
||||
</CodeBlock>
|
||||
|
||||
@ -687,6 +682,16 @@ On Windows, the command should be run in WSL.
|
||||
./ch xlsx.chakra.js
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
The "Integration Example" stores `ch` in the `ChakraCore/out/Test/` folder:
|
||||
|
||||
```bash
|
||||
./ChakraCore/out/Test/ch xlsx.chakra.js
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
|
||||
@ -82,7 +82,8 @@ Boa supports `ArrayBuffer` natively. This snippet reads data from a file into
|
||||
```rust
|
||||
/* read file */
|
||||
let data: Vec<u8> = std::fs::read("pres.xlsx").unwrap();
|
||||
let array: boa_engine::object::builtins::JsArrayBuffer = boa_engine::object::builtins::JsArrayBuffer::from_byte_block(file, context).unwrap();
|
||||
let aligned = boa_engine::object::builtins::AlignedVec::from_iter(0, file.into_iter());
|
||||
let array: boa_engine::object::builtins::JsArrayBuffer = boa_engine::object::builtins::JsArrayBuffer::from_byte_block(aligned, context).unwrap();
|
||||
let attrs = boa_engine::property::Attribute::WRITABLE | boa_engine::property::Attribute::ENUMERABLE | boa_engine::property::Attribute::CONFIGURABLE;
|
||||
let _ = context.register_global_property(boa_engine::js_string!("buf"), array, attrs);
|
||||
|
||||
@ -104,12 +105,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Boa | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `0.20.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `0.20.0` | 2025-09-03 |
|
||||
| `darwin-x64` | `0.20.1` | 2026-01-21 |
|
||||
| `darwin-arm` | `0.21.0` | 2026-03-07 |
|
||||
| `win11-x64` | `0.20.0` | 2025-04-28 |
|
||||
| `win11-arm` | `0.20.0` | 2025-02-23 |
|
||||
| `linux-x64` | `0.20.0` | 2025-04-21 |
|
||||
| `linux-arm` | `0.20.0` | 2025-02-15 |
|
||||
| `win11-arm` | `0.21.0` | 2026-03-22 |
|
||||
| `linux-x64` | `0.21.0` | 2026-01-08 |
|
||||
| `linux-arm` | `0.21.0` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -68,10 +68,12 @@ String.prototype.match = function(p) {
|
||||
|
||||
When loading the ExtendScript build, the BOM must be removed:
|
||||
|
||||
```perl
|
||||
```perl title="Remove BOM from the SheetJS ExtendScript build and evaluate"
|
||||
## Load SheetJS source
|
||||
my $src = read_file('xlsx.extendscript.js', { binmode => ':raw' });
|
||||
$src =~ s/^\xEF\xBB\xBF//; ## remove UTF8 BOM
|
||||
|
||||
## evaluate the updated source
|
||||
my $XLSX = $je->eval($src);
|
||||
```
|
||||
|
||||
@ -79,7 +81,7 @@ my $XLSX = $je->eval($src);
|
||||
|
||||
Data should be passed as Base64 strings:
|
||||
|
||||
```perl
|
||||
```perl title="Read spreadsheet file in Perl and parse with SheetJS"
|
||||
use File::Slurp;
|
||||
use MIME::Base64 qw( encode_base64 );
|
||||
|
||||
@ -102,7 +104,7 @@ $return_val = $je->method(sheetjsparse => $raw_data);
|
||||
Due to bugs in data interchange, it is strongly recommended to use a simple
|
||||
format like `.fods`:
|
||||
|
||||
```perl
|
||||
```perl title="Generate FODS with SheetJS and write to file in Perl"
|
||||
use File::Slurp;
|
||||
|
||||
## Set up conversion method
|
||||
@ -127,10 +129,14 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `0.066` | 2025-03-31 |
|
||||
| `darwin-arm` | `0.066` | 2025-09-03 |
|
||||
| `linux-x64` | `0.066` | 2025-06-16 |
|
||||
| `linux-arm` | `0.066` | 2025-02-15 |
|
||||
| `darwin-x64` | `0.066` | 2026-01-21 |
|
||||
| `darwin-arm` | `0.066` | 2026-03-07 |
|
||||
| `win11-x64` | `0.066` | 2026-01-10 |
|
||||
| `win11-arm` | `0.066` | 2026-01-10 |
|
||||
| `linux-x64` | `0.066` | 2026-03-07 |
|
||||
| `linux-arm` | `0.066` | 2026-03-07 |
|
||||
|
||||
The Windows tests were run in WSL.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -36,12 +36,12 @@ This demo was tested in the following environments:
|
||||
|
||||
| Architecture | Commit | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `5020015` | 2025-03-31 |
|
||||
| `darwin-arm` | `355ab24` | 2025-09-03 |
|
||||
| `darwin-x64` | `b706935` | 2026-01-21 |
|
||||
| `darwin-arm` | `b706935` | 2026-03-07 |
|
||||
| `win11-x64` | `5020015` | 2025-04-23 |
|
||||
| `win11-arm` | `5020015` | 2025-02-23 |
|
||||
| `linux-x64` | `5020015` | 2025-04-21 |
|
||||
| `linux-arm` | `5020015` | 2025-02-15 |
|
||||
| `linux-x64` | `b706935` | 2026-03-07 |
|
||||
| `linux-arm` | `b706935` | 2026-03-07 |
|
||||
|
||||
The Windows tests were run in WSL.
|
||||
|
||||
@ -52,7 +52,7 @@ The Windows tests were run in WSL.
|
||||
:::info pass
|
||||
|
||||
The official JerryScript documentation and examples are out of date. This
|
||||
explanation was verified against the latest release (commit `5020015`).
|
||||
explanation was verified against the latest release (commit `b706935`).
|
||||
|
||||
:::
|
||||
|
||||
@ -366,6 +366,18 @@ python3 tools/build.py --error-messages=ON --logging=ON --mem-heap=8192 --cpoint
|
||||
cd ..
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
In some tests, the build step failed with compiler warnings treated as errors.
|
||||
The flags `-Wno-error` and `-Wno-unterminated-string-initialization` should be
|
||||
added to the build:
|
||||
|
||||
```bash
|
||||
python3 tools/build.py --error-messages=ON --logging=ON --mem-heap=8192 --cpointer-32bit=ON --compile-flag="-Wno-error" --compile-flag="-Wno-unterminated-string-initialization"
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
3) Download the SheetJS Standalone script, shim script and test file. Move all
|
||||
three files to the `SheetJSJerry` directory:
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ as [Duktape](/docs/demos/engines/duktape).
|
||||
:::info pass
|
||||
|
||||
Many MuJS functions are not documented. The explanation was verified against
|
||||
version `1.3.6`.
|
||||
version `1.3.8`.
|
||||
|
||||
:::
|
||||
|
||||
@ -322,12 +322,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Version | Date |
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `1.3.6` | 2025-03-31 |
|
||||
| `darwin-arm` | `1.3.6` | 2025-09-03 |
|
||||
| `win11-x64` | `1.3.6` | 2025-04-23 |
|
||||
| `darwin-x64` | `1.3.8` | 2026-01-20 |
|
||||
| `darwin-arm` | `1.3.8` | 2026-01-20 |
|
||||
| `win11-x64` | `1.3.8` | 2026-03-08 |
|
||||
| `win11-arm` | `1.3.5` | 2025-02-23 |
|
||||
| `linux-x64` | `1.3.6` | 2025-06-16 |
|
||||
| `linux-arm` | `1.3.5` | 2025-02-15 |
|
||||
| `linux-x64` | `1.3.8` | 2026-03-07 |
|
||||
| `linux-arm` | `1.3.8` | 2026-01-10 |
|
||||
|
||||
:::
|
||||
|
||||
@ -355,9 +355,9 @@ cd sheetjs-mu
|
||||
2) Build the MuJS shared library from source:
|
||||
|
||||
```bash
|
||||
curl -LO https://mujs.com/downloads/mujs-1.3.6.zip
|
||||
unzip mujs-1.3.6.zip
|
||||
cd mujs-1.3.6
|
||||
curl -LO https://mujs.com/downloads/mujs-1.3.8.zip
|
||||
unzip mujs-1.3.8.zip
|
||||
cd mujs-1.3.8
|
||||
make release
|
||||
cd ..
|
||||
```
|
||||
@ -365,7 +365,7 @@ cd ..
|
||||
3) Copy the `mujs.h` header file and `libmujs.a` library to the project folder:
|
||||
|
||||
```bash
|
||||
cp mujs-1.3.6/build/release/libmujs.a mujs-1.3.6/mujs.h .
|
||||
cp mujs-1.3.8/build/release/libmujs.a mujs-1.3.8/mujs.h .
|
||||
```
|
||||
|
||||
4) Download [`SheetJSMu.c`](pathname:///mujs/SheetJSMu.c):
|
||||
|
||||
@ -176,12 +176,12 @@ This demo was tested in the following deployments:
|
||||
|
||||
| Architecture | Jurassic | Date |
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `3.2.9` | 2025-03-31 |
|
||||
| `darwin-arm` | `3.2.9` | 2025-09-03 |
|
||||
| `darwin-x64` | `3.2.9` | 2026-01-21 |
|
||||
| `darwin-arm` | `3.2.9` | 2026-03-07 |
|
||||
| `win11-x64` | `3.2.9` | 2025-04-23 |
|
||||
| `win11-arm` | `3.2.9` | 2025-02-23 |
|
||||
| `linux-x64` | `3.2.9` | 2025-06-16 |
|
||||
| `linux-arm` | `3.2.9` | 2025-02-15 |
|
||||
| `win11-arm` | `3.2.9` | 2026-03-22 |
|
||||
| `linux-x64` | `3.2.9` | 2026-03-07 |
|
||||
| `linux-arm` | `3.2.9` | 2026-03-07 |
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -100,6 +100,9 @@ Asterisks (✱) in the Windows columns mark tests that were run in Windows
|
||||
Subsystem for Linux (WSL). In some cases, community efforts have produced forks
|
||||
with native Windows support.
|
||||
|
||||
Crosses (✘) mark tests for Windows on ARM that use the X64 compatibility layer.
|
||||
Proper Windows x64 binaries were cross-compiled and run in Windows on ARM.
|
||||
|
||||
Blank cells mark untested or unsupported configurations. With cross-compilation,
|
||||
V8 can run natively in Windows on ARM. The `win11-arm` platform is not tested
|
||||
since the official build infrastructure does not support Windows on ARM and the
|
||||
|
||||
@ -8,6 +8,23 @@ hide_table_of_contents: true
|
||||
Demos include complete examples and short discussions. For features that can
|
||||
run in the web browser, demos will include interactive examples.
|
||||
|
||||
:::info pass
|
||||
|
||||
**These demos were tested or verified by SheetJS teammates!**
|
||||
|
||||
Many demos were borne from requests by [SheetJS Pro](https://sheetjs.com/pro)
|
||||
customers and written based on experience from interactive debugging sessions.
|
||||
|
||||
When possible, SheetJS teammates test demos on local infrastructure. Some cloud
|
||||
service tests were verified in screen-share sessions.
|
||||
|
||||
The web ecosystem moves fast and break things. Demos that worked a week ago may
|
||||
not work today if a dependency makes a breaking change. Please leave a note in
|
||||
the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues) if
|
||||
a demo does not currently work.
|
||||
|
||||
:::
|
||||
|
||||
:::tip pass
|
||||
|
||||
If a demo for a library or framework is not included here, please leave a note
|
||||
|
||||
@ -29,7 +29,6 @@ var workbook = XLSX.read(data, opts);
|
||||
The `read` method can extract data from spreadsheet bytes stored in a JS string,
|
||||
"binary string", NodeJS buffer or typed array (`Uint8Array` or `ArrayBuffer`).
|
||||
|
||||
|
||||
_Read spreadsheet bytes from a local file and extract data_
|
||||
|
||||
```js
|
||||
@ -38,8 +37,8 @@ var workbook = XLSX.readFile(filename, opts);
|
||||
|
||||
The `readFile` method attempts to read a spreadsheet file at the supplied path.
|
||||
|
||||
The second `opts` argument is optional. ["Parsing Options"](/docs/api/parse-options)
|
||||
covers the supported properties and behaviors.
|
||||
The ["Reading Files"](/docs/api/parse-options) section covers the supported
|
||||
properties and behaviors.
|
||||
|
||||
:::danger pass
|
||||
|
||||
@ -48,7 +47,6 @@ security risk), and running `XLSX.readFile` in the browser will throw an error.
|
||||
|
||||
Deno scripts must be invoked with `--allow-read` to read from the filesystem.
|
||||
|
||||
|
||||
:::
|
||||
|
||||
#### Examples
|
||||
@ -165,7 +163,6 @@ const workbook = read(Buffer.from(readFileSync(path)));
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Example: User Submissions
|
||||
|
||||
This example focuses on user-submitted files through a drag-and-drop event, HTML
|
||||
@ -188,7 +185,6 @@ Assume `drop_dom_element` is the DOM element that will listen for changes:
|
||||
The event property is `e.dataTransfer`. The code snippet highlights the
|
||||
difference between the drag-and-drop example and the file input example:
|
||||
|
||||
|
||||
```js
|
||||
// XLSX is a global from the standalone script
|
||||
|
||||
@ -238,7 +234,6 @@ input_dom_element.addEventListener("change", handleFileAsync, false);
|
||||
|
||||
https://oss.sheetjs.com/sheetjs/ demonstrates the FileReader technique.
|
||||
|
||||
|
||||
**For maximal compatibility (IE10+)**, the `FileReader` approach is recommended:
|
||||
|
||||
<Tabs>
|
||||
@ -387,11 +382,9 @@ curl -X POST -F "file=@test.xlsx" http://localhost:7262/
|
||||
|
||||
:::
|
||||
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Example: Remote File
|
||||
|
||||
This example focuses on fetching files ("Ajax" in browser parlance) using APIs
|
||||
@ -587,7 +580,6 @@ other tools.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="browser" label="Browser">
|
||||
|
||||
@ -731,7 +723,6 @@ var worksheet = XLSX.utils.aoa_to_sheet([
|
||||
["Array of Arrays Input"](/docs/api/utilities/array#array-of-arrays-input) describes
|
||||
the function and the optional `opts` argument in more detail.
|
||||
|
||||
|
||||
_Create a worksheet from an array of JS objects_
|
||||
|
||||
```js
|
||||
@ -765,7 +756,6 @@ databases and query results.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
## Processing HTML Tables
|
||||
|
||||
#### API
|
||||
@ -781,8 +771,6 @@ through the rows to generate a worksheet. The `opts` argument is optional.
|
||||
["HTML Table Input"](/docs/api/utilities/html#html-table-input) describes the
|
||||
function in more detail.
|
||||
|
||||
|
||||
|
||||
_Create a workbook by scraping an HTML TABLE in the page_
|
||||
|
||||
```js
|
||||
|
||||
@ -33,110 +33,34 @@ to mark a dynamic array formula in the XLS file format.
|
||||
SheetJS supports reading and writing formulae for a number of file formats. When
|
||||
supported, formulae will always be exported.
|
||||
|
||||
By default, formulae are not always imported. To ensure formula parsing, the
|
||||
option `cellFormula: true` should be passed to the parser.
|
||||
The ["A1-Style"](/docs/csf/general#a1-style) formula string is stored in the `f`
|
||||
field of the cell object. The SheetJS formula string closely matches the text
|
||||
representation in spreadsheet file formats.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="browser" label="Browser">
|
||||
:::caution pass
|
||||
|
||||
Typically file data will be available as an `ArrayBuffer`, either downloaded
|
||||
with `fetch` / `XMLHttpRequest` or user-submitted with a File Input element.
|
||||
`cellFormula: true` should be added to the second options argument:
|
||||
**SheetJS formula strings do not always match Excel or other spreadsheets!**
|
||||
|
||||
```js
|
||||
/* using read in the browser, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
- Spreadsheet software typically represent formulae with a leading `=` sign, but
|
||||
SheetJS formulae omit the `=`.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nodejs" label="NodeJS">
|
||||
- Spreadsheet software [localize formulae](#localization), but SheetJS formulae
|
||||
always use the `en-US` form.
|
||||
|
||||
Typically file data will be available as a `Buffer` from a network request / API
|
||||
or stored in the file system. `cellFormula: true` should be added to the second
|
||||
options argument to `read` or `readFile`:
|
||||
- Spreadsheet software may display formulae in RC notation, but SheetJS formulae
|
||||
always use A1-Style.
|
||||
|
||||
**`XLSX.read`**
|
||||
- Spreadsheet software will hide [prefixes](#prefixed-future-functions). SheetJS
|
||||
parsers provide options to replicate that behavior.
|
||||
|
||||
```js
|
||||
/* using read in NodeJS, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
When building new exports, it is strongly recommended to create a sample file in
|
||||
Excel, parse with the SheetJS library, and inspect the formula string.
|
||||
|
||||
**`XLSX.readFile`**
|
||||
:::
|
||||
|
||||
```js
|
||||
/* using readFile in NodeJS, add `cellFormula` to the second argument */
|
||||
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
|
||||
// -------------------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
## Live Demo
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="bun" label="Bun">
|
||||
|
||||
Typically file data will be available as a `Uint8Array` from a network request
|
||||
or stored in the file system. `cellFormula: true` should be set in the options
|
||||
argument to `read` or `readFile`:
|
||||
|
||||
**`XLSX.read`**
|
||||
|
||||
```js
|
||||
/* using read in Bun, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
**`XLSX.readFile`**
|
||||
|
||||
```js
|
||||
/* using readFile in Bun, add `cellFormula` to the second argument */
|
||||
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
|
||||
// -------------------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="deno" label="Deno">
|
||||
|
||||
Typically file data will be available as a `Uint8Array` or `ArrayBuffer` from
|
||||
API or stored in the file system. `cellFormula: true` should be set in the
|
||||
options argument to `read` or `readFile`:
|
||||
|
||||
**`XLSX.read`**
|
||||
|
||||
```js
|
||||
/* using read in Deno, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
**`XLSX.readFile`**
|
||||
|
||||
```js
|
||||
/* using readFile in Deno, add `cellFormula` to the second argument */
|
||||
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
|
||||
// -------------------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## A1-Style Formulae
|
||||
|
||||
The A1-Style formula string is stored in the `f` field of the cell object.
|
||||
Spreadsheet software typically represent formulae with a leading `=` sign, but
|
||||
SheetJS formulae omit the `=`.
|
||||
|
||||
["A1-Style"](/docs/csf/general#a1-style) describes A1-Style in more detail.
|
||||
|
||||
<details open>
|
||||
<summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
For example, consider [this test file](pathname:///files/concat.xlsx):
|
||||
[This test file](pathname:///files/concat.xlsx) includes a formula in cell `D1`:
|
||||
|
||||

|
||||
|
||||
@ -144,7 +68,7 @@ The following code block fetches the file, parses and prints info on cell `D1`:
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ConcatFormula(props) {
|
||||
function InspectCellFormula(props) {
|
||||
const [ws, setWS] = React.useState({"!ref":"A1"});
|
||||
const [addr, setAddr] = React.useState("D1");
|
||||
const setaddr = React.useCallback((evt)=>{ setAddr(evt.target.value) });
|
||||
@ -163,7 +87,8 @@ function ConcatFormula(props) {
|
||||
process_ab(await e.target.files[0].arrayBuffer());
|
||||
};
|
||||
return ( <>
|
||||
<input type="file" onChange={process_file}/><br/>
|
||||
<b>Select a file to inspect cell formulae</b><br/>
|
||||
<input type="file" onChange={process_file}/><br/><br/>
|
||||
<b>Cell: </b><input type="text" value={addr} onChange={setaddr} size="6"/>
|
||||
{!ws[addr] ? ( <b>Cell {addr} not found</b> ) : ( <table>
|
||||
<tr><td>Formula</td><td><code>{ws[addr].f}</code></td></tr>
|
||||
@ -174,9 +99,9 @@ function ConcatFormula(props) {
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
## Storage
|
||||
|
||||
## Single-Cell Formulae
|
||||
### Single-Cell Formulae
|
||||
|
||||
For simple formulae, the `f` key of the desired cell can be set to the actual
|
||||
formula text. This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`:
|
||||
@ -250,7 +175,7 @@ values and dependent cells, and refreshing entire workbooks.
|
||||
|
||||
:::
|
||||
|
||||
## Array Formulae
|
||||
### Array Formulae
|
||||
|
||||
_Assign an array formula_
|
||||
|
||||
@ -393,20 +318,129 @@ function ExportDynamicArrayFormulae(props) {
|
||||
|
||||
</details>
|
||||
|
||||
## Functions
|
||||
|
||||
#### Reading Files
|
||||
|
||||
[`read` and `readFile`](/docs/api/parse-options) accept an options argument. The
|
||||
`cellFormula` option should be set to `true` to expose cell formulae:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="browser" label="Browser">
|
||||
|
||||
Typically file data will be available as an `ArrayBuffer`, either downloaded
|
||||
with `fetch` / `XMLHttpRequest` or user-submitted with a File Input element.
|
||||
`cellFormula: true` should be added to the second options argument:
|
||||
|
||||
```js
|
||||
/* using read in the browser, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nodejs" label="NodeJS">
|
||||
|
||||
Typically file data will be available as a `Buffer` from a network request / API
|
||||
or stored in the file system. `cellFormula: true` should be added to the second
|
||||
options argument to `read` or `readFile`:
|
||||
|
||||
**`XLSX.read`**
|
||||
|
||||
```js
|
||||
/* using read in NodeJS, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
**`XLSX.readFile`**
|
||||
|
||||
```js
|
||||
/* using readFile in NodeJS, add `cellFormula` to the second argument */
|
||||
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
|
||||
// -------------------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="bun" label="Bun">
|
||||
|
||||
Typically file data will be available as a `Uint8Array` from a network request
|
||||
or stored in the file system. `cellFormula: true` should be set in the options
|
||||
argument to `read` or `readFile`:
|
||||
|
||||
**`XLSX.read`**
|
||||
|
||||
```js
|
||||
/* using read in Bun, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
**`XLSX.readFile`**
|
||||
|
||||
```js
|
||||
/* using readFile in Bun, add `cellFormula` to the second argument */
|
||||
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
|
||||
// -------------------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="deno" label="Deno">
|
||||
|
||||
Typically file data will be available as a `Uint8Array` or `ArrayBuffer` from
|
||||
API or stored in the file system. `cellFormula: true` should be set in the
|
||||
options argument to `read` or `readFile`:
|
||||
|
||||
**`XLSX.read`**
|
||||
|
||||
```js
|
||||
/* using read in Deno, `cellFormula` is in the second argument */
|
||||
const ab = await (await fetch("test.xlsx")).arrayBuffer();
|
||||
const workbook = XLSX.read(ab, { cellFormula: true });
|
||||
// ------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
**`XLSX.readFile`**
|
||||
|
||||
```js
|
||||
/* using readFile in Deno, add `cellFormula` to the second argument */
|
||||
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
|
||||
// -------------------------------------------^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Localization
|
||||
|
||||
SheetJS operates at the file level. Excel stores formula expressions using the
|
||||
English (United States) function names. For non-English users, Excel uses a
|
||||
localized set of function names.
|
||||
Excel and other spreadsheet software will display different formula strings in
|
||||
different countries and locales.
|
||||
|
||||
SheetJS parsers and writers do not attempt locale-specific changes.
|
||||
|
||||
For example, the Spanish Excel formula `=CONTAR(A1:C3;B4:D6)` is equivalent to
|
||||
the SheetJS formula string `COUNT(A1:A3,B4:D6)` .
|
||||
|
||||
### Grammar
|
||||
|
||||
SheetJS formula function arguments are always separated with commas (`,`).
|
||||
|
||||
| SheetJS | `en-US` Excel | `es-ES` Excel |
|
||||
|:-------------|:--------------|:--------------|
|
||||
| `ATAN2(1,1)` | `=ATAN2(1,1)` | `=ATAN2(1;1)` |
|
||||
|
||||
### Function Names
|
||||
|
||||
Excel stores formula expressions using the English (United States) function
|
||||
names. For non-English users, Excel uses a localized set of function names.
|
||||
|
||||
For example, when the computer language and region is set to Spanish, Excel
|
||||
interprets `=CONTAR(A1:C3)` as if `CONTAR` is the `COUNT` function. However,
|
||||
in the actual file, Excel stores `COUNT(A1:C3)`.
|
||||
|
||||
Function arguments are separated with commas. For example, the Spanish Excel
|
||||
formula `=CONTAR(A1:C3;B4:D6)` is equivalent to the SheetJS formula string
|
||||
`COUNT(A1:A3,B4:D6)`
|
||||
|
||||
[JSON Translation table](https://docs.sheetjs.com/fmla/table.json).
|
||||
|
||||
<details open>
|
||||
|
||||
@ -4,6 +4,9 @@ sidebar_label: Cell Comments
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<details>
|
||||
<summary><b>File Format Support</b> (click to show)</summary>
|
||||
|
||||
@ -34,7 +37,7 @@ support Excel styled comments or Excel legacy notes.
|
||||
|
||||
The letter R (R) marks features parsed but not written in the format.
|
||||
|
||||
:::note pass
|
||||
:::tip pass
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) supports comment rich text and styling.
|
||||
|
||||
@ -43,25 +46,66 @@ The letter R (R) marks features parsed but not written in the format.
|
||||
</details>
|
||||
|
||||
Comments and notes are cell annotations. Cells with comments or notes are marked
|
||||
with a small triangle or `¬` in the upper-right corner.
|
||||
with `◥` or `¬` in the upper-right corner.
|
||||
|
||||
Excel notes are standalone text boxes with adjustable background colors and
|
||||
support for rich text. Historically people "replied" to comments by adding text
|
||||
to the end of existing comments.
|
||||
|
||||
Excel comments are simple text boxes that allow users to enter plain text. Users
|
||||
can reply to comments.
|
||||
can reply to comments. The replies are typically shown in a vertical stack.
|
||||
|
||||
The following screenshot shows a spreadsheet with comments and a note.
|
||||
#### Live Example
|
||||
|
||||
The following live example shows a spreadsheet with comments and a note.
|
||||
|
||||
- The note is associated with cell A1 (the cell with the red triangle). It has
|
||||
a green gradient background fill.
|
||||
- The comments are associated with cell A2 (the cell with the blue `¬`). There
|
||||
are 2 comments from different authors. A "Reply" box appears below the thread.
|
||||
|
||||
:::caution pass
|
||||
|
||||
Excel for Mac and other software that lack full support for threaded comments
|
||||
will show a fallback note that includes each reply on a separate line.
|
||||
|
||||
:::
|
||||
|
||||

|
||||
|
||||
:::info pass
|
||||
<details open>
|
||||
<summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
```jsx live
|
||||
function SheetJSThreadedComments() {
|
||||
return ( <button onClick={() => {
|
||||
var ws = XLSX.utils.aoa_to_sheet([["SheetJS"], [5433795]], {dense: true});
|
||||
var cell_A1 = (ws["!data"][0]??=[])[0]??={t:"z"}; // Cell A1
|
||||
var cell_A2 = (ws["!data"][1]??=[])[0]??={t:"z"}; // Cell A2
|
||||
|
||||
/* normal comment in cell A1 */
|
||||
cell_A1.c ??= [];
|
||||
cell_A1.c.push({a:"SheetJS", t:"This is not threaded"});
|
||||
|
||||
/* threaded comment in cell A2 */
|
||||
cell_A2.c ??= [];
|
||||
|
||||
/* add parts */
|
||||
cell_A2.c.push({a:"SheetJS", t:"This is threaded", T: true});
|
||||
|
||||
var part = {a:"JSSheet", t:"This is also threaded"};
|
||||
cell_A2.c.push({...part, T: true});
|
||||
|
||||
/* create workbook and export */
|
||||
var wb = XLSX.utils.book_new(ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSThreadedComments.xlsx");
|
||||
}}>Click me to generate a sample file</button> );
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
:::info Application Support
|
||||
|
||||
Google Sheets "notes" do not currently support rich text or background colors.
|
||||
|
||||
@ -71,19 +115,18 @@ Apple Numbers supports "comments" but does not support "notes".
|
||||
|
||||
## Basic Structure
|
||||
|
||||
Cell comments are objects stored in the `c` array of cell objects.
|
||||
|
||||
The comment content is split into parts based on the comment author.
|
||||
|
||||
The `a` field of each comment part is the author of the comment and the `t`
|
||||
field is the plain text representation.
|
||||
Cell comments are stored in the `c` property of cell objects. They are expected
|
||||
to be arrays of fragments objects that include text and metadata.
|
||||
|
||||
For example, the following snippet appends a cell comment into cell `A1`:
|
||||
|
||||
```js
|
||||
<Tabs groupId="sheetrep">
|
||||
<TabItem value="sparse" label="Sparse Sheets">
|
||||
|
||||
```js title="Add cell comment to cell A1 in a sparse worksheet"
|
||||
/* get cell A1, creating an empty cell if necessary */
|
||||
var cell = ws["A1"];
|
||||
if(!ws["A1"]) ws["A1"] = { t: "z" };
|
||||
if(!cell) cell = ws["A1"] = { t: "z" };
|
||||
|
||||
/* create comment array if it does not exist */
|
||||
if(!cell.c) cell.c = [];
|
||||
@ -98,6 +141,78 @@ var comment_part = {
|
||||
cell.c.push(comment_part);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="dense" label="Dense Sheets">
|
||||
|
||||
:::info pass
|
||||
|
||||
[`read`](/docs/api/parse-options), [`aoa_to_sheet`](/docs/api/utilities/array),
|
||||
and other SheetJS methods will generate sparse worksheets by default.
|
||||
|
||||
[Dense mode worksheets](/docs/csf/sheet#dense-mode) require explicit opt-in.
|
||||
|
||||
:::
|
||||
|
||||
```js title="Add cell comment to cell A1 in a dense worksheet"
|
||||
/* get cell A1, creating an empty cell if necessary */
|
||||
var row = ws["!data"][0];
|
||||
if(!row) row = ws["!data"][0] = [];
|
||||
var cell = row[0];
|
||||
if(!row[0]) cell = row[0] = { t: "z" };
|
||||
|
||||
/* create comment array if it does not exist */
|
||||
if(!cell.c) cell.c = [];
|
||||
|
||||
/* create a comment part */
|
||||
var comment_part = {
|
||||
a: "SheetJS",
|
||||
t: "I'm a little comment, short and stout!"
|
||||
};
|
||||
|
||||
/* Add comment part to the comment array */
|
||||
cell.c.push(comment_part);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Fragment Properties
|
||||
|
||||
Fragments support the following properties:
|
||||
|
||||
| Key | Description |
|
||||
|:----|:-------------------------------------------------------------------|
|
||||
| `t` | [Text](#fragment-text) |
|
||||
| `a` | [Author](#fragment-author) |
|
||||
| `T` | If true, fragment is a [threaded comment](#threaded-comments) part |
|
||||
|
||||
#### Fragment Text
|
||||
|
||||
Each fragment must include text.
|
||||
|
||||
Note and comment fragment texts are concatenated to form the full text.
|
||||
|
||||
[Threaded comment](#threaded-comments) fragments are visually distinct.
|
||||
|
||||
:::tip pass
|
||||
|
||||
SheetJS CE supports plaintext comments.
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) supports comment styling and rich text.
|
||||
|
||||
Google Sheets and Excel threaded comments currently do not support styling.
|
||||
|
||||
:::
|
||||
|
||||
#### Fragment Author
|
||||
|
||||
The fragment author is optional.
|
||||
|
||||
Note and comment fragment authors are not displayed in Excel.
|
||||
|
||||
[Threaded comment](#threaded-comments) fragment authors are displayed in the
|
||||
thread in Excel.
|
||||
|
||||
:::note XLSB Author limits
|
||||
|
||||
XLSB enforces a 54 character limit on the Author name. Names longer than 54
|
||||
@ -105,6 +220,46 @@ characters may cause issues with other formats.
|
||||
|
||||
:::
|
||||
|
||||
### Comment Properties
|
||||
|
||||
#### Visibility
|
||||
|
||||
The `hidden` property of the comment block indicates comment visibility. If set
|
||||
to `true`, the comment will not be visible until users hover over the comment.
|
||||
|
||||
```js title="Mark a cell comment as hidden"
|
||||
if(!cell.c) cell.c = [];
|
||||
// highlight-next-line
|
||||
cell.c.hidden = true;
|
||||
cell.c.push({a:"SheetJS", t:"This comment will be hidden"});
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Live Example</b> (click to show)</summary>
|
||||
|
||||
The following demo creates a worksheet with two comments. The comment in cell A1
|
||||
will be visibile and the comment in cell A2 will be hidden.
|
||||
|
||||
```jsx live
|
||||
function SheetJSComments2() {
|
||||
return (<button onClick={() => {
|
||||
var ws = XLSX.utils.aoa_to_sheet([["SheetJS"], [5433795]]);
|
||||
|
||||
if(!ws.A1.c) ws.A1.c = [];
|
||||
ws.A1.c.push({a:"SheetJS", t:"This comment is visible"});
|
||||
|
||||
if(!ws.A2.c) ws.A2.c = [];
|
||||
ws.A2.c.hidden = true;
|
||||
ws.A2.c.push({a:"SheetJS", t:"This comment will be hidden"});
|
||||
|
||||
var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSComments2.xlsx");
|
||||
}}>Click me to generate a sample file</button>);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Demos
|
||||
|
||||
#### Export
|
||||
@ -172,44 +327,6 @@ function SheetJSParseComments(props) {
|
||||
|
||||
</details>
|
||||
|
||||
## Visibility
|
||||
|
||||
The `hidden` property of the comment block indicates comment visibility. If set
|
||||
to `true`, the comment will not be visible until users hover over the comment.
|
||||
|
||||
```js
|
||||
if(!cell.c) cell.c = [];
|
||||
// highlight-next-line
|
||||
cell.c.hidden = true;
|
||||
cell.c.push({a:"SheetJS", t:"This comment will be hidden"});
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Live Example</b> (click to show)</summary>
|
||||
|
||||
The following demo creates a worksheet with two comments. The comment in cell A1
|
||||
will be visibile and the comment in cell A2 will be hidden.
|
||||
|
||||
```jsx live
|
||||
function SheetJSComments2() {
|
||||
return (<button onClick={() => {
|
||||
var ws = XLSX.utils.aoa_to_sheet([["SheetJS"], [5433795]]);
|
||||
|
||||
if(!ws.A1.c) ws.A1.c = [];
|
||||
ws.A1.c.push({a:"SheetJS", t:"This comment is visible"});
|
||||
|
||||
if(!ws.A2.c) ws.A2.c = [];
|
||||
ws.A2.c.hidden = true;
|
||||
ws.A2.c.push({a:"SheetJS", t:"This comment will be hidden"});
|
||||
|
||||
var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSComments2.xlsx");
|
||||
}}>Click me to generate a sample file</button>);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Threaded Comments
|
||||
|
||||
Threaded comments are plain text comment snippets with author metadata and
|
||||
@ -217,7 +334,7 @@ parent references. They are supported in XLSX, XLSB, and NUMBERS files.
|
||||
|
||||
To mark a comment as threaded, each comment part must have a true `T` property:
|
||||
|
||||
```js
|
||||
```js title="Create a threaded comment with a reply"
|
||||
if(!cell.c) cell.c = [];
|
||||
|
||||
var part1 = {
|
||||
@ -237,34 +354,8 @@ var part2 = {
|
||||
cell.c.push({ ...part2, T: true});
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
There is no Active Directory or Office 365 metadata associated with authors.
|
||||
|
||||
<details open>
|
||||
<summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
```jsx live
|
||||
function SheetJSThreadedComments() {
|
||||
return ( <button onClick={() => {
|
||||
var ws = XLSX.utils.aoa_to_sheet([["SheetJS"], [5433795]]);
|
||||
|
||||
/* normal comment */
|
||||
if(!ws.A1.c) ws.A1.c = [];
|
||||
ws.A1.c.push({a:"SheetJS", t:"This is not threaded"});
|
||||
|
||||
/* threaded comment */
|
||||
if(!ws.A2.c) ws.A2.c = [];
|
||||
|
||||
/* add parts */
|
||||
ws.A2.c.push({a:"SheetJS", t:"This is threaded", T: true});
|
||||
|
||||
var part = {a:"JSSheet", t:"This is also threaded"};
|
||||
ws.A2.c.push({...part, T: true});
|
||||
|
||||
/* create workbook and export */
|
||||
var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSThreadedComments.xlsx");
|
||||
}}>Click me to generate a sample file</button> );
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
:::
|
||||
|
||||
@ -15,31 +15,31 @@ is stored as the formatted value. The formatted values can be generated from
|
||||
many different values and number formats. SheetJS parsers expose options to
|
||||
control value parsing and number format speculation.
|
||||
|
||||
| Formats | Basic | Storage Representation |
|
||||
|:------------------|:-----:|:-----------------------|
|
||||
| XLSX / XLSM | ✔ | Number Format Code |
|
||||
| XLSB | ✔ | Number Format Code |
|
||||
| XLS | ✔ | Number Format Code |
|
||||
| XLML | ✔ | Number Format Code |
|
||||
| SYLK | R | Number Format Code |
|
||||
| ODS / FODS / UOS | ✔ | XML Tokens |
|
||||
| NUMBERS | | Binary encoding |
|
||||
| WK1 | + | Fixed set of formats |
|
||||
| WK3 / WK4 | | Binary encoding |
|
||||
| WKS Lotus | + | Fixed set of formats |
|
||||
| WKS Works | + | Fixed set of formats |
|
||||
| WQ1 | + | Fixed set of formats |
|
||||
| WQ2 | | Binary encoding |
|
||||
| WB1 / WB2 / WB3 | | Binary encoding |
|
||||
| QPW | + | Binary encoding |
|
||||
| DBF | | Implied by field types |
|
||||
| HTML | ! | Special override |
|
||||
| CSV | * | N/A |
|
||||
| PRN | * | N/A |
|
||||
| DIF | * | N/A |
|
||||
| RTF | * | N/A |
|
||||
| Formats | Basic | Storage Representation |
|
||||
|:------------------|:-----:|:--------------------------|
|
||||
| XLSX / XLSM | ✔ | Number Format Code |
|
||||
| XLSB | ✔ | Number Format Code |
|
||||
| XLS | ✔ | Number Format Code |
|
||||
| XLML | ✔ | Number Format Code |
|
||||
| SYLK | R | Number Format Code |
|
||||
| ODS / FODS / UOS | ✔ | XML Tokens |
|
||||
| NUMBERS | | Binary encoding |
|
||||
| WK1 | + | Fixed set of formats |
|
||||
| WK3 / WK4 | | Binary encoding |
|
||||
| WKS Lotus | + | Fixed set of formats |
|
||||
| WKS Works | + | Fixed set of formats |
|
||||
| WQ1 | + | Fixed set of formats |
|
||||
| WQ2 | | Binary encoding |
|
||||
| WB1 / WB2 / WB3 | | Binary encoding |
|
||||
| QPW | + | Binary encoding |
|
||||
| DBF | | Inferred from field types |
|
||||
| HTML | ! | Special override |
|
||||
| CSV | * | N/A |
|
||||
| PRN | * | N/A |
|
||||
| DIF | * | N/A |
|
||||
| RTF | * | N/A |
|
||||
|
||||
(+) mark formats with limited support. The QPW (Quattro Pro Workbooks) parser
|
||||
Plus symbols (+) mark formats with limited support. The QPW (Quattro Pro) parser
|
||||
supports the built-in date and built-in time formats but does not support
|
||||
custom number formats. [Date and Time support](/docs/csf/features/dates) in
|
||||
modern Excel formats requires limited number format support to distinguish date
|
||||
|
||||
@ -5,7 +5,7 @@ hide_table_of_contents: true
|
||||
---
|
||||
|
||||
The main SheetJS method for reading files is `read`. It expects developers to
|
||||
supply the actual data in a supported representation.
|
||||
supply the actual data in a [supported representation](#input-type).
|
||||
|
||||
The `readFile` helper method accepts a filename and tries to read the specified
|
||||
file using standard APIs. *It does not work in web browsers!*
|
||||
@ -38,64 +38,130 @@ includes additional instructions for non-standard use cases.
|
||||
|
||||
:::
|
||||
|
||||
:::tip pass
|
||||
|
||||
The SheetJS file format import codecs focus on raw data. Not all codecs support
|
||||
all features. Features not described in the documentation may not be extracted.
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) offers support for additional features,
|
||||
including styling, images, graphs, and PivotTables.
|
||||
|
||||
:::
|
||||
|
||||
## Parsing Options
|
||||
|
||||
The read functions accept an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
|:------------|:--------|:-----------------------------------------------------|
|
||||
|`type` | | [Input data representation](#input-type) |
|
||||
|`raw` | `false` | If true, plain text parsing will not parse values ** |
|
||||
|`dense` | `false` | If true, use a [dense sheet representation](#dense) |
|
||||
|`codepage` | | If specified, use code page when appropriate ** |
|
||||
|`cellFormula`| `true` | Save [formulae to the `.f` field](#formulae) |
|
||||
|`cellHTML` | `true` | Parse rich text and save HTML to the `.h` field |
|
||||
|`cellNF` | `false` | Save number format string to the `.z` field |
|
||||
|`cellStyles` | `false` | Save style/theme info to the `.s` field |
|
||||
|`cellText` | `true` | Generated formatted text to the `.w` field |
|
||||
|`cellDates` | `false` | Store dates as type `d` (default is `n`) |
|
||||
|`dateNF` | | If specified, use the string for date code 14 ** |
|
||||
|`sheetStubs` | `false` | Create cell objects of type `z` for stub cells |
|
||||
|`sheetRows` | `0` | If >0, read the [specified number of rows](#range) |
|
||||
|`bookDeps` | `false` | If true, parse calculation chains |
|
||||
|`bookFiles` | `false` | If true, add raw files to book object ** |
|
||||
|`bookProps` | `false` | If true, only parse enough to get book metadata ** |
|
||||
|`bookSheets` | `false` | If true, only parse enough to get the sheet names |
|
||||
|`bookVBA` | `false` | If true, generate [VBA blob](#vba) |
|
||||
|`password` | `""` | If defined and file is encrypted, use password ** |
|
||||
|`WTF` | `false` | If true, throw errors on unexpected file features ** |
|
||||
|`sheets` | | If specified, only parse specified sheets ** |
|
||||
|`nodim` | `false` | If true, calculate [worksheet ranges](#range) |
|
||||
|`PRN` | `false` | If true, allow parsing of PRN files ** |
|
||||
|`xlfn` | `false` | If true, [preserve prefixes](#formulae) in formulae |
|
||||
|`FS` | | DSV Field Separator override |
|
||||
|`UTC` | `true` | If explicitly false, parse text dates in local time |
|
||||
| Option Name | Default | Description |
|
||||
|:--------------|:--------|:---------------------------------------------------|
|
||||
| `type` | | [Input data representation](#input-type) |
|
||||
| `raw` | `false` | Disable [value parsing in plaintext formats](#raw) |
|
||||
| `dense` | `false` | If true, [generate dense worksheets](#dense) |
|
||||
| `codepage` | | Use specified [code page encoding](#codepage) |
|
||||
| `cellFormula` | `true` | Save [formulae to the `f` field](#formulae) |
|
||||
| `cellHTML` | `true` | Parse text and [save HTML to the `h` field](#html) |
|
||||
| `cellNF` | `false` | Save [number format to the `z` field](#text) |
|
||||
| `cellStyles` | `false` | Save [style/theme info to the `s` field](#style) |
|
||||
| `cellText` | `true` | Save [formatted text to the `w` field](#text) |
|
||||
| `cellDates` | `false` | [Generate proper date (type `d`) cells](#dates) |
|
||||
| `dateNF` | | If specified, [override date code 14](#dates) |
|
||||
| `sheetStubs` | `false` | [Create cells of type `z` for stub cells](#stubs) |
|
||||
| `sheetRows` | `0` | If >0, read the [specified number of rows](#range) |
|
||||
| `bookDeps` | `false` | If true, parse calculation chains |
|
||||
| `bookFiles` | `false` | Add [raw files](#files) to book object |
|
||||
| `bookProps` | `false` | If true, [only parse book metadata](#metadata) |
|
||||
| `bookSheets` | `false` | If true, [only parse sheet names](#metadata) |
|
||||
| `bookVBA` | `false` | If true, generate [VBA blob](#vba) |
|
||||
| `password` | `""` | If specified, [decrypt workbook](#password) |
|
||||
| `WTF` | `false` | [Do not suppress worksheet parsing errors](#wtf) |
|
||||
| `sheets` | | Only parse [specified sheets](#sheets) |
|
||||
| `nodim` | `false` | If true, calculate [worksheet ranges](#range) |
|
||||
| `PRN` | `false` | If true, [allow parsing of PRN files](#prn) |
|
||||
| `xlfn` | `false` | Use [raw formula function names](#formulae) |
|
||||
| `FS` | | [DSV Field Separator override](#dsv) |
|
||||
| `UTC` | `true` | Parse [text dates and times using UTC](#tz) |
|
||||
|
||||
- Even if `cellNF` is false, formatted text will be generated and saved to `.w`
|
||||
- In some cases, sheets may be parsed even if `bookSheets` is false.
|
||||
- Excel aggressively tries to interpret values from CSV and other plain text.
|
||||
This leads to surprising behavior! The `raw` option suppresses value parsing.
|
||||
- `bookSheets` and `bookProps` combine to give both sets of information
|
||||
- `Deps` will be an empty object if `bookDeps` is false
|
||||
- `bookFiles` behavior depends on file type:
|
||||
* `keys` array (paths in the ZIP) for ZIP-based formats
|
||||
* `files` hash (mapping paths to objects representing the files) for ZIP
|
||||
* `cfb` object for formats using CFB containers
|
||||
- By default all worksheets are parsed. `sheets` restricts based on input type:
|
||||
* number: zero-based index of worksheet to parse (`0` is first worksheet)
|
||||
* string: name of worksheet to parse (case insensitive)
|
||||
* array of numbers and strings to select multiple worksheets.
|
||||
- `codepage` is applied to BIFF2 - BIFF5 files without `CodePage` records and to
|
||||
CSV files without BOM in `type:"binary"`. BIFF8 XLS always defaults to 1200.
|
||||
- `PRN` affects parsing of text files without a common delimiter character.
|
||||
- Currently only XOR encryption is supported. Unsupported error will be thrown
|
||||
for files employing other encryption methods.
|
||||
- `WTF` is mainly for development. By default, the parser will suppress read
|
||||
errors on single worksheets, allowing you to read from the worksheets that do
|
||||
parse properly. Setting `WTF:true` forces those errors to be thrown.
|
||||
- `UTC` applies to CSV, Text and HTML formats. When explicitly set to `false`,
|
||||
the parsers will assume the files are specified in local time. By default, as
|
||||
is the case for other file formats, dates and times are interpreted in UTC.
|
||||
### Cell-Level Options
|
||||
|
||||
#### Dates
|
||||
|
||||
By default, for consistency with spreadsheet applications, date cells are stored
|
||||
as numeric cells (type `n`) with special number formats. If `cellDates` is
|
||||
enabled, date codes are converted to proper Date objects.
|
||||
|
||||
Excel file formats (including XLSX, XLSB, and XLS) support a locale-specific
|
||||
date format, typically stored as date code 14 or the string `m/d/yy`. The
|
||||
formatted text for some cells will change based on the computer locale. SheetJS
|
||||
parsers use the `en-US` form by default. If the `dateNF` option is set, that
|
||||
number format string will be used.
|
||||
|
||||
["Dates and Times"](/docs/csf/features/dates) covers features in more detail.
|
||||
|
||||
#### Formulae
|
||||
|
||||
For some file formats, the `cellFormula` option must be explicitly enabled to
|
||||
ensure that formulae are extracted.
|
||||
|
||||
Newer Excel functions are serialized with the `_xlfn.` prefix, hidden from the
|
||||
user. By default, the file parsers will strip `_xlfn.` and similar prefixes.
|
||||
If the `xlfn` option is enabled, the prefixes will be preserved.
|
||||
|
||||
[The "Formulae" docs](/docs/csf/features/formulae#prefixed-future-functions)
|
||||
covers this in more detail.
|
||||
|
||||
#### Formatted Text {#text}
|
||||
|
||||
Many common spreadsheet formats (including XLSX, XLSB, and XLS) store numeric
|
||||
values and number formats. Applications are expected to use the number formats
|
||||
to display currency strings, dates, and other values.
|
||||
|
||||
Under the hood, parsers use the [SSF Number Formatter](/docs/constellation/ssf)
|
||||
library to generated formatted text.
|
||||
|
||||
By default, formatted text is generated. If the `cellText` option is false,
|
||||
formatted text will not be written.
|
||||
|
||||
By default, cell number formats are not preserved. If the `cellNF` option is
|
||||
enabled, number format strings will be saved to the `z` field of cell objects.
|
||||
|
||||
["Number Formats"](/docs/csf/features/nf) covers the features in more detail.
|
||||
|
||||
:::note pass
|
||||
|
||||
Even if `cellNF` is false, formatted text will be generated and saved to `w`.
|
||||
|
||||
:::
|
||||
|
||||
#### Text and Cell Styling {#style}
|
||||
|
||||
By default, SheetJS CE parsers focus on data extraction.
|
||||
|
||||
If the `cellStyles` option is `true`, other styling metadata including
|
||||
[row](/docs/csf/features/rowprops) and [column](/docs/csf/features/colprops)
|
||||
properties will be parsed.
|
||||
|
||||
:::tip pass
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) offers cell / text styling, conditional
|
||||
formatting and additional styling options.
|
||||
|
||||
:::
|
||||
|
||||
#### HTML Formatted Text {#html}
|
||||
|
||||
Spreadsheet applications support a limited form of rich text styling.
|
||||
|
||||
If the `cellHTML` option is `true`, some file parsers will attempt to translate
|
||||
the rich text to standard HTML with inner tags for bold text and other styles.
|
||||
|
||||
:::tip pass
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) offers additional styling options,
|
||||
conversions for all supported file formats, and whole-worsheet HTML generation.
|
||||
|
||||
:::
|
||||
|
||||
### Sheet-Level Options
|
||||
|
||||
#### Dense
|
||||
|
||||
@ -130,17 +196,16 @@ The `nodim` option instructs the parser to ignore self-reported ranges and use
|
||||
the actual cells in the worksheet to determine the range. This addresses known
|
||||
issues with non-compliant third-party exporters.
|
||||
|
||||
#### Formulae
|
||||
#### Stubs
|
||||
|
||||
For some file formats, the `cellFormula` option must be explicitly enabled to
|
||||
ensure that formulae are extracted.
|
||||
Some file formats, including XLSX and XLS, can specify cells without cell data.
|
||||
For example, cells covered by a [merged cell block](/docs/csf/features/merges)
|
||||
are technically invalid but files may include metadata.
|
||||
|
||||
Newer Excel functions are serialized with the `_xlfn.` prefix, hidden from the
|
||||
user. SheetJS will strip `_xlfn.` normally. The `xlfn` option preserves them.
|
||||
[The "Formulae" docs](/docs/csf/features/formulae#prefixed-future-functions)
|
||||
covers this in more detail.
|
||||
By default, the cells are skipped. If the `sheetStubs` option is `true`, these
|
||||
cells will be parsed as [stub cells](/docs/csf/cell#cell-types)
|
||||
|
||||
["Formulae"](/docs/csf/features/formulae) covers the features in more detail.
|
||||
### Book-Level Options
|
||||
|
||||
#### VBA
|
||||
|
||||
@ -160,18 +225,166 @@ new blob from the XLS CFB container that works in XLSM and XLSB files.
|
||||
|
||||
</details>
|
||||
|
||||
#### Workbook Metadata {#metadata}
|
||||
|
||||
By default, the data from each worksheet is parsed.
|
||||
|
||||
If any of the following options are passed, parsers will not parse sheet data.
|
||||
They will parse enough of the workbook to extract the requested information.
|
||||
|
||||
| Option | Extracted Data |
|
||||
|:-------------|:--------------------|
|
||||
| `bookProps` | Workbook properties |
|
||||
| `bookSheets` | Worksheet names |
|
||||
|
||||
The options apply to XLSX, XLSB, XLS and XLML parsers.
|
||||
|
||||
#### Worksheets {#sheets}
|
||||
|
||||
By default, all worksheets are parsed. The `sheets` option limits which sheets
|
||||
are parsed.
|
||||
|
||||
If the `sheets` option is a number, the number is interpreted as a zero-based
|
||||
index. For example, `sheets: 2` instructs the parser to read the third sheet.
|
||||
|
||||
If the `sheets` option is text, the string is interpreted as a worksheet name.
|
||||
The name is case-insensitive. `sheets: "Sheet1"` instructs the parser to read
|
||||
the worksheet named "Sheet1".
|
||||
|
||||
If the `sheets` option is an array of numbers and text, each worksheets will
|
||||
be parsed. `sheets: [2, "Sheet1"]` instructs the parser to read the third sheet
|
||||
and the sheet named "Sheet1". If the third worksheet is coincidentally named
|
||||
"Sheet1", only one worksheet will be parsed
|
||||
|
||||
### File-Level Options
|
||||
|
||||
#### Password Protection {#password}
|
||||
|
||||
SheetJS CE currently supports XOR encryption in XLS files. Errors will be thrown
|
||||
when trying to parse files using unsupported encryption methods.
|
||||
|
||||
:::tip pass
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) offers support for additional encryption
|
||||
schemes, including the AES-CBC schemes used in XLSX / XLSM / XLSB files and the
|
||||
RC4 schemes used in newer XLS files.
|
||||
|
||||
:::
|
||||
|
||||
#### Lotus Formatted Text (PRN) {#prn}
|
||||
|
||||
Lotus Formatted Text (`PRN`) worksheets are plain text files that do not include
|
||||
delimiter characters. Each cell in a column has the same width.
|
||||
|
||||
If the `PRN` option is set, the plaintext parser will attempt to parse some
|
||||
plaintext files as if they follow the `PRN` format.
|
||||
|
||||
:::note pass
|
||||
|
||||
If the `PRN` option is set, text files that do not include commas or semicolons
|
||||
or other common delimiters may not be parsed as expected.
|
||||
|
||||
This option should not be enabled unless it is known that the file was exported
|
||||
from Lotus 1-2-3 or from Excel using the "Lotus Formatted Text (`PRN`)" format.
|
||||
|
||||
:::
|
||||
|
||||
#### Value Parsing {#raw}
|
||||
|
||||
Spreadsheet software including Excel aggressively try to interpret values from
|
||||
CSV and other plain text. This leads to surprising behavior[^1]!
|
||||
|
||||
If the `raw` option is true, value parsing will be suppressed. All cells values
|
||||
are treated as strings.
|
||||
|
||||
The `raw` option affects the following formats: HTML, CSV, PRN, DIF, RTF.
|
||||
|
||||
The `raw` option does not affect XLSX, XLSB, XLS and other file formats that
|
||||
support explicit value typing.
|
||||
|
||||
:::note pass
|
||||
|
||||
See [Issue #3331](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145) in the
|
||||
SheetJS CE bug tracker for more details.
|
||||
|
||||
:::
|
||||
|
||||
#### Code Page Encoding {#codepage}
|
||||
|
||||
Spreadsheet applications support a number of legacy encodings. Plaintext files
|
||||
will appear different when opened in different computers in different regions.
|
||||
|
||||
By default, the parsers use the most common "English (United States)" encodings.
|
||||
The `codepage` option controls the encoding in BIFF2 - BIFF5 XLS files without
|
||||
`CodePage` records, some legacy formats including DBF, and in CSV files without
|
||||
BOM in `type: "binary"`. BIFF8 XLS always defaults to 1200.
|
||||
|
||||
The `codepage` support library is not guaranteed to be loaded by default. The
|
||||
["Installation"](/docs/getting-started/installation/) section describes how to
|
||||
install and load the support library.
|
||||
|
||||
See ["Legacy Codepages"](/docs/constellation/codepage) for more details.
|
||||
|
||||
#### Date Processing {#tz}
|
||||
|
||||
Plaintext formats may include date and time values without timezone info. The
|
||||
time `12:30 AM` is ambiguous.
|
||||
|
||||
In the wild, there are two popular approaches:
|
||||
|
||||
A) Spreadsheet software typically interpret time values using local timezones.
|
||||
When opening a file in New York, `12:30 AM` will be parsed as `12:30 AM ET`.
|
||||
When opening a file in Los Angeles, the time will be parsed as `12:30 AM PT`.
|
||||
|
||||
B) APIs use [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time), the
|
||||
most popular global time standard. `12:30 AM` will be parsed as the absolute
|
||||
moment in time corresponding to `8:30 PM EDT` or `7:30 PM EST`.
|
||||
|
||||
By default, the parsers assume files are specified in UTC. When the `UTC` option
|
||||
is explicitly set to `false`, dates and times are interpreted in timezone of the
|
||||
web browser or JavaScript engine.
|
||||
|
||||
#### Delimiter-Separated Values {#dsv}
|
||||
|
||||
The plaintext parser applies a number of heuristics to determine if files are
|
||||
CSV (fields separated by commas), TSV (fields separated by tabs), PSV (fields
|
||||
separated by `|`) or SSV (fields separated by `;`). The heuristics are based on
|
||||
the presence of characters not in a double-quoted value.
|
||||
|
||||
The `FS` option instructs the parser to use the specified delimiter if multiple
|
||||
delimiter characters are in the text. This bypasses the default heuristics.
|
||||
|
||||
#### Internal Files {#files}
|
||||
|
||||
Some file formats are structured as larger containers that include sub-files.
|
||||
For example, XLSX files are ZIP files with XML sub-files.
|
||||
|
||||
If the `bookFiles` option is `true`, each sub-file will be preserved in the
|
||||
workbook. The behavior depends on file type:
|
||||
|
||||
- `keys` array (paths in the ZIP) for ZIP-based formats
|
||||
- `files` hash (mapping paths to objects representing the files) for ZIP
|
||||
- `cfb` object for formats using CFB containers
|
||||
|
||||
#### Parsing Errors {#wtf}
|
||||
|
||||
By default, the workbook parser will suppress errors when parsing worksheets.
|
||||
This ensures the valid worksheets from a multi-sheet workbook are parsed.
|
||||
|
||||
If the `WTF` option is enabled, the errors will not be suppressed.
|
||||
|
||||
### Input Type
|
||||
|
||||
The `type` parameter for `read` controls how data is interpreted:
|
||||
|
||||
| `type` | expected input |
|
||||
|:-----------|:----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (only appropriate for UTF-8 text formats) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"array"` | array: array of 8-bit unsigned integers (byte `n` is `data[n]`) |
|
||||
| `"file"` | string: path of file that will be read (nodejs only) |
|
||||
| `type` | expected input |
|
||||
|:---------|:----------------------------------------------------------------|
|
||||
| `base64` | string: Base64 encoding of the file |
|
||||
| `binary` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `string` | string: JS string (only appropriate for UTF-8 text formats) |
|
||||
| `buffer` | nodejs Buffer |
|
||||
| `array` | array: array of 8-bit unsigned integers (byte `n` is `data[n]`) |
|
||||
| `file` | string: path of file that will be read (nodejs only) |
|
||||
|
||||
Some common types are automatically deduced from the data input type, including
|
||||
NodeJS `Buffer` objects, `Uint8Array` and `ArrayBuffer` objects, and arrays of
|
||||
@ -246,3 +459,6 @@ were CSV or TSV. SheetJS attempts to replicate that behavior.
|
||||
|
||||
</details>
|
||||
|
||||
[^1]: The gene [`SEPT1`](https://en.wikipedia.org/wiki/SEPTIN1) was renamed to
|
||||
`SEPTIN1` to avoid Excel value interpretations: the string `SEPT1` is parsed as
|
||||
the date "September 1".
|
||||
@ -8,13 +8,15 @@ import current from '/version.js';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import Link from '@docusaurus/Link';
|
||||
|
||||
The main SheetJS method for writing workbooks is `write`. Scripts receive common
|
||||
[JavaScript data representations](#output-type) and are expected to write or
|
||||
share files using platform-specific APIs.
|
||||
The main SheetJS method for writing workbooks is `write`. It accepts a SheetJS
|
||||
[workbook object](/docs/csf/book) and returns the file data stored in common
|
||||
[JavaScript data representations](#output-type). Scripts calling `write` are
|
||||
expected to write or share files using platform-specific APIs.
|
||||
|
||||
The `writeFile` helper method accepts a filename and tries to write to a local
|
||||
file using [standard APIs](/docs/demos/local/file).
|
||||
file using [standard local file APIs](/docs/demos/local/file).
|
||||
|
||||
**Export a SheetJS workbook object in a specified file format**
|
||||
|
||||
@ -24,9 +26,9 @@ var file_data = XLSX.write(wb, opts);
|
||||
|
||||
`write` attempts to write the workbook `wb` and return the file.
|
||||
|
||||
The `options` argument is required. It must specify
|
||||
- [`bookType`](#supported-output-formats) (file format of the exported file)
|
||||
- [`type`](#output-type) (return value type)
|
||||
The `options` argument is required. It must specify
|
||||
- [`bookType`](#bookType): file format of the exported file
|
||||
- [`type`](#output-type): return value type
|
||||
|
||||
**Export a SheetJS workbook object and attempt to write a local file**
|
||||
|
||||
@ -39,17 +41,18 @@ XLSX.writeFile(wb, filename, options);
|
||||
In browser-based environments, it will attempt to force a client-side download.
|
||||
It also supports NodeJS, ExtendScript applications, and Chromium extensions.
|
||||
|
||||
The `options` argument is optional.
|
||||
|
||||
If `options` is omitted or if `bookType` is missing from the `options` object,
|
||||
the output file format will be deduced from the filename extension.
|
||||
the output file format will be [inferred from the filename](#extension).
|
||||
|
||||
**Special functions for exporting data in the XLSX format**
|
||||
|
||||
```js
|
||||
// limited form of `write`
|
||||
/* `write` (XLSX only) */
|
||||
var file_data = XLSX.writeXLSX(wb, options);
|
||||
|
||||
|
||||
// limited form of `writeFile`
|
||||
/* `writeFile` (XLSX only) */
|
||||
XLSX.writeFileXLSX(wb, filename, options);
|
||||
```
|
||||
|
||||
@ -60,111 +63,357 @@ For websites that exclusively export to XLSX, these functions can reduce the
|
||||
size of the production site. The general `write` and `writeFile` functions are
|
||||
more appropriate when exporting to XLS or XLSB or other formats.
|
||||
|
||||
|
||||
<details>
|
||||
<summary><b>NodeJS-specific methods</b> (click to show)</summary>
|
||||
|
||||
**Export a workbook and attempt to write a local file using `fs.writeFile`**
|
||||
|
||||
```js
|
||||
// callback equivalent of `XLSX.writeFile`
|
||||
/* callback equivalent of `XLSX.writeFile(wb, filename)` */
|
||||
XLSX.writeFileAsync(filename, wb, cb);
|
||||
|
||||
// callback equivalent with options argument
|
||||
/* callback equivalent of `XLSX.writeFile(wb, filename, options)` */
|
||||
XLSX.writeFileAsync(filename, wb, options, cb);
|
||||
```
|
||||
|
||||
|
||||
`writeFileAsync` attempts to write `wb` to `filename` and invoke the callback
|
||||
`cb` on completion.
|
||||
|
||||
When an `options` object is specified, it is expected to be the third argument.
|
||||
|
||||
This method only works in NodeJS and uses `fs.writeFile` under the hood.
|
||||
This method only works in NodeJS. It uses `fs.writeFile` under the hood.
|
||||
|
||||
</details>
|
||||
|
||||
:::note Recommendation
|
||||
|
||||
`writeFile` wraps a number of export techniques, making it suitable for browser
|
||||
downloads, NodeJS, ExtendScript apps, and Chromium extensions. It does not work
|
||||
in other environments with more advanced export methods.
|
||||
`writeFile` wraps a number of export techniques, making it suitable for web
|
||||
browsers, [Photoshop and InDesign](/docs/demos/extensions/extendscript), and
|
||||
server-side platforms including NodeJS. It does not work in other environments
|
||||
with more advanced export methods.
|
||||
|
||||
The `write` method returns raw bytes or strings that can be exported in
|
||||
[Desktop apps](/docs/demos/desktop/) , [Mobile apps](/docs/demos/mobile) , and
|
||||
[Servers](/docs/demos/net/server).
|
||||
`write` returns raw bytes or strings that can be exported with platform-specific
|
||||
APIs in [Desktop apps](/docs/demos/desktop), [Mobile apps](/docs/demos/mobile),
|
||||
[Servers](/docs/demos/net/server), and [extensions](/docs/demos/extensions).
|
||||
|
||||
The [demos](/docs/demos) preferentially use `writeFile`. When `writeFile` is not
|
||||
supported, the demos show file creation using `write` and platform APIs.
|
||||
|
||||
:::
|
||||
|
||||
:::tip pass
|
||||
|
||||
The SheetJS file format export codecs focus on raw data. Not all codecs support
|
||||
all features. Features not described in the documentation may not be serialized.
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) offers support for additional features,
|
||||
including styling, images, graphs, and PivotTables.
|
||||
|
||||
:::
|
||||
|
||||
## Writing Options
|
||||
|
||||
The write functions accept an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | -------: | :------------------------------------------------- |
|
||||
|`type` | | Output data encoding (see Output Type below) |
|
||||
|`cellDates` | `false` | Store dates as type `d` (default is `n`) |
|
||||
|`cellStyles` | `false` | Save style/theme info to the `.s` field |
|
||||
|`codepage` | | If specified, use code page when appropriate ** |
|
||||
|`bookSST` | `false` | Generate Shared String Table ** |
|
||||
|`bookType` | `"xlsx"` | Type of Workbook (see below for supported formats) |
|
||||
|`bookVBA` | | Add VBA blob from workbook object to the file ** |
|
||||
|`WTF` | `false` | If true, throw errors on unexpected features ** |
|
||||
|`sheet` | `""` | Name of Worksheet for single-sheet formats ** |
|
||||
|`compression`| `false` | Use ZIP compression for ZIP-based formats ** |
|
||||
|`Props` | | Override workbook properties when writing ** |
|
||||
|`themeXLSX` | | Override theme XML when writing XLSX/XLSB/XLSM ** |
|
||||
|`ignoreEC` | `true` | Suppress "number as text" errors ** |
|
||||
|`numbers` | | Payload for NUMBERS export ** |
|
||||
|`FS` | `","` | "Field Separator" delimiter between fields ** |
|
||||
|`RS` | `"\n"` | "Record Separator" delimiter between rows ** |
|
||||
| Option Name | Default | Description |
|
||||
|:--------------|:---------|:---------------------------------------------------|
|
||||
| `type` | | [Output data encoding](#output-type) |
|
||||
| `cellDates` | `false` | Convert [numeric date codes to strings](#dates) |
|
||||
| `cellStyles` | `false` | Export [style/theme info](#style) |
|
||||
| `codepage` | | Use specified [code page encoding](#codepage) |
|
||||
| `bookSST` | `false` | Generate [Shared String Table](#sst) |
|
||||
| `bookType` | `"xlsx"` | [Type of Workbook](#supported-output-formats) |
|
||||
| `bookVBA` | | [Add VBA blob from workbook object](#vba) |
|
||||
| `WTF` | `false` | [Do not suppress warnings and errors](#wtf) |
|
||||
| `sheet` | `""` | [Export the named sheet](#sheet) |
|
||||
| `compression` | `false` | [Try to reduce file size](#compression) |
|
||||
| `Props` | | Override [workbook properties](#props) |
|
||||
| `themeXLSX` | | Override [theme XML for XLSX/XLSB/XLSM](#theme) |
|
||||
| `ignoreEC` | `true` | [Suppress "number as text" errors](#ec) |
|
||||
| `numbers` | | [Payload for NUMBERS export](#numbers) |
|
||||
| `FS` | `","` | [Field Separator](#dsv) for CSV and Text exports |
|
||||
| `RS` | `"\n"` | [Record Separator](#dsv) for CSV and Text exports |
|
||||
|
||||
- `bookSST` is slower and more memory intensive, but has better compatibility
|
||||
with older versions of iOS Numbers
|
||||
- The raw data is the only thing guaranteed to be saved. Features not described
|
||||
in this README may not be serialized.
|
||||
- `cellDates` only applies to XLSX output and is not guaranteed to work with
|
||||
third-party readers. Excel itself does not usually write cells with type `d`
|
||||
so non-Excel tools may ignore the data or error in the presence of dates.
|
||||
- `codepage` is applied to legacy formats including DBF. Characters missing
|
||||
from the encoding will be replaced with underscore characters (`_`).
|
||||
- `Props` is an object mirroring the workbook `Props` field. See the table from
|
||||
the [Workbook File Properties](/docs/csf/book#file-properties) section.
|
||||
- if specified, the string from `themeXLSX` will be saved as the primary theme
|
||||
for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP)
|
||||
- Due to a bug in the program, some features like "Text to Columns" will crash
|
||||
Excel on worksheets where error conditions are ignored. The writer will mark
|
||||
files to ignore the error by default. Set `ignoreEC` to `false` to suppress.
|
||||
- `FS` and `RS` apply to CSV and Text output formats. The options are discussed
|
||||
in ["CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output)
|
||||
- `bookVBA` only applies to supported formats. ["VBA"](/docs/csf/features/vba)
|
||||
section explains the feature in more detail.
|
||||
- `WTF` is mainly for development.
|
||||
## Supported Output Formats
|
||||
|
||||
<Link id="bookType"/>
|
||||
|
||||
For broad compatibility with third-party tools, SheetJS CE supports many output
|
||||
formats. The writer will select the file type based on the `bookType` option:
|
||||
|
||||
| `bookType` | extension | sheets | Description |
|
||||
|:-----------|:-----------|:-------|:--------------------------------|
|
||||
| `xlsx` | `.xlsx` | multi | Excel 2007+ XML Format |
|
||||
| `xlsm` | `.xlsm` | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | multi | Excel 2007+ Binary Format |
|
||||
| `biff8` | `.xls` | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff5` | `.xls` | multi | Excel 5.0/95 Workbook Format |
|
||||
| `biff4` | `.xls` | single | Excel 4.0 Worksheet Format |
|
||||
| `biff3` | `.xls` | single | Excel 3.0 Worksheet Format |
|
||||
| `biff2` | `.xls` | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `numbers` | `.numbers` | multi | Numbers 3.0+ Spreadsheet |
|
||||
| `ods` | `.ods` | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | multi | Flat OpenDocument Spreadsheet |
|
||||
| `wk3` | `.wk3` | multi | Lotus Workbook (WK3) |
|
||||
| `csv` | `.csv` | single | Comma Separated Values |
|
||||
| `txt` | `.txt` | single | UTF-16 Unicode Text (TXT) |
|
||||
| `sylk` | `.sylk` | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | single | HTML Document |
|
||||
| `dif` | `.dif` | single | Data Interchange Format (DIF) |
|
||||
| `dbf` | `.dbf` | single | dBASE II + VFP Extensions (DBF) |
|
||||
| `wk1` | `.wk1` | single | Lotus Worksheet (WK1) |
|
||||
| `rtf` | `.rtf` | single | Rich Text Format (RTF) |
|
||||
| `prn` | `.prn` | single | Lotus Formatted Text |
|
||||
| `eth` | `.eth` | single | Ethercalc Record Format (ETH) |
|
||||
|
||||
If the output format supports multiple worksheets, the workbook writer will try
|
||||
to export each worksheet. If the format only supports one worksheet, the writer
|
||||
will export the first worksheet. If the [`sheet` option](#sheet) is a string,
|
||||
the writer will use the named sheet.
|
||||
|
||||
#### Output Format inference from File Extension {#extension}
|
||||
|
||||
`writeFile` will automatically guess the output file format based on the file
|
||||
extension if `bookType` is not specified.
|
||||
|
||||
| extension | Description |
|
||||
|:-----------|:--------------------------------|
|
||||
| `.csv` | Comma Separated Values |
|
||||
| `.dbf` | dBASE II + VFP Extensions (DBF) |
|
||||
| `.dif` | Data Interchange Format (DIF) |
|
||||
| `.eth` | Ethercalc Record Format (ETH) |
|
||||
| `.fods` | Flat OpenDocument Spreadsheet |
|
||||
| `.html` | HTML Document |
|
||||
| `.numbers` | Numbers 3.0+ Spreadsheet |
|
||||
| `.ods` | OpenDocument Spreadsheet |
|
||||
| `.prn` | Lotus Formatted Text |
|
||||
| `.rtf` | Rich Text Format (RTF) |
|
||||
| `.sylk` | Symbolic Link (SYLK) |
|
||||
| `.txt` | UTF-16 Unicode Text (TXT) |
|
||||
| `.wk1` | Lotus Worksheet (WK1) |
|
||||
| `.wk3` | Lotus Workbook (WK3) |
|
||||
| `.xls` | Excel 97-2004 Workbook Format |
|
||||
| `.xlsb` | Excel 2007+ Binary Format |
|
||||
| `.xlsm` | Excel 2007+ Macro XML Format |
|
||||
| `.xlsx` | Excel 2007+ XML Format |
|
||||
|
||||
## Output Type
|
||||
|
||||
The `type` option specifies the JS form of the output:
|
||||
|
||||
| `type` | output |
|
||||
|----------|-----------------------------------------------------------------|
|
||||
| `base64` | string: Base64 encoding of the file |
|
||||
| `binary` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `string` | string: JS string (not compatible with binary formats) |
|
||||
| `buffer` | NodeJS `Buffer` or `Uint8Array` |
|
||||
| `array` | `ArrayBuffer` or array of 8-bit unsigned int |
|
||||
| `file` | (attempt to download a file) |
|
||||
|
||||
:::note pass
|
||||
|
||||
For compatibility with Excel, `csv` output will always include the UTF-8 byte
|
||||
order mark ("BOM").
|
||||
|
||||
The raw [`sheet_to_csv` method](/docs/api/utilities/csv#csv-output) will return
|
||||
JavaScript strings without the UTF-8 BOM.
|
||||
|
||||
:::
|
||||
|
||||
## Other Options
|
||||
|
||||
### Cell-Level Options
|
||||
|
||||
#### Dates
|
||||
|
||||
Plaintext files store dates using formatted strings. XLS and most Excel file
|
||||
formats store dates using numeric date codes.
|
||||
|
||||
XLSX and ODS/FODS support both numeric date codes and ISO 8601 date strings.
|
||||
|
||||
By default, when both numeric date codes and date strings are supported, the
|
||||
writers will export date codes. Date cells (type `d`) will be converted to
|
||||
numeric cells.
|
||||
|
||||
If the `cellDates` option is set, writers will export date strings. If number
|
||||
formats include [date tokens](/docs/csf/features/nf#dates-and-times), numeric
|
||||
cells (type `n`) will be converted to date cells.
|
||||
|
||||
:::caution pass
|
||||
|
||||
Generated files are not guaranteed to work with third-party spreadsheet readers!
|
||||
Third-party tools may ignore cells or reject files that use proper date cells.
|
||||
|
||||
:::
|
||||
|
||||
["Dates and Times"](/docs/csf/features/dates) covers features in more detail.
|
||||
|
||||
#### Text and Cell Styling {#style}
|
||||
|
||||
By default, SheetJS CE writers focus on data preservation.
|
||||
|
||||
If the `cellStyles` option is `true`, other styling metadata including
|
||||
[row](/docs/csf/features/rowprops) and [column](/docs/csf/features/colprops)
|
||||
will be exported.
|
||||
|
||||
:::tip pass
|
||||
|
||||
[SheetJS Pro](https://sheetjs.com/pro) offers cell / text styling, conditional
|
||||
formatting and additional styling options.
|
||||
|
||||
:::
|
||||
|
||||
### Sheet-Level Options
|
||||
|
||||
#### Error Checking {#ec}
|
||||
|
||||
By default, Excel warns users when creating text cells when the text could be
|
||||
parsed as a number. People and software systems commonly use text to store US
|
||||
ZIP Codes, as many ZIP Codes in New Jersey start with "0".
|
||||
|
||||
By default, SheetJS writers add special marks to instruct Excel not to elicit
|
||||
warnings on cells containing text that look like numbers.
|
||||
|
||||
Due to a bug in Excel, "Text to Columns" and other features may lead to crashes
|
||||
in files where error conditions are ignored. If the `ignoreEC` option is
|
||||
explicitly set to `false`, SheetJS writers will not add the offending marks.
|
||||
|
||||
### Book-Level Options
|
||||
|
||||
#### VBA
|
||||
|
||||
When exporting to file formats that support VBA (XLSX, XLSB, XLS), macros are
|
||||
not guaranteed to be exported by default. The `bookVBA` option should be set
|
||||
to a truthy value (`true` or `1`).
|
||||
|
||||
The ["VBA"](/docs/csf/features/vba) section explains the feature in more detail.
|
||||
|
||||
#### Workbook Properties {#props}
|
||||
|
||||
When exporting to a file format that supports workbook properties, the SheetJS
|
||||
export codecs will look in the workbook object for file properties.
|
||||
|
||||
If the `Props` option is specified, the export codecs will ignore properties
|
||||
from the workbook object.
|
||||
|
||||
The ["File Properties"](/docs/csf/features/props) section lists the supported
|
||||
file properties.
|
||||
|
||||
### File-Level Options
|
||||
|
||||
#### Compression
|
||||
|
||||
XLSX, XLSB, NUMBERS, and ODS files use ZIP containers. The ZIP container format
|
||||
supports different levels of compression. Spreadsheet software typically use
|
||||
compression when exporting files.
|
||||
|
||||
By default, SheetJS writers optimize for speed. Exports are faster but the
|
||||
generated files are larger.
|
||||
|
||||
If the `compression` option is set, writers will optimize for file size. Exports
|
||||
are smaller but will take more time.
|
||||
|
||||
#### Target Sheet {#sheet}
|
||||
|
||||
Some output formats support multiple worksheets. By default, the SheetJS export
|
||||
codecs will export all worksheets.
|
||||
|
||||
Other output formats, including CSV and legacy Excel and Lotus worksheet files,
|
||||
only support one worksheet. By default, the SheetJS export codecs will use the
|
||||
first worksheet from the workbook.
|
||||
|
||||
If the `sheet` option is set to the name of a valid worksheet in the workbook,
|
||||
the SheetJS writers will use the named sheet even if it is not the first sheet.
|
||||
|
||||
#### Shared String Table (SST) {#sst}
|
||||
|
||||
XLSX, XLS, and XLSB can store text cells in two ways.
|
||||
|
||||
By default, the writers use "inline" strings. The content of each text cell is
|
||||
stored in the cell representation. This approach is conceptually simple, but it
|
||||
uses features that may not be supported in iOS Numbers and other apps.
|
||||
|
||||
If the `bookSST` option is set, writers use the "shared string table" (SST)
|
||||
feature. A separate lookup table houses each text string and cells store indices
|
||||
into the SST. Multiple cells can point to the same SST entry.
|
||||
|
||||
Exporting with SST is typically slower and more memory intensive, but the files
|
||||
may be smaller and have better compatibility with third-party software.
|
||||
|
||||
#### Delimiter-Separated Values {#dsv}
|
||||
|
||||
The SheetJS CSV writer uses commas to separate fields within a row and adds line
|
||||
separators between rows.
|
||||
|
||||
The characters used to separate fields and rows can be controlled through the
|
||||
`FS` ("field separator") and `RS` ("row separator") options.
|
||||
|
||||
["CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output) discusses
|
||||
the options in more detail.
|
||||
|
||||
#### Code Page Encoding {#codepage}
|
||||
|
||||
Spreadsheet applications support a number of legacy encodings. Plaintext files
|
||||
will appear different when opened in different computers in different regions.
|
||||
|
||||
By default, the writers use the most common "English (United States)" encodings.
|
||||
The `codepage` option controls the encoding in BIFF2 - BIFF5 XLS files without
|
||||
`CodePage` records, some legacy formats including DBF, and in CSV files without
|
||||
BOM in `type: "binary"`.
|
||||
|
||||
Characters missing from the specified encoding will be replaced with underscore
|
||||
characters (`_`).
|
||||
|
||||
The `codepage` support library is not guaranteed to be loaded by default. The
|
||||
["Installation"](/docs/getting-started/installation/) section describes how to
|
||||
install and load the support library.
|
||||
|
||||
See ["Legacy Codepages"](/docs/constellation/codepage) for more details.
|
||||
|
||||
#### XLSX and XLSB Theme {#theme}
|
||||
|
||||
By default, the SheetJS XLSX and XLSB output codecs use a predetermined theme.
|
||||
This simplifies [column widths](/docs/csf/features/colprops#column-widths) and
|
||||
other features that depend on font metrics.
|
||||
|
||||
If the `themeXLSX` option is a string, the XLSB and XLSX codecs will suppress
|
||||
the default theme. The default theme `xl/theme/theme1.xml` will be overridden.
|
||||
|
||||
#### Writing Errors {#wtf}
|
||||
|
||||
If the `WTF` option is enabled, workbook writers will show warnings and errors
|
||||
when workbooks use features that may be considered unsafe. For example, some
|
||||
file features are only supported in specific versions of Excel.
|
||||
|
||||
#### NUMBERS Exports {#numbers}
|
||||
|
||||
<details open>
|
||||
<summary><b>Exporting NUMBERS files</b> (click to show)</summary>
|
||||
<summary><b>Rationale</b> (click to hide)</summary>
|
||||
|
||||
The NUMBERS writer requires a fairly large base. The supplementary `xlsx.zahl`
|
||||
scripts provide support. `xlsx.zahl.js` is designed for standalone and NodeJS
|
||||
use, while `xlsx.zahl.mjs` is suitable for ESM.
|
||||
Apple Numbers has broken backwards compatibility many times over the years.
|
||||
Files generated by older versions of Numbers are not guaranteed to work with
|
||||
newer versions of Numbers or third-party tools.
|
||||
|
||||
Adding NUMBERS export support involves two steps:
|
||||
The NUMBERS exporter starts from a working file and rewrites the data blocks.
|
||||
This ensures exports still work
|
||||
|
||||
1) Load the `xlsx.zahl` script
|
||||
The current design allows for updating the base file without disrupting the rest
|
||||
of the library.
|
||||
|
||||
2) Pass the payload into the `numbers` option to `write` or `writeFile`.
|
||||
</details>
|
||||
|
||||
The `numbers` option is required for exporting NUMBERS files. It is expected to
|
||||
be a Base64 string that encodes a valid Numbers file. The supplementary
|
||||
`xlsx.zahl` scripts include the required string.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="browser" label="Browser">
|
||||
<TabItem value="standalone" label="Standalone">
|
||||
|
||||
<p><a href={"https://cdn.sheetjs.com/xlsx-" + current + "/package/dist/xlsx.zahl.js"}>{"https://cdn.sheetjs.com/xlsx-" + current + "/package/dist/xlsx.zahl.js"}</a> is the URL for {current}</p>
|
||||
|
||||
<CodeBlock language="html">{`\
|
||||
<meta charset="utf8">\n\
|
||||
<body>\n\
|
||||
<CodeBlock language="html" title="Sample HTML">{`\
|
||||
<html><head><meta charset="utf8"></head><body>\n\
|
||||
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>\n\
|
||||
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.zahl.js"></script>\n\
|
||||
<script>\n\
|
||||
@ -176,7 +425,7 @@ var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([\n\
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");\n\
|
||||
XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression: true});\n\
|
||||
</script>\n\
|
||||
</body>`}
|
||||
</body></html>`}
|
||||
</CodeBlock>
|
||||
|
||||
</TabItem>
|
||||
@ -250,67 +499,3 @@ XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression:
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
## Supported Output Formats
|
||||
|
||||
For broad compatibility with third-party tools, this library supports many
|
||||
output formats. The specific file type is controlled with `bookType` option:
|
||||
|
||||
| `bookType` | extension | sheets | Description |
|
||||
|:-----------|:-----------|:-------|:--------------------------------|
|
||||
| `xlsx` | `.xlsx` | multi | Excel 2007+ XML Format |
|
||||
| `xlsm` | `.xlsm` | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | multi | Excel 2007+ Binary Format |
|
||||
| `biff8` | `.xls` | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff5` | `.xls` | multi | Excel 5.0/95 Workbook Format |
|
||||
| `biff4` | `.xls` | single | Excel 4.0 Worksheet Format |
|
||||
| `biff3` | `.xls` | single | Excel 3.0 Worksheet Format |
|
||||
| `biff2` | `.xls` | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `numbers` | `.numbers` | multi | Numbers 3.0+ Spreadsheet |
|
||||
| `ods` | `.ods` | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | multi | Flat OpenDocument Spreadsheet |
|
||||
| `wk3` | `.wk3` | multi | Lotus Workbook (WK3) |
|
||||
| `csv` | `.csv` | single | Comma Separated Values |
|
||||
| `txt` | `.txt` | single | UTF-16 Unicode Text (TXT) |
|
||||
| `sylk` | `.sylk` | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | single | HTML Document |
|
||||
| `dif` | `.dif` | single | Data Interchange Format (DIF) |
|
||||
| `dbf` | `.dbf` | single | dBASE II + VFP Extensions (DBF) |
|
||||
| `wk1` | `.wk1` | single | Lotus Worksheet (WK1) |
|
||||
| `rtf` | `.rtf` | single | Rich Text Format (RTF) |
|
||||
| `prn` | `.prn` | single | Lotus Formatted Text |
|
||||
| `eth` | `.eth` | single | Ethercalc Record Format (ETH) |
|
||||
|
||||
- `compression` applies to ZIP-based formats (XLSX, XLSM, XLSB, NUMBERS, ODS)
|
||||
- Formats that only support a single sheet require a `sheet` option specifying
|
||||
the worksheet. If the string is empty, the first worksheet is used.
|
||||
- `writeFile` will automatically guess the output file format based on the file
|
||||
extension if `bookType` is not specified. It will choose the first format in
|
||||
the aforementioned table that matches the extension.
|
||||
|
||||
## Output Type
|
||||
|
||||
The `type` option specifies the JS form of the output:
|
||||
|
||||
| `type` | output |
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (not compatible with binary formats) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"array"` | ArrayBuffer, fallback array of 8-bit unsigned int |
|
||||
| `"file"` | string: path of file that will be created (nodejs only) |
|
||||
|
||||
:::note pass
|
||||
|
||||
For compatibility with Excel, `csv` output will always include the UTF-8 byte
|
||||
order mark ("BOM").
|
||||
|
||||
The raw [`sheet_to_csv` method](/docs/api/utilities/csv#csv-output) will return
|
||||
JavaScript strings without the UTF-8 BOM.
|
||||
|
||||
:::
|
||||
|
||||
@ -26,7 +26,7 @@ HTML format and HTML table utilities.
|
||||
var html = XLSX.utils.sheet_to_html(ws, opts);
|
||||
```
|
||||
|
||||
The `sheet_to_html` method generates HTML strings from SheetJS worksheets[^1].
|
||||
The `sheet_to_html` method generates HTML strings from [SheetJS worksheet objects](/docs/csf/sheet).
|
||||
|
||||
The following options are supported:
|
||||
|
||||
@ -513,5 +513,3 @@ browser. ["Browser Automation"](/docs/demos/net/headless) covers some browsers.
|
||||
|
||||
Some ecosystems provide DOM-like frameworks that are compatible with SheetJS.
|
||||
Examples are included in the ["Synthetic DOM"](/docs/demos/net/dom) demo
|
||||
|
||||
[^1]: See ["Worksheet Object" in "SheetJS Data Model"](/docs/csf/sheet) for more details.
|
||||
|
||||
@ -41,12 +41,12 @@ These instructions were tested on the following platforms:
|
||||
|
||||
| Platform | Architecture | Test Date |
|
||||
|:------------------------------|:-------------|:-----------|
|
||||
| Linux (Ubuntu Linux x64) | `linux-x64` | 2025-07-06 |
|
||||
| Linux (Debian Linux AArch64) | `linux-arm` | 2025-01-14 |
|
||||
| MacOS 15.3 (x64) | `darwin-x64` | 2025-03-31 |
|
||||
| MacOS 15.2 (ARM64) | `darwin-arm` | 2025-03-07 |
|
||||
| Linux (Ubuntu Linux x64) | `linux-x64` | 2026-02-02 |
|
||||
| Linux (Debian Linux AArch64) | `linux-arm` | 2026-03-05 |
|
||||
| MacOS 15.6 (x64) | `darwin-x64` | 2026-01-21 |
|
||||
| MacOS 15.7 (ARM64) | `darwin-arm` | 2026-02-02 |
|
||||
| Windows 11 (x64) + WSL Ubuntu | `win11-x64` | 2025-06-20 |
|
||||
| Windows 11 (ARM) + WSL Ubuntu | `win11-arm` | 2025-02-23 |
|
||||
| Windows 11 (ARM) + WSL Ubuntu | `win11-arm` | 2026-03-08 |
|
||||
|
||||
With some additional dependencies, the unminified scripts are reproducible and
|
||||
tests will pass in Windows XP with NodeJS 5.10.0.
|
||||
@ -303,7 +303,7 @@ browser.
|
||||
|
||||
*In the `"Get Node.js®"` section:*
|
||||
|
||||
1. Select the LTS version (currently `"v22.14.0 (LTS)"`) in the first dropdown
|
||||
1. Select the LTS version (currently `"v24.13.0 (LTS)"`) in the first dropdown
|
||||
|
||||
*In the `"Or get a prebuilt Node.js® for"` section:*
|
||||
|
||||
@ -734,6 +734,20 @@ Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/)
|
||||
^^^^^^^^^^^^^^^^^^^^ URL
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
The local server is configured to start on port 8000. If another service is
|
||||
listening on that port, the process will fail to start.
|
||||
|
||||
If the other process cannot be stopped, run the server manually. The following
|
||||
snippet starts a server on port 9999:
|
||||
|
||||
```bash
|
||||
npx -y http-server -p 9999 tests
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
11) Open a browser window and access the displayed URL.
|
||||
|
||||
## Development
|
||||
|
||||
@ -25,6 +25,15 @@ Metadata standards. XLSX files must reference `http://purl.org/dc/elements/1.1/`
|
||||
Any tool that generates XML files must generate URLs to domains outside of the
|
||||
control of the vendor.
|
||||
|
||||
### JavaScript Links
|
||||
|
||||
Excel and other spreadsheet tools support hyperlinks using the `javascript:`
|
||||
protocol. When exporting to HTML, they will not sanitize or strip these URLs.
|
||||
|
||||
**Microsoft does not currently believe this is a vulnerability!**
|
||||
|
||||
The SheetJS HTML exporter mirrors established behavior.
|
||||
|
||||
### Non-ASCII Characters
|
||||
|
||||
XLS, CSV and other legacy file formats use system-specific encodings. Excel and
|
||||
|
||||
@ -48,7 +48,7 @@ Alias variables (supported in DTA versions 120-121) are not processed.
|
||||
|
||||
This demo fetches a [sample DTA file](pathname:///dta/pres.dta), parses the data
|
||||
using the SheetJS DTA Codec and displays the data in an HTML table using the
|
||||
`sheet_to_html` method[^1].
|
||||
[`sheet_to_html` utility function](/docs/api/utilities/html#html-table-output):
|
||||
|
||||
:::tip pass
|
||||
|
||||
@ -97,5 +97,3 @@ function SheetJSDTA() {
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
||||
[^1]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output)
|
||||
|
||||
@ -91,7 +91,7 @@ export default App;
|
||||
If you are starting from scratch, create a new ViteJS + ReactJS project:
|
||||
|
||||
```bash
|
||||
npm create vite@latest -- sheetjs-react --template react --default
|
||||
npm create vite@latest -- sheetjs-react --template react --no-rolldown --no-interactive
|
||||
cd sheetjs-react
|
||||
npm install
|
||||
npm run dev
|
||||
@ -123,19 +123,19 @@ yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
|
||||
2) Ensure that your component script imports `useRef` from the `react` library:
|
||||
|
||||
```js
|
||||
```js title="src/App.tsx (add useRef import if it does not exist)"
|
||||
import { useRef } from "react";
|
||||
```
|
||||
|
||||
3) Add the following line at the top of your component script:
|
||||
|
||||
```js
|
||||
```js title="src/App.tsx (add import to the top of your component script)"
|
||||
import { utils, writeFileXLSX } from "xlsx";
|
||||
```
|
||||
|
||||
4) Create a ref in the body of your function component:
|
||||
|
||||
```jsx
|
||||
```jsx title="src/App.tsx (add highlighted line)"
|
||||
function App() {
|
||||
// highlight-next-line
|
||||
const tbl = useRef(null);
|
||||
@ -144,7 +144,7 @@ function App() {
|
||||
|
||||
5) Attach the ref to the table element:
|
||||
|
||||
```jsx
|
||||
```jsx title="src/App.tsx (add ref attribute to TABLE element)"
|
||||
function App() {
|
||||
// ...
|
||||
return (
|
||||
@ -156,7 +156,7 @@ function App() {
|
||||
|
||||
6) Add a button with a click handler that will export table data to XLSX:
|
||||
|
||||
```jsx
|
||||
```jsx title="src/App.tsx (add button element to JSX)"
|
||||
function App() {
|
||||
// ...
|
||||
return (
|
||||
@ -172,6 +172,9 @@ function App() {
|
||||
{/*...*/}
|
||||
```
|
||||
|
||||
7) Start the development server (typically `npm run dev`) and open the app.
|
||||
Click the "Export XLSX" button and open the generated file.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@ -367,7 +370,7 @@ This,is,a,Test
|
||||
The test suite is regularly run against a number of modern and legacy browsers
|
||||
using [Sauce Labs](https://saucelabs.com/).
|
||||
|
||||
The following chart shows test results on 2025-05-15 for version `0.20.3`:
|
||||
Browser tests for SheetJS version `0.20.3` were run on 2026-01-12:
|
||||
|
||||
[](https://saucelabs.com/u/sheetjs)
|
||||
|
||||
|
||||
@ -31,9 +31,10 @@ fn main() {
|
||||
let path: String = iter.nth(1).expect("must specify a file name");
|
||||
|
||||
let file: Vec<u8> = std::fs::read(path.clone()).unwrap();
|
||||
|
||||
|
||||
/* push data to boa */
|
||||
let array: boa_engine::object::builtins::JsArrayBuffer = boa_engine::object::builtins::JsArrayBuffer::from_byte_block(file, context).unwrap();
|
||||
let aligned = boa_engine::object::builtins::AlignedVec::from_iter(0, file.into_iter());
|
||||
let array: boa_engine::object::builtins::JsArrayBuffer = boa_engine::object::builtins::JsArrayBuffer::from_byte_block(aligned, context).unwrap();
|
||||
let attrs = boa_engine::property::Attribute::WRITABLE | boa_engine::property::Attribute::ENUMERABLE | boa_engine::property::Attribute::CONFIGURABLE;
|
||||
let _ = context.register_global_property(boa_engine::js_string!("buf"), array, attrs);
|
||||
}
|
||||
|
||||
@ -50,8 +50,6 @@ int main(int argc, char *argv[]) {
|
||||
JsValueRef global;
|
||||
FAIL_CHECK(JsGetGlobalObject(&global));
|
||||
|
||||
EVAL_FILE("shim.min.js")
|
||||
|
||||
EVAL_FILE("xlsx.full.min.js")
|
||||
|
||||
JsValueRef buf_str;
|
||||
|
||||
BIN
docz/static/data/pres.numbers
Normal file
BIN
docz/static/data/pres.numbers
Normal file
Binary file not shown.
@ -45,7 +45,7 @@ fn main() {
|
||||
let csv: ducc::Value = ctx.compile("XLSX.utils.sheet_to_csv(ws)", None).unwrap().call(()).unwrap();
|
||||
println!("{}", get_string(csv));
|
||||
}
|
||||
|
||||
|
||||
/* write file */
|
||||
{
|
||||
/* due to issues with the duktape crate, it is easier to pass a base64-encoded string and decode in Rust */
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
"version": "0.0.0",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
"@electron/remote": "2.1.2",
|
||||
"@electron/remote": "2.1.3",
|
||||
"xlsx": "https://sheet.lol/balls/xlsx-0.20.3.tgz"
|
||||
},
|
||||
"scripts": {
|
||||
@ -15,12 +15,12 @@
|
||||
"make": "electron-forge make"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "7.8.0",
|
||||
"@electron-forge/maker-deb": "7.8.0",
|
||||
"@electron-forge/maker-rpm": "7.8.0",
|
||||
"@electron-forge/maker-squirrel": "7.8.0",
|
||||
"@electron-forge/maker-zip": "7.8.0",
|
||||
"electron": "35.1.2"
|
||||
"@electron-forge/cli": "7.11.1",
|
||||
"@electron-forge/maker-deb": "7.11.1",
|
||||
"@electron-forge/maker-rpm": "7.11.1",
|
||||
"@electron-forge/maker-squirrel": "7.11.1",
|
||||
"@electron-forge/maker-zip": "7.11.1",
|
||||
"electron": "40.8.0"
|
||||
},
|
||||
"config": {
|
||||
"forge": {
|
||||
|
||||
BIN
docz/static/flutter/enbable_and_install_cmd_tools.png
Normal file
BIN
docz/static/flutter/enbable_and_install_cmd_tools.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 182 KiB |
@ -77,7 +77,7 @@ class SheetJSFlutterState extends State<SheetJSFlutter> {
|
||||
XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);
|
||||
""");
|
||||
setState(() {
|
||||
_data = CsvToListConverter(eol: "\n").convert(func.stringResult);
|
||||
_data = const CsvDecoder().convert(func.stringResult);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
BIN
docz/static/flutter/open_sdk_manager.png
Normal file
BIN
docz/static/flutter/open_sdk_manager.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 467 KiB |
@ -66,5 +66,5 @@ const aoo = offset.map((name, idx) => ({
|
||||
const ws = json_to_sheet(aoo);
|
||||
/* write workbook */
|
||||
const wb = book_new(ws, "Offsets");
|
||||
/* write to XLSX */
|
||||
/* write to XLSX */
|
||||
writeFileXLSX(wb, "SheetJSGhidraTSTCell.xlsx");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Note: The official Hermes documentation includes zero guidance on embedding.=
|
||||
# Tested against commit 8ef11b45d7b078434605658421efb34cf436c005 on darwin-x64
|
||||
# Tested against commit f45c6bcb2d6e6516b25abbf6c5964f9dc95c5761 on darwin-x64
|
||||
# History https://git.sheetjs.com/sheetjs/docs.sheetjs.com/commits/branch/master/docz/static/hermes/Makefile
|
||||
|
||||
MYCC=llvm-g++
|
||||
@ -33,8 +33,8 @@ clean-all: clean
|
||||
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 \
|
||||
-lhermes \
|
||||
-Lbuild_release/API/hermes/ -lsynthTrace -lsynthTraceParser \
|
||||
-lhermesapi \
|
||||
-Lbuild_release/lib/VM/ -lhermesVMRuntime \
|
||||
-Lbuild_release/lib/BCGen/HBC/ -lhermesHBCBackend \
|
||||
-Lbuild_release/lib/BCGen/ -lhermesBackend \
|
||||
@ -45,24 +45,24 @@ sheetjs-hermes: sheetjs-hermes.cpp init
|
||||
-Lbuild_release/external/llvh/lib/Demangle/ -lLLVHDemangle \
|
||||
-Lbuild_release/external/llvh/lib/Support/ -lLLVHSupport \
|
||||
-Lbuild_release/jsi/ -ljsi \
|
||||
-Lbuild_release/lib/ -lhermesFrontend \
|
||||
-Lbuild_release/lib/ -lhermesOptimizer \
|
||||
-Lbuild_release/lib/ -lhermesFrontend \
|
||||
-Lbuild_release/lib/ADT -lhermesADT \
|
||||
-Lbuild_release/lib/AST/ -lhermesAST \
|
||||
-Lbuild_release/lib/AST2JS/ -lhermesAST2JS \
|
||||
-Lbuild_release/lib/CompilerDriver/ -lhermesCompilerDriver \
|
||||
-Lbuild_release/lib/ConsoleHost/ -lhermesConsoleHost \
|
||||
-Lbuild_release/lib/DependencyExtractor/ -lhermesDependencyExtractor \
|
||||
-Lbuild_release/lib/FlowParser/ -lhermesFlowParser \
|
||||
-Lbuild_release/lib/FrontEndDefs/ -lhermesFrontEndDefs \
|
||||
-Lbuild_release/lib/Inst/ -lhermesInst \
|
||||
-Lbuild_release/lib/InternalBytecode/ -lhermesInternalBytecode \
|
||||
-Lbuild_release/lib/Platform/ -lhermesPlatform \
|
||||
-Lbuild_release/lib/Platform/Intl/ -lhermesBCP47Parser \
|
||||
-Lbuild_release/lib/Regex/ -lhermesRegex \
|
||||
-Lbuild_release/lib/Support/ -lhermesSupport \
|
||||
-Lbuild_release/lib/Sema/ -lhermesSema \
|
||||
-Lbuild_release/lib/InternalJavaScript/ -lhermesInternalUnit -lhermesInternalBytecode \
|
||||
-Lbuild_release/external/boost/boost_1_86_0/libs/context/ -lboost_context \
|
||||
-Lbuild_release/public/hermes/Public -lhermesPublic \
|
||||
-Lhermes/external/flowparser/ -lflowparser-mac \
|
||||
-Lbuild_release/external/dtoa/ -ldtoa \
|
||||
$(POSTAMBLE)
|
||||
|
||||
@ -71,5 +71,5 @@ sheetjs-hermes.cpp:
|
||||
|
||||
.PHONY: init
|
||||
init:
|
||||
if [ ! -e hermes ]; then git clone https://github.com/facebook/hermes.git; cd hermes; git checkout 8ef11b45d7b078434605658421efb34cf436c005; cd ..; fi
|
||||
if [ ! -e hermes ]; then git clone https://github.com/facebook/hermes.git; cd hermes; git checkout f45c6bcb2d6e6516b25abbf6c5964f9dc95c5761; 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
|
||||
@ -2,3 +2,25 @@
|
||||
fn main() {
|
||||
println!("cargo::rustc-link-lib=framework=JavaScriptCore");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn main() {
|
||||
// Link against JavaScriptCore libraries built from WebKit source
|
||||
// Libraries are static archives (.a files)
|
||||
println!("cargo::rustc-link-lib=static=JavaScriptCore");
|
||||
println!("cargo::rustc-link-lib=static=WTF");
|
||||
println!("cargo::rustc-link-lib=static=bmalloc");
|
||||
println!("cargo::rustc-link-lib=icui18n");
|
||||
println!("cargo::rustc-link-lib=icuuc");
|
||||
println!("cargo::rustc-link-lib=atomic");
|
||||
|
||||
// Required system libraries for the C++ runtime dependencies
|
||||
println!("cargo::rustc-link-lib=stdc++");
|
||||
println!("cargo::rustc-link-lib=pthread");
|
||||
println!("cargo::rustc-link-lib=m");
|
||||
println!("cargo::rustc-link-lib=dl");
|
||||
println!("cargo::rustc-link-lib=c");
|
||||
|
||||
// Search path to the pre-built JavaScriptCore libraries
|
||||
println!("cargo::rustc-link-search=native=/tmp/sheetjs-jsc/Release/lib");
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user