7.6 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	| title | pagination_prev | pagination_next | sidebar_position | sidebar_custom_props | ||
|---|---|---|---|---|---|---|
| NativeScript | demos/static/index | demos/desktop/index | 2 | 
 | 
import current from '/version.js';
The NodeJS Module 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 | 
|---|
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:
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:
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:
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.
:::
- 
Follow the official Environment Setup instructions 
- 
Create a skeleton NativeScript + Angular app: 
ns create SheetJSNS --ng
- Launch the app in the iOS simulator to verify that the demo built properly:
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
- From the project folder, install the library:
{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
- 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:
// highlight-next-line
import { version } from 'xlsx';
import { Component, OnInit } from '@angular/core'
// ...
export class ItemsComponent implements OnInit {
  items: Array<Item>
  // highlight-next-line
  version = `SheetJS - ${version}`;
  constructor(private itemService: ItemService) {}
// ...
src/app/item/items.component.html should use the version in the title:
<!-- highlight-next-line -->
<ActionBar [title]="version"></ActionBar>
<GridLayout>
<!-- ... -->
Relaunch the app with ns run ios and the title bar should show the version.
- Add the Import and Export buttons to the template:
<ActionBar [title]="version"></ActionBar>
<!-- highlight-start -->
<StackLayout>
  <StackLayout orientation="horizontal">
    <Button text="Import File" (tap)="import()" style="padding: 10px"></Button>
    <Button text="Export File" (tap)="export()" style="padding: 10px"></Button>
  </StackLayout>
<!-- highlight-end -->
  <ListView [items]="items">
    <!-- ... -->
  </ListView>
<!-- highlight-next-line -->
</StackLayout>
// 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<Item>
  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:
- Implement import and export by adding the highlighted lines:
  /* 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<Item>(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:



