docs.sheetjs.com/docz/docs/03-demos/03-net/03-server/09-elysia.md

173 lines
5.1 KiB
Markdown
Raw Permalink Normal View History

2023-10-18 02:07:06 +00:00
---
title: Sheets in Elysia
sidebar_label: ElysiaJS
2023-11-20 02:51:39 +00:00
pagination_prev: demos/net/network/index
2023-10-23 01:20:18 +00:00
pagination_next: demos/net/email/index
2023-10-18 02:07:06 +00:00
---
import current from '/version.js';
import CodeBlock from '@theme/CodeBlock';
[Elysia](https://elysiajs.com/) is a BunJS server-side framework.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses ElysiaJS and SheetJS to read and write data. We'll explore how to
parse uploaded files in a POST request handler and respond to GET requests with
downloadable spreadsheets.
The ["Complete Example"](#complete-example) section includes a complete server.
2024-03-12 06:47:52 +00:00
:::note Tested Deployments
2023-10-18 02:07:06 +00:00
2024-03-12 06:47:52 +00:00
This demo was last tested on 2024 March 11 with ElysiaJS 0.8.17 and BunJS 1.0.30.
2023-10-18 02:07:06 +00:00
:::
## Integration Details
The [SheetJS BunJS module](/docs/getting-started/installation/bun) can be
imported from ElysiaJS server scripts.
### Reading Data
The ElysiaJS body parser accepts a schema[^1]. The `t.File` method marks that a
field is expected to be a file.
The following schema indicates the field `upload` should be a submitted file:
```js
{
body: t.Object({
upload: t.File()
})
}
```
ElysiaJS exposes the file as a `Blob` object. The `Blob#arrayBuffer` method
returns a Promise that resolves to an `ArrayBuffer`. That `ArrayBuffer` can be
parsed with the SheetJS `read` method[^2].
This example server responds to POST requests. The server will look for a file
in the request body under the `"upload"` key. If a file is present, the server
will parse the file, generate an HTML table using the `sheet_to_html` method[^3]
and respond with the HTML code:
```js
import { Elysia, t } from "elysia";
import { read, utils } from "xlsx";
const app = new Elysia();
app.post("/", async({ body: { upload } }) => {
// highlight-start
const data = await upload.arrayBuffer();
const wb = read(data);
// highlight-end
return utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);
}, {
body: t.Object({
// highlight-next-line
upload: t.File()
})
});
app.listen(3000);
```
### Writing Data
Given a SheetJS workbook object, the `write` method using `type: "buffer"`[^4]
generates data objects which can be passed to the BunJS `File` constructor. The
`File` constructor accepts a second parameter for the generated file name.
This example server responds to GET requests. The server will generate a SheetJS
worksheet object from an array of arrays[^5], build up a new workbook using the
`book_new`[^6] and `book_append_sheet`[^7] utility methods, generate a XLSX file
using `write`, and send the file with appropriate headers to initiate a download
with file name `SheetJSElysia.xlsx`:
```js
import { Elysia } from "elysia";
import { utils, write } from "xlsx";
const app = new Elysia();
app.get("/", () => {
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 new File([buf], "SheetJSElysia.xlsx");
// highlight-end
});
app.listen(3000);
```
## Complete Example
1) Create a new ElysiaJS project:
```bash
bun create elysia sheetjs-elysia
cd sheetjs-elysia
```
2) Install the [SheetJS BunJS module](/docs/getting-started/installation/bun):
<CodeBlock language="bash">{`\
bun install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
</CodeBlock>
3) Save the following script to `src/SheetJSElysia.ts`:
```ts title="src/SheetJSElysia.ts"
import { Elysia, t } from "elysia";
import { read, utils, write } from "xlsx";
const app = new Elysia();
app.get("/", () => {
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");
/* generate buffer */
var buf = write(wb, {type: "buffer", bookType: "xlsx"});
return new File([buf], "SheetJSElysia.xlsx");
/* set headers */
});
app.post("/", async({ body: { upload } }) => {
const data = await upload.arrayBuffer();
const wb = read(data);
return utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);
}, {
body: t.Object({
upload: t.File()
})
});
app.listen(3000);
```
4) Run the server:
```bash
bun run src/SheetJSElysia.ts
```
2024-04-26 04:16:13 +00:00
5) Test POST requests using https://docs.sheetjs.com/pres.numbers . The commands
should be run in a new terminal window:
2023-10-18 02:07:06 +00:00
```bash
2024-04-26 04:16:13 +00:00
curl -LO https://docs.sheetjs.com/pres.numbers
2023-10-18 02:07:06 +00:00
curl -X POST -F upload=@pres.numbers http://localhost:3000/
```
6) Test GET requests by opening `http://localhost:3000/` in your browser.
The page should attempt to download `SheetJSElysia.xlsx` . Open the new file.
[^1]: See ["Explicit Body"](https://elysiajs.com/concept/explicit-body.html) in the ElysiaJS documentation.
[^2]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^3]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output)
[^4]: See [`write` in "Writing Files"](/docs/api/write-options)
[^5]: See [`aoa_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-arrays-input)
[^6]: See [`book_new` in "Utilities"](/docs/api/utilities/wb)
[^7]: See [`book_append_sheet` in "Utilities"](/docs/api/utilities/wb)