Skip to main content

Sheets in Elysia

Elysia is a BunJS server-side framework.

SheetJS 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" section includes a complete server.

Tested Deployments

This demo was last tested on 2024 March 11 with ElysiaJS 0.8.17 and BunJS 1.0.30.

Integration Details​

The SheetJS BunJS module can be imported from ElysiaJS server scripts.

Reading Data​

The ElysiaJS body parser accepts a schema1. 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:

{
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 method2.

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 method3 and respond with the HTML code:

import { Elysia, t } from "elysia";
import { read, utils } from "xlsx";

const app = new Elysia();
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);

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 arrays5, build up a new workbook using the book_new6 and book_append_sheet7 utility methods, generate a XLSX file using write, and send the file with appropriate headers to initiate a download with file name SheetJSElysia.xlsx:

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");
/* generate buffer */
var buf = write(wb, {type: "buffer", bookType: "xlsx"});
return new File([buf], "SheetJSElysia.xlsx");
});
app.listen(3000);

Complete Example​

  1. Create a new ElysiaJS project:
bun create elysia sheetjs-elysia
cd sheetjs-elysia
  1. Install the SheetJS BunJS module:
bun install https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
  1. Save the following script to src/SheetJSElysia.ts:
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);
  1. Run the server:
bun run src/SheetJSElysia.ts
  1. Test POST requests using https://docs.sheetjs.com/pres.numbers . The commands should be run in a new terminal window:
curl -LO https://docs.sheetjs.com/pres.numbers
curl -X POST -F upload=@pres.numbers http://localhost:3000/
  1. Test GET requests by opening http://localhost:3000/ in your browser.

The page should attempt to download SheetJSElysia.xlsx . Open the new file.

Footnotes​

  1. See "Explicit Body" in the ElysiaJS documentation. ↩

  2. See read in "Reading Files" ↩

  3. See sheet_to_html in "Utilities" ↩

  4. See write in "Writing Files" ↩

  5. See aoa_to_sheet in "Utilities" ↩

  6. See book_new in "Utilities" ↩

  7. See book_append_sheet in "Utilities" ↩