--- title: NativeScript pagination_prev: demos/static/index pagination_next: demos/desktop/index sidebar_position: 2 sidebar_custom_props: summary: JS + Native Elements --- import current from '/version.js'; The [NodeJS Module](/docs/getting-started/installation/nodejs) can be imported from the main entrypoint or any script in the project. The "Complete Example" creates an app that looks like the screenshots below:
iOS
![iOS screenshot](pathname:///mobile/nsios.png)
## Integration Details The discussion covers the NativeScript + Angular integration. Familiarity with Angular and TypeScript is assumed. The `@nativescript/core/file-system` package provides classes for file access. The `File` class does not support binary data, but the file access singleton from `@nativescript/core` does support reading and writing `ArrayBuffer`. Reading and writing data require a URL. The following snippet searches typical document folders for a specified filename: ```ts import { Folder, knownFolders, path } from '@nativescript/core/file-system'; function get_url_for_filename(filename: string): string { const target: Folder = knownFolders.documents() || knownFolders.ios.sharedPublic(); return path.normalize(target.path + "///" + filename); } ``` #### Reading data `getFileAccess().readBufferAsync` can read data: ```ts import { getFileAccess } from '@nativescript/core'; /* find appropriate path */ const url = get_url_for_filename("SheetJSNS.xls"); /* get data */ const ab: ArrayBuffer = await getFileAccess().readBufferAsync(url); /* read workbook */ const wb = read(ab); ``` #### Writing data `getFileAccess().writeBufferAsync` can write data: ```ts import { getFileAccess } from '@nativescript/core'; /* find appropriate path */ const url = get_url_for_filename("SheetJSNS.xls"); /* generate Uint8Array */ const u8: Uint8Array = write(wb, { bookType: 'xls', type: 'binary' }); /* attempt to save Uint8Array to file */ await getFileAccess().writeBufferAsync(url, u8); ``` ## Demo :::note This demo was tested on an Intel Mac on 2023 April 03. NativeScript version (as verified with `ns --version`) is `8.5.1`. The iOS simulator runs iOS 16.2 on an iPhone 14 Pro Max. ::: 0) Follow the official Environment Setup instructions 1) Create a skeleton NativeScript + Angular app: ```bash ns create SheetJSNS --ng ``` 2) Launch the app in the iOS simulator to verify that the demo built properly: ```bash cd SheetJSNS ns run ios ``` (this may take a while) Once the simulator launches and the test app is displayed, end the script by selecting the terminal and entering the key sequence `CTRL + C` 3) From the project folder, install the library:
{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
4) To confirm the library was loaded, change the title to show the version. The differences are highlighted. `src/app/item/items.component.ts` should import the version string: ```ts title="src/app/item/items.component.ts" // highlight-next-line import { version } from 'xlsx'; import { Component, OnInit } from '@angular/core' // ... export class ItemsComponent implements OnInit { items: Array // highlight-next-line version = `SheetJS - ${version}`; constructor(private itemService: ItemService) {} // ... ``` `src/app/item/items.component.html` should use the version in the title: ```xml title="src/app/item/items.component.html" ``` Relaunch the app with `ns run ios` and the title bar should show the version. ![NativeScript Step 4](pathname:///mobile/nativescript4.png) 5) Add the Import and Export buttons to the template: ```xml title="src/app/item/items.component.html" ``` ```ts title="src/app/item/items.component.ts" // highlight-start import { version, utils, read, write } from 'xlsx'; import { Dialogs, getFileAccess } from '@nativescript/core'; import { Folder, knownFolders, path } from '@nativescript/core/file-system'; // highlight-end import { Component, OnInit } from '@angular/core' import { Item } from './item' import { ItemService } from './item.service' // highlight-start function get_url_for_filename(filename: string): string { const target: Folder = knownFolders.documents() || knownFolders.ios.sharedPublic(); return path.normalize(target.path + "///" + filename); } // highlight-end @Component({ selector: 'ns-items', templateUrl: './items.component.html', }) export class ItemsComponent implements OnInit { items: Array version: string = `SheetJS - ${version}`; constructor(private itemService: ItemService) {} ngOnInit(): void { this.items = this.itemService.getItems() } // highlight-start /* Import button */ async import() { } /* Export button */ async export() { } // highlight-end } ``` Restart the app process and two buttons should show up at the top: ![NativeScript Step 5](pathname:///mobile/nativescript5.png) 6) Implement import and export by adding the highlighted lines: ```ts title="src/app/item/items.component.ts" /* Import button */ async import() { // highlight-start /* find appropriate path */ const url = get_url_for_filename("SheetJSNS.xls"); try { await Dialogs.alert(`Attempting to read from SheetJSNS.xls at ${url}`); /* get data */ const ab: ArrayBuffer = await getFileAccess().readBufferAsync(url); /* read workbook */ const wb = read(ab); /* grab first sheet */ const wsname: string = wb.SheetNames[0]; const ws = wb.Sheets[wsname]; /* update table */ this.items = utils.sheet_to_json(ws); } catch(e) { await Dialogs.alert(e.message); } // highlight-end } /* Export button */ async export() { // highlight-start /* find appropriate path */ const url = get_url_for_filename("SheetJSNS.xls"); try { /* create worksheet from data */ const ws = utils.json_to_sheet(this.items); /* create workbook from worksheet */ const wb = utils.book_new(); utils.book_append_sheet(wb, ws, "Sheet1"); /* generate Uint8Array */ const u8: Uint8Array = write(wb, { bookType: 'xls', type: 'buffer' }); /* attempt to save Uint8Array to file */ await getFileAccess().writeBufferAsync(url, u8); await Dialogs.alert(`Wrote to SheetJSNS.xls at ${url}`); } catch(e) { await Dialogs.alert(e.message); } // highlight-end } ``` ### iOS Relaunch the app with `ns run ios` The app can be tested with the following sequence in the simulator: - Tap "Export File". A dialog will print where the file was written - Open the file with a spreadsheet editor. After the header row, insert a row with cell A2 = 0, B2 = SheetJS, C2 = Library: ``` id | name | role 0 | SheetJS | Library 1 | Ter Stegen | Goalkeeper 3 | Piqué | Defender ... ``` Restart the app after saving the file. - Tap "Import File". A dialog will print the path of the file that was read. The first item in the list will change: ![NativeScript Step 7](pathname:///mobile/nativescript7.png)