Skip to main content

HTTP Network Requests

XMLHttpRequest and fetch browser APIs enable binary data transfer between web browser clients and web servers. Since this library works in web browsers, server conversion work can be offloaded to the client! This demo shows a few common scenarios involving browser APIs and popular wrapper libraries.

Third-Party Hosts and Binary Data

Some services like AWS will corrupt raw binary uploads / downloads by encoding requests and responses in UTF-8. Typically, these services have options for disabling this behavior.

For AWS, in the "Binary Media Types" section of the API Gateway console, the following types should be added to ensure smooth uploads and downloads:

  • "multipart/form-data" (for Lambda functions to receive files from clients)
  • "application/vnd.ms-excel" (for Lambda functions to send files to clients)

Downloading Binary Data

Most interesting spreadsheet files are binary data that contain byte sequences that represent invalid UTF-8 characters.

The APIs generally have a way to control the interpretation of the downloaded data. The arraybuffer response type usually forces the data to be presented as a pure ArrayBuffer which can be parsed directly with XLSX.read.

For example, with fetch:

const res = await fetch("https://sheetjs.com/pres.numbers");
const ab = res.arrayBuffer(); // recover data as ArrayBuffer

const wb = XLSX.read(ab);

Uploading Binary Data

FormData objects can hold File blobs generated from XLSX.write:

/* generate XLSX file bytes */
var data = XLSX.write(workbook, {bookType: 'xlsx', type: 'array'});

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

The FormData object can be passed along to the POST request. For example:

var req = new XMLHttpRequest();
req.open("POST", "/upload", true);
req.send(fdata);

Browser Demos

The included demos focus on an editable table. There are two separate flows:

  • When the page is accessed, the browser will attempt to download https://sheetjs.com/pres.numbers and read the workbook. The old table will be replaced with an editable table whose contents match the first worksheet. The table is generated using the sheet_to_html utility with editable:true option

  • When the upload button is clicked, the browser will generate a new worksheet using table_to_book and build up a new workbook. It will then attempt to generate a file, upload it to https://s2c.sheetjs.com and show the response.

XMLHttpRequest

For downloading data, the arraybuffer response type generates an ArrayBuffer that can be viewed as an Uint8Array and fed to XLSX.read using array type:

/* set up an async GET request */
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.responseType = "arraybuffer";

req.onload = function(e) {
/* parse the data when it is received */
var data = new Uint8Array(req.response);
var workbook = XLSX.read(data, {type:"array"});
/* DO SOMETHING WITH workbook HERE */
};
req.send();
Live Download demo (click to show)

This demo uses XMLHttpRequest to download https://sheetjs.com/pres.numbers and show the data in an HTML table.

Result
Loading...
Live Editor

For uploading data, this demo populates a FormData object with an ArrayBuffer generated with the array output type:

/* generate XLSX as array buffer */
var data = XLSX.write(workbook, {bookType: 'xlsx', type: 'array'});

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

/* send data */
var req = new XMLHttpRequest();
req.open("POST", url, true);
req.send(fd);
Live Upload demo (click to show)

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

Result
Loading...
Live Editor

fetch

For downloading data, Response#arrayBuffer resolves to an ArrayBuffer that can be converted to Uint8Array and passed to XLSX.read:

fetch(url).then(function(res) {
/* get the data as a Blob */
if(!res.ok) throw new Error("fetch failed");
return res.arrayBuffer();
}).then(function(ab) {
/* parse the data when it is received */
var data = new Uint8Array(ab);
var workbook = XLSX.read(data, {type:"array"});

/* DO SOMETHING WITH workbook HERE */
});
Live Download demo (click to show)

This demo uses fetch to download https://sheetjs.com/pres.numbers and show the data in an HTML table.

Result
Loading...
Live Editor

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

// assuming `fdata` is a FormData object from "Uploading Binary Data" section
fetch("/upload", { method: "POST", body: fdata });
Live Upload 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

The axios library presents a Promise interface. Setting responseType to arraybuffer ensures the return type is an ArrayBuffer:

async function workbook_dl_axios(url) {
const res = await axios(url, {responseType:'arraybuffer'});
const workbook = XLSX.read(res.data);
return workbook;
}
Live Download demo (click to show)

This demo uses axios to download https://sheetjs.com/pres.numbers and show the data in an HTML table.

Result
Loading...
Live Editor

Uploading form data is nearly identical to the fetch example:

axios("/upload", { method: "POST", data: fdata });
Live Upload 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.

Result
Loading...
Live Editor

superagent Wrapper Library

The superagent library usage mirrors XHR:

/* set up an async GET request with superagent */
superagent.get(url).responseType('arraybuffer').end(function(err, res) {
/* parse the data when it is received */
var data = new Uint8Array(res.body);
var workbook = XLSX.read(data, {type:"array"});

/* DO SOMETHING WITH workbook HERE */
});
Live Download demo (click to show)

This demo uses superagent to download https://sheetjs.com/pres.numbers and show the data in an HTML table.

Result
Loading...
Live Editor

The upload portion only differs in the actual request command:

/* send data (fd is the FormData object) */
superagent.post("/upload").send(fd);
Live Upload 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.

Result
Loading...
Live Editor