sheetjs/README.md

2403 lines
90 KiB
Markdown
Raw Normal View History

# [SheetJS js-xlsx](http://sheetjs.com)
2012-12-04 19:27:20 +00:00
Parser and writer for various spreadsheet formats. Pure-JS cleanroom
implementation from official specifications, related documents, and test files.
Emphasis on parsing and writing robustness, cross-format feature compatibility
with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.
2017-04-20 03:24:48 +00:00
This is the community version. We also offer a pro version with performance
enhancements, additional features by request, and dedicated support.
2017-04-20 03:24:48 +00:00
[**Pro Version**](http://sheetjs.com/pro)
2017-04-20 03:24:48 +00:00
[**Commercial Support**](http://sheetjs.com/support)
2017-03-10 17:33:08 +00:00
[**Rendered Documentation**](http://docs.sheetjs.com/)
2017-04-20 03:24:48 +00:00
[**In-Browser Demos**](http://sheetjs.com/demos)
[**Source Code**](http://git.io/xlsx)
[**Issues and Bug Reports**](https://github.com/sheetjs/js-xlsx/issues)
[**Other General Support Issues**](https://discourse.sheetjs.com)
[**File format support for known spreadsheet data formats:**](#file-formats)
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Graph of supported formats</b> (click to show)</summary>
![circo graph of format support](formats.png)
![graph legend](legend.png)
2012-12-04 19:27:20 +00:00
</details>
[**Browser Test**](http://oss.sheetjs.com/js-xlsx/tests/)
[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
2017-09-24 23:40:09 +00:00
[![npm Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
## Table of Contents
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Expand to show Table of Contents</b></summary>
<!-- toc -->
- [Installation](#installation)
* [JS Ecosystem Demos](#js-ecosystem-demos)
* [Optional Modules](#optional-modules)
* [ECMAScript 5 Compatibility](#ecmascript-5-compatibility)
- [Philosophy](#philosophy)
- [Parsing Workbooks](#parsing-workbooks)
* [Parsing Examples](#parsing-examples)
* [Streaming Read](#streaming-read)
- [Working with the Workbook](#working-with-the-workbook)
* [Parsing and Writing Examples](#parsing-and-writing-examples)
- [Writing Workbooks](#writing-workbooks)
* [Writing Examples](#writing-examples)
* [Streaming Write](#streaming-write)
- [Interface](#interface)
* [Parsing functions](#parsing-functions)
* [Writing functions](#writing-functions)
* [Utilities](#utilities)
- [Common Spreadsheet Format](#common-spreadsheet-format)
* [General Structures](#general-structures)
* [Cell Object](#cell-object)
+ [Data Types](#data-types)
+ [Dates](#dates)
2017-03-31 21:46:02 +00:00
* [Sheet Objects](#sheet-objects)
+ [Worksheet Object](#worksheet-object)
+ [Chartsheet Object](#chartsheet-object)
* [Workbook Object](#workbook-object)
+ [Workbook File Properties](#workbook-file-properties)
* [Workbook-Level Attributes](#workbook-level-attributes)
+ [Defined Names](#defined-names)
+ [Miscellaneous Workbook Properties](#miscellaneous-workbook-properties)
* [Document Features](#document-features)
+ [Formulae](#formulae)
+ [Column Properties](#column-properties)
+ [Row Properties](#row-properties)
+ [Number Formats](#number-formats)
+ [Hyperlinks](#hyperlinks)
+ [Cell Comments](#cell-comments)
+ [Sheet Visibility](#sheet-visibility)
- [Parsing Options](#parsing-options)
* [Input Type](#input-type)
* [Guessing File Type](#guessing-file-type)
- [Writing Options](#writing-options)
* [Supported Output Formats](#supported-output-formats)
* [Output Type](#output-type)
- [Utility Functions](#utility-functions)
* [Array of Arrays Input](#array-of-arrays-input)
* [Array of Objects Input](#array-of-objects-input)
* [HTML Table Input](#html-table-input)
* [Formulae Output](#formulae-output)
* [Delimiter-Separated Output](#delimiter-separated-output)
+ [UTF-16 Unicode Text](#utf-16-unicode-text)
* [HTML Output](#html-output)
* [JSON](#json)
- [File Formats](#file-formats)
* [Excel 2007+ XML (XLSX/XLSM)](#excel-2007-xml-xlsxxlsm)
* [Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)](#excel-20-95-biff2biff3biff4biff5)
* [Excel 97-2004 Binary (BIFF8)](#excel-97-2004-binary-biff8)
* [Excel 2003-2004 (SpreadsheetML)](#excel-2003-2004-spreadsheetml)
* [Excel 2007+ Binary (XLSB, BIFF12)](#excel-2007-binary-xlsb-biff12)
* [Delimiter-Separated Values (CSV/TXT)](#delimiter-separated-values-csvtxt)
2017-04-04 16:09:41 +00:00
* [Other Workbook Formats](#other-workbook-formats)
+ [Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123)](#lotus-1-2-3-wkswk1wk2wk3wk4123)
+ [Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW)](#quattro-pro-wq1wq2wb1wb2wb3qpw)
+ [OpenDocument Spreadsheet (ODS/FODS)](#opendocument-spreadsheet-odsfods)
+ [Uniform Office Spreadsheet (UOS1/2)](#uniform-office-spreadsheet-uos12)
* [Other Single-Worksheet Formats](#other-single-worksheet-formats)
+ [dBASE and Visual FoxPro (DBF)](#dbase-and-visual-foxpro-dbf)
+ [Symbolic Link (SYLK)](#symbolic-link-sylk)
+ [Lotus Formatted Text (PRN)](#lotus-formatted-text-prn)
+ [Data Interchange Format (DIF)](#data-interchange-format-dif)
+ [HTML](#html)
- [Testing](#testing)
2017-04-13 17:05:42 +00:00
* [Node](#node)
* [Browser](#browser)
* [Tested Environments](#tested-environments)
* [Test Files](#test-files)
- [Contributing](#contributing)
* [OSX/Linux](#osxlinux)
* [Windows](#windows)
* [Tests](#tests)
- [License](#license)
- [References](#references)
<!-- tocstop -->
</details>
2012-12-04 19:27:20 +00:00
## Installation
In the browser, just add a script tag:
2012-12-04 19:27:20 +00:00
```html
<script lang="javascript" src="dist/xlsx.full.min.js"></script>
```
2012-12-04 19:27:20 +00:00
2017-09-24 23:40:09 +00:00
<details>
<summary><b>CDN Availability</b> (click to show)</summary>
| CDN | URL |
|-----------:|:-----------------------------------------|
| `unpkg` | <https://unpkg.com/xlsx/> |
| `jsDelivr` | <https://jsdelivr.com/package/npm/xlsx> |
| `CDNjs` | <http://cdnjs.com/libraries/xlsx> |
`unpkg` makes the latest version available at:
```html
<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
```
</details>
With [npm](https://www.npmjs.org/package/xlsx):
2012-12-04 19:27:20 +00:00
```bash
$ npm install xlsx
```
With [bower](http://bower.io/search/?q=js-xlsx):
```bash
$ bower install js-xlsx
```
2017-03-10 17:33:08 +00:00
### JS Ecosystem Demos
2017-09-24 23:40:09 +00:00
The [`demos` directory](demos/) includes sample projects for:
2017-03-10 17:33:08 +00:00
**Frameworks and APIs**
2017-06-21 23:10:36 +00:00
- [`angular 1.x`](demos/angular/)
- [`angular 2.x / 4.x`](demos/angular2/)
2017-05-24 22:52:35 +00:00
- [`meteor`](demos/meteor/)
- [`react and react-native`](demos/react/)
- [`vue 2.x and weex`](demos/vue/)
- [`XMLHttpRequest and fetch`](demos/xhr/)
- [`nodejs server`](demos/server/)
**Bundlers and Tooling**
- [`browserify`](demos/browserify/)
- [`requirejs`](demos/requirejs/)
2017-06-08 06:19:11 +00:00
- [`rollup`](demos/rollup/)
- [`systemjs`](demos/systemjs/)
- [`webpack 2.x`](demos/webpack/)
2017-03-10 17:33:08 +00:00
**Platforms and Integrations**
- [`electron application`](demos/electron/)
- [`nw.js application`](demos/nwjs/)
- [`Adobe ExtendScript`](demos/extendscript/)
- [`Headless Browsers`](demos/headless/)
- [`canvas-datagrid`](demos/datagrid/)
- [`Swift JSC and other engines`](demos/altjs/)
### Optional Modules
2017-05-24 22:52:35 +00:00
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Optional features</b> (click to show)</summary>
2017-05-24 22:52:35 +00:00
The node version automatically requires modules for additional features. Some
of these modules are rather large in size and are only needed in special
circumstances, so they do not ship with the core. For browser use, they must
be included directly:
```html
<!-- international support from js-codepage -->
<script src="dist/cpexcel.js"></script>
```
An appropriate version for each dependency is included in the dist/ directory.
The complete single-file version is generated at `dist/xlsx.full.min.js`
2017-09-24 23:40:09 +00:00
Webpack and Browserify builds include optional modules by default. Webpack can
be configured to remove support with `resolve.alias`:
```js
/* uncomment the lines below to remove support */
resolve: {
alias: { "./dist/cpexcel.js": "" } // <-- omit international support
}
```
2017-05-24 22:52:35 +00:00
</details>
### ECMAScript 5 Compatibility
2014-06-03 18:39:46 +00:00
2017-09-24 23:40:09 +00:00
Since the library uses functions like `Array#forEach`, older browsers require
[shims to provide missing functions](http://oss.sheetjs.com/js-xlsx/shim.js).
2014-06-03 18:39:46 +00:00
2017-09-24 23:40:09 +00:00
To use the shim, add the shim before the script tag that loads `xlsx.js`:
2014-06-03 18:39:46 +00:00
```html
2017-09-24 23:40:09 +00:00
<!-- add the shim first -->
<script type="text/javascript" src="shim.js"></script>
<!-- after the shim is referenced, add the library -->
<script type="text/javascript" src="xlsx.full.min.js"></script>
```
2014-06-03 18:39:46 +00:00
## Philosophy
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Philosophy</b> (click to show)</summary>
Prior to SheetJS, APIs for processing spreadsheet files were format-specific.
Third-party libraries either supported one format, or they involved a separate
set of classes for each supported file type. Even though XLSB was introduced in
Excel 2007, nothing outside of SheetJS or Excel supported the format.
To promote a format-agnostic view, js-xlsx starts from a pure-JS representation
that we call the ["Common Spreadsheet Format"](#common-spreadsheet-format).
Emphasizing a uniform object representation enables new features like format
2017-09-24 23:40:09 +00:00
conversion (reading an XLSX template and saving as XLS) and circumvents the
"class trap". By abstracting the complexities of the various formats, tools
need not worry about the specific file type!
A simple object representation combined with careful coding practices enables
use cases in older browsers and in alternative environments like ExtendScript
and Web Workers. It is always tempting to use the latest and greatest features,
but they tend to require the latest versions of browsers, limiting usability.
Utility functions capture common use cases like generating JS objects or HTML.
Most simple operations should only require a few lines of code. More complex
operations generally should be straightforward to implement.
Excel pushes the XLSX format as default starting in Excel 2007. However, there
are other formats with more appealing properties. For example, the XLSB format
is spiritually similar to XLSX but files often tend up taking less than half the
space and open much faster! Even though an XLSX writer is available, other
format writers are available so users can take advantage of the unique
characteristics of each format.
</details>
2014-05-28 18:31:33 +00:00
## Parsing Workbooks
2012-12-04 19:27:20 +00:00
For parsing, the first step is to read the file. This involves acquiring the
data and feeding it into the library. Here are a few common scenarios:
2012-12-04 19:27:20 +00:00
<details>
2017-09-24 23:40:09 +00:00
<summary><b>nodejs read a file</b> (click to show)</summary>
2012-12-04 19:27:20 +00:00
`readFile` is only available in server environments. Browsers have no API for
reading arbitrary files given a path, so another strategy must be used.
```js
2014-05-28 18:31:33 +00:00
if(typeof require !== 'undefined') XLSX = require('xlsx');
var workbook = XLSX.readFile('test.xlsx');
/* DO SOMETHING WITH workbook HERE */
```
</details>
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Browser read TABLE element from page</b> (click to show)</summary>
The `table_to_book` and `table_to_sheet` utility functions take a DOM TABLE
element and iterate through the child nodes.
```js
var worksheet = XLSX.utils.table_to_book(document.getElementById('tableau'));
/* DO SOMETHING WITH workbook HERE */
```
Alternatively, the HTML code can be extracted and parsed:
```js
var htmlstr = document.getElementById('tableau').outerHTML;
var worksheet = XLSX.read(htmlstr, {type:'string'});
```
</details>
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Browser download file (ajax)</b> (click to show)</summary>
Note: for a more complete example that works in older browsers, check the demo
2017-09-24 23:40:09 +00:00
at <http://oss.sheetjs.com/js-xlsx/ajax.html>). The <demos/xhr/> directory also
includes more examples with `XMLHttpRequest` and `fetch`.
2014-05-28 18:31:33 +00:00
```js
2017-09-24 23:40:09 +00:00
var url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx";
2014-05-28 18:31:33 +00:00
2017-09-24 23:40:09 +00:00
/* set up async GET request */
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.responseType = "arraybuffer";
2014-05-28 18:31:33 +00:00
2017-09-24 23:40:09 +00:00
req.onload = function(e) {
var data = new Uint8Array(req.response);
var workbook = XLSX.read(data, {type:"array"});
2014-05-28 18:31:33 +00:00
/* DO SOMETHING WITH workbook HERE */
}
2017-09-24 23:40:09 +00:00
req.send();
2014-05-28 18:31:33 +00:00
```
</details>
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Browser drag-and-drop</b> (click to show)</summary>
2017-09-24 23:40:09 +00:00
Drag-and-drop uses the HTML5 `FileReader` API, loading the data with
`readAsBinaryString` or `readAsArrayBuffer`. Since not all browsers support the
full `FileReader` API, dynamic feature tests are highly recommended.
2014-05-28 18:31:33 +00:00
```js
var rABS = true; // true: readAsBinaryString ; false: readAsArrayBuffer
2014-05-28 18:31:33 +00:00
function handleDrop(e) {
2017-09-24 23:40:09 +00:00
e.stopPropagation(); e.preventDefault();
var files = e.dataTransfer.files, f = files[0];
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
if(!rABS) data = new Uint8Array(data);
var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'});
/* DO SOMETHING WITH workbook HERE */
};
if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f);
2014-05-28 18:31:33 +00:00
}
drop_dom_element.addEventListener('drop', handleDrop, false);
```
</details>
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Browser file upload form element</b> (click to show)</summary>
Data from file input elements can be processed using the same `FileReader` API
as in the drag-and-drop example:
```js
2017-09-24 23:40:09 +00:00
var rABS = true; // true: readAsBinaryString ; false: readAsArrayBuffer
function handleFile(e) {
2017-09-24 23:40:09 +00:00
var files = e.target.files, f = files[0];
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
if(!rABS) data = new Uint8Array(data);
var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'});
/* DO SOMETHING WITH workbook HERE */
};
if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f);
}
input_dom_element.addEventListener('change', handleFile, false);
```
</details>
### Parsing Examples
- <http://oss.sheetjs.com/js-xlsx/> HTML5 File API / Base64 Text / Web Workers
2017-09-24 23:40:09 +00:00
Note that older versions of IE do not support HTML5 File API, so the Base64 mode
2017-06-03 07:19:09 +00:00
is used for testing.
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Get Base64 encoding on OSX / Windows</b> (click to show)</summary>
2017-06-03 07:19:09 +00:00
2017-09-24 23:40:09 +00:00
On OSX you can get the Base64 encoding with:
```bash
$ <target_file base64 | pbcopy
```
2017-09-24 23:40:09 +00:00
On Windows XP and up you can get the Base64 encoding using `certutil`:
```cmd
> certutil -encode target_file target_file.b64
```
(note: You have to open the file and remove the header and footer lines)
2017-06-03 07:19:09 +00:00
</details>
- <http://oss.sheetjs.com/js-xlsx/ajax.html> XMLHttpRequest
### Streaming Read
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Why is there no Streaming Read API?</b> (click to show)</summary>
The most common and interesting formats (XLS, XLSX/M, XLSB, ODS) are ultimately
ZIP or CFB containers of files. Neither format puts the directory structure at
the beginning of the file: ZIP files place the Central Directory records at the
end of the logical file, while CFB files can place the storage info anywhere in
the file! As a result, to properly handle these formats, a streaming function
would have to buffer the entire file before commencing. That belies the
expectations of streaming, so we do not provide any streaming read API.
</details>
When dealing with Readable Streams, the easiest approach is to buffer the stream
and process the whole thing at the end. This can be done with a temporary file
or by explicitly concatenating the stream:
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Explicitly concatenating streams</b> (click to show)</summary>
```js
var fs = require('fs');
var XLSX = require('xlsx');
function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{
2017-09-24 23:40:09 +00:00
var buffers = [];
stream.on('data', function(data) { buffers.push(data); });
stream.on('end', function() {
var buffer = Buffer.concat(buffers);
var workbook = XLSX.read(buffer, {type:"buffer"});
/* DO SOMETHING WITH workbook IN THE CALLBACK */
cb(workbook);
});
}
```
More robust solutions are available using modules like `concat-stream`.
</details>
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Writing to filesystem first</b> (click to show)</summary>
2017-09-24 23:40:09 +00:00
This example uses [`tempfile`](https://npm.im/tempfile) to generate file names:
```js
var fs = require('fs'), tempfile = require('tempfile');
var XLSX = require('xlsx');
function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{
2017-09-24 23:40:09 +00:00
var fname = tempfile('.sheetjs');
console.log(fname);
var ostream = fs.createWriteStream(fname);
stream.pipe(ostream);
ostream.on('finish', function() {
var workbook = XLSX.readFile(fname);
fs.unlinkSync(fname);
/* DO SOMETHING WITH workbook IN THE CALLBACK */
cb(workbook);
});
}
```
</details>
## Working with the Workbook
The full object format is described later in this README.
2017-05-24 22:52:35 +00:00
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Reading a specific cell </b> (click to show)</summary>
2017-05-24 22:52:35 +00:00
This example extracts the value stored in cell A1 from the first worksheet:
```js
var first_sheet_name = workbook.SheetNames[0];
var address_of_cell = 'A1';
/* Get worksheet */
var worksheet = workbook.Sheets[first_sheet_name];
/* Find desired cell */
var desired_cell = worksheet[address_of_cell];
/* Get the value */
var desired_value = (desired_cell ? desired_cell.v : undefined);
```
2017-05-24 22:52:35 +00:00
</details>
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Adding a new worksheet to a workbook</b> (click to show)</summary>
2017-05-24 22:52:35 +00:00
This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input) to make a
worksheet and appends the new worksheet to the workbook:
```js
var new_ws_name = "SheetJS";
/* make worksheet */
var ws_data = [
2017-09-24 23:40:09 +00:00
[ "S", "h", "e", "e", "t", "J", "S" ],
[ 1 , 2 , 3 , 4 , 5 ]
2017-05-24 22:52:35 +00:00
];
var ws = XLSX.utils.aoa_to_sheet(ws_data);
/* Add the sheet name to the list */
wb.SheetNames.push(ws_name);
/* Load the worksheet object */
wb.Sheets[ws_name] = ws;
```
</details>
### Parsing and Writing Examples
- <http://sheetjs.com/demos/modify.html> read + modify + write files
2014-05-28 18:31:33 +00:00
- <https://github.com/SheetJS/js-xlsx/blob/master/bin/xlsx.njs> node
2014-05-28 18:31:33 +00:00
The node version installs a command line tool `xlsx` which can read spreadsheet
2014-05-28 18:31:33 +00:00
files and output the contents in various formats. The source is available at
`xlsx.njs` in the bin directory.
2014-01-27 09:38:50 +00:00
Some helper functions in `XLSX.utils` generate different views of the sheets:
- `XLSX.utils.sheet_to_csv` generates CSV
- `XLSX.utils.sheet_to_html` generates HTML
2014-05-28 18:31:33 +00:00
- `XLSX.utils.sheet_to_json` generates an array of objects
- `XLSX.utils.sheet_to_formulae` generates a list of formulae
2014-01-27 09:38:50 +00:00
2014-05-28 18:31:33 +00:00
## Writing Workbooks
For writing, the first step is to generate output data. The helper functions
`write` and `writeFile` will produce the data in various formats suitable for
dissemination. The second step is to actual share the data with the end point.
Assuming `workbook` is a workbook object:
2014-05-28 18:31:33 +00:00
<details>
2017-09-24 23:40:09 +00:00
<summary><b>nodejs write a file</b> (click to show)</summary>
2014-05-28 18:31:33 +00:00
`writeFile` is only available in server environments. Browsers have no API for
writing arbitrary files given a path, so another strategy must be used.
```js
if(typeof require !== 'undefined') XLSX = require('xlsx');
2014-05-28 18:31:33 +00:00
/* output format determined by filename */
XLSX.writeFile(workbook, 'out.xlsb');
/* at this point, out.xlsb is a file that you can distribute */
2014-05-28 18:31:33 +00:00
```
</details>
<details>
<summary><b>Browser add to web page</b> (click to show)</summary>
The `sheet_to_html` utility function generates HTML code that can be added to
any DOM element.
```js
var worksheet = workbook.Sheets[workbook.SheetNames[0]];
var container = document.getElementById('tableau');
container.innerHTML = XLSX.utils.sheet_to_html(worksheet);
```
</details>
<details>
<summary><b>Browser save file</b> (click to show)</summary>
Note: browser generates binary blob and forces a "download" to client. This
2017-09-24 23:40:09 +00:00
example uses [FileSaver](https://github.com/eligrey/FileSaver.js/):
2014-05-28 18:31:33 +00:00
```js
/* bookType can be any supported output type */
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
2014-05-28 18:31:33 +00:00
var wbout = XLSX.write(workbook,wopts);
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
/* the saveAs call downloads a file on the local machine */
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
2014-05-28 18:31:33 +00:00
```
</details>
2014-05-28 18:31:33 +00:00
<details>
2017-09-24 23:40:09 +00:00
<summary><b>Browser upload to server</b> (click to show)</summary>
2017-09-24 23:40:09 +00:00
A complete example using XHR is [included in the XHR demo](demos/xhr/), along
with examples for fetch and wrapper libraries. This example assumes the server
can handle Base64-encoded files (see the demo for a basic nodejs server):
```js
/* in this example, send a base64 string to the server */
var wopts = { bookType:'xlsx', bookSST:false, type:'base64' };
var wbout = XLSX.write(workbook,wopts);
2017-09-24 23:40:09 +00:00