sheetjs/README.md

2852 lines
107 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
2018-05-21 01:41:01 +00:00
enhancements, additional features like styling, 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)
[**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)
[![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)
+ [Macrosheet Object](#macrosheet-object)
+ [Dialogsheet Object](#dialogsheet-object)
* [Workbook Object](#workbook-object)
+ [Workbook File Properties](#workbook-file-properties)
* [Workbook-Level Attributes](#workbook-level-attributes)
+ [Defined Names](#defined-names)
+ [Workbook Views](#workbook-views)
+ [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)
+ [VBA and Macros](#vba-and-macros)
- [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)
+ [Rich Text Format (RTF)](#rich-text-format-rtf)
+ [Ethercalc Record Format (ETH)](#ethercalc-record-format-eth)
- [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> |
| `packd` | <https://bundle.run/xlsx@latest?name=XLSX> |
2017-09-24 23:40:09 +00:00
`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**
- [`angularjs`](demos/angular/)
2018-05-21 01:41:01 +00:00
- [`angular 2 / 4 / 5 / 6 and ionic`](demos/angular2/)
- [`knockout`](demos/knockout/)
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/)
2018-01-27 00:52:46 +00:00
- [`databases and key/value stores`](demos/database/)
- [`typed arrays and math`](demos/array/)
**Bundlers and Tooling**
- [`browserify`](demos/browserify/)
2018-01-27 00:52:46 +00:00
- [`fusebox`](demos/fusebox/)
- [`parcel`](demos/parcel/)
- [`requirejs`](demos/requirejs/)
2017-06-08 06:19:11 +00:00
- [`rollup`](demos/rollup/)
- [`systemjs`](demos/systemjs/)
- [`typescript`](demos/typescript/)
- [`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/)
- [`Chrome / Chromium extensions`](demos/chrome/)
- [`Adobe ExtendScript`](demos/extendscript/)
- [`Headless Browsers`](demos/headless/)
- [`canvas-datagrid`](demos/datagrid/)
- [`Swift JSC and other engines`](demos/altjs/)
- [`"serverless" functions`](demos/function/)
- [`internet explorer`](demos/oldie/)
Other examples are included in the [showcase](demos/showcase/).
### 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`
A slimmer build with XLSX / HTML support is generated at `dist/xlsx.mini.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.min.js"></script>
2017-09-24 23:40:09 +00:00
<!-- 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
The script also includes `IE_LoadFile` and `IE_SaveFile` for loading and saving
files in Internet Explorer versions 6-9. The `xlsx.extendscript.js` script
bundles the shim in a format suitable for Photoshop and other Adobe products.
## 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.
2018-05-21 01:41:01 +00:00
The primary focus of the Community Edition is correct data interchange, focused
on extracting data from any compatible data representation and exporting data in
various formats suitable for any third party interface.
</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>
<summary><b>Photoshop ExtendScript read a file</b> (click to show)</summary>
`readFile` wraps the `File` logic in Photoshop and other ExtendScript targets.
The specified path should be an absolute path:
```js
#include "xlsx.extendscript.js"
/* Read test.xlsx from the Documents folder */
var workbook = XLSX.readFile(Folder.myDocuments + '/' + 'test.xlsx');
/* DO SOMETHING WITH workbook HERE */
```
The [`extendscript` demo](demos/extendscript/) includes a more complex example.
</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 workbook = XLSX.utils.table_to_book(document.getElementById('tableau'));
/* DO SOMETHING WITH workbook HERE */
```
Multiple tables on a web page can be converted to individual worksheets:
```js
/* create new workbook */
var workbook = XLSX.utils.book_new();
/* convert table 'table1' to worksheet named "Sheet1" */
var ws1 = XLSX.utils.table_to_sheet(document.getElementById('table1'));
XLSX.utils.book_append_sheet(workbook, ws1, "Sheet1");
/* convert table 'table2' to worksheet named "Sheet2" */
var ws2 = XLSX.utils.table_to_sheet(document.getElementById('table2'));
XLSX.utils.book_append_sheet(workbook, ws2, "Sheet2");
/* workbook now has 2 worksheets */
```
Alternatively, the HTML code can be extracted and parsed:
```js
var htmlstr = document.getElementById('tableau').outerHTML;
var workbook = 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
at <http://oss.sheetjs.com/js-xlsx/ajax.html>. The [`xhr` demo](demos/xhr/)
2017-09-24 23:40:09 +00:00
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>
Drag-and-drop uses the HTML5 `FileReader` API.
2014-05-28 18:31:33 +00:00
```js
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 = new Uint8Array(e.target.result);
var workbook = XLSX.read(data, {type: 'array'});
2017-09-24 23:40:09 +00:00
/* DO SOMETHING WITH workbook HERE */
};
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
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 = new Uint8Array(e.target.result);
var workbook = XLSX.read(data, {type: 'array'});
2017-09-24 23:40:09 +00:00
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsArrayBuffer(f);
}
input_dom_element.addEventListener('change', handleFile, false);
```
The [`oldie` demo](demos/oldie/) shows an IE-compatible fallback scenario.
</details>
More specialized cases, including mobile app file processing, are covered in the
[included demos](demos/)
### 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
sheet and `XLSX.utils.book_append_sheet` to append the sheet to the workbook:
2017-05-24 22:52:35 +00:00
```js
2019-07-29 10:14:10 +00:00
var ws_name = "SheetJS";
2017-05-24 22:52:35 +00:00
/* 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 worksheet to the workbook */
XLSX.utils.book_append_sheet(wb, ws, ws_name);
```
</details>
2017-05-24 22:52:35 +00:00
<details>
<summary><b>Creating a new workbook from scratch</b> (click to show)</summary>
2017-05-24 22:52:35 +00:00
The workbook object contains a `SheetNames` array of names and a `Sheets` object
mapping sheet names to sheet objects. The `XLSX.utils.book_new` utility function
creates a new workbook object:
```js
/* create a new blank workbook */
var wb = XLSX.utils.book_new();
2017-05-24 22:52:35 +00:00
```
The new workbook is blank and contains no worksheets. The write functions will
error if the workbook is empty.
2017-05-24 22:52:35 +00:00
</details>
### Parsing and Writing Examples
- <http://sheetjs.com/demos/modify.html> read + modify + write files
2014-05-28 18:31:33 +00:00