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.
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 = await 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 witheditable:true
optionWhen 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.
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.
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.
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.
jQuery
jQuery.ajax
($.ajax
) does not support binary data out of the box. A custom
ajaxTransport
can add required functionality. SheetJS users have reported
success with jquery.binarytransport.js
.
After including the main jquery.js
and jquery.binarytransport.js
scripts,
$.ajax
will support dataType: "binary"
and processData: false
.
Download Files
In a GET request, the default behavior is to return a Blob
object. Passing
responseType: "arraybuffer"
returns a proper ArrayBuffer
object in IE10:
$.ajax({
type: "GET", url: "https://sheetjs.com/pres.numbers",
/* suppress jQuery post-processing */
processData: false,
/* use the binary transport */
dataType: "binary",
/* pass an ArrayBuffer in the callback */
responseType: "arraybuffer",
success: function (ab) {
/* at this point, ab is an ArrayBuffer */
var wb = XLSX.read(ab);
/* do something with workbook here */
var ws = wb.Sheets[wb.SheetNames[0]];
var html = XLSX.utils.sheet_to_html(ws);
$("#out").html(html);
}
});
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.
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.
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.
superagent
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.
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.
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.
NodeJS Demos
These examples show how to download data in NodeJS.
HTTPS GET
The https
module provides a low-level get
method for HTTPS GET requests:
var https = require("https"), XLSX = require("xlsx");
https.get('https://sheetjs.com/pres.numbers', function(res) {
var bufs = [];
res.on('data', function(chunk) { bufs.push(chunk); });
res.on('end', function() {
var buf = Buffer.concat(bufs);
var wb = XLSX.read(buf);
/* print the first worksheet to console */
var ws = wb.Sheets[wb.SheetNames[0]];
console.log(XLSX.utils.sheet_to_csv(ws));
});
});
fetch
The fetch
implementation has the same return types as the browser version:
async function parse_from_url(url) {
const res = await fetch(url);
if(!res.ok) throw new Error("fetch failed");
const ab = await res.arrayBuffer();
const workbook = XLSX.read(ab);
return workbook;
}
Wrapper Libraries
The latest releases of NodeJS support fetch
natively. Before fetch
support
was added to the platform, third party modules wrapped the native APIs.
request
request
has been deprecated and should only be used in legacy deployments.
Setting the option encoding: null
passes raw buffers:
var XLSX = require('xlsx'), request = require('request');
var url = 'https://sheetjs.com/pres.numbers';
/* call `request` with the option `encoding: null` */
request(url, {encoding: null}, function(err, res, data) {
if(err || res.statusCode !== 200) return;
/* if the request was succesful, parse the data */
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));
});
axios
When the responseType
is "arraybuffer"
, axios
actually captures the data
in a NodeJS Buffer. XLSX.read
will transparently handle Buffers:
const XLSX = require("xlsx"), axios = require("axios");
async function workbook_dl_axios(url) {
const res = await axios(url, {responseType:'arraybuffer'});
/* at this point, res.data is a Buffer */
const workbook = XLSX.read(res.data);
return workbook;
}