diff --git a/docz/docs/03-demos/06-network.mdx b/docz/docs/03-demos/06-network.mdx index 555156b..166d121 100644 --- a/docz/docs/03-demos/06-network.mdx +++ b/docz/docs/03-demos/06-network.mdx @@ -482,3 +482,37 @@ function SheetJSSuperAgentUL() { ``` + +## NodeJS Demos + +This demo focuses on a number of strategies. Some of these demos were written +before NodeJS added `fetch`. + +### request + +:::warning + +`request` has been deprecated and should only be used in legacy deployments. + +::: + +Setting the option `encoding: null` passes raw buffers: + +```js +var XLSX = require('xlsx'), request = require('request'); +var url = 'https://sheetjs.com/pres.numbers'; + +/* call `request` with the option `encoding: null` */ +// highlight-next-line +request(url, {encoding: null}, function(err, res, data) { + if(err || res.statusCode !== 200) return; + + /* if the request was succesful, parse the data */ + // highlight-next-line + var wb = XLSX.read(data); + + /* print the first worksheet to console */ + var ws = wb.Sheets[wb.SheetNames[0]]; + console.log(XLSX.utils.sheet_to_csv(ws, {blankrows:false})); +}); +``` \ No newline at end of file diff --git a/docz/docs/03-demos/24-server.md b/docz/docs/03-demos/24-server.md index 1690076..453b2bd 100644 --- a/docz/docs/03-demos/24-server.md +++ b/docz/docs/03-demos/24-server.md @@ -1,5 +1,5 @@ --- -sidebar_position: 23 +sidebar_position: 24 title: HTTP Server Processing --- @@ -65,7 +65,7 @@ require("http").createServer(function(req, res) { ## Deno -:::warning +:::caution Many hosted services like Deno Deploy do not offer filesystem access. @@ -222,4 +222,196 @@ Click "Choose File" and select `pres.numbers`. Then click "Submit" The page should show the contents of the file as an HTML table. + + +## NodeJS + +### Express + +The `express-formidable` middleware is powered by the `formidable` parser. It +adds a `files` property to the request. + +When downloading binary data, Express handles `Buffer` data in `res.end`. The +convenience `attachment` method adds the required header: + +```js +// Header 'Content-Disposition: attachment; filename="SheetJS.xlsx"' +res.attachment("SheetJS.xlsx"); +``` + +The following demo Express server will respond to POST requests to `/upload` +with a CSV output of the first sheet. It will also respond to GET requests to +`/download`, responding with a fixed XLSX worksheet: + +```js title="SheetJSExpressCSV.js" +var XLSX = require('xlsx'), express = require('express'); + +/* create app */ +var app = express(); +/* add express-formidable middleware */ +// highlight-next-line +app.use(require('express-formidable')()); +/* route for handling uploaded data */ +app.post('/upload', function(req, res) { + // highlight-start + var f = req.files["upload"]; // + var wb = XLSX.readFile(f.path); + // highlight-end + /* respond with CSV data from the first sheet */ + res.status(200).end(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])); +}); +app.get('/download', function(req, res) { + /* generate workbook object */ + var ws = XLSX.utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]); + var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Data"); + // highlight-start + /* generate buffer */ + var buf = XLSX.write(wb, {type: "buffer", bookType: "xlsx"}); + /* set headers */ + res.attachment("SheetJSExpress.xlsx"); + /* respond with file data */ + res.status(200).end(buf); + // highlight-end +}); +app.listen(+process.env.PORT||3000); +``` + +
Testing (click to show) + +0) Save the code sample to `SheetJSExpressCSV.js` + +1) Install dependencies: + +```bash +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz express express-formidable +``` + +2) Start server (note: it will not print anything to console when running) + +```bash +node SheetJSExpressCSV.js +``` + +3) Test POST requests using : + +```bash +curl -LO https://sheetjs.com/pres.numbers +curl -X POST -F upload=@pres.numbers http://localhost:3000/upload +``` + +The response should show the data in CSV rows. + +4) Test GET requests by opening http://localhost:3000/download in your browser. + +It should prompt to download `SheetJSExpress.xlsx` + +
+ +### NestJS + +[The NestJS docs](https://docs.nestjs.com/techniques/file-upload) have detailed +instructions for file upload support. In the controller, the `path` property +works with `XLSX.readFile`. + +When downloading binary data, NestJS expects `StreamableFile`-wrapped Buffers. + +The following demo NestJS Controller will respond to POST requests to `/upload` +with a CSV output of the first sheet. It will also respond to GET requests to +`/download`, responding with a fixed export: + +```ts title="src/sheetjs/sheetjs.controller.js" +import { Controller, Get, Header, Post, StreamableFile, UploadedFile, UseInterceptors } from '@nestjs/common'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { readFile, utils } from 'xlsx'; + +@Controller('sheetjs') +export class SheetjsController { + @Post('upload') // + @UseInterceptors(FileInterceptor('upload')) + async uploadXlsxFile(@UploadedFile() file: Express.Multer.File) { + /* file.path is a path to the workbook */ + // highlight-next-line + const wb = readFile(file.path); + /* generate CSV of first worksheet */ + return utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]); + } + + @Get('download') + @Header('Content-Disposition', 'attachment; filename="SheetJSNest.xlsx"') + async downloadXlsxFile(): Promise { + var ws = utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]); + var wb = utils.book_new(); utils.book_append_sheet(wb, ws, "Data"); + // highlight-start + /* generate buffer */ + var buf = write(wb, {type: "buffer", bookType: "xlsx"}); + /* Return a streamable file */ + return new StreamableFile(buf); + // highlight-end + } +} +``` + +
Testing (click to show) + +1) Create a new project: + +```bash +npx @nestjs/cli new -p npm sheetjs-nest +cd sheetjs-nest +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +npm i --save-dev @types/multer +mkdir -p upload +``` + +2) Create a new controller and a new module: + +```bash +npx @nestjs/cli generate module sheetjs +npx @nestjs/cli generate controller sheetjs +``` + +3) Add Multer to the new module by editing `src/sheetjs/sheetjs.module.ts`. +Changes are highlighted below: + +```ts title="src/sheetjs/sheetjs.module.ts" +import { Module } from '@nestjs/common'; +import { SheetjsController } from './sheetjs.controller'; +// highlight-next-line +import { MulterModule } from '@nestjs/platform-express'; + +@Module({ +// highlight-start + imports: [ + MulterModule.register({ + dest: './upload', + }), + ], +// highlight-end + controllers: [SheetjsController] +}) +export class SheetjsModule {} +``` + +4) Copy the `src/sheetjs/sheetjs.controller.ts` example from earlier, replacing +the contents of the existing file. + +5) Start the server with + +```bash +npx @nestjs/cli start +``` + +3) Test POST requests using : + +```bash +curl -LO https://sheetjs.com/pres.numbers +curl -X POST -F upload=@pres.numbers http://localhost:3000/sheetjs/upload +``` + +The response should show the data in CSV rows. + +4) Test GET requests by opening http://localhost:3000/sheetjs/download in your browser. + +It should prompt to download `SheetJSNest.xlsx` +
\ No newline at end of file