Skip to main content

HTTP Uploads

Browsers and other platforms offer solutions for uploading files to servers and cloud storage solutions. Spreadsheets can be written using SheetJS and uploaded.

This demo explores file uploads using a number of browser APIs and wrapper libraries. The upload process will generate a sample XLSX workbook, upload the file to a test server, and display the response.

This demo focuses on uploading files. Other demos cover other HTTP use cases:

Third-Party Hosts and Binary Data

Third-party cloud platforms such as AWS may corrupt raw binary uploads by encoding requests and responses in UTF-8 strings.

For AWS, in the "Binary Media Types" section of the API Gateway console, the "multipart/form-data" type should be added to ensure that AWS Lambda functions can receive uploads from clients.

Uploading Binary Data

The SheetJS write method1 generates file data stored in ArrayBuffer objects. The ArrayBuffer can be added to a FormData object. The FormData object can be passed along to POST requests.

/* create sample SheetJS workbook object */
var aoa = [
["S", "h", "e", "e", "t", "J", "S"],
[ 5, 4, 3, 3, 7, 9, 5]
];
var ws = XLSX.utils.aoa_to_sheet(aoa);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

/* export SheetJS workbook object to XLSX file bytes */
var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'});

/* build FormData with the generated file */
var fdata = new FormData();
fdata.append('file', new File([data], 'sheetjs.xlsx'));
// field name ^^^^ file name ^^^^^^^^^^^^

/* send data using XMLHttpRequest */
var req = new XMLHttpRequest();
req.open("POST", "https://s2c.sheetjs.com", true);
req.send(fdata);

Test Server

The https://s2c.sheetjs.com service is currently hosted on Deno Deploy. The "Deno Deploy" demo covers the exact steps for deploying the service.

The CORS-enabled service handles POST requests by looking for uploaded files in the "file" key. If a file is found, the file will be parsed using the SheetJS read method2 and the first worksheet will be converted to HTML using the sheet_to_html method3.

Browser Demos

When the upload button is clicked, the browser will build up a new workbook, generate a XLSX file, upload it to https://s2c.sheetjs.com and show the response. If the process was successful, a HTML table will be displayed

Tested Deployments

Each browser demo was tested in the following environments:

BrowserDate
Chrome 1202024-01-15
Safari 17.22023-01-15

XMLHttpRequest

This demo uses the code snippet from the intro.

Live demo (click to show)

This demo starts from an array of arrays of data. When the button is clicked, a workbook file will be generated and uploaded to https://s2c.sheetjs.com. The service will return a HTML table.

Result
Loading...
Live Editor

fetch

fetch takes a second parameter which allows for setting POST request body:

/* create sample SheetJS workbook object */
var aoa = [
["S", "h", "e", "e", "t", "J", "S"],
[ 5, 4, 3, 3, 7, 9, 5]
];
const ws = XLSX.utils.aoa_to_sheet(aoa);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

/* export SheetJS workbook object to XLSX file bytes */
var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'});

/* build FormData with the generated file */
var fdata = new FormData();
fdata.append('file', new File([data], 'sheetjs.xlsx'));
// field name ^^^^ file name ^^^^^^^^^^^^

/* send data using fetch */
fetch("https://s2c.sheetjs.com", { method: "POST", body: fdata });
Live demo (click to show)

This demo uses fetch to upload data to https://s2c.sheetjs.com. It will parse the workbook and return an HTML table.

Result
Loading...
Live Editor

Wrapper Libraries

Before fetch shipped with browsers, there were various wrapper libraries to simplify XMLHttpRequest. Due to limitations with fetch, these libraries are still relevant.

axios

axios presents a Promise based interface.

Uploading form data is nearly identical to the fetch example:

/* create sample SheetJS workbook object */
var aoa = [
["S", "h", "e", "e", "t", "J", "S"],
[ 5, 4, 3, 3, 7, 9, 5]
];
const ws = XLSX.utils.aoa_to_sheet(aoa);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

/* export SheetJS workbook object to XLSX file bytes */
var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'});

/* build FormData with the generated file */
var fdata = new FormData();
fdata.append('file', new File([data], 'sheetjs.xlsx'));
// field name ^^^^ file name ^^^^^^^^^^^^

/* send data using axios */
axios("https://s2c.sheetjs.com", { method: "POST", data: fdata });
Live demo (click to show)

This demo uses axios to upload data to https://s2c.sheetjs.com. It will parse the workbook and return an HTML table.

If the live demo shows a message

ReferenceError: axios is not defined

please refresh the page. This is a known bug in the documentation generator.

Result
Loading...
Live Editor

superagent

superagent is a network request library with a "Fluent Interface".

The send method accepts a FormData object as the first argument:

/* create sample SheetJS workbook object */
var aoa = [
["S", "h", "e", "e", "t", "J", "S"],
[ 5, 4, 3, 3, 7, 9, 5]
];
const ws = XLSX.utils.aoa_to_sheet(aoa);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

/* export SheetJS workbook object to XLSX file bytes */
var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'});

/* build FormData with the generated file */
var fdata = new FormData();
fdata.append('file', new File([data], 'sheetjs.xlsx'));
// field name ^^^^ file name ^^^^^^^^^^^^

/* send data (fd is the FormData object) */
superagent.post("https://s2c.sheetjs.com").send(fd);
Live demo (click to show)

This demo uses superagent to upload data to https://s2c.sheetjs.com. It will parse the workbook and return an HTML table.

If the live demo shows a message

ReferenceError: superagent is not defined

please refresh the page. This is a known bug in the documentation generator.

Result
Loading...
Live Editor

NodeJS Demos

These examples show how to upload data in NodeJS.

fetch

The fetch implementation mirrors the browser fetch.

Tested Deployments

This demo was last tested on 2023 November 19 against NodeJS 20.9.0

Complete Example (click to show)

This demo uses fetch to upload data to https://s2c.sheetjs.com. It will parse the workbook and return data in CSV rows.

1) Install the SheetJS NodeJS module:

npm i --save https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz

2) Save the following to SheetJSFetch.js:

SheetJSFetch.js
const XLSX = require("xlsx");

/* create sample SheetJS workbook object */
var aoa = [
["S", "h", "e", "e", "t", "J", "S"],
[ 5, 4, 3, 3, 7, 9, 5]
];
const ws = XLSX.utils.aoa_to_sheet(aoa);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

/* export SheetJS workbook object to XLSX file bytes */
var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'});

/* build FormData with the generated file */
var fdata = new FormData();
fdata.append('file', new File([data], 'sheetjs.xlsx'));
// field name ^^^^ file name ^^^^^^^^^^^^
fdata.append('type', 'csv');

(async() => {
/* send data using fetch */
const res = await fetch("https://s2c.sheetjs.com", { method: "POST", body: fdata });
const txt = await res.text();
console.log(txt);
})();

3) Run the script:

node SheetJSFetch.js

It will print CSV contents of the test file.

Troubleshooting

Some SheetJS users have reported corrupted files. To diagnose the error, it is strongly recommended to write local files.

For example, using fetch in the browser, the bytes can be downloaded using the HTML5 Download Attribute. The highlighted lines should be added immediately after write:

Diagnosing issues in a fetch upload
/* Generate XLSX file */
const data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'});

/* Write to Local File */
const blob = new Blob([data]);
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.download = "SheetJS.xlsx";
a.href = url;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);

/* Make FormData */
const fdata = new FormData();
fdata.append('file', new File([data], 'sheetjs.xlsx'));

/* Upload */
const url = "https://s2c.sheetjs.com";
const res = await fetch(url, {method:"POST", body: fdata});

If the generated file is valid, then the issue is in the server infrastructure.