Skip to main content

Data Export

The "Export Tutorial" is a gentle introduction to data processing and export.

Writing Workbooks

API

Generate spreadsheet bytes (file) from data

var data = XLSX.write(workbook, opts);

The write method attempts to package data from the workbook into a file in memory. By default, XLSX files are generated, but that can be controlled with the bookType property of the opts argument. Based on the type option, the data can be stored as a "binary string", JS string, Uint8Array or Buffer.

The second opts argument is required. "Writing Options" covers the supported properties and behaviors.

Generate and attempt to save file

XLSX.writeFile(workbook, filename, opts);

The writeFile method packages the data and attempts to save the new file. The export file format is determined by the extension of filename (SheetJS.xlsx signals XLSX export, SheetJS.xlsb signals XLSB export, etc).

The second opts argument is optional. "Writing Options" covers the supported properties and behaviors.

Generate and attempt to save an XLSX file

XLSX.writeFileXLSX(workbook, filename, opts);

The writeFile method embeds a number of different export functions. This is great for developer experience but not amenable to tree shaking using the current developer tools. When only XLSX exports are needed, this method avoids referencing the other export functions.

The second opts argument is optional. "Writing Options" covers the supported properties and behaviors.

The writeFile and writeFileXLSX methods uses platform-specific APIs to save files. The APIs do not generally provide feedback on whether files were created.

Examples

Here are a few common scenarios (click on each subtitle to see the code).

The demos cover special deployments in more detail.

Example: Local File

XLSX.writeFile supports writing local files in platforms like NodeJS. In other platforms like React Native, XLSX.write should be called with file data.

XLSX.writeFile wraps a few techniques for triggering a file save:

  • URL browser API creates an object URL for the file, which the library uses by creating a link and forcing a click. It is supported in modern browsers.
  • msSaveBlob is an IE10+ API for triggering a file save.
  • IE_FileSave uses VBScript and ActiveX to write a file in IE6+ for Windows XP and Windows 7. The shim must be included in the containing HTML page.

There is no standard way to determine if the actual file has been downloaded.

/* output format determined by filename */
XLSX.writeFile(workbook, "out.xlsb");
/* at this point, out.xlsb will have been downloaded */
Web Workers

None of the file writing APIs work from Web Workers. To generate a file:

  1. use XLSX.write with type array to generate a Uint8Array:
// in the web worker, generate the XLSX file as a Uint8Array
const u8 = XLSX.write(workbook, { type: "array", bookType: "xlsx" });
  1. send the data back to the main thread:
// in the web worker, send the generated data back to the main thread
postMessage({t: "export", v: u8 });
  1. from the main thread, add an event listener to write to file:
// in the main page
worker.addEventListener('message', function(e) {
if(e && e.data && e.data.t == "export") {
e.stopPropagation();
e.preventDefault();
// data will be the Uint8Array from the worker
const data = e.data.v;

var blob = new Blob([data], {type:"application/octet-stream"});
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.download = "SheetJSXPort.xlsx";
a.href = url;
document.body.appendChild(a);
a.click();
}
});
SWF workaround for Windows 95+ (click to show)

Each moving part in this solution has been deprecated years ago:

  • Adobe stopped supporting Flash Player at the end of 2020
  • Microsoft stopped supporting IE8 in 2019 and stopped supporting IE9 in 2020
  • Downloadify support ended in 2010 and SWFObject support ended in 2016

New projects should strongly consider requiring modern browsers. This info is provided on an "as is" basis and there is no realistic way to provide support given that every related vendor stopped providing support for their software.

XLSX.writeFile techniques work for most modern browsers as well as older IE. For much older browsers, there are workarounds implemented by wrapper libraries.

Downloadify uses a Flash SWF button to generate local files, suitable for environments where ActiveX is unavailable:

Downloadify.create(id,{
/* other options are required! read the downloadify docs for more info */
filename: "test.xlsx",
data: function() { return XLSX.write(wb, {bookType:"xlsx", type:"base64"}); },
append: false,
dataType: "base64"
});

The oldie demo shows an IE-compatible fallback scenario.

Example: Server Responses

This example focuses on responses to network requests in a server-side platform like NodeJS. While files can be generated in the web browser, server-side file generation allows for exact audit trails and has better mobile user support.

Production deployments should use a server framework like ExpressJS. These snippets use low-level APIs for illustration purposes.

The Content-Type header should be set to application/vnd.ms-excel for Excel exports including XLSX. The default application/octet-stream can be used, but iOS will not automatically suggest to open files in Numbers or Excel for iOS

The Content-Disposition header instructs browsers to download the response into a file. The header can also include the desired file name.

NodeJS http.ServerResponse#end can accept Buffer objects. XLSX.write with buffer type returns Buffer objects.

/* generate Buffer */
const buf = XLSX.write(wb, { type:"buffer", bookType:"xlsx" });

/* prepare response headers */
res.statusCode = 200;
res.setHeader('Content-Disposition', 'attachment; filename="SheetJSNode.xlsx"');
res.setHeader('Content-Type', 'application/vnd.ms-excel');
res.end(buf);
Complete Example (click to show)

Install the library with

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

Save the following script to node.js and run with node node.js:

node.js
const http = require('http');
const XLSX = require('xlsx');

const hostname = '127.0.0.1';
const port = 7262;

/* fixed sample worksheet */
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet([
["a","b","c"], [1,2,3]
]), "Sheet1");

const server = http.createServer((req, res) => {
const buf = XLSX.write(wb, { type:"buffer", bookType:"xlsx" });
res.statusCode = 200;
res.setHeader('Content-Disposition', 'attachment; filename="SheetJSNode.xlsx"');
res.setHeader('Content-Type', 'application/vnd.ms-excel');
res.end(buf);
});

server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});

Example: Remote File

This example focuses on uploading files ("Ajax" in browser parlance) using APIs like XMLHttpRequest and fetch as well as third-party libraries.

Some platforms like Azure and AWS will attempt to parse POST request bodies as UTF-8 strings before user code can see the data. This will result in corrupt data parsed by the server. There are some workarounds, but the safest approach is to adjust the server process or Lambda function to accept Base64 strings.

The HTTP Uploads demo includes examples using browser APIs and wrapper libraries.

Under normal circumstances, a Blob can be generated from the array output:

/* in this example, send a Blob to the server */
var wbout = XLSX.write(workbook, { bookType: "xlsx", type: "array" });

/* prepare data for POST */
var blob = new Blob([new Uint8Array(wbout)], {type:"application/octet-stream"});
var formdata = new FormData();
formdata.append("file", blob, "test.xlsx");

/* perform POST request */
fetch("/upload", { method: 'POST', body: formdata });

When binary data is not supported, Base64 strings should be passed along. This will require the server to expect and decode the data:

/* in this example, send a Base64 string to the server */
var wbout = XLSX.write(workbook, { bookType: "xlsx", type: "base64" });

/* prepare data for POST */
var formdata = new FormData();
formdata.append("file", "test.xlsx"); // <-- server expects `file` to hold name
formdata.append("data", wbout); // <-- `data` holds the data encoded in Base64

/* perform POST request */
var req = new XMLHttpRequest();
req.open("POST", "/upload", true);
req.send(formdata);

Generating JSON and JS Data

JSON and JS data tend to represent single worksheets. The utility functions in this section work with single worksheets.

The "Common Spreadsheet Format" section describes the object structure in more detail. workbook.SheetNames is an ordered list of the worksheet names. workbook.Sheets is an object whose keys are sheet names and whose values are worksheet objects.

The "first worksheet" is stored at workbook.Sheets[workbook.SheetNames[0]].

API

Create an array of JS objects from a worksheet

var jsa = XLSX.utils.sheet_to_json(worksheet, opts);

Create an array of arrays of JS values from a worksheet

var aoa = XLSX.utils.sheet_to_json(worksheet, {...opts, header: 1});

The sheet_to_json utility function walks a workbook in row-major order, generating an array of objects. The second opts argument controls a number of export decisions including the type of values (JS values or formatted text). The "Array Output" section describes supported options.

By default, sheet_to_json scans the first row and uses the values as headers. With the header: 1 option, the function exports an array of arrays of values.

Examples

Example: Data Grids

x-spreadsheet is an interactive data grid for previewing and modifying structured data in the web browser.

Example: Data Loading

"TensorFlow.js" covers strategies for generating typed arrays and tensors from worksheet data.

Populating a database (SQL or no-SQL) (click to show)

The data demo includes examples of working with databases and query results.

Generating HTML Tables

API

Generate HTML Table from Worksheet

var html = XLSX.utils.sheet_to_html(worksheet);

The sheet_to_html utility function generates HTML code based on the worksheet data. Each cell in the worksheet is mapped to a <TD> element. Merged cells in the worksheet are serialized by setting colspan and rowspan attributes.

Examples

The sheet_to_html utility function generates HTML code that can be added to any DOM element by setting the innerHTML:

var container = document.getElementById("tavolo");
container.innerHTML = XLSX.utils.sheet_to_html(worksheet);

Combining with fetch, constructing a site from a workbook is straightforward:

This example assigns the innerHTML of a DIV element:

<body>
<style>TABLE { border-collapse: collapse; } TD { border: 1px solid; }</style>
<div id="tavolo"></div>
<script src="https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js"></script>
<script type="text/javascript">
(async() => {
/* fetch and parse workbook -- see the fetch example for details */
const workbook = XLSX.read(await (await fetch("sheetjs.xlsx")).arrayBuffer());

let output = [];
/* loop through the worksheet names in order */
workbook.SheetNames.forEach(name => {

/* generate HTML from the corresponding worksheets */
const worksheet = workbook.Sheets[name];
const html = XLSX.utils.sheet_to_html(worksheet);

/* add a header with the title name followed by the table */
output.push(`<H3>${name}</H3>${html}`);
});
/* write to the DOM at the end */
tavolo.innerHTML = output.join("\n");
})();
</script>
</body>

Generating Single-Worksheet Snapshots

The sheet_to_* functions accept a worksheet object.

API

Generate a CSV from a single worksheet

var csv = XLSX.utils.sheet_to_csv(worksheet, opts);

This snapshot is designed to replicate the "CSV UTF-8 (.csv)" output type. "CSV and Text" describes the function and the optional opts argument in more detail.

Generate "Text" from a single worksheet

var txt = XLSX.utils.sheet_to_txt(worksheet, opts);

This snapshot is designed to replicate the "UTF-16 Text (.txt)" output type. "CSV and Text" describes the function and the optional opts argument in more detail.

Generate a list of formulae from a single worksheet

var fmla = XLSX.utils.sheet_to_formulae(worksheet);

This snapshot generates an array of entries representing the embedded formulae. Array formulae are rendered in the form range=formula while plain cells are rendered in the form cell=formula or value. String literals are prefixed with an apostrophe ', consistent with Excel's formula bar display.

"Formulae Output" describes the function in more detail.

Streaming Write

The streaming write functions are available in the XLSX.stream object. They take the same arguments as the normal write functions but return a NodeJS Readable Stream.

  • XLSX.stream.to_csv is the streaming version of XLSX.utils.sheet_to_csv.
  • XLSX.stream.to_html is the streaming version of XLSX.utils.sheet_to_html.
  • XLSX.stream.to_json is the streaming version of XLSX.utils.sheet_to_json.

Examples are included in "Large Datasets"