forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			247 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			247 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|  | --- | ||
|  | 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]: | ||
|  | 
 | ||
|  | <Tabs groupId="triple"> | ||
|  |   <TabItem value="darwin-x64" label="MacOS"> | ||
|  | 
 | ||
|  | ```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 | ||
|  | ``` | ||
|  | 
 | ||
|  |   </TabItem> | ||
|  |   <TabItem value="linux-x64" label="Linux"> | ||
|  | 
 | ||
|  | ```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 .. | ||
|  | ``` | ||
|  | 
 | ||
|  |   </TabItem> | ||
|  |   <TabItem value="win11-x64" label="Windows"> | ||
|  | 
 | ||
|  | ```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\* . | ||
|  | ``` | ||
|  | 
 | ||
|  |   </TabItem> | ||
|  | </Tabs> | ||
|  | 
 | ||
|  | 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: | ||
|  | 
 | ||
|  | <ul> | ||
|  | <li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li> | ||
|  | </ul> | ||
|  | 
 | ||
|  | <CodeBlock language="bash">{`\ | ||
|  | curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`} | ||
|  | </CodeBlock> | ||
|  | 
 | ||
|  | :::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: | ||
|  | 
 | ||
|  | <CodeBlock language="bash">{`\ | ||
|  | curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`} | ||
|  | </CodeBlock> | ||
|  | 
 | ||
|  | ::: | ||
|  | 
 | ||
|  | 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. |