This commit is contained in:
SheetJS 2023-05-21 03:03:46 -04:00
parent 8000cfcbd7
commit 173ba31e0a
6 changed files with 216 additions and 12 deletions

@ -7,6 +7,8 @@ title: HTTP Network Requests
<script src="https://unpkg.com/superagent@7.1.1/dist/superagent.min.js"></script>
</head>
import current from '/version.js';
import CodeBlock from '@theme/CodeBlock';
`XMLHttpRequest` and `fetch` browser APIs enable binary data transfer between
web browser clients and web servers. Since this library works in web browsers,
@ -376,6 +378,7 @@ function SheetJSAxiosDL() {
/* Fetch and update HTML */
React.useEffect(async() => {
if(typeof axios != "function") return setHTML("ReferenceError: axios is not defined");
/* Fetch file */
const res = await axios("https://sheetjs.com/pres.numbers", {responseType: "arraybuffer"});
@ -479,6 +482,8 @@ function SheetJSSuperAgentDL() {
/* Fetch and update HTML */
React.useEffect(async() => {
if(typeof superagent == "undefined" || typeof superagent.get != "function")
return setHTML("ReferenceError: superagent is not defined");
/* Fetch file */
superagent
.get("https://sheetjs.com/pres.numbers")
@ -557,7 +562,7 @@ These examples show how to download data in NodeJS.
The `https` module provides a low-level `get` method for HTTPS GET requests:
```js
```js title="SheetJSHTTPSGet.js"
var https = require("https"), XLSX = require("xlsx");
https.get('https://sheetjs.com/pres.numbers', function(res) {
@ -573,6 +578,26 @@ https.get('https://sheetjs.com/pres.numbers', function(res) {
});
```
<details><summary><b>Complete Example</b> (click to show)</summary>
:::note
This demo was last tested on 2023 May 21 against NodeJS `18.16.0`
:::
1) Install the [NodeJS module](/docs/getting-started/installation/nodejs)
<CodeBlock language="bash">{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
</CodeBlock>
2) Copy the `SheetJSHTTPSGet.js` code snippet to a file `SheetJSHTTPSGet.js`
3) Run `node SheetJSHTTPSGet.js`. It will print CSV contents of the test file.
</details>
### fetch
The `fetch` implementation has the same return types as the browser version:
@ -587,6 +612,45 @@ async function parse_from_url(url) {
}
```
<details><summary><b>Complete Example</b> (click to show)</summary>
:::note
This demo was last tested on 2023 May 21 against NodeJS `18.16.0`
:::
1) Install the [NodeJS module](/docs/getting-started/installation/nodejs)
<CodeBlock language="bash">{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
</CodeBlock>
2) Save the following to `SheetJSFetch.js`:
```js title="SheetJSFetch.js"
var XLSX = require("xlsx");
async function parse_from_url(url) {
const res = await fetch(url);
if(!res.ok) throw new Error("fetch failed");
const ab = await res.arrayBuffer();
const workbook = XLSX.read(ab);
return workbook;
}
(async() => {
const wb = await parse_from_url('https://sheetjs.com/pres.numbers');
/* print the first worksheet to console */
var ws = wb.Sheets[wb.SheetNames[0]];
console.log(XLSX.utils.sheet_to_csv(ws));
})();
```
3) Run `node SheetJSFetch.js`. It will print CSV contents of the test file.
</details>
### Wrapper Libraries
The latest releases of NodeJS support `fetch` natively. Before `fetch` support
@ -602,7 +666,7 @@ was added to the platform, third party modules wrapped the native APIs.
Setting the option `encoding: null` passes raw buffers:
```js
```js title="SheetJSRequest.js"
var XLSX = require('xlsx'), request = require('request');
var url = 'https://sheetjs.com/pres.numbers';
@ -621,12 +685,32 @@ request(url, {encoding: null}, function(err, res, data) {
});
```
<details><summary><b>Complete Example</b> (click to show)</summary>
:::note
This demo was last tested on 2023 May 21 against request `2.88.2`
:::
1) Install the [NodeJS module](/docs/getting-started/installation/nodejs)
<CodeBlock language="bash">{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz request@2.88.2`}
</CodeBlock>
2) Copy the `SheetJSRequest.js` code snippet to a file `SheetJSRequest.js`
3) Run `node SheetJSRequest.js`. It will print CSV contents of the test file.
</details>
#### axios
When the `responseType` is `"arraybuffer"`, `axios` actually captures the data
in a NodeJS Buffer. `XLSX.read` will transparently handle Buffers:
```js
```js title="SheetJSAxios.js"
const XLSX = require("xlsx"), axios = require("axios");
async function workbook_dl_axios(url) {
@ -636,3 +720,48 @@ async function workbook_dl_axios(url) {
return workbook;
}
```
<details><summary><b>Complete Example</b> (click to show)</summary>
:::note
This demo was last tested on 2023 May 21 against Axios `1.4.0`
:::
1) Install the [NodeJS module](/docs/getting-started/installation/nodejs)
<CodeBlock language="bash">{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz axios@1.4.0`}
</CodeBlock>
2) Save the following to `SheetJSAxios.js`:
```js title="SheetJSAxios.js"
const XLSX = require("xlsx"), axios = require("axios");
async function workbook_dl_axios(url) {
const res = await axios(url, {responseType:'arraybuffer'});
/* at this point, res.data is a Buffer */
const workbook = XLSX.read(res.data);
return workbook;
}
(async() => {
const wb = await workbook_dl_axios('https://sheetjs.com/pres.numbers');
/* print the first worksheet to console */
var ws = wb.Sheets[wb.SheetNames[0]];
console.log(XLSX.utils.sheet_to_csv(ws));
})();
```
3) Run `node SheetJSAxios.js`. It will print CSV contents of the test file.
</details>
## Other Platforms
Other demos show network operations in special platforms:
- [React Native "Fetching Remote Data"](/docs/demos/mobile/reactnative#fetching-remote-data)
- [NativeScript "Fetching Remote Files"](/docs/demos/mobile/nativescript#fetching-remote-files)

@ -20,11 +20,11 @@ The "Complete Example" creates an app that looks like the screenshots below:
<th><a href="#demo">Android</a></th>
</tr></thead><tbody><tr><td>
![iOS screenshot](pathname:///mobile/nsios.png)
![iOS screenshot](pathname:///nativescript/ios.png)
</td><td>
![Android screenshot](pathname:///mobile/nsand.png)
![Android screenshot](pathname:///nativescript/and.png)
</td></tr></tbody></table>
@ -49,12 +49,13 @@ function get_url_for_filename(filename: string): string {
}
```
#### Reading data
### Reading Local Files
`getFileAccess().readBufferAsync` can read data:
```ts
import { getFileAccess } from '@nativescript/core';
import { read } from 'xlsx';
/* find appropriate path */
const url = get_url_for_filename("SheetJSNS.xls");
@ -66,13 +67,14 @@ const ab: ArrayBuffer = await getFileAccess().readBufferAsync(url);
const wb = read(ab);
```
#### Writing data
### Writing Local Files
`getFileAccess().writeBufferAsync` can write data. iOS supports `Uint8Array`
directly but Android requires a true array of numbers:
```ts
import { getFileAccess } from '@nativescript/core';
import { write } from 'xlsx';
/* find appropriate path */
const url = get_url_for_filename("SheetJSNS.xls");
@ -84,15 +86,40 @@ const u8: Uint8Array = write(wb, { bookType: 'xls', type: 'binary' });
await getFileAccess().writeBufferAsync(url, global.isAndroid ? (Array.from(u8) as any) : u8);
```
### Fetching Remote Files
`getFile` from `@nativescript/core/http` can download files. After storing the
file in a temporary folder, `getFileAccess().readBufferAsync` can read the data:
```ts
import { knownFolders, path, getFileAccess } from '@nativescript/core'
import { getFile } from '@nativescript/core/http';
import { read } from 'xlsx';
/* generate temporary path for the new file */
const temp: string = path.join(knownFolders.temp().path, "pres.xlsx");
/* download file */
const file = await getFile("https://sheetjs.com/pres.xlsx", temp)
/* get data */
const ab: ArrayBuffer = await getFileAccess().readBufferAsync(file.path);
/* read workbook */
const wb = read(ab);
```
## Demo
:::note
This demo was tested on an Intel Mac on 2023 May 07. NativeScript version
This demo was tested on an Intel Mac on 2023 May 21. NativeScript version
(as verified with `ns --version`) is `8.5.3`.
The iOS simulator runs iOS 16.2 on an iPhone 14 Pro Max.
The Android simulator runs Android 12.0 (S) API 31 on a Pixel 3.
:::
0) Follow the official Environment Setup instructions
@ -158,6 +185,8 @@ Relaunch the app with `ns run ios` and the title bar should show the version.
![NativeScript Step 4](pathname:///mobile/nativescript4.png)
### Local Files
5) Add the Import and Export buttons to the template:
```xml title="src/app/item/items.component.html"
@ -340,4 +369,49 @@ adb push SheetJSNS.xls /data/user/0/org.nativescript.SheetJSNS/files/SheetJSNS.x
```
- Tap "Import File". A dialog will print the path of the file that was read.
The first item in the list will change.
The first item in the list will change.
### Fetching Files
7) In `src/app/item/items.component.ts`, make `ngOnInit` asynchronous:
```ts title="src/app/item/items.component.ts"
async ngOnInit(): Promise<void> {
this.items = await this.itemService.getItems()
}
```
8) Replace `item.service.ts` with the following:
```ts title="src/app/item/item.service.ts"
import { Injectable } from '@angular/core'
import { knownFolders, path, getFileAccess } from '@nativescript/core'
import { getFile } from '@nativescript/core/http';
import { read, utils } from 'xlsx';
import { Item } from './item'
interface IPresident { Name: string; Index: number };
@Injectable({ providedIn: 'root' })
export class ItemService {
private items: Array<Item>;
async getItems(): Promise<Array<Item>> {
/* fetch https://sheetjs.com/pres.xlsx */
const temp: string = path.join(knownFolders.temp().path, "pres.xlsx");
const ab = await getFile("https://sheetjs.com/pres.xlsx", temp)
/* read the temporary file */
const wb = read(await getFileAccess().readBufferAsync(ab.path));
/* translate the first worksheet to the required Item type */
const data = utils.sheet_to_json<IPresident>(wb.Sheets[wb.SheetNames[0]]);
return this.items = data.map((pres, id) => ({id, name: pres.Name, role: ""+pres.Index} as Item));
}
getItem(id: number): Item {
return this.items.filter((item) => item.id === id)[0]
}
}
```
Relaunching the app in iOS or Android simulator should show Presidential data.

@ -107,9 +107,10 @@ The resulting `buf` can be written to file with `fwrite`.
This demo was tested in the following deployments:
| V8 Version | Platform | OS Version | Compiler | Date |
|:--------------|:-------------|:-----------|:---------------|:-----------|
| `11.3.244.11` | `darwin-x64` | macOS 13.2 | `clang 14.0.3` | 2023-05-20 |
| V8 Version | Platform | OS Version | Compiler | Date |
|:--------------|:-------------|:-------------|:---------------|:-----------|
| `11.3.244.11` | `darwin-x64` | macOS 13.2 | `clang 14.0.3` | 2023-05-20 |
| `11.3.244.11` | `linux-x64` | HoloOS 3.4.6 | `gcc 12.2.0` | 2023-05-20 |
:::

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB