sheetjs/demos/server/README.md

199 lines
6.1 KiB
Markdown
Raw Normal View History

# NodeJS Server Deployments
This library is 100% pure JS. This is great for compatibility but tends to lock
up long-running processes. In the web browser, Web Workers are used to offload
work from the main browser thread. In NodeJS, there are other strategies. This
demo shows a few different strategies applied to different server frameworks.
NOTE: these examples merely demonstrate the core concepts and do not include
appropriate error checking or other production-level features.
### Express Setup
The following commands are required in order to test the [Express](https://github.com/expressjs/express) demo:
```bash
npm install express printj xlsx express-formidable
node express.js
```
### Koa Setup
The following commands are required in order to test the [Koa](https://github.com/koajs/koa) demo:
```bash
npm install koa printj formidable xlsx
node koa.js
2022-02-26 05:48:40 +00:00
```
### Hapi Setup
**Note: Hapi demo as written only works with Hapi version 16 and below.**
The following commands are required in order to test the [Hapi](https://github.com/hapijs/hapi) demo:
```bash
npm install hapi@16.x printj tiny-worker xlsx
node hapi.js
2022-02-26 05:48:40 +00:00
```
### Node Buffer
The `read` and `write` functions can handle `Buffer` data with `type:"buffer"`.
For example, the `request` library returns data in a buffer:
```js
var XLSX = require('xlsx'), request = require('request');
request(url, {encoding: null}, function(err, res, data) {
if(err || res.statusCode !== 200) return;
/* data is a node Buffer that can be passed to XLSX.read */
var workbook = XLSX.read(data, {type:'buffer'});
/* DO SOMETHING WITH workbook HERE */
});
```
2017-09-24 23:40:09 +00:00
The `readFile` / `writeFile` functions wrap `fs.{read,write}FileSync`:
```js
/* equivalent to `var wb = XLSX.readFile("sheetjs.xlsx");` */
var buf = fs.readFileSync("sheetjs.xlsx");
var wb = XLSX.read(buf, {type:'buffer'});
```
### Responding to Form Uploads
Using `formidable`, files uploaded to forms are stored to temporary files that
can be read with `readFile`:
```js
/* within the server callback function(request, response) { */
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
var f = files[Object.keys(files)[0]];
var workbook = XLSX.readFile(f.path);
/* DO SOMETHING WITH workbook HERE */
});
```
The `node.js` demo shows a plain HTTP server that accepts file uploads and
converts data to requested output format.
2017-09-24 23:40:09 +00:00
### Example servers
Each example server is expected to hold an array-of-arrays in memory. They are
expected to handle:
- `POST / ` accepts an encoded `file` and updates the internal storage
- `GET /?t=<type>` returns the internal storage in the specified type
- `POST /?f=<name>` reads the local file and updates the internal storage
- `GET /?f=<name>` writes the file to the specified name
Testing with cURL is straightforward:
```bash
# upload sheetjs.csv and update data
curl -X POST -F "data=@sheetjs.csv" http://localhost:7262/
# download data in SYLK format
curl -X GET http://localhost:7262/?t=slk
# read sheetjs.csv from the server directory
curl -X POST http://localhost:7262/?f=sheetjs.csv
# write sheetjs.xlsb in the XLSB format
curl -X GET http://localhost:7262/?f=sheetjs.xlsb
```
## Main-process logic with express
The most straightforward approach is to handle the data directly in HTTP event
handlers. The `buffer` type for `XLSX.read` and `XLSX.write` work with `http`
module and with express directly. The following snippet generates a workbook
based on an array of arrays and sends it to the client:
```js
function send_aoa_to_client(req, res, data, bookType) {
/* generate workbook */
var ws = XLSX.utils.aoa_to_sheet(data);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
/* generate buffer */
var buf = XLSX.write(wb, {type:'buffer', bookType:bookType || "xlsx"});
/* send to client */
res.status(200).send(buf);
}
```
## fork with koa
`child_process.fork` provides a light-weight and customizable way to offload
work from the main server process. This demo passes commands to a custom child
process and the child passes back buffers of data.
The main server script is `koa.js` and the worker script is `koasub.js`. State
is maintained in the worker script.
2017-09-24 23:40:09 +00:00
## tiny-worker with hapi
`tiny-worker` provides a Web Worker-like interface. Binary strings and simple
objects are readily passed across the Worker divide.
The main server script is `hapi.js` and the worker script is `worker.js`. State
is maintained in the server script.
Note: due to an issue with hapi payload parsing, the route `POST /file` is used
to handle the case of reading from file, so the cURL test is:
```bash
# upload sheetjs.csv and update data
curl -X POST -F "data=@sheetjs.csv" http://localhost:7262/
2017-09-24 23:40:09 +00:00
# download data in SYLK format
curl -X GET http://localhost:7262/?t=slk
# read sheetjs.csv from the server directory
curl -X POST http://localhost:7262/file?f=sheetjs.csv
2017-09-24 23:40:09 +00:00
# write sheetjs.xlsb in the XLSB format
curl -X GET http://localhost:7262/?f=sheetjs.xlsb
```
2022-02-26 05:48:40 +00:00
## NestJS
[NestJS](https://nestjs.com/) is a Node.js framework for server-side web applications.
This demo uses SheetJS to parse a spreadsheet via a POST API endpoint. The file
arrives to the endpoint as body `form-data`, accessible using the `file` key.
2022-02-26 05:48:40 +00:00
After parsing the file, CSV contents of the first worksheet will be returned.
[Body parsing uses `multer`](https://docs.nestjs.com/techniques/file-upload).
Before running the demo, the NestJS CLI tool must be installed. The instruction
is described in the NestJS ["First Steps"](https://docs.nestjs.com/first-steps):
```bash
npm i -g @nestjs/cli
make nest
```
The demo can be tested using the `/sheetjs/upload-xlsx-file` endpoint:
```bash
curl -X POST -F "file=@test.xlsx" http://localhost:3000/sheetjs/upload-xlsx-file
```
The included [`nest.sh`](./nest.sh) script creates and configures the project.
This demo creates a module and a controller. The controller handles the actual
requests (creating the endpoint) while the module is used to configure `multer`.
2017-09-24 23:40:09 +00:00
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)