diff --git a/docz/data/cli.xls b/docz/data/cli.xls index 47a8962..e5dbd32 100644 --- a/docz/data/cli.xls +++ b/docz/data/cli.xls @@ -34,7 +34,7 @@ - +
@@ -110,6 +110,15 @@ + + txiki.js + + + + + + + V8 Engine diff --git a/docz/data/engines.xls b/docz/data/engines.xls index fe97536..edb5040 100644 --- a/docz/data/engines.xls +++ b/docz/data/engines.xls @@ -132,8 +132,8 @@ C - - + + @@ -304,8 +304,8 @@ - - + + Duktape diff --git a/docz/docs/03-demos/17-mobile/03-quasar.md b/docz/docs/03-demos/17-mobile/03-quasar.md index df40147..d71a79b 100644 --- a/docz/docs/03-demos/17-mobile/03-quasar.md +++ b/docz/docs/03-demos/17-mobile/03-quasar.md @@ -311,6 +311,13 @@ adb exec-out run-as org.sheetjs.quasar cat files/files/SheetJSQuasar.xlsx > /tmp npx xlsx-cli /tmp/SheetJSQuasar.xlsx ``` +:::caution pass + +PowerShell file redirects will corrupt binary data. In Windows, commands must be +run from a Command Prompt session. + +::: + ### iOS 8) Create the iOS project: diff --git a/docz/docs/03-demos/20-cli/12-bunsea.md b/docz/docs/03-demos/20-cli/12-bunsea.md index 34532c4..be05e2f 100644 --- a/docz/docs/03-demos/20-cli/12-bunsea.md +++ b/docz/docs/03-demos/20-cli/12-bunsea.md @@ -54,22 +54,22 @@ For example, the following script accepts one command line argument, parses the specified file using the SheetJS `readFile` method[^1], generates CSV text from the first worksheet using `sheet_to_csv`[^2], and prints to terminal: -{`\ +```ts title="sheet2csv.ts" const XLSX = require("xlsx"); -\n\ + /* process.argv[2] is the first argument to the script */ const filename = process.argv[2]; -\n\ + /* read file */ const wb = XLSX.readFile(filename); -\n\ + /* generate CSV of first sheet */ const ws = wb.Sheets[wb.SheetNames[0]]; const csv = XLSX.utils.sheet_to_csv(ws); -\n\ + /* print to terminal */ -console.log(csv);`} - +console.log(csv); +``` ## Complete Example diff --git a/docz/docs/03-demos/20-cli/21-txiki.md b/docz/docs/03-demos/20-cli/21-txiki.md new file mode 100644 index 0000000..208ccd3 --- /dev/null +++ b/docz/docs/03-demos/20-cli/21-txiki.md @@ -0,0 +1,247 @@ +--- +title: TxikiJS Standalone Apps +sidebar_label: txiki.js +pagination_prev: demos/desktop/index +pagination_next: demos/data/index +sidebar_custom_props: + summary: Compiled apps powered by QuickJS and txiki.js +--- + +import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +`txiki.js` is a small runtime powered by [QuickJS](/docs/demos/engines/quickjs). + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses `txiki.js` and SheetJS to create a standalone CLI tool for +parsing spreadsheets and generating CSV rows. + +:::caution TxikiJS support is considered experimental. + +Great open source software grows with user tests and reports. Any issues should +be reported to the `txiki.js` project for further diagnosis. + +::: + +## Integration Details + +The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone) +can be evaluated and consumed in TxikiJS. + +The platform provides APIs for filesystem operations that differ from NodeJS: + +- `tjs.readFile` reads raw data from a specified filename and returns a Promise + that resolves to a `Uint8Array` +- `tjs.args` is an array of arguments. In the compiled program, the first value + will be the program name and the second value will be the first argument. + +The SheetJS filesystem methods ([`readFile`](/docs/api/parse-options) and +[`writeFile`](/docs/api/parse-options)) do not recognize the `txiki.js` APIs. +Fortunately, `read` and `write` directly work with `Uint8Array` data. + +The following example reads and parses `pres.xlsx` in the current directory: + +```js title="Parse pres.xlsx in TxikiJS" +/* read data from pres.xlsx into a Uint8Array */ +const data = await tjs.readFile("pres.xlsx"); + +/* parse data and generate a SheetJS workbook object */ +const wb = XLSX.read(data); +``` + +### Script Requirements + +The compiler does not bundle scripts automatically. Scripts that exclusively use +web APIs, SheetJS API methods, and `tjs` API methods can be bundled and compiled. + +[`esbuild`](/docs/demos/frontend/bundler/esbuild) is the recommended bundler. + +For example, the following script accepts one command line argument, parses the +specified file using `tjs.readFile` and the SheetJS `read` method[^1], generates +CSV text from the first sheet using `sheet_to_csv`[^2], and prints the result: + +```js title="sheet2csv.js (before bundling)" +const XLSX = require("./xlsx.full.min"); + +/* tjs.args[1] is the first argument to the script */ +const filename = tjs.args[1]; + +/* read and parse file */ +const data = await tjs.readFile(filename); +const wb = XLSX.read(data); + +/* generate CSV of first sheet */ +const ws = wb.Sheets[wb.SheetNames[0]]; +const csv = XLSX.utils.sheet_to_csv(ws); + +/* print to terminal */ +console.log(csv); +``` + +## Complete Example + +:::note Tested Deployments + +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 | + +::: + +:::caution pass + +TxikiJS on Windows on ARM uses the X64 compatibility layer. It does not generate +a native ARM64 binary! + +::: + +0) Create a new project folder and download `txiki.js`[^3]: + + + + +```bash +mkdir sheetjs-txiki +cd sheetjs-txiki +curl -LO https://github.com/saghul/txiki.js/releases/download/v24.12.0/txiki-macos.zip +unzip txiki-macos.zip +mv txiki-macos/tjs . +chmod +x tjs +``` + + + + +```bash +mkdir sheetjs-txiki +cd sheetjs-txiki +git clone --recursive https://github.com/saghul/txiki.js --shallow-submodules +cd txiki.js +make +cp build/tjs ../ +cd .. +``` + + + + +```bash +mkdir sheetjs-txiki +cd sheetjs-txiki +curl.exe -LO https://github.com/saghul/txiki.js/releases/download/v24.12.0/txiki-windows-x86_64.zip +tar xf txiki-windows-x86_64.zip +mv txiki-windows-x86_64\* . +``` + + + + +1) Download the test file https://docs.sheetjs.com/pres.numbers: + +```bash +curl -LO https://docs.sheetjs.com/pres.numbers +``` + +:::note pass + +In PowerShell, the command may fail with a parameter error: + +``` +Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'. +``` + +`curl.exe` must be invoked directly: + +```bash +curl.exe -LO https://docs.sheetjs.com/pres.numbers +``` + +::: + +2) Save the [contents of the `sheet2csv.js` code block](#script-requirements) +to `sheet2csv.js` in the project folder. + +```bash +curl -LO https://docs.sheetjs.com/txikijs/sheet2csv.js +``` + +:::note pass + +In PowerShell, the command may fail with a parameter error: + +``` +Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'. +``` + +`curl.exe` must be invoked directly: + +```bash +curl.exe -LO https://docs.sheetjs.com/txikijs/sheet2csv.js +``` + +::: + +3) Download the SheetJS Standalone script and move to the project directory: + + + +{`\ +curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`} + + +:::note pass + +In PowerShell, the command may fail with a parameter error: + +``` +Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'. +``` + +`curl.exe` must be invoked directly: + +{`\ +curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`} + + +::: + +4) Bundle the script: + +```js +npx -y esbuild sheet2csv.js --bundle --outfile=bundle.js --platform=neutral +``` + +5) Compile and run `sheet2csv`: + +```bash +./tjs compile bundle.js sheet2csv +./sheet2csv pres.numbers +``` + +The program should display the same CSV contents as the script: + +```text title="Expected Output" +Name,Index +Bill Clinton,42 +GeorgeW Bush,43 +Barack Obama,44 +Donald Trump,45 +Joseph Biden,46 +``` + +[^1]: See [`read` in "Reading Files"](/docs/api/parse-options) +[^2]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output) +[^3]: When this demo was last tested, the [ZIP archive for version `24.12.0`](https://github.com/saghul/txiki.js/releases/tag/v24.12.0) was downloaded and extracted. \ No newline at end of file diff --git a/docz/docs/03-demos/42-engines/01-duktape.md b/docz/docs/03-demos/42-engines/01-duktape.md index 05c254e..158439e 100644 --- a/docz/docs/03-demos/42-engines/01-duktape.md +++ b/docz/docs/03-demos/42-engines/01-duktape.md @@ -1115,6 +1115,8 @@ This demo was tested in the following deployments: | `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 | ::: diff --git a/docz/docs/03-demos/42-engines/08-quickjs.md b/docz/docs/03-demos/42-engines/08-quickjs.md index c45a7fb..f8e2b9f 100644 --- a/docz/docs/03-demos/42-engines/08-quickjs.md +++ b/docz/docs/03-demos/42-engines/08-quickjs.md @@ -252,34 +252,29 @@ At this point, `csvstr` is a C string that can be printed to standard output. ## Complete Example -The "Integration Example" covers a traditional integration in a C application, -while the "CLI Test" demonstrates other concepts using the `quickjs` CLI tool. - -### Integration Example +- ["Integration Example"](#integration-example) covers a traditional integration + of the official library in a C application. +- ["Windows Example"](#windows-example) uses the QuickJS-NG fork +- ["CLI Test"](#cli-test) uses the `quickjs` CLI tool. :::note Tested Deployments This demo was tested in the following deployments: -| Architecture | Git Commit | Date | -|:-------------|:-----------|:-----------| -| `darwin-x64` | `0d7aaed` | 2025-03-31 | -| `darwin-arm` | `6e2e68f` | 2024-12-17 | -| `win11-x64` | `6e2e68f` | 2024-12-19 | -| `win11-arm` | `6e2e68f` | 2025-02-23 | -| `linux-x64` | `6e2e68f` | 2025-01-09 | -| `linux-arm` | `6e2e68f` | 2025-02-15 | +| Architecture | Library | Git Commit | Date | +|:-------------|:-----------|:-----------|:-----------| +| `darwin-x64` | QuickJS | `0d7aaed` | 2025-03-31 | +| `darwin-arm` | QuickJS | `6e2e68f` | 2024-12-17 | +| `win11-x64` | QuickJS-NG | `865ba1f` | 2025-04-18 | +| `win11-arm` | QuickJS-NG | `865ba1f` | 2025-04-18 | +| `linux-x64` | QuickJS | `6e2e68f` | 2025-01-09 | +| `linux-arm` | QuickJS | `6e2e68f` | 2025-02-15 | When the demo was tested, `0d7aaed` was the HEAD commit on the `master` branch. ::: -:::caution pass - -QuickJS does not officially support Windows. The `win11-x64` and `win11-arm` -tests were run entirely within Windows Subsystem for Linux. - -::: +### Integration Example 0) Build `libquickjs.a`: @@ -350,6 +345,80 @@ curl -LO https://docs.sheetjs.com/pres.numbers`} If successful, the program will print the library version number, file size, first worksheet name, and the contents of the first sheet as CSV rows. +### Windows Example + +The [QuickJS-NG fork](https://quickjs-ng.github.io/quickjs/) explicitly aims to +support Windows. It provides a source amalgamation for easy integration. + +:::info pass + +The Windows build requires Visual Studio with "Desktop development with C++". +Commands must be run in a "Native Tools Command Prompt" session. + +::: + +0) Create a project folder: + +```bash +mkdir sheetjs-quick +cd sheetjs-quick +``` + +1) Build the QuickJS-NG amalgamation: + +```bash +git clone https://github.com/quickjs-ng/quickjs +cd quickjs +git checkout 865ba1f1 +cmake -B build -DQJS_BUILD_EXAMPLES=ON +cmake --build build --config Release +build\Release\qjs.exe amalgam.js +cd .. +``` + +2) Copy `quickjs-amalgam.c` and `quickjs.h` into the working directory: + +``` +copy quickjs\quickjs-amalgam.c . +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 +``` + +4) Build the sample application: + +```bash +cl sheetjs.quick.c quickjs-amalgam.c /std:c11 /experimental:c11atomics /w /I .\ +``` + +This program tries to parse the file specified by the first argument + +5) Download the SheetJS Standalone script and test file. Save both files in +the project directory: + + + +{`\ +curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js +curl -LO https://docs.sheetjs.com/pres.numbers`} + + +6) Run the test program: + +```bash +.\sheetjs.quick.exe pres.numbers +``` + +If successful, the program will print the library version number, file size, +first worksheet name, and the contents of the first sheet as CSV rows. + ### CLI Test diff --git a/docz/docs/09-miscellany/06-security.md b/docz/docs/09-miscellany/06-security.md new file mode 100644 index 0000000..bb4fdf2 --- /dev/null +++ b/docz/docs/09-miscellany/06-security.md @@ -0,0 +1,41 @@ +--- +title: Security +sidebar_position: 7 +hide_table_of_contents: true +--- + +Please report any potential vulnerability or question to security@sheetjs.com + +## Known Issues + +SheetJS libraries use techniques that may be flagged by overzealous scanners. + +**The issues in this section are fundamentally unavoidable.** + +### URL References and XML + +XLSX, SpreadsheetML2003, and a number of other spreadsheet file formats use XML. + +XML namespaces are specified as URLs. For example, XLSX file properties follow +[Dublin Core](https://www.dublincore.org/specifications/dublin-core/dcmi-terms/) +Metadata standards. XLSX files must reference `http://purl.org/dc/elements/1.1/`. + +**This is a design flaw of XML!** + +Any tool that generates XML files must generate URLs to domains outside of the +control of the vendor. + +### Non-ASCII Characters + +XLS, CSV and other legacy file formats use system-specific encodings. Excel and +other established software predate UTF-8. As a result, SheetJS libraries ship +with [the `codepage` encodings](/docs/constellation/codepage). + +SheetJS libraries include CJK ("Chinese, Japanese and Korean") characters to +support CSV and XLS files generated by East Asian versions of Excel. + +**The encodings are required for correct parsing of spreadsheet data!** + +[The SheetJS library scripts are reproducible](/docs/miscellany/contributing). +Security-conscious developers should audit the source code and verify that the +build artifacts are identical to the official releases. diff --git a/docz/docs/12-constellation/02-frac/index.md b/docz/docs/12-constellation/02-frac/index.md index cb959b3..47e2c4c 100644 --- a/docz/docs/12-constellation/02-frac/index.md +++ b/docz/docs/12-constellation/02-frac/index.md @@ -1,7 +1,7 @@ --- title: Rational Approximation pagination_prev: constellation/ssf -pagination_next: constellation/crc32 +pagination_next: constellation/codepage --- diff --git a/docz/docs/12-constellation/03-codepage.md b/docz/docs/12-constellation/03-codepage.md new file mode 100644 index 0000000..3c7f36c --- /dev/null +++ b/docz/docs/12-constellation/03-codepage.md @@ -0,0 +1,12 @@ +--- +title: Legacy Codepages +hide_table_of_contents: true +pagination_prev: constellation/frac/index +--- + +The SheetJS `codepage` library provides lookup tables and utility functions for +processing data encoded with legacy codepages. It is a core component of file +processing for XLS, CSV, and a number of legacy file formats. + +Source code and project documentation are hosted on the SheetJS Git server at +https://git.sheetjs.com/sheetjs/js-codepage diff --git a/docz/docs/12-constellation/11-crc32.md b/docz/docs/12-constellation/11-crc32.md index 437aed4..52a3a21 100644 --- a/docz/docs/12-constellation/11-crc32.md +++ b/docz/docs/12-constellation/11-crc32.md @@ -1,7 +1,6 @@ --- title: CRC32 Checksum hide_table_of_contents: true -pagination_prev: constellation/frac/index --- diff --git a/docz/docs/12-constellation/index.md b/docz/docs/12-constellation/index.md index b214d9a..e060cd9 100644 --- a/docz/docs/12-constellation/index.md +++ b/docz/docs/12-constellation/index.md @@ -5,7 +5,9 @@ pagination_prev: miscellany/index import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; -Many related projects have been separated into dedicated libraries. +For historical and legal reasons, many related projects have been separated into +dedicated libraries and tools. Some projects live in separate repositories and +others live in the [main repo](https://git.sheetjs.com/sheetjs/sheetjs/issues). ### Contents diff --git a/docz/static/txikijs/sheet2csv.js b/docz/static/txikijs/sheet2csv.js new file mode 100644 index 0000000..6edc3c5 --- /dev/null +++ b/docz/static/txikijs/sheet2csv.js @@ -0,0 +1,15 @@ +const XLSX = require("./xlsx.full.min"); + +/* tjs.args[1] is the first argument to the script */ +const filename = tjs.args[1]; + +/* read and parse file */ +const data = await tjs.readFile(filename); +const wb = XLSX.read(data); + +/* generate CSV of first sheet */ +const ws = wb.Sheets[wb.SheetNames[0]]; +const csv = XLSX.utils.sheet_to_csv(ws); + +/* print to terminal */ +console.log(csv); \ No newline at end of file