From 6449ecc35eb1ed2dfb8c17be2d13b82ef5ab925a Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sun, 15 May 2022 23:26:04 -0400 Subject: [PATCH] docusaurus --- .spelling | 3 + Makefile | 8 +- README.md | 4580 +---------------- docz/.gitignore | 20 + docz/README.md | 3 + docz/babel.config.js | 3 + docz/blog/2019-05-28-first-blog-post.md | 12 + docz/blog/2019-05-29-long-blog-post.md | 44 + docz/blog/2021-08-01-mdx-blog-post.mdx | 20 + .../docusaurus-plushie-banner.jpeg | Bin 0 -> 96122 bytes docz/blog/2021-08-26-welcome/index.md | 25 + docz/blog/authors.yml | 17 + docz/docs/02-installation/01-standalone.mdx | 112 + docz/docs/02-installation/02-frameworks.md | 54 + docz/docs/02-installation/03-deno.md | 31 + docz/docs/02-installation/04-nodejs.md | 104 + docz/docs/02-installation/05-extendscript.md | 21 + docz/docs/02-installation/_category_.json | 4 + docz/docs/02-installation/index.md | 20 + docz/docs/03-example.mdx | 375 ++ docz/docs/04-getting-started/01-roadmap.md | 67 + docz/docs/04-getting-started/02-zen.md | 37 + docz/docs/04-getting-started/03-demos.md | 50 + docz/docs/04-getting-started/_category_.json | 4 + .../img/docsVersionDropdown.png | Bin 0 -> 25427 bytes .../04-getting-started/img/localeDropdown.png | Bin 0 -> 27841 bytes docz/docs/05-interface.md | 70 + docz/docs/06-solutions/01-input.md | 782 +++ docz/docs/06-solutions/03-processing.md | 139 + docz/docs/06-solutions/05-output.md | 624 +++ docz/docs/06-solutions/_category_.json | 4 + docz/docs/07-csf/01-general.md | 150 + docz/docs/07-csf/02-sheet.md | 144 + docz/docs/07-csf/03-book.md | 107 + docz/docs/07-csf/07-features.md | 701 +++ docz/docs/07-csf/_category_.json | 4 + docz/docs/08-api/05-parse-options.md | 155 + docz/docs/08-api/07-write-options.md | 102 + docz/docs/08-api/09-utilities.md | 497 ++ docz/docs/08-api/_category_.json | 4 + docz/docs/09-miscellany/01-formats.md | 255 + docz/docs/09-miscellany/06-testing.md | 111 + docz/docs/09-miscellany/07-contributing.md | 122 + docz/docs/09-miscellany/08-license.md | 218 + docz/docs/09-miscellany/09-references.md | 46 + docz/docs/09-miscellany/_category_.json | 4 + docz/docs/img/final.png | Bin 0 -> 32461 bytes docz/docs/img/formats.png | Bin 0 -> 208619 bytes docz/docs/img/legend.png | Bin 0 -> 33608 bytes docz/docs/img/rough.png | Bin 0 -> 28971 bytes docz/docs/img/tools.svg | 38 + docz/docs/index.md | 223 + docz/docusaurus.config.js | 161 + docz/package.json | 43 + docz/sidebars.js | 31 + docz/src/components/HomepageFeatures/index.js | 93 + .../HomepageFeatures/styles.module.css | 11 + docz/src/components/Playground.tsx | 40 + docz/src/css/custom.css | 39 + docz/src/pages/index.js | 40 + docz/src/pages/index.module.css | 23 + docz/static/.nojekyll | 0 docz/static/data.json | 2364 +++++++++ docz/static/img/data.svg | 41 + docz/static/img/favicon.ico | Bin 0 -> 65931 bytes docz/static/img/formats.svg | 534 ++ docz/static/img/logo.svg | 26 + docz/static/img/places.svg | 35 + docz/static/img/tools.svg | 36 + docz/version.js | 2 + 70 files changed, 9054 insertions(+), 4579 deletions(-) create mode 100644 docz/.gitignore create mode 100644 docz/README.md create mode 100644 docz/babel.config.js create mode 100644 docz/blog/2019-05-28-first-blog-post.md create mode 100644 docz/blog/2019-05-29-long-blog-post.md create mode 100644 docz/blog/2021-08-01-mdx-blog-post.mdx create mode 100644 docz/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg create mode 100644 docz/blog/2021-08-26-welcome/index.md create mode 100644 docz/blog/authors.yml create mode 100644 docz/docs/02-installation/01-standalone.mdx create mode 100644 docz/docs/02-installation/02-frameworks.md create mode 100644 docz/docs/02-installation/03-deno.md create mode 100644 docz/docs/02-installation/04-nodejs.md create mode 100644 docz/docs/02-installation/05-extendscript.md create mode 100644 docz/docs/02-installation/_category_.json create mode 100644 docz/docs/02-installation/index.md create mode 100644 docz/docs/03-example.mdx create mode 100644 docz/docs/04-getting-started/01-roadmap.md create mode 100644 docz/docs/04-getting-started/02-zen.md create mode 100644 docz/docs/04-getting-started/03-demos.md create mode 100644 docz/docs/04-getting-started/_category_.json create mode 100644 docz/docs/04-getting-started/img/docsVersionDropdown.png create mode 100644 docz/docs/04-getting-started/img/localeDropdown.png create mode 100644 docz/docs/05-interface.md create mode 100644 docz/docs/06-solutions/01-input.md create mode 100644 docz/docs/06-solutions/03-processing.md create mode 100644 docz/docs/06-solutions/05-output.md create mode 100644 docz/docs/06-solutions/_category_.json create mode 100644 docz/docs/07-csf/01-general.md create mode 100644 docz/docs/07-csf/02-sheet.md create mode 100644 docz/docs/07-csf/03-book.md create mode 100644 docz/docs/07-csf/07-features.md create mode 100644 docz/docs/07-csf/_category_.json create mode 100644 docz/docs/08-api/05-parse-options.md create mode 100644 docz/docs/08-api/07-write-options.md create mode 100644 docz/docs/08-api/09-utilities.md create mode 100644 docz/docs/08-api/_category_.json create mode 100644 docz/docs/09-miscellany/01-formats.md create mode 100644 docz/docs/09-miscellany/06-testing.md create mode 100644 docz/docs/09-miscellany/07-contributing.md create mode 100644 docz/docs/09-miscellany/08-license.md create mode 100644 docz/docs/09-miscellany/09-references.md create mode 100644 docz/docs/09-miscellany/_category_.json create mode 100644 docz/docs/img/final.png create mode 100644 docz/docs/img/formats.png create mode 100644 docz/docs/img/legend.png create mode 100644 docz/docs/img/rough.png create mode 100644 docz/docs/img/tools.svg create mode 100644 docz/docs/index.md create mode 100644 docz/docusaurus.config.js create mode 100644 docz/package.json create mode 100644 docz/sidebars.js create mode 100644 docz/src/components/HomepageFeatures/index.js create mode 100644 docz/src/components/HomepageFeatures/styles.module.css create mode 100644 docz/src/components/Playground.tsx create mode 100644 docz/src/css/custom.css create mode 100644 docz/src/pages/index.js create mode 100644 docz/src/pages/index.module.css create mode 100644 docz/static/.nojekyll create mode 100644 docz/static/data.json create mode 100644 docz/static/img/data.svg create mode 100644 docz/static/img/favicon.ico create mode 100644 docz/static/img/formats.svg create mode 100644 docz/static/img/logo.svg create mode 100644 docz/static/img/places.svg create mode 100644 docz/static/img/tools.svg create mode 100644 docz/version.js diff --git a/.spelling b/.spelling index 787ba4b..8d944eb 100644 --- a/.spelling +++ b/.spelling @@ -5,6 +5,7 @@ js-xlsx xls xlsb xlsx +docs.sheetjs.com # Excel-related terms A1-style @@ -48,6 +49,7 @@ NPM Nuxt PhantomJS Photoshop +ReactJS Redis RequireJS Rollup @@ -58,6 +60,7 @@ VueJS WebKit WebSQL WK_ +axios iOS iWork nodejs diff --git a/Makefile b/Makefile index c4f7919..85b73c1 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,9 @@ +.PHONY: build +build: + cd docz; pnpm build; cd .. + rm -rf docs + mv docz/build/ docs + .PHONY: index index: readme ## Rebuild site sed -i .bak 's/](d/](https:\/\/github.com\/SheetJS\/SheetJS\/tree\/master\/d/g' README.md @@ -21,7 +27,7 @@ formats.png legend.png: %.png: misc/%.svg node misc/coarsify.js misc/$*.svg misc/$*.svg.svg npx svgexport misc/$*.svg.svg $@ 0.5x -MDLINT=README.md +MDLINT=README.md $(wildcard docz/*.md*) $(wildcard docz/docs/*.md*) $(wildcard docz/docs/*/*.md*) .PHONY: mdlint mdlint: $(MDLINT) ## Check markdown documents npx alex $^ diff --git a/README.md b/README.md index 9f1dd85..786cbd6 100644 --- a/README.md +++ b/README.md @@ -1,4579 +1,3 @@ -# [SheetJS](https://sheetjs.com) +# SheetJS CE Docs -The SheetJS Community Edition offers battle-tested open-source solutions for -extracting useful data from almost any complex spreadsheet and generating new -spreadsheets that will work with legacy and modern software alike. - -[SheetJS Pro](https://sheetjs.com/pro) offers solutions beyond data processing: -Edit complex templates with ease; let out your inner Picasso with styling; make -custom sheets with images/graphs/PivotTables; evaluate formula expressions and -port calculations to web apps; automate common spreadsheet tasks, and much more! - -![License](https://img.shields.io/github/license/SheetJS/sheetjs) -[![Build Status](https://img.shields.io/github/workflow/status/sheetjs/sheetjs/Tests:%20node.js)](https://github.com/SheetJS/sheetjs/actions) -[![Snyk Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/SheetJS/sheetjs)](https://snyk.io/test/github/SheetJS/sheetjs) -[![npm Downloads](https://img.shields.io/npm/dm/xlsx.svg)](https://npmjs.org/package/xlsx) -[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/sheetjs?pixel)](https://github.com/SheetJS/sheetjs) - -[**Browser Test and Support Matrix**](https://oss.sheetjs.com/sheetjs/tests/) - -[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs) - -**Supported File Formats** - -![circo graph of format support](formats.png) - -![graph legend](legend.png) - -## Table of Contents - -
- Expand to show Table of Contents - - - -- [Getting Started](#getting-started) - * [Installation](#installation) - + [Standalone Browser Scripts](#standalone-browser-scripts) - + [ECMAScript Modules](#ecmascript-modules) - + [Deno](#deno) - + [NodeJS](#nodejs) - + [Photoshop and InDesign](#photoshop-and-indesign) - * [Usage](#usage) - * [The Zen of SheetJS](#the-zen-of-sheetjs) - * [JS Ecosystem Demos](#js-ecosystem-demos) -- [Acquiring and Extracting Data](#acquiring-and-extracting-data) - * [Parsing Workbooks](#parsing-workbooks) - * [Processing JSON and JS Data](#processing-json-and-js-data) - * [Processing HTML Tables](#processing-html-tables) -- [Processing Data](#processing-data) - * [Modifying Workbook Structure](#modifying-workbook-structure) - * [Modifying Cell Values](#modifying-cell-values) - * [Modifying Other Worksheet / Workbook / Cell Properties](#modifying-other-worksheet--workbook--cell-properties) -- [Packaging and Releasing Data](#packaging-and-releasing-data) - * [Writing Workbooks](#writing-workbooks) - * [Writing Examples](#writing-examples) - * [Streaming Write](#streaming-write) - * [Generating JSON and JS Data](#generating-json-and-js-data) - * [Generating HTML Tables](#generating-html-tables) - * [Generating Single-Worksheet Snapshots](#generating-single-worksheet-snapshots) -- [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) - * [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) - + [Row and Column Properties](#row-and-column-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) -- [Testing](#testing) - * [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) - - - -
- -## Getting Started - -### Installation - -#### Standalone Browser Scripts - -Each standalone release script is available at . - -The current version is `0.18.7` and can be referenced as follows: - -```html - - -``` - -The `latest` tag references the latest version and updates with each release: - -```html - - -``` - -**For production use, scripts should be downloaded and added to a public folder -alongside other scripts.** - -
- Browser builds (click to show) - -The complete single-file version is generated at `dist/xlsx.full.min.js` - -`dist/xlsx.core.min.js` omits codepage library (no support for XLS encodings) - -A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build: -- codepage library skipped (no support for XLS encodings) -- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers -- node stream utils removed - -These scripts are also available on the CDN: - -```html - - -``` - -
- - -[Bower](https://bower.io/) plays nice with the CDN tarballs: - -```bash -$ npx bower install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz -``` - -Bower will place the standalone scripts in `bower_components/js-xlsx/dist/` - -
- Internet Explorer and ECMAScript 3 Compatibility (click to show) - -For broad compatibility with JavaScript engines, the library is written using -ECMAScript 3 language dialect as well as some ES5 features like `Array#forEach`. -Older browsers require shims to provide missing functions. - -To use the shim, add the shim before the script tag that loads `xlsx.js`: - -```html - - - - -``` - -Due to SSL certificate compatibility issues, it is highly recommended to save -the Standalone and Shim scripts from and add to a -public directory in the site. - -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. - -
- - -#### ECMAScript Modules - -_Browser ESM_ - -The ECMAScript Module build is saved to `xlsx.mjs` and can be directly added to -a page with a `script` tag using `type="module"`: - -```html - -``` - -_Frameworks (Angular, VueJS, React) and Bundlers (webpack, etc)_ - -The NodeJS package is readily installed from the tarballs: - -```bash -$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm -$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm -$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn -``` - -Once installed, the library can be imported under the name `xlsx`: - -```ts -import { read, writeFileXLSX } from "xlsx"; - -/* load the codepage support library for extended support with older formats */ -import { set_cptable } from "xlsx"; -import * as cptable from 'xlsx/dist/cpexcel.full.mjs'; -set_cptable(cptable); -``` - -#### Deno - -`xlsx.mjs` can be imported in Deno: - -```ts -// @deno-types="https://cdn.sheetjs.com/xlsx-0.18.7/package/types/index.d.ts" -import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs'; - -/* load the codepage support library for extended support with older formats */ -import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs'; -XLSX.set_cptable(cptable); -``` - -#### NodeJS - -Tarballs are available on . - -Each individual version can be referenced using a similar URL pattern. - is the URL for `0.18.7` - - is a link to the latest -version and will refresh on each release. - -_Installation_ - -Tarballs can be directly installed using a package manager: - -```bash -$ npm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm -$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm -$ yarn add https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn -``` - -For general stability, "vendoring" modules is the recommended approach: - -1) Download the tarball (`xlsx-0.18.7.tgz`) for the desired version. The current - version is available at - -2) Create a `vendor` subdirectory at the root of your project and move the - tarball to that folder. Add it to your project repository. - -3) Install the tarball using a package manager: - -```bash -$ npm install --save file:vendor/xlsx-0.18.7.tgz # npm -$ pnpm install --save file:vendor/xlsx-0.18.7.tgz # pnpm -$ yarn add file:vendor/xlsx-0.18.7.tgz # yarn -``` - -The package will be installed and accessible as `xlsx`. - -_Usage_ - -By default, the module supports `require` and it will automatically add support -for streams and filesystem access: - -```js -var XLSX = require("xlsx"); -``` - -The module also ships with `xlsx.mjs` for use with `import`. The `mjs` version -does not automatically load native node modules: - -```js -import * as XLSX from 'xlsx/xlsx.mjs'; - -/* load 'fs' for readFile and writeFile support */ -import * as fs from 'fs'; -XLSX.set_fs(fs); - -/* load 'stream' for stream support */ -import { Readable } from 'stream'; -XLSX.stream.set_readable(Readable); - -/* load the codepage support library for extended support with older formats */ -import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs'; -XLSX.set_cptable(cpexcel); -``` - -#### Photoshop and InDesign - -`dist/xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign. - is the -current version. After downloading the script, it can be directly referenced -with a `#include` directive: - -```extendscript -#include "xlsx.extendscript.js" -``` - - -### Usage - -Most scenarios involving spreadsheets and data can be broken into 5 parts: - -1) **Acquire Data**: Data may be stored anywhere: local or remote files, - databases, HTML TABLE, or even generated programmatically in the web browser. - -2) **Extract Data**: For spreadsheet files, this involves parsing raw bytes to - read the cell data. For general JS data, this involves reshaping the data. - -3) **Process Data**: From generating summary statistics to cleaning data - records, this step is the heart of the problem. - -4) **Package Data**: This can involve making a new spreadsheet or serializing - with `JSON.stringify` or writing XML or simply flattening data for UI tools. - -5) **Release Data**: Spreadsheet files can be uploaded to a server or written - locally. Data can be presented to users in an HTML TABLE or data grid. - -A common problem involves generating a valid spreadsheet export from data stored -in an HTML table. In this example, an HTML TABLE on the page will be scraped, -a row will be added to the bottom with the date of the report, and a new file -will be generated and downloaded locally. `XLSX.writeFile` takes care of -packaging the data and attempting a local download: - -```js -// Acquire Data (reference to the HTML table) -var table_elt = document.getElementById("my-table-id"); - -// Extract Data (create a workbook object from the table) -var workbook = XLSX.utils.table_to_book(table_elt); - -// Process Data (add a new row) -var ws = workbook.Sheets["Sheet1"]; -XLSX.utils.sheet_add_aoa(ws, [["Created "+new Date().toISOString()]], {origin:-1}); - -// Package and Release Data (`writeFile` tries to write and save an XLSB file) -XLSX.writeFile(workbook, "Report.xlsb"); -``` - -This library tries to simplify steps 2 and 4 with functions to extract useful -data from spreadsheet files (`read` / `readFile`) and generate new spreadsheet -files from data (`write` / `writeFile`). Additional utility functions like -`table_to_book` work with other common data sources like HTML tables. - -This documentation and various demo projects cover a number of common scenarios -and approaches for steps 1 and 5. - -Utility functions help with step 3. - -["Acquiring and Extracting Data"](#acquiring-and-extracting-data) describes -solutions for common data import scenarios. - -["Packaging and Releasing Data"](#packaging-and-releasing-data) describes -solutions for common data export scenarios. - -["Processing Data"](#packaging-and-releasing-data) describes solutions for -common workbook processing and manipulation scenarios. - -["Utility Functions"](#utility-functions) details utility functions for -translating JSON Arrays and other common JS structures into worksheet objects. - -### The Zen of SheetJS - -_Data processing should fit in any workflow_ - -The library does not impose a separate lifecycle. It fits nicely in websites -and apps built using any framework. The plain JS data objects play nice with -Web Workers and future APIs. - -_JavaScript is a powerful language for data processing_ - -The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object -representation of the core concepts of a workbook. The various functions in the -library provide low-level tools for working with the object. - -For friendly JS processing, there are utility functions for converting parts of -a worksheet to/from an Array of Arrays. The following example combines powerful -JS Array methods with a network request library to download data, select the -information we want and create a workbook file: - -
- Get Data from a JSON Endpoint and Generate a Workbook (click to show) - -The goal is to generate a XLSB workbook of US President names and birthdays. - -**Acquire Data** - -_Raw Data_ - - has the desired -data. For example, John Adams: - -```js -{ - "id": { /* (data omitted) */ }, - "name": { - "first": "John", // <-- first name - "last": "Adams" // <-- last name - }, - "bio": { - "birthday": "1735-10-19", // <-- birthday - "gender": "M" - }, - "terms": [ - { "type": "viceprez", /* (other fields omitted) */ }, - { "type": "viceprez", /* (other fields omitted) */ }, - { "type": "prez", /* (other fields omitted) */ } // <-- look for "prez" - ] -} -``` - -_Filtering for Presidents_ - -The dataset includes Aaron Burr, a Vice President who was never President! - -`Array#filter` creates a new array with the desired rows. A President served -at least one term with `type` set to `"prez"`. To test if a particular row has -at least one `"prez"` term, `Array#some` is another native JS function. The -complete filter would be: - -```js -const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); -``` - -_Lining up the data_ - -For this example, the name will be the first name combined with the last name -(`row.name.first + " " + row.name.last`) and the birthday will be the subfield -`row.bio.birthday`. Using `Array#map`, the dataset can be massaged in one call: - -```js -const rows = prez.map(row => ({ - name: row.name.first + " " + row.name.last, - birthday: row.bio.birthday -})); -``` - -The result is an array of "simple" objects with no nesting: - -```js -[ - { name: "George Washington", birthday: "1732-02-22" }, - { name: "John Adams", birthday: "1735-10-19" }, - // ... one row per President -] -``` - -**Extract Data** - -With the cleaned dataset, `XLSX.utils.json_to_sheet` generates a worksheet: - -```js -const worksheet = XLSX.utils.json_to_sheet(rows); -``` - -`XLSX.utils.book_new` creates a new workbook and `XLSX.utils.book_append_sheet` -appends a worksheet to the workbook. The new worksheet will be called "Dates": - -```js -const workbook = XLSX.utils.book_new(); -XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); -``` - -**Process Data** - -_Fixing headers_ - -By default, `json_to_sheet` creates a worksheet with a header row. In this case, -the headers come from the JS object keys: "name" and "birthday". - -The headers are in cells A1 and B1. `XLSX.utils.sheet_add_aoa` can write text -values to the existing worksheet starting at cell A1: - -```js -XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); -``` - -_Fixing Column Widths_ - -Some of the names are longer than the default column width. Column widths are -set by [setting the `"!cols"` worksheet property](#row-and-column-properties). - -The following line sets the width of column A to approximately 10 characters: - -```js -worksheet["!cols"] = [ { wch: 10 } ]; // set column A width to 10 characters -``` - -One `Array#reduce` call over `rows` can calculate the maximum width: - -```js -const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); -worksheet["!cols"] = [ { wch: max_width } ]; -``` - -Note: If the starting point was a file or HTML table, `XLSX.utils.sheet_to_json` -will generate an array of JS objects. - -**Package and Release Data** - -`XLSX.writeFile` creates a spreadsheet file and tries to write it to the system. -In the browser, it will try to prompt the user to download the file. In NodeJS, -it will write to the local directory. - -```js -XLSX.writeFile(workbook, "Presidents.xlsx"); -``` - -**Complete Example** - -```js -// Uncomment the next line for use in NodeJS: -// const XLSX = require("xlsx"), axios = require("axios"); - -(async() => { - /* fetch JSON data and parse */ - const url = "https://theunitedstates.io/congress-legislators/executive.json"; - const raw_data = (await axios(url, {responseType: "json"})).data; - - /* filter for the Presidents */ - const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); - - /* flatten objects */ - const rows = prez.map(row => ({ - name: row.name.first + " " + row.name.last, - birthday: row.bio.birthday - })); - - /* generate worksheet and workbook */ - const worksheet = XLSX.utils.json_to_sheet(rows); - const workbook = XLSX.utils.book_new(); - XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); - - /* fix headers */ - XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); - - /* calculate column width */ - const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); - worksheet["!cols"] = [ { wch: max_width } ]; - - /* create an XLSX file and try to save to Presidents.xlsx */ - XLSX.writeFile(workbook, "Presidents.xlsx"); -})(); -``` - -For use in the web browser, assuming the snippet is saved to `snippet.js`, -script tags should be used to include the `axios` and `xlsx` standalone builds: - -```html - - - -``` - - -
- -_File formats are implementation details_ - -The parser covers a wide gamut of common spreadsheet file formats to ensure that -"HTML-saved-as-XLS" files work as well as actual XLS or XLSX files. - -The writer supports a number of common output formats for broad compatibility -with the data ecosystem. - -To the greatest extent possible, data processing code should not have to worry -about the specific file formats involved. - - -### JS Ecosystem Demos - -The [`demos` directory](https://github.com/SheetJS/SheetJS/tree/master/demos/) includes sample projects for: - -**Frameworks and APIs** -- [`angularjs`](https://github.com/SheetJS/SheetJS/tree/master/demos/angular/) -- [`angular and ionic`](https://github.com/SheetJS/SheetJS/tree/master/demos/angular2/) -- [`knockout`](https://github.com/SheetJS/SheetJS/tree/master/demos/knockout/) -- [`meteor`](https://github.com/SheetJS/SheetJS/tree/master/demos/meteor/) -- [`react, react-native, next`](https://github.com/SheetJS/SheetJS/tree/master/demos/react/) -- [`vue 2.x, weex, nuxt`](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/) -- [`XMLHttpRequest and fetch`](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) -- [`nodejs server`](https://github.com/SheetJS/SheetJS/tree/master/demos/server/) -- [`databases and key/value stores`](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) -- [`typed arrays and math`](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) - -**Bundlers and Tooling** -- [`browserify`](https://github.com/SheetJS/SheetJS/tree/master/demos/browserify/) -- [`fusebox`](https://github.com/SheetJS/SheetJS/tree/master/demos/fusebox/) -- [`parcel`](https://github.com/SheetJS/SheetJS/tree/master/demos/parcel/) -- [`requirejs`](https://github.com/SheetJS/SheetJS/tree/master/demos/requirejs/) -- [`rollup`](https://github.com/SheetJS/SheetJS/tree/master/demos/rollup/) -- [`systemjs`](https://github.com/SheetJS/SheetJS/tree/master/demos/systemjs/) -- [`typescript`](https://github.com/SheetJS/SheetJS/tree/master/demos/typescript/) -- [`webpack 2.x`](https://github.com/SheetJS/SheetJS/tree/master/demos/webpack/) - -**Platforms and Integrations** -- [`deno`](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) -- [`electron application`](https://github.com/SheetJS/SheetJS/tree/master/demos/electron/) -- [`nw.js application`](https://github.com/SheetJS/SheetJS/tree/master/demos/nwjs/) -- [`Chrome / Chromium extensions`](https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/) -- [`Download a Google Sheet locally`](https://github.com/SheetJS/SheetJS/tree/master/demos/google-sheet/) -- [`Adobe ExtendScript`](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) -- [`Headless Browsers`](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) -- [`canvas-datagrid`](https://github.com/SheetJS/SheetJS/tree/master/demos/datagrid/) -- [`x-spreadsheet`](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet/) -- [`react-data-grid`](https://github.com/SheetJS/SheetJS/tree/master/demos/react/modify/) -- [`vue3-table-light`](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/) -- [`Swift JSC and other engines`](https://github.com/SheetJS/SheetJS/tree/master/demos/altjs/) -- [`"serverless" functions`](https://github.com/SheetJS/SheetJS/tree/master/demos/function/) -- [`internet explorer`](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) - -Other examples are included in the [showcase](https://github.com/SheetJS/SheetJS/tree/master/demos/showcase/). - - shows a complete example of reading, -modifying, and writing files. - - is the command-line -tool included with node installations, reading spreadsheet files and exporting -the contents in various formats. -## Acquiring and Extracting Data - -### Parsing Workbooks - -**API** - -_Extract data from spreadsheet bytes_ - -```js -var workbook = XLSX.read(data, opts); -``` - -The `read` method can extract data from spreadsheet bytes stored in a JS string, -"binary string", NodeJS buffer or typed array (`Uint8Array` or `ArrayBuffer`). - - -_Read spreadsheet bytes from a local file and extract data_ - -```js -var workbook = XLSX.readFile(filename, opts); -``` - -The `readFile` method attempts to read a spreadsheet file at the supplied path. -Browsers generally do not allow reading files in this way (it is deemed a -security risk), and attempts to read files in this way will throw an error. - -The second `opts` argument is optional. ["Parsing Options"](#parsing-options) -covers the supported properties and behaviors. - -**Examples** - -Here are a few common scenarios (click on each subtitle to see the code): - -
- Local file in a NodeJS server (click to show) - -`readFile` uses `fs.readFileSync` under the hood: - -```js -var XLSX = require("xlsx"); - -var workbook = XLSX.readFile("test.xlsx"); -``` - -For Node ESM, the `readFile` helper is not enabled. Instead, `fs.readFileSync` -should be used to read the file data as a `Buffer` for use with `XLSX.read`: - -```js -import { readFileSync } from "fs"; -import { read } from "xlsx/xlsx.mjs"; - -const buf = readFileSync("test.xlsx"); -/* buf is a Buffer */ -const workbook = read(buf); -``` - -
- -
- Local file in a Deno application (click to show) - -`readFile` uses `Deno.readFileSync` under the hood: - -```js -// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts" -import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs' - -const workbook = XLSX.readFile("test.xlsx"); -``` - -Applications reading files must be invoked with the `--allow-read` flag. The -[`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples - -
- -
- User-submitted file in a web page ("Drag-and-Drop") (click to show) - -For modern websites targeting Chrome 76+, `File#arrayBuffer` is recommended: - -```js -// XLSX is a global from the standalone script - -async function handleDropAsync(e) { - e.stopPropagation(); e.preventDefault(); - const f = e.dataTransfer.files[0]; - /* f is a File */ - const data = await f.arrayBuffer(); - /* data is an ArrayBuffer */ - const workbook = XLSX.read(data); - - /* DO SOMETHING WITH workbook HERE */ -} -drop_dom_element.addEventListener("drop", handleDropAsync, false); -``` - -For maximal compatibility, the `FileReader` API should be used: - -```js -function handleDrop(e) { - e.stopPropagation(); e.preventDefault(); - var f = e.dataTransfer.files[0]; - /* f is a File */ - var reader = new FileReader(); - reader.onload = function(e) { - var data = e.target.result; - /* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */ - var workbook = XLSX.read(data); - - /* DO SOMETHING WITH workbook HERE */ - }; - reader.readAsArrayBuffer(f); -} -drop_dom_element.addEventListener("drop", handleDrop, false); -``` - - demonstrates the FileReader technique. - -
- -
- User-submitted file with an HTML INPUT element (click to show) - -Starting with an HTML INPUT element with `type="file"`: - -```html - -``` - -For modern websites targeting Chrome 76+, `Blob#arrayBuffer` is recommended: - -```js -// XLSX is a global from the standalone script - -async function handleFileAsync(e) { - const file = e.target.files[0]; - const data = await file.arrayBuffer(); - /* data is an ArrayBuffer */ - const workbook = XLSX.read(data); - - /* DO SOMETHING WITH workbook HERE */ -} -input_dom_element.addEventListener("change", handleFileAsync, false); -``` - -For broader support (including IE10+), the `FileReader` approach is recommended: - -```js -function handleFile(e) { - var file = e.target.files[0]; - var reader = new FileReader(); - reader.onload = function(e) { - var data = e.target.result; - /* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */ - var workbook = XLSX.read(e.target.result); - - /* DO SOMETHING WITH workbook HERE */ - }; - reader.readAsArrayBuffer(file); -} -input_dom_element.addEventListener("change", handleFile, false); -``` - -The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario. - -
- -
- Fetching a file in the web browser ("Ajax") (click to show) - -For modern websites targeting Chrome 42+, `fetch` is recommended: - -```js -// XLSX is a global from the standalone script - -(async() => { - const url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"; - const data = await (await fetch(url)).arrayBuffer(); - /* data is an ArrayBuffer */ - const workbook = XLSX.read(data); - - /* DO SOMETHING WITH workbook HERE */ -})(); -``` - -For broader support, the `XMLHttpRequest` approach is recommended: - -```js -var url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"; - -/* set up async GET request */ -var req = new XMLHttpRequest(); -req.open("GET", url, true); -req.responseType = "arraybuffer"; - -req.onload = function(e) { - var workbook = XLSX.read(req.response); - - /* DO SOMETHING WITH workbook HERE */ -}; - -req.send(); -``` - -The [`xhr` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) includes a longer discussion and more examples. - - shows fallback approaches for IE6+. - -
- -
- Local file in a PhotoShop or InDesign plugin (click to show) - -`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"); -``` - -The [`extendscript` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) includes a more complex example. - -
- -
- Local file in an Electron app (click to show) - -`readFile` can be used in the renderer process: - -```js -/* From the renderer process */ -var XLSX = require("xlsx"); - -var workbook = XLSX.readFile(path); -``` - -Electron APIs have changed over time. The [`electron` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/electron/) -shows a complete example and details the required version-specific settings. - -
- -
- Local file in a mobile app with React Native (click to show) - -The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes a sample React Native app. - -Since React Native does not provide a way to read files from the filesystem, a -third-party library must be used. The following libraries have been tested: - -- [`react-native-file-access`](https://npm.im/react-native-file-access) - -The `base64` encoding returns strings compatible with the `base64` type: - -```js -import XLSX from "xlsx"; -import { FileSystem } from "react-native-file-access"; - -const b64 = await FileSystem.readFile(path, "base64"); -/* b64 is a base64 string */ -const workbook = XLSX.read(b64, {type: "base64"}); -``` - -- [`react-native-fs`](https://npm.im/react-native-fs) - -The `ascii` encoding returns binary strings compatible with the `binary` type: - -```js -import XLSX from "xlsx"; -import { readFile } from "react-native-fs"; - -const bstr = await readFile(path, "ascii"); -/* bstr is a binary string */ -const workbook = XLSX.read(bstr, {type: "binary"}); -``` - -
- -
- NodeJS Server File Uploads (click to show) - -`read` can accept a NodeJS buffer. `readFile` can read files generated by a -HTTP POST request body parser like [`formidable`](https://npm.im/formidable): - -```js -const XLSX = require("xlsx"); -const http = require("http"); -const formidable = require("formidable"); - -const server = http.createServer((req, res) => { - const form = new formidable.IncomingForm(); - form.parse(req, (err, fields, files) => { - /* grab the first file */ - const f = Object.entries(files)[0][1]; - const path = f.filepath; - const workbook = XLSX.readFile(path); - - /* DO SOMETHING WITH workbook HERE */ - }); -}).listen(process.env.PORT || 7262); -``` - -The [`server` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/server) has more advanced examples. - -
- -
- Download files in a NodeJS process (click to show) - -Node 17.5 and 18.0 have native support for fetch: - -```js -const XLSX = require("xlsx"); - -const data = await (await fetch(url)).arrayBuffer(); -/* data is an ArrayBuffer */ -const workbook = XLSX.read(data); -``` - -For broader compatibility, third-party modules are recommended. - -[`request`](https://npm.im/request) requires a `null` encoding to yield Buffers: - -```js -var XLSX = require("xlsx"); -var request = require("request"); - -request({url: url, encoding: null}, function(err, resp, body) { - var workbook = XLSX.read(body); - - /* DO SOMETHING WITH workbook HERE */ -}); -``` - -[`axios`](https://npm.im/axios) works the same way in browser and in NodeJS: - -```js -const XLSX = require("xlsx"); -const axios = require("axios"); - -(async() => { - const res = await axios.get(url, {responseType: "arraybuffer"}); - /* res.data is a Buffer */ - const workbook = XLSX.read(res.data); - - /* DO SOMETHING WITH workbook HERE */ -})(); -``` - -
- -
- Download files in an Electron app (click to show) - -The `net` module in the main process can make HTTP/HTTPS requests to external -resources. Responses should be manually concatenated using `Buffer.concat`: - -```js -const XLSX = require("xlsx"); -const { net } = require("electron"); - -const req = net.request(url); -req.on("response", (res) => { - const bufs = []; // this array will collect all of the buffers - res.on("data", (chunk) => { bufs.push(chunk); }); - res.on("end", () => { - const workbook = XLSX.read(Buffer.concat(bufs)); - - /* DO SOMETHING WITH workbook HERE */ - }); -}); -req.end(); -``` - -
- -
- Readable Streams in NodeJS (click to show) - -When dealing with Readable Streams, the easiest approach is to buffer the stream -and process the whole thing at the end: - -```js -var fs = require("fs"); -var XLSX = require("xlsx"); - -function process_RS(stream, cb) { - 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); - }); -} -``` - -
- -
- ReadableStream in the browser (click to show) - -When dealing with `ReadableStream`, the easiest approach is to buffer the stream -and process the whole thing at the end: - -```js -// XLSX is a global from the standalone script - -async function process_RS(stream) { - /* collect data */ - const buffers = []; - const reader = stream.getReader(); - for(;;) { - const res = await reader.read(); - if(res.value) buffers.push(res.value); - if(res.done) break; - } - - /* concat */ - const out = new Uint8Array(buffers.reduce((acc, v) => acc + v.length, 0)); - - let off = 0; - for(const u8 of buffers) { - out.set(u8, off); - off += u8.length; - } - - return out; -} - -const data = await process_RS(stream); -/* data is Uint8Array */ -const workbook = XLSX.read(data, {type: 'array'}); -``` - -
- -More detailed examples are covered in the [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) - -### Processing JSON and JS Data - -JSON and JS data tend to represent single worksheets. This section will use a -few utility functions to generate workbooks. - -_Create a new Workbook_ - -```js -var workbook = XLSX.utils.book_new(); -``` - -The `book_new` utility function creates an empty workbook with no worksheets. - -Spreadsheet software generally require at least one worksheet and enforce the -requirement in the user interface. This library enforces the requirement at -write time, throwing errors if an empty workbook is passed to write functions. - - -**API** - -_Create a worksheet from an array of arrays of JS values_ - -```js -var worksheet = XLSX.utils.aoa_to_sheet(aoa, opts); -``` - -The `aoa_to_sheet` utility function walks an "array of arrays" in row-major -order, generating a worksheet object. The following snippet generates a sheet -with cell `A1` set to the string `A1`, cell `B1` set to `B1`, etc: - -```js -var worksheet = XLSX.utils.aoa_to_sheet([ - ["A1", "B1", "C1"], - ["A2", "B2", "C2"], - ["A3", "B3", "C3"] -]); -``` - -["Array of Arrays Input"](#array-of-arrays-input) describes the function and the -optional `opts` argument in more detail. - - -_Create a worksheet from an array of JS objects_ - -```js -var worksheet = XLSX.utils.json_to_sheet(jsa, opts); -``` - -The `json_to_sheet` utility function walks an array of JS objects in order, -generating a worksheet object. By default, it will generate a header row and -one row per object in the array. The optional `opts` argument has settings to -control the column order and header output. - -["Array of Objects Input"](#array-of-objects-input) describes the function and -the optional `opts` argument in more detail. - -**Examples** - -["Zen of SheetJS"](#the-zen-of-sheetjs) contains a detailed example "Get Data -from a JSON Endpoint and Generate a Workbook" - - -[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive -data grid for previewing and modifying structured data in the web browser. The -[`xspreadsheet` demo](/demos/xspreadsheet) includes a sample script with the -`xtos` function for converting from x-spreadsheet data object to a workbook. - is a live demo. - -
- Records from a database query (SQL or no-SQL) (click to show) - -The [`database` demo](/demos/database/) includes examples of working with -databases and query results. - -
- - -
- Numerical Computations with TensorFlow.js (click to show) - -[`@tensorflow/tfjs`](@tensorflow/tfjs) and other libraries expect data in simple -arrays, well-suited for worksheets where each column is a data vector. That is -the transpose of how most people use spreadsheets, where each row is a vector. - -When recovering data from `tfjs`, the returned data points are stored in a typed -array. An array of arrays can be constructed with loops. `Array#unshift` can -prepend a title row before the conversion: - -```js -const XLSX = require("xlsx"); -const tf = require('@tensorflow/tfjs'); - -/* suppose xs and ys are vectors (1D tensors) -> tfarr will be a typed array */ -const tfdata = tf.stack([xs, ys]).transpose(); -const shape = tfdata.shape; -const tfarr = tfdata.dataSync(); - -/* construct the array of arrays */ -const aoa = []; -for(let j = 0; j < shape[0]; ++j) { - aoa[j] = []; - for(let i = 0; i < shape[1]; ++i) aoa[j][i] = tfarr[j * shape[1] + i]; -} -/* add headers to the top */ -aoa.unshift(["x", "y"]); - -/* generate worksheet */ -const worksheet = XLSX.utils.aoa_to_sheet(aoa); -``` - -The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) shows a complete example. - -
- - -### Processing HTML Tables - -**API** - -_Create a worksheet by scraping an HTML TABLE in the page_ - -```js -var worksheet = XLSX.utils.table_to_sheet(dom_element, opts); -``` - -The `table_to_sheet` utility function takes a DOM TABLE element and iterates -through the rows to generate a worksheet. The `opts` argument is optional. -["HTML Table Input"](#html-table-input) describes the function in more detail. - - - -_Create a workbook by scraping an HTML TABLE in the page_ - -```js -var workbook = XLSX.utils.table_to_book(dom_element, opts); -``` - -The `table_to_book` utility function follows the same logic as `table_to_sheet`. -After generating a worksheet, it creates a blank workbook and appends the -spreadsheet. - -The options argument supports the same options as `table_to_sheet`, with the -addition of a `sheet` property to control the worksheet name. If the property -is missing or no options are specified, the default name `Sheet1` is used. - -**Examples** - -Here are a few common scenarios (click on each subtitle to see the code): - -
- HTML TABLE element in a webpage (click to show) - -```html - - - - - - - - -
SheetJS
1234567
- - - -``` - -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 sheet1 = XLSX.utils.table_to_sheet(document.getElementById("table1")); -XLSX.utils.book_append_sheet(workbook, sheet1, "Sheet1"); - -/* convert table "table2" to worksheet named "Sheet2" */ -var sheet2 = XLSX.utils.table_to_sheet(document.getElementById("table2")); -XLSX.utils.book_append_sheet(workbook, sheet2, "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"}); -``` - -
- -
- Chrome/Chromium Extension (click to show) - -The [`chrome` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/) shows a complete example and details the -required permissions and other settings. - -In an extension, it is recommended to generate the workbook in a content script -and pass the object back to the extension: - -```js -/* in the worker script */ -chrome.runtime.onMessage.addListener(function(msg, sender, cb) { - /* pass a message like { sheetjs: true } from the extension to scrape */ - if(!msg || !msg.sheetjs) return; - /* create a new workbook */ - var workbook = XLSX.utils.book_new(); - /* loop through each table element */ - var tables = document.getElementsByTagName("table") - for(var i = 0; i < tables.length; ++i) { - var worksheet = XLSX.utils.table_to_sheet(tables[i]); - XLSX.utils.book_append_sheet(workbook, worksheet, "Table" + i); - } - /* pass back to the extension */ - return cb(workbook); -}); -``` - -
- -
- Server-Side HTML Tables with Headless Chrome (click to show) - -The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML -files to XLSB workbooks. The core idea is to add the script to the page, parse -the table in the page context, generate a `base64` workbook and send it back -for further processing: - -```js -const XLSX = require("xlsx"); -const { readFileSync } = require("fs"), puppeteer = require("puppeteer"); - -const url = `https://sheetjs.com/demos/table`; - -/* get the standalone build source (node_modules/xlsx/dist/xlsx.full.min.js) */ -const lib = readFileSync(require.resolve("xlsx/dist/xlsx.full.min.js"), "utf8"); - -(async() => { - /* start browser and go to web page */ - const browser = await puppeteer.launch(); - const page = await browser.newPage(); - await page.goto(url, {waitUntil: "networkidle2"}); - - /* inject library */ - await page.addScriptTag({content: lib}); - - /* this function `s5s` will be called by the script below, receiving the Base64-encoded file */ - await page.exposeFunction("s5s", async(b64) => { - const workbook = XLSX.read(b64, {type: "base64" }); - - /* DO SOMETHING WITH workbook HERE */ - }); - - /* generate XLSB file in webpage context and send back result */ - await page.addScriptTag({content: ` - /* call table_to_book on first table */ - var workbook = XLSX.utils.table_to_book(document.querySelector("TABLE")); - - /* generate XLSX file */ - var b64 = XLSX.write(workbook, {type: "base64", bookType: "xlsb"}); - - /* call "s5s" hook exposed from the node process */ - window.s5s(b64); - `}); - - /* cleanup */ - await browser.close(); -})(); -``` - -
- -
- Server-Side HTML Tables with Headless WebKit (click to show) - -The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML -files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). The core idea -is to add the script to the page, parse the table in the page context, generate -a `binary` workbook and send it back for further processing: - -```js -var XLSX = require('xlsx'); -var page = require('webpage').create(); - -/* this code will be run in the page */ -var code = [ "function(){", - /* call table_to_book on first table */ - "var wb = XLSX.utils.table_to_book(document.body.getElementsByTagName('table')[0]);", - - /* generate XLSB file and return binary string */ - "return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});", -"}" ].join(""); - -page.open('https://sheetjs.com/demos/table', function() { - /* Load the browser script from the UNPKG CDN */ - page.includeJs("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", function() { - /* The code will return an XLSB file encoded as binary string */ - var bin = page.evaluateJavaScript(code); - - var workbook = XLSX.read(bin, {type: "binary"}); - /* DO SOMETHING WITH workbook HERE */ - - phantom.exit(); - }); -}); -``` - -
- -
- NodeJS HTML Tables without a browser (click to show) - -NodeJS does not include a DOM implementation and Puppeteer requires a hefty -Chromium build. [`jsdom`](https://npm.im/jsdom) is a lightweight alternative: - -```js -const XLSX = require("xlsx"); -const { readFileSync } = require("fs"); -const { JSDOM } = require("jsdom"); - -/* obtain HTML string. This example reads from test.html */ -const html_str = fs.readFileSync("test.html", "utf8"); -/* get first TABLE element */ -const doc = new JSDOM(html_str).window.document.querySelector("table"); -/* generate workbook */ -const workbook = XLSX.utils.table_to_book(doc); -``` - -
- -## Processing Data - -The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object -representation of the core concepts of a workbook. The utility functions work -with the object representation and are intended to handle common use cases. - -### Modifying Workbook Structure - -**API** - -_Append a Worksheet to a Workbook_ - -```js -XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name); -``` - -The `book_append_sheet` utility function appends a worksheet to the workbook. -The third argument specifies the desired worksheet name. Multiple worksheets can -be added to a workbook by calling the function multiple times. If the worksheet -name is already used in the workbook, it will throw an error. - -_Append a Worksheet to a Workbook and find a unique name_ - -```js -var new_name = XLSX.utils.book_append_sheet(workbook, worksheet, name, true); -``` - -If the fourth argument is `true`, the function will start with the specified -worksheet name. If the sheet name exists in the workbook, a new worksheet name -will be chosen by finding the name stem and incrementing the counter: - -```js -XLSX.utils.book_append_sheet(workbook, sheetA, "Sheet2", true); // Sheet2 -XLSX.utils.book_append_sheet(workbook, sheetB, "Sheet2", true); // Sheet3 -XLSX.utils.book_append_sheet(workbook, sheetC, "Sheet2", true); // Sheet4 -XLSX.utils.book_append_sheet(workbook, sheetD, "Sheet2", true); // Sheet5 -``` - -_List the Worksheet names in tab order_ - -```js -var wsnames = workbook.SheetNames; -``` - -The `SheetNames` property of the workbook object is a list of the worksheet -names in "tab order". API functions will look at this array. - -_Replace a Worksheet in place_ - -```js -workbook.Sheets[sheet_name] = new_worksheet; -``` - -The `Sheets` property of the workbook object is an object whose keys are names -and whose values are worksheet objects. By reassigning to a property of the -`Sheets` object, the worksheet object can be changed without disrupting the -rest of the worksheet structure. - -**Examples** - -
- Add a new worksheet to a workbook (click to show) - -This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input). - -```js -var ws_name = "SheetJS"; - -/* Create worksheet */ -var ws_data = [ - [ "S", "h", "e", "e", "t", "J", "S" ], - [ 1 , 2 , 3 , 4 , 5 ] -]; -var ws = XLSX.utils.aoa_to_sheet(ws_data); - -/* Add the worksheet to the workbook */ -XLSX.utils.book_append_sheet(wb, ws, ws_name); -``` - -
- -### Modifying Cell Values - -**API** - -_Modify a single cell value in a worksheet_ - -```js -XLSX.utils.sheet_add_aoa(worksheet, [[new_value]], { origin: address }); -``` - -_Modify multiple cell values in a worksheet_ - -```js -XLSX.utils.sheet_add_aoa(worksheet, aoa, opts); -``` - -The `sheet_add_aoa` utility function modifies cell values in a worksheet. The -first argument is the worksheet object. The second argument is an array of -arrays of values. The `origin` key of the third argument controls where cells -will be written. The following snippet sets `B3=1` and `E5="abc"`: - -```js -XLSX.utils.sheet_add_aoa(worksheet, [ - [1], // <-- Write 1 to cell B3 - , // <-- Do nothing in row 4 - [/*B5*/, /*C5*/, /*D5*/, "abc"] // <-- Write "abc" to cell E5 -], { origin: "B3" }); -``` - -["Array of Arrays Input"](#array-of-arrays-input) describes the function and the -optional `opts` argument in more detail. - -**Examples** - -
- Appending rows to a worksheet (click to show) - -The special origin value `-1` instructs `sheet_add_aoa` to start in column A of -the row after the last row in the range, appending the data: - -```js -XLSX.utils.sheet_add_aoa(worksheet, [ - ["first row after data", 1], - ["second row after data", 2] -], { origin: -1 }); -``` - -
- - -### Modifying Other Worksheet / Workbook / Cell Properties - -The ["Common Spreadsheet Format"](#common-spreadsheet-format) section describes -the object structures in greater detail. - -## Packaging and Releasing Data - -### Writing Workbooks - -**API** - -_Generate spreadsheet bytes (file) from data_ - -```js -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"](#writing-options) -covers the supported properties and behaviors. - -_Generate and attempt to save file_ - -```js -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 `writeFile` method uses platform-specific APIs to initiate the file save. In -NodeJS, `fs.readFileSync` can create a file. In the web browser, a download is -attempted using the HTML5 `download` attribute, with fallbacks for IE. - -_Generate and attempt to save an XLSX file_ - -```js -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"](#writing-options) -covers the supported properties and behaviors. - -**Examples** - -
- Local file in a NodeJS server (click to show) - -`writeFile` uses `fs.writeFileSync` in server environments: - -```js -var XLSX = require("xlsx"); - -/* output format determined by filename */ -XLSX.writeFile(workbook, "out.xlsb"); -``` - -For Node ESM, the `writeFile` helper is not enabled. Instead, `fs.writeFileSync` -should be used to write the file data to a `Buffer` for use with `XLSX.write`: - -```js -import { writeFileSync } from "fs"; -import { write } from "xlsx/xlsx.mjs"; - -const buf = write(workbook, {type: "buffer", bookType: "xlsb"}); -/* buf is a Buffer */ -const workbook = writeFileSync("out.xlsb", buf); -``` - -
- -
- Local file in a Deno application (click to show) - -`writeFile` uses `Deno.writeFileSync` under the hood: - -```js -// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts" -import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs' - -XLSX.writeFile(workbook, "test.xlsx"); -``` - -Applications writing files must be invoked with the `--allow-write` flag. The -[`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples - -
- -
- Local file in a PhotoShop or InDesign plugin (click to show) - -`writeFile` wraps the `File` logic in Photoshop and other ExtendScript targets. -The specified path should be an absolute path: - -```js -#include "xlsx.extendscript.js" - -/* output format determined by filename */ -XLSX.writeFile(workbook, "out.xlsx"); -/* at this point, out.xlsx is a file that you can distribute */ -``` - -The [`extendscript` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) includes a more complex example. - -
- -
- Download a file in the browser to the user machine (click to show) - -`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. - -```js -/* output format determined by filename */ -XLSX.writeFile(workbook, "out.xlsb"); -/* at this point, out.xlsb will have been downloaded */ -``` - -
- -
- Download a file in legacy browsers (click to show) - -`XLSX.writeFile` techniques work for most modern browsers as well as older IE. -For much older browsers, there are workarounds implemented by wrapper libraries. - -[`FileSaver.js`](https://github.com/eligrey/FileSaver.js/) implements `saveAs`. -Note: `XLSX.writeFile` will automatically call `saveAs` if available. - -```js -/* bookType can be any supported output type */ -var wopts = { bookType:"xlsx", bookSST:false, type:"array" }; - -var wbout = XLSX.write(workbook,wopts); - -/* the saveAs call downloads a file on the local machine */ -saveAs(new Blob([wbout],{type:"application/octet-stream"}), "test.xlsx"); -``` - -[`Downloadify`](https://github.com/dcneiner/downloadify) uses a Flash SWF button -to generate local files, suitable for environments where ActiveX is unavailable: - -```js -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](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario. - -
- -
- Browser upload file (ajax) (click to show) - -A complete example using XHR is [included in the XHR demo](https://github.com/SheetJS/SheetJS/tree/master/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); - -var req = new XMLHttpRequest(); -req.open("POST", "/upload", true); -var formdata = new FormData(); -formdata.append("file", "test.xlsx"); // <-- server expects `file` to hold name -formdata.append("data", wbout); // <-- `data` holds the base64-encoded data -req.send(formdata); -``` - -
- -
- PhantomJS (Headless Webkit) File Generation (click to show) - -The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML -files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). PhantomJS -`fs.write` supports writing files from the main process but has a different -interface from the NodeJS `fs` module: - -```js -var XLSX = require('xlsx'); -var fs = require('fs'); - -/* generate a binary string */ -var bin = XLSX.write(workbook, { type:"binary", bookType: "xlsx" }); -/* write to file */ -fs.write("test.xlsx", bin, "wb"); -``` - -Note: The section ["Processing HTML Tables"](#processing-html-tables) shows how -to generate a workbook from HTML tables in a page in "Headless WebKit". - -
- - - -The [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) cover mobile apps and other special deployments. - -### Writing Examples - -- exporting an HTML table -- generates a simple file - -### 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`. - -
- nodejs convert to CSV and write file (click to show) - -```js -var output_file_name = "out.csv"; -var stream = XLSX.stream.to_csv(worksheet); -stream.pipe(fs.createWriteStream(output_file_name)); -``` - -
- -
- nodejs write JSON stream to screen (click to show) - -```js -/* to_json returns an object-mode stream */ -var stream = XLSX.stream.to_json(worksheet, {raw:true}); - -/* the following stream converts JS objects to text via JSON.stringify */ -var conv = new Transform({writableObjectMode:true}); -conv._transform = function(obj, e, cb){ cb(null, JSON.stringify(obj) + "\n"); }; - -stream.pipe(conv); conv.pipe(process.stdout); -``` - -
- -
- Exporting NUMBERS files (click to show) - -The NUMBERS writer requires a fairly large base. The supplementary `xlsx.zahl` -scripts provide support. `xlsx.zahl.js` is designed for standalone and NodeJS -use, while `xlsx.zahl.mjs` is suitable for ESM. - -_Browser_ - -```html - - - - -``` - -_Node_ - -```js -var XLSX = require("./xlsx.flow"); -var XLSX_ZAHL = require("./dist/xlsx.zahl"); -var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([ - ["SheetJS", "<3","விரிதாள்"], - [72,,"Arbeitsblätter"], - [,62,"数据"], - [true,false,], -]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); -XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true}); -``` - -_Deno_ - -```ts -import * as XLSX from './xlsx.mjs'; -import XLSX_ZAHL from './dist/xlsx.zahl.mjs'; - -var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([ - ["SheetJS", "<3","விரிதாள்"], - [72,,"Arbeitsblätter"], - [,62,"数据"], - [true,false,], -]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); -XLSX.writeFile(wb, "textports.numbers", {numbers: XLSX_ZAHL, compression: true}); -``` - -
- - pipes write streams to nodejs response. - -### 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"](#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_ - -```js -var jsa = XLSX.utils.sheet_to_json(worksheet, opts); -``` - -_Create an array of arrays of JS values from a worksheet_ - -```js -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 -["JSON"](#json) section describes the argument in more detail. - -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** - -[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive -data grid for previewing and modifying structured data in the web browser. The -[`xspreadsheet` demo](/demos/xspreadsheet) includes a sample script with the -`stox` function for converting from a workbook to x-spreadsheet data object. - is a live demo. - -
- Previewing data in a React data grid (click to show) - -[`react-data-grid`](https://npm.im/react-data-grid) is a data grid tailored for -react. It expects two properties: `rows` of data objects and `columns` which -describe the columns. For the purposes of massaging the data to fit the react -data grid API it is easiest to start from an array of arrays. - -This demo starts by fetching a remote file and using `XLSX.read` to extract: - -```js -import { useEffect, useState } from "react"; -import DataGrid from "react-data-grid"; -import { read, utils } from "xlsx"; - -const url = "https://oss.sheetjs.com/test_files/RkNumber.xls"; - -export default function App() { - const [columns, setColumns] = useState([]); - const [rows, setRows] = useState([]); - useEffect(() => {(async () => { - const wb = read(await (await fetch(url)).arrayBuffer(), { WTF: 1 }); - - /* use sheet_to_json with header: 1 to generate an array of arrays */ - const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 }); - - /* see react-data-grid docs to understand the shape of the expected data */ - setColumns(data[0].map((r) => ({ key: r, name: r }))); - setRows(data.slice(1).map((r) => r.reduce((acc, x, i) => { - acc[data[0][i]] = x; - return acc; - }, {}))); - })(); }); - - return ; -} -``` - -
- -
- Previewing data in a VueJS data grid (click to show) - -[`vue3-table-lite`](https://github.com/linmasahiro/vue3-table-lite) is a simple -VueJS 3 data table. It is featured [in the VueJS demo](/demos/vue/modify/). - -
- -
- Populating a database (SQL or no-SQL) (click to show) - -The [`database` demo](/demos/database/) includes examples of working with -databases and query results. - -
- -
- Numerical Computations with TensorFlow.js (click to show) - -[`@tensorflow/tfjs`](@tensorflow/tfjs) and other libraries expect data in simple -arrays, well-suited for worksheets where each column is a data vector. That is -the transpose of how most people use spreadsheets, where each row is a vector. - -A single `Array#map` can pull individual named rows from `sheet_to_json` export: - -```js -const XLSX = require("xlsx"); -const tf = require('@tensorflow/tfjs'); - -const key = "age"; // this is the field we want to pull -const ages = XLSX.utils.sheet_to_json(worksheet).map(r => r[key]); -const tf_data = tf.tensor1d(ages); -``` - -All fields can be processed at once using a transpose of the 2D tensor generated -with the `sheet_to_json` export with `header: 1`. The first row, if it contains -header labels, should be removed with a slice: - -```js -const XLSX = require("xlsx"); -const tf = require('@tensorflow/tfjs'); - -/* array of arrays of the data starting on the second row */ -const aoa = XLSX.utils.sheet_to_json(worksheet, {header: 1}).slice(1); -/* dataset in the "correct orientation" */ -const tf_dataset = tf.tensor2d(aoa).transpose(); -/* pull out each dataset with a slice */ -const tf_field0 = tf_dataset.slice([0,0], [1,tensor.shape[1]]).flatten(); -const tf_field1 = tf_dataset.slice([1,0], [1,tensor.shape[1]]).flatten(); -``` - -The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) shows a complete example. - -
- - -### Generating HTML Tables - -**API** - -_Generate HTML Table from Worksheet_ - -```js -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 `` 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`: - -```js -var container = document.getElementById("tavolo"); -container.innerHTML = XLSX.utils.sheet_to_html(worksheet); -``` - -Combining with `fetch`, constructing a site from a workbook is straightforward: - -
- Vanilla JS + HTML fetch workbook and generate table previews (click to show) - -```html - - -
- - - -``` - -
- -
- React fetch workbook and generate HTML table previews (click to show) - -It is generally recommended to use a React-friendly workflow, but it is possible -to generate HTML and use it in React with `dangerouslySetInnerHTML`: - -```jsx -function Tabeller(props) { - /* the workbook object is the state */ - const [workbook, setWorkbook] = React.useState(XLSX.utils.book_new()); - - /* fetch and update the workbook with an effect */ - React.useEffect(() => { (async() => { - /* fetch and parse workbook -- see the fetch example for details */ - const wb = XLSX.read(await (await fetch("sheetjs.xlsx")).arrayBuffer()); - setWorkbook(wb); - })(); }); - - return workbook.SheetNames.map(name => (<> -

name

-
- )); -} -``` - -The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes more React examples. - -
- -
- VueJS fetch workbook and generate HTML table previews (click to show) - -It is generally recommended to use a VueJS-friendly workflow, but it is possible -to generate HTML and use it in VueJS with the `v-html` directive: - -```jsx -import { read, utils } from 'xlsx'; -import { reactive } from 'vue'; - -const S5SComponent = { - mounted() { (async() => { - /* fetch and parse workbook -- see the fetch example for details */ - const workbook = read(await (await fetch("sheetjs.xlsx")).arrayBuffer()); - /* loop through the worksheet names in order */ - workbook.SheetNames.forEach(name => { - /* generate HTML from the corresponding worksheets */ - const html = utils.sheet_to_html(workbook.Sheets[name]); - /* add to state */ - this.wb.wb.push({ name, html }); - }); - })(); }, - /* this state mantra is required for array updates to work */ - setup() { return { wb: reactive({ wb: [] }) }; }, - template: ` -
-

{{ ws.name }}

-
-
` -}; -``` - -The [`vuejs` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue) includes more React examples. - -
- -### Generating Single-Worksheet Snapshots - -The `sheet_to_*` functions accept a worksheet object. - -**API** - -_Generate a CSV from a single worksheet_ - -```js -var csv = XLSX.utils.sheet_to_csv(worksheet, opts); -``` - -This snapshot is designed to replicate the "CSV UTF8 (`.csv`)" output type. -["Delimiter-Separated Output"](#delimiter-separated-output) describes the -function and the optional `opts` argument in more detail. - -_Generate "Text" from a single worksheet_ - -```js -var txt = XLSX.utils.sheet_to_txt(worksheet, opts); -``` - -This snapshot is designed to replicate the "UTF16 Text (`.txt`)" output type. -["Delimiter-Separated Output"](#delimiter-separated-output) describes the -function and the optional `opts` argument in more detail. - -_Generate a list of formulae from a single worksheet_ - -```js -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"](#formulae-output) describes the function in more detail. - -## Interface - -`XLSX` is the exposed variable in the browser and the exported node variable - -`XLSX.version` is the version of the library (added by the build script). - -`XLSX.SSF` is an embedded version of the [format library](https://github.com/SheetJS/ssf). - -### Parsing functions - -`XLSX.read(data, read_opts)` attempts to parse `data`. - -`XLSX.readFile(filename, read_opts)` attempts to read `filename` and parse. - -Parse options are described in the [Parsing Options](#parsing-options) section. - -### Writing functions - -`XLSX.write(wb, write_opts)` attempts to write the workbook `wb` - -`XLSX.writeFile(wb, filename, write_opts)` attempts to write `wb` to `filename`. -In browser-based environments, it will attempt to force a client-side download. - -`XLSX.writeFileAsync(filename, wb, o, cb)` attempts to write `wb` to `filename`. -If `o` is omitted, the writer will use the third argument as the callback. - -`XLSX.stream` contains a set of streaming write functions. - -Write options are described in the [Writing Options](#writing-options) section. - -### Utilities - -Utilities are available in the `XLSX.utils` object and are described in the -[Utility Functions](#utility-functions) section: - -**Constructing:** - -- `book_new` creates an empty workbook -- `book_append_sheet` adds a worksheet to a workbook - -**Importing:** - -- `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. -- `json_to_sheet` converts an array of JS objects to a worksheet. -- `table_to_sheet` converts a DOM TABLE element to a worksheet. -- `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet. -- `sheet_add_json` adds an array of JS objects to an existing worksheet. - - -**Exporting:** - -- `sheet_to_json` converts a worksheet object to an array of JSON objects. -- `sheet_to_csv` generates delimiter-separated-values output. -- `sheet_to_txt` generates UTF16 formatted text. -- `sheet_to_html` generates HTML output. -- `sheet_to_formulae` generates a list of the formulae (with value fallbacks). - - -**Cell and cell address manipulation:** - -- `format_cell` generates the text value for a cell (using number formats). -- `encode_row / decode_row` converts between 0-indexed rows and 1-indexed rows. -- `encode_col / decode_col` converts between 0-indexed columns and column names. -- `encode_cell / decode_cell` converts cell addresses. -- `encode_range / decode_range` converts cell ranges. - -## Common Spreadsheet Format - -SheetJS conforms to the Common Spreadsheet Format (CSF): - -### General Structures - -Cell address objects are stored as `{c:C, r:R}` where `C` and `R` are 0-indexed -column and row numbers, respectively. For example, the cell address `B5` is -represented by the object `{c:1, r:4}`. - -Cell range objects are stored as `{s:S, e:E}` where `S` is the first cell and -`E` is the last cell in the range. The ranges are inclusive. For example, the -range `A3:B7` is represented by the object `{s:{c:0, r:2}, e:{c:1, r:6}}`. -Utility functions perform a row-major order walk traversal of a sheet range: - -```js -for(var R = range.s.r; R <= range.e.r; ++R) { - for(var C = range.s.c; C <= range.e.c; ++C) { - var cell_address = {c:C, r:R}; - /* if an A1-style address is needed, encode the address */ - var cell_ref = XLSX.utils.encode_cell(cell_address); - } -} -``` - -### Cell Object - -Cell objects are plain JS objects with keys and values following the convention: - -| Key | Description | -| --- | ---------------------------------------------------------------------- | -| `v` | raw value (see Data Types section for more info) | -| `w` | formatted text (if applicable) | -| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub | -| `f` | cell formula encoded as an A1-style string (if applicable) | -| `F` | range of enclosing array if formula is array formula (if applicable) | -| `D` | if true, array formula is dynamic (if applicable) | -| `r` | rich text encoding (if applicable) | -| `h` | HTML rendering of the rich text (if applicable) | -| `c` | comments associated with the cell | -| `z` | number format string associated with the cell (if requested) | -| `l` | cell hyperlink object (`.Target` holds link, `.Tooltip` is tooltip) | -| `s` | the style/theme of the cell (if applicable) | - -Built-in export utilities (such as the CSV exporter) will use the `w` text if it -is available. To change a value, be sure to delete `cell.w` (or set it to -`undefined`) before attempting to export. The utilities will regenerate the `w` -text from the number format (`cell.z`) and the raw value if possible. - -The actual array formula is stored in the `f` field of the first cell in the -array range. Other cells in the range will omit the `f` field. - -#### Data Types - -The raw value is stored in the `v` value property, interpreted based on the `t` -type property. This separation allows for representation of numbers as well as -numeric text. There are 6 valid cell types: - -| Type | Description | -| :--: | :-------------------------------------------------------------------- | -| `b` | Boolean: value interpreted as JS `boolean` | -| `e` | Error: value is a numeric code and `w` property stores common name ** | -| `n` | Number: value is a JS `number` ** | -| `d` | Date: value is a JS `Date` object or string to be parsed as Date ** | -| `s` | Text: value interpreted as JS `string` and written as text ** | -| `z` | Stub: blank stub cell that is ignored by data processing utilities ** | - -
- Error values and interpretation (click to show) - -| Value | Error Meaning | -| -----: | :-------------- | -| `0x00` | `#NULL!` | -| `0x07` | `#DIV/0!` | -| `0x0F` | `#VALUE!` | -| `0x17` | `#REF!` | -| `0x1D` | `#NAME?` | -| `0x24` | `#NUM!` | -| `0x2A` | `#N/A` | -| `0x2B` | `#GETTING_DATA` | - -
- -Type `n` is the Number type. This includes all forms of data that Excel stores -as numbers, such as dates/times and Boolean fields. Excel exclusively uses data -that can be fit in an IEEE754 floating point number, just like JS Number, so the -`v` field holds the raw number. The `w` field holds formatted text. Dates are -stored as numbers by default and converted with `XLSX.SSF.parse_date_code`. - -Type `d` is the Date type, generated only when the option `cellDates` is passed. -Since JSON does not have a natural Date type, parsers are generally expected to -store ISO 8601 Date strings like you would get from `date.toISOString()`. On -the other hand, writers and exporters should be able to handle date strings and -JS Date objects. Note that Excel disregards timezone modifiers and treats all -dates in the local timezone. The library does not correct for this error. - -Type `s` is the String type. Values are explicitly stored as text. Excel will -interpret these cells as "number stored as text". Generated Excel files -automatically suppress that class of error, but other formats may elicit errors. - -Type `z` represents blank stub cells. They are generated in cases where cells -have no assigned value but hold comments or other metadata. They are ignored by -the core library data processing utility functions. By default these cells are -not generated; the parser `sheetStubs` option must be set to `true`. - - -#### Dates - -
- Excel Date Code details (click to show) - -By default, Excel stores dates as numbers with a format code that specifies date -processing. For example, the date `19-Feb-17` is stored as the number `42785` -with a number format of `d-mmm-yy`. The `SSF` module understands number formats -and performs the appropriate conversion. - -XLSX also supports a special date type `d` where the data is an ISO 8601 date -string. The formatter converts the date back to a number. - -The default behavior for all parsers is to generate number cells. Setting -`cellDates` to true will force the generators to store dates. - -
- -
- Time Zones and Dates (click to show) - -Excel has no native concept of universal time. All times are specified in the -local time zone. Excel limitations prevent specifying true absolute dates. - -Following Excel, this library treats all dates as relative to local time zone. - -
- -
- Epochs: 1900 and 1904 (click to show) - -Excel supports two epochs (January 1 1900 and January 1 1904). -The workbook's epoch can be determined by examining the workbook's -`wb.Workbook.WBProps.date1904` property: - -```js -!!(((wb.Workbook||{}).WBProps||{}).date1904) -``` - -
- -### Sheet Objects - -Each key that does not start with `!` maps to a cell (using `A-1` notation) - -`sheet[address]` returns the cell object for the specified address. - -**Special sheet keys (accessible as `sheet[key]`, each starting with `!`):** - -- `sheet['!ref']`: A-1 based range representing the sheet range. Functions that - work with sheets should use this parameter to determine the range. Cells that - are assigned outside of the range are not processed. In particular, when - writing a sheet by hand, cells outside of the range are not included - - Functions that handle sheets should test for the presence of `!ref` field. - If the `!ref` is omitted or is not a valid range, functions are free to treat - the sheet as empty or attempt to guess the range. The standard utilities that - ship with this library treat sheets as empty (for example, the CSV output is - empty string). - - When reading a worksheet with the `sheetRows` property set, the ref parameter - will use the restricted range. The original range is set at `ws['!fullref']` - -- `sheet['!margins']`: Object representing the page margins. The default values - follow Excel's "normal" preset. Excel also has a "wide" and a "narrow" preset - but they are stored as raw measurements. The main properties are listed below: - -
- Page margin details (click to show) - -| key | description | "normal" | "wide" | "narrow" | -|----------|------------------------|:---------|:-------|:-------- | -| `left` | left margin (inches) | `0.7` | `1.0` | `0.25` | -| `right` | right margin (inches) | `0.7` | `1.0` | `0.25` | -| `top` | top margin (inches) | `0.75` | `1.0` | `0.75` | -| `bottom` | bottom margin (inches) | `0.75` | `1.0` | `0.75` | -| `header` | header margin (inches) | `0.3` | `0.5` | `0.3` | -| `footer` | footer margin (inches) | `0.3` | `0.5` | `0.3` | - -```js -/* Set worksheet sheet to "normal" */ -ws["!margins"]={left:0.7, right:0.7, top:0.75,bottom:0.75,header:0.3,footer:0.3} -/* Set worksheet sheet to "wide" */ -ws["!margins"]={left:1.0, right:1.0, top:1.0, bottom:1.0, header:0.5,footer:0.5} -/* Set worksheet sheet to "narrow" */ -ws["!margins"]={left:0.25,right:0.25,top:0.75,bottom:0.75,header:0.3,footer:0.3} -``` -
- -#### Worksheet Object - -In addition to the base sheet keys, worksheets also add: - -- `ws['!cols']`: array of column properties objects. Column widths are actually - stored in files in a normalized manner, measured in terms of the "Maximum - Digit Width" (the largest width of the rendered digits 0-9, in pixels). When - parsed, the column objects store the pixel width in the `wpx` field, character - width in the `wch` field, and the maximum digit width in the `MDW` field. - -- `ws['!rows']`: array of row properties objects as explained later in the docs. - Each row object encodes properties including row height and visibility. - -- `ws['!merges']`: array of range objects corresponding to the merged cells in - the worksheet. Plain text formats do not support merge cells. CSV export - will write all cells in the merge range if they exist, so be sure that only - the first cell (upper-left) in the range is set. - -- `ws['!outline']`: configure how outlines should behave. Options default to - the default settings in Excel 2019: - -| key | Excel feature | default | -|:----------|:----------------------------------------------|:--------| -| `above` | Uncheck "Summary rows below detail" | `false` | -| `left` | Uncheck "Summary rows to the right of detail" | `false` | - -- `ws['!protect']`: object of write sheet protection properties. The `password` - key specifies the password for formats that support password-protected sheets - (XLSX/XLSB/XLS). The writer uses the XOR obfuscation method. The following - keys control the sheet protection -- set to `false` to enable a feature when - sheet is locked or set to `true` to disable a feature: - -
- Worksheet Protection Details (click to show) - -| key | feature (true=disabled / false=enabled) | default | -|:----------------------|:----------------------------------------|:-----------| -| `selectLockedCells` | Select locked cells | enabled | -| `selectUnlockedCells` | Select unlocked cells | enabled | -| `formatCells` | Format cells | disabled | -| `formatColumns` | Format columns | disabled | -| `formatRows` | Format rows | disabled | -| `insertColumns` | Insert columns | disabled | -| `insertRows` | Insert rows | disabled | -| `insertHyperlinks` | Insert hyperlinks | disabled | -| `deleteColumns` | Delete columns | disabled | -| `deleteRows` | Delete rows | disabled | -| `sort` | Sort | disabled | -| `autoFilter` | Filter | disabled | -| `pivotTables` | Use PivotTable reports | disabled | -| `objects` | Edit objects | enabled | -| `scenarios` | Edit scenarios | enabled | -
- -- `ws['!autofilter']`: AutoFilter object following the schema: - -```typescript -type AutoFilter = { - ref:string; // A-1 based range representing the AutoFilter table range -} -``` - -#### Chartsheet Object - -Chartsheets are represented as standard sheets. They are distinguished with the -`!type` property set to `"chart"`. - -The underlying data and `!ref` refer to the cached data in the chartsheet. The -first row of the chartsheet is the underlying header. - -#### Macrosheet Object - -Macrosheets are represented as standard sheets. They are distinguished with the -`!type` property set to `"macro"`. - -#### Dialogsheet Object - -Dialogsheets are represented as standard sheets. They are distinguished with the -`!type` property set to `"dialog"`. - -### Workbook Object - -`workbook.SheetNames` is an ordered list of the sheets in the workbook - -`wb.Sheets[sheetname]` returns an object representing the worksheet. - -`wb.Props` is an object storing the standard properties. `wb.Custprops` stores -custom properties. Since the XLS standard properties deviate from the XLSX -standard, XLS parsing stores core properties in both places. - -`wb.Workbook` stores [workbook-level attributes](#workbook-level-attributes). - -#### Workbook File Properties - -The various file formats use different internal names for file properties. The -workbook `Props` object normalizes the names: - -
- File Properties (click to show) - -| JS Name | Excel Description | -|:--------------|:-------------------------------| -| `Title` | Summary tab "Title" | -| `Subject` | Summary tab "Subject" | -| `Author` | Summary tab "Author" | -| `Manager` | Summary tab "Manager" | -| `Company` | Summary tab "Company" | -| `Category` | Summary tab "Category" | -| `Keywords` | Summary tab "Keywords" | -| `Comments` | Summary tab "Comments" | -| `LastAuthor` | Statistics tab "Last saved by" | -| `CreatedDate` | Statistics tab "Created" | - -
- -For example, to set the workbook title property: - -```js -if(!wb.Props) wb.Props = {}; -wb.Props.Title = "Insert Title Here"; -``` - -Custom properties are added in the workbook `Custprops` object: - -```js -if(!wb.Custprops) wb.Custprops = {}; -wb.Custprops["Custom Property"] = "Custom Value"; -``` - -Writers will process the `Props` key of the options object: - -```js -/* force the Author to be "SheetJS" */ -XLSX.write(wb, {Props:{Author:"SheetJS"}}); -``` - -### Workbook-Level Attributes - -`wb.Workbook` stores workbook-level attributes. - -#### Defined Names - -
- Format Support (click to show) - -**Defined Names**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK - -**Unicode Defined Names**: XLSX/M, XLSB, BIFF8 XLS, XLML - -**Defined Name Comment**: XLSX/M, XLSB, BIFF8 XLS - -
- -`wb.Workbook.Names` is an array of defined name objects which have the keys: - -
- Defined Name Properties (click to show) - -| Key | Description | -|:----------|:-----------------------------------------------------------------| -| `Sheet` | Name scope. Sheet Index (0 = first sheet) or `null` (Workbook) | -| `Name` | Case-sensitive name. Standard rules apply ** | -| `Ref` | A1-style Reference (`"Sheet1!$A$1:$D$20"`) | -| `Comment` | Comment (only applicable for XLS/XLSX/XLSB) | - -
- -Excel allows two sheet-scoped defined names to share the same name. However, a -sheet-scoped name cannot collide with a workbook-scope name. Workbook writers -may not enforce this constraint. - -#### Workbook Views - -`wb.Workbook.Views` is an array of workbook view objects which have the keys: - -| Key | Description | -|:----------------|:----------------------------------------------------| -| `RTL` | If true, display right-to-left | - -#### Miscellaneous Workbook Properties - -`wb.Workbook.WBProps` holds other workbook properties: - -| Key | Description | -|:----------------|:----------------------------------------------------| -| `CodeName` | [VBA Project Workbook Code Name](#vba-and-macros) | -| `date1904` | epoch: 0/false for 1900 system, 1/true for 1904 | -| `filterPrivacy` | Warn or strip personally identifying info on save | - -### Document Features - -Even for basic features like date storage, the official Excel formats store the -same content in different ways. The parsers are expected to convert from the -underlying file format representation to the Common Spreadsheet Format. Writers -are expected to convert from CSF back to the underlying file format. - -#### Formulae - -The A1-style formula string is stored in the `f` field. Even though different -file formats store the formulae in different ways, the formats are translated. -Even though some formats store formulae with a leading equal sign, CSF formulae -do not start with `=`. - -
- Formulae File Format Support (click to show) - -| Storage Representation | Formats | Read | Write | -|:-----------------------|:-------------------------|:-----:|:-----:| -| A1-style strings | XLSX | ✔ | ✔ | -| RC-style strings | XLML and plain text | ✔ | ✔ | -| BIFF Parsed formulae | XLSB and all XLS formats | ✔ | | -| OpenFormula formulae | ODS/FODS/UOS | ✔ | ✔ | -| Lotus Parsed formulae | All Lotus WK_ formats | ✔ | | - -Since Excel prohibits named cells from colliding with names of A1 or RC style -cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed -formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula -formulae can be converted with regular expressions. - -Shared formulae are decompressed and each cell has the formula corresponding to -its cell. Writers generally do not attempt to generate shared formulae. -
- -**Single-Cell Formulae** - -For simple formulae, the `f` key of the desired cell can be set to the actual -formula text. This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`: - -```js -var worksheet = { - "!ref": "A1:A3", - A1: { t:'n', v:1 }, - A2: { t:'n', v:2 }, - A3: { t:'n', v:3, f:'A1+A2' } -}; -``` - -Utilities like `aoa_to_sheet` will accept cell objects in lieu of values: - -```js -var worksheet = XLSX.utils.aoa_to_sheet([ - [ 1 ], // A1 - [ 2 ], // A2 - [ {t: "n", v: 3, f: "A1+A2"} ] // A3 -]); -``` - -Cells with formula entries but no value will be serialized in a way that Excel -and other spreadsheet tools will recognize. This library will not automatically -compute formula results! For example, the following worksheet will include the -`BESSELJ` function but the result will not be available in JavaScript: - -```js -var worksheet = XLSX.utils.aoa_to_sheet([ - [ 3.14159, 2 ], // Row "1" - [ { t:'n', f:'BESSELJ(A1,B1)' } ] // Row "2" will be calculated on file open -} -``` - -If the actual results are needed in JS, [SheetJS Pro](https://sheetjs.com/pro) -offers a formula calculator component for evaluating expressions, updating -values and dependent cells, and refreshing entire workbooks. - - -**Array Formulae** - -_Assign an array formula_ - -```js -XLSX.utils.sheet_set_array_formula(worksheet, range, formula); -``` - -Array formulae are stored in the top-left cell of the array block. All cells -of an array formula have a `F` field corresponding to the range. A single-cell -formula can be distinguished from a plain formula by the presence of `F` field. - -For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`: - -```js -// API function -XLSX.utils.sheet_set_array_formula(worksheet, "C1", "SUM(A1:A3*B1:B3)"); - -// ... OR raw operations -worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" }; -``` - -For a multi-cell array formula, every cell has the same array range but only the -first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`: - -```js -// API function -XLSX.utils.sheet_set_array_formula(worksheet, "D1:D3", "A1:A3*B1:B3"); - -// ... OR raw operations -worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" }; -worksheet['D2'] = { t:'n', F:"D1:D3" }; -worksheet['D3'] = { t:'n', F:"D1:D3" }; -``` - -Utilities and writers are expected to check for the presence of a `F` field and -ignore any possible formula element `f` in cells other than the starting cell. -They are not expected to perform validation of the formulae! - - -**Dynamic Array Formulae** - -_Assign a dynamic array formula_ - -```js -XLSX.utils.sheet_set_array_formula(worksheet, range, formula, true); -``` - -Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB -file formats. They are represented like normal array formulae but have special -cell metadata indicating that the formula should be allowed to adjust the range. - -An array formula can be marked as dynamic by setting the cell's `D` property to -true. The `F` range is expected but can be the set to the current cell: - -```js -// API function -XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1); - -// ... OR raw operations -worksheet['C1'] = { t: "s", f: "_xlfn.UNIQUE(A1:A3)", F:"C1", D: 1 }; // dynamic -``` - -**Localization with Function Names** - -SheetJS operates at the file level. Excel stores formula expressions using the -English (United States) function names. For non-English users, Excel uses a -localized set of function names. - -For example, when the computer language and region is set to French (France), -Excel interprets `=SOMME(A1:C3)` as if `SOMME` is the `SUM` function. However, -in the actual file, Excel stores `SUM(A1:C3)`. - -**Prefixed "Future Functions"** - -Functions introduced in newer versions of Excel are prefixed with `_xlfn.` when -stored in files. When writing formula expressions using these functions, the -prefix is required for maximal compatibility: - -```js -// Broadest compatibility -XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1); - -// Can cause errors in spreadsheet software -XLSX.utils.sheet_set_array_formula(worksheet, "C1", "UNIQUE(A1:A3)", 1); -``` - -When reading a file, the `xlfn` option preserves the prefixes. - -
- Functions requiring `_xlfn.` prefix (click to show) - -This list is growing with each Excel release. - -``` -ACOT -ACOTH -AGGREGATE -ARABIC -BASE -BETA.DIST -BETA.INV -BINOM.DIST -BINOM.DIST.RANGE -BINOM.INV -BITAND -BITLSHIFT -BITOR -BITRSHIFT -BITXOR -BYCOL -BYROW -CEILING.MATH -CEILING.PRECISE -CHISQ.DIST -CHISQ.DIST.RT -CHISQ.INV -CHISQ.INV.RT -CHISQ.TEST -COMBINA -CONFIDENCE.NORM -CONFIDENCE.T -COT -COTH -COVARIANCE.P -COVARIANCE.S -CSC -CSCH -DAYS -DECIMAL -ERF.PRECISE -ERFC.PRECISE -EXPON.DIST -F.DIST -F.DIST.RT -F.INV -F.INV.RT -F.TEST -FIELDVALUE -FILTERXML -FLOOR.MATH -FLOOR.PRECISE -FORMULATEXT -GAMMA -GAMMA.DIST -GAMMA.INV -GAMMALN.PRECISE -GAUSS -HYPGEOM.DIST -IFNA -IMCOSH -IMCOT -IMCSC -IMCSCH -IMSEC -IMSECH -IMSINH -IMTAN -ISFORMULA -ISOMITTED -ISOWEEKNUM -LAMBDA -LET -LOGNORM.DIST -LOGNORM.INV -MAKEARRAY -MAP -MODE.MULT -MODE.SNGL -MUNIT -NEGBINOM.DIST -NORM.DIST -NORM.INV -NORM.S.DIST -NORM.S.INV -NUMBERVALUE -PDURATION -PERCENTILE.EXC -PERCENTILE.INC -PERCENTRANK.EXC -PERCENTRANK.INC -PERMUTATIONA -PHI -POISSON.DIST -QUARTILE.EXC -QUARTILE.INC -QUERYSTRING -RANDARRAY -RANK.AVG -RANK.EQ -REDUCE -RRI -SCAN -SEC -SECH -SEQUENCE -SHEET -SHEETS -SKEW.P -SORTBY -STDEV.P -STDEV.S -T.DIST -T.DIST.2T -T.DIST.RT -T.INV -T.INV.2T -T.TEST -UNICHAR -UNICODE -UNIQUE -VAR.P -VAR.S -WEBSERVICE -WEIBULL.DIST -XLOOKUP -XOR -Z.TEST -``` - -
- -#### Row and Column Properties - -
- Format Support (click to show) - -**Row Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM, ODS - -**Column Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM - -
- - -Row and Column properties are not extracted by default when reading from a file -and are not persisted by default when writing to a file. The option -`cellStyles: true` must be passed to the relevant read or write function. - -_Column Properties_ - -The `!cols` array in each worksheet, if present, is a collection of `ColInfo` -objects which have the following properties: - -```typescript -type ColInfo = { - /* visibility */ - hidden?: boolean; // if true, the column is hidden - - /* column width is specified in one of the following ways: */ - wpx?: number; // width in screen pixels - width?: number; // width in Excel's "Max Digit Width", width*256 is integral - wch?: number; // width in characters - - /* other fields for preserving features from files */ - level?: number; // 0-indexed outline / group level - MDW?: number; // Excel's "Max Digit Width" unit, always integral -}; -``` - -_Row Properties_ - -The `!rows` array in each worksheet, if present, is a collection of `RowInfo` -objects which have the following properties: - -```typescript -type RowInfo = { - /* visibility */ - hidden?: boolean; // if true, the row is hidden - - /* row height is specified in one of the following ways: */ - hpx?: number; // height in screen pixels - hpt?: number; // height in points - - level?: number; // 0-indexed outline / group level -}; -``` - -_Outline / Group Levels Convention_ - -The Excel UI displays the base outline level as `1` and the max level as `8`. -Following JS conventions, SheetJS uses 0-indexed outline levels wherein the base -outline level is `0` and the max level is `7`. - -
- Why are there three width types? (click to show) - -There are three different width types corresponding to the three different ways -spreadsheets store column widths: - -SYLK and other plain text formats use raw character count. Contemporaneous tools -like Visicalc and Multiplan were character based. Since the characters had the -same width, it sufficed to store a count. This tradition was continued into the -BIFF formats. - -SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel -count throughout the file. Column widths, row heights, and other measures use -pixels. When the pixel and character counts do not align, Excel rounds values. - -XLSX internally stores column widths in a nebulous "Max Digit Width" form. The -Max Digit Width is the width of the largest digit when rendered (generally the -"0" character is the widest). The internal width must be an integer multiple of -the the width divided by 256. ECMA-376 describes a formula for converting -between pixels and the internal width. This represents a hybrid approach. - -Read functions attempt to populate all three properties. Write functions will -try to cycle specified values to the desired type. In order to avoid potential -conflicts, manipulation should delete the other properties first. For example, -when changing the pixel width, delete the `wch` and `width` properties. -
- -
- Implementation details (click to show) - -_Row Heights_ - -Excel internally stores row heights in points. The default resolution is 72 DPI -or 96 PPI, so the pixel and point size should agree. For different resolutions -they may not agree, so the library separates the concepts. - -Even though all of the information is made available, writers are expected to -follow the priority order: - -1) use `hpx` pixel height if available -2) use `hpt` point height if available - -_Column Widths_ - -Given the constraints, it is possible to determine the MDW without actually -inspecting the font! The parsers guess the pixel width by converting from width -to pixels and back, repeating for all possible MDW and selecting the MDW that -minimizes the error. XLML actually stores the pixel width, so the guess works -in the opposite direction. - -Even though all of the information is made available, writers are expected to -follow the priority order: - -1) use `width` field if available -2) use `wpx` pixel width if available -3) use `wch` character count if available - -
- -#### Number Formats - -The `cell.w` formatted text for each cell is produced from `cell.v` and `cell.z` -format. If the format is not specified, the Excel `General` format is used. -The format can either be specified as a string or as an index into the format -table. Parsers are expected to populate `workbook.SSF` with the number format -table. Writers are expected to serialize the table. - -Custom tools should ensure that the local table has each used format string -somewhere in the table. Excel convention mandates that the custom formats start -at index 164. The following example creates a custom format from scratch: - -
- New worksheet with custom format (click to show) - -```js -var wb = { - SheetNames: ["Sheet1"], - Sheets: { - Sheet1: { - "!ref":"A1:C1", - A1: { t:"n", v:10000 }, // <-- General format - B1: { t:"n", v:10000, z: "0%" }, // <-- Builtin format - C1: { t:"n", v:10000, z: "\"T\"\ #0.00" } // <-- Custom format - } - } -} -``` -
- -The rules are slightly different from how Excel displays custom number formats. -In particular, literal characters must be wrapped in double quotes or preceded -by a backslash. For more info, see the Excel documentation article -`Create or delete a custom number format` or ECMA-376 18.8.31 (Number Formats) - - -
- Default Number Formats (click to show) - -The default formats are listed in ECMA-376 18.8.30: - -| ID | Format | -|---:|:---------------------------| -| 0 | `General` | -| 1 | `0` | -| 2 | `0.00` | -| 3 | `#,##0` | -| 4 | `#,##0.00` | -| 9 | `0%` | -| 10 | `0.00%` | -| 11 | `0.00E+00` | -| 12 | `# ?/?` | -| 13 | `# ??/??` | -| 14 | `m/d/yy` (see below) | -| 15 | `d-mmm-yy` | -| 16 | `d-mmm` | -| 17 | `mmm-yy` | -| 18 | `h:mm AM/PM` | -| 19 | `h:mm:ss AM/PM` | -| 20 | `h:mm` | -| 21 | `h:mm:ss` | -| 22 | `m/d/yy h:mm` | -| 37 | `#,##0 ;(#,##0)` | -| 38 | `#,##0 ;[Red](#,##0)` | -| 39 | `#,##0.00;(#,##0.00)` | -| 40 | `#,##0.00;[Red](#,##0.00)` | -| 45 | `mm:ss` | -| 46 | `[h]:mm:ss` | -| 47 | `mmss.0` | -| 48 | `##0.0E+0` | -| 49 | `@` | - -
- -Format 14 (`m/d/yy`) is localized by Excel: even though the file specifies that -number format, it will be drawn differently based on system settings. It makes -sense when the producer and consumer of files are in the same locale, but that -is not always the case over the Internet. To get around this ambiguity, parse -functions accept the `dateNF` option to override the interpretation of that -specific format string. - -#### Hyperlinks - -
- Format Support (click to show) - -**Cell Hyperlinks**: XLSX/M, XLSB, BIFF8 XLS, XLML, ODS - -**Tooltips**: XLSX/M, XLSB, BIFF8 XLS, XLML - -
- -Hyperlinks are stored in the `l` key of cell objects. The `Target` field of the -hyperlink object is the target of the link, including the URI fragment. Tooltips -are stored in the `Tooltip` field and are displayed when you move your mouse -over the text. - -For example, the following snippet creates a link from cell `A3` to - with the tip `"Find us @ SheetJS.com!"`: - -```js -ws['A1'].l = { Target:"https://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" }; -``` - -Note that Excel does not automatically style hyperlinks -- they will generally -be displayed as normal text. - -_Remote Links_ - -HTTP / HTTPS links can be used directly: - -```js -ws['A2'].l = { Target:"https://docs.sheetjs.com/#hyperlinks" }; -ws['A3'].l = { Target:"http://localhost:7262/yes_localhost_works" }; -``` - -Excel also supports `mailto` email links with subject line: - -```js -ws['A4'].l = { Target:"mailto:ignored@dev.null" }; -ws['A5'].l = { Target:"mailto:ignored@dev.null?subject=Test Subject" }; -``` - -_Local Links_ - -Links to absolute paths should use the `file://` URI scheme: - -```js -ws['B1'].l = { Target:"file:///SheetJS/t.xlsx" }; /* Link to /SheetJS/t.xlsx */ -ws['B2'].l = { Target:"file:///c:/SheetJS.xlsx" }; /* Link to c:\SheetJS.xlsx */ -``` - -Links to relative paths can be specified without a scheme: - -```js -ws['B3'].l = { Target:"SheetJS.xlsb" }; /* Link to SheetJS.xlsb */ -ws['B4'].l = { Target:"../SheetJS.xlsm" }; /* Link to ../SheetJS.xlsm */ -``` - -Relative Paths have undefined behavior in the SpreadsheetML 2003 format. Excel -2019 will treat a `..\` parent mark as two levels up. - -_Internal Links_ - -Links where the target is a cell or range or defined name in the same workbook -("Internal Links") are marked with a leading hash character: - -```js -ws['C1'].l = { Target:"#E2" }; /* Link to cell E2 */ -ws['C2'].l = { Target:"#Sheet2!E2" }; /* Link to cell E2 in sheet Sheet2 */ -ws['C3'].l = { Target:"#SomeDefinedName" }; /* Link to Defined Name */ -``` - -#### Cell Comments - -Cell comments are objects stored in the `c` array of cell objects. The actual -contents of the comment are split into blocks based on the comment author. The -`a` field of each comment object is the author of the comment and the `t` field -is the plain text representation. - -For example, the following snippet appends a cell comment into cell `A1`: - -```js -if(!ws.A1.c) ws.A1.c = []; -ws.A1.c.push({a:"SheetJS", t:"I'm a little comment, short and stout!"}); -``` - -Note: XLSB enforces a 54 character limit on the Author name. Names longer than -54 characters may cause issues with other formats. - -To mark a comment as normally hidden, set the `hidden` property: - -```js -if(!ws.A1.c) ws.A1.c = []; -ws.A1.c.push({a:"SheetJS", t:"This comment is visible"}); - -if(!ws.A2.c) ws.A2.c = []; -ws.A2.c.hidden = true; -ws.A2.c.push({a:"SheetJS", t:"This comment will be hidden"}); -``` - - -_Threaded Comments_ - -Introduced in Excel 365, threaded comments are plain text comment snippets with -author metadata and parent references. They are supported in XLSX and XLSB. - -To mark a comment as threaded, each comment part must have a true `T` property: - -```js -if(!ws.A1.c) ws.A1.c = []; -ws.A1.c.push({a:"SheetJS", t:"This is not threaded"}); - -if(!ws.A2.c) ws.A2.c = []; -ws.A2.c.hidden = true; -ws.A2.c.push({a:"SheetJS", t:"This is threaded", T: true}); -ws.A2.c.push({a:"JSSheet", t:"This is also threaded", T: true}); -``` - -There is no Active Directory or Office 365 metadata associated with authors in a thread. - -#### Sheet Visibility - -Excel enables hiding sheets in the lower tab bar. The sheet data is stored in -the file but the UI does not readily make it available. Standard hidden sheets -are revealed in the "Unhide" menu. Excel also has "very hidden" sheets which -cannot be revealed in the menu. It is only accessible in the VB Editor! - -The visibility setting is stored in the `Hidden` property of sheet props array. - -
- More details (click to show) - -| Value | Definition | -|:-----:|:------------| -| 0 | Visible | -| 1 | Hidden | -| 2 | Very Hidden | - -With : - -```js -> wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] }) -[ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ] -``` - -Non-Excel formats do not support the Very Hidden state. The best way to test -if a sheet is visible is to check if the `Hidden` property is logical truth: - -```js -> wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] }) -[ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ] -``` -
- -#### VBA and Macros - -VBA Macros are stored in a special data blob that is exposed in the `vbaraw` -property of the workbook object when the `bookVBA` option is `true`. They are -supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats. The supported format -writers automatically insert the data blobs if it is present in the workbook and -associate with the worksheet names. - -
- Custom Code Names (click to show) - -The workbook code name is stored in `wb.Workbook.WBProps.CodeName`. By default, -Excel will write `ThisWorkbook` or a translated phrase like `DieseArbeitsmappe`. -Worksheet and Chartsheet code names are in the worksheet properties object at -`wb.Workbook.Sheets[i].CodeName`. Macrosheets and Dialogsheets are ignored. - -The readers and writers preserve the code names, but they have to be manually -set when adding a VBA blob to a different workbook. - -
- -
- Macrosheets (click to show) - -Older versions of Excel also supported a non-VBA "macrosheet" sheet type that -stored automation commands. These are exposed in objects with the `!type` -property set to `"macro"`. - -
- -
- Detecting macros in workbooks (click to show) - -The `vbaraw` field will only be set if macros are present, so testing is simple: - -```js -function wb_has_macro(wb/*:workbook*/)/*:boolean*/ { - if(!!wb.vbaraw) return true; - const sheets = wb.SheetNames.map((n) => wb.Sheets[n]); - return sheets.some((ws) => !!ws && ws['!type']=='macro'); -} -``` - -
- -## Parsing Options - -The exported `read` and `readFile` functions accept an options argument: - -| Option Name | Default | Description | -| :---------- | ------: | :--------------------------------------------------- | -|`type` | | Input data encoding (see Input Type below) | -|`raw` | false | If true, plain text parsing will not parse values ** | -|`codepage` | | If specified, use code page when appropriate ** | -|`cellFormula`| true | Save formulae to the .f field | -|`cellHTML` | true | Parse rich text and save HTML to the `.h` field | -|`cellNF` | false | Save number format string to the `.z` field | -|`cellStyles` | false | Save style/theme info to the `.s` field | -|`cellText` | true | Generated formatted text to the `.w` field | -|`cellDates` | false | Store dates as type `d` (default is `n`) | -|`dateNF` | | If specified, use the string for date code 14 ** | -|`sheetStubs` | false | Create cell objects of type `z` for stub cells | -|`sheetRows` | 0 | If >0, read the first `sheetRows` rows ** | -|`bookDeps` | false | If true, parse calculation chains | -|`bookFiles` | false | If true, add raw files to book object ** | -|`bookProps` | false | If true, only parse enough to get book metadata ** | -|`bookSheets` | false | If true, only parse enough to get the sheet names | -|`bookVBA` | false | If true, copy VBA blob to `vbaraw` field ** | -|`password` | "" | If defined and file is encrypted, use password ** | -|`WTF` | false | If true, throw errors on unexpected file features ** | -|`sheets` | | If specified, only parse specified sheets ** | -|`PRN` | false | If true, allow parsing of PRN files ** | -|`xlfn` | false | If true, preserve `_xlfn.` prefixes in formulae ** | -|`FS` | | DSV Field Separator override | - -- Even if `cellNF` is false, formatted text will be generated and saved to `.w` -- In some cases, sheets may be parsed even if `bookSheets` is false. -- Excel aggressively tries to interpret values from CSV and other plain text. - This leads to surprising behavior! The `raw` option suppresses value parsing. -- `bookSheets` and `bookProps` combine to give both sets of information -- `Deps` will be an empty object if `bookDeps` is false -- `bookFiles` behavior depends on file type: - * `keys` array (paths in the ZIP) for ZIP-based formats - * `files` hash (mapping paths to objects representing the files) for ZIP - * `cfb` object for formats using CFB containers -- `sheetRows-1` rows will be generated when looking at the JSON object output - (since the header row is counted as a row when parsing the data) -- By default all worksheets are parsed. `sheets` restricts based on input type: - * number: zero-based index of worksheet to parse (`0` is first worksheet) - * string: name of worksheet to parse (case insensitive) - * array of numbers and strings to select multiple worksheets. -- `bookVBA` merely exposes the raw VBA CFB object. It does not parse the data. - XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`. BIFF8 XLS mixes - the VBA entries alongside the core Workbook entry, so the library generates a - new XLSB-compatible blob from the XLS CFB container. -- `codepage` is applied to BIFF2 - BIFF5 files without `CodePage` records and to - CSV files without BOM in `type:"binary"`. BIFF8 XLS always defaults to 1200. -- `PRN` affects parsing of text files without a common delimiter character. -- Currently only XOR encryption is supported. Unsupported error will be thrown - for files employing other encryption methods. -- Newer Excel functions are serialized with the `_xlfn.` prefix, hidden from the - user. SheetJS will strip `_xlfn.` normally. The `xlfn` option preserves them. -- WTF is mainly for development. By default, the parser will suppress read - errors on single worksheets, allowing you to read from the worksheets that do - parse properly. Setting `WTF:true` forces those errors to be thrown. - -### Input Type - -Strings can be interpreted in multiple ways. The `type` parameter for `read` -tells the library how to parse the data argument: - -| `type` | expected input | -|------------|-----------------------------------------------------------------| -| `"base64"` | string: Base64 encoding of the file | -| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | -| `"string"` | string: JS string (characters interpreted as UTF8) | -| `"buffer"` | nodejs Buffer | -| `"array"` | array: array of 8-bit unsigned int (byte `n` is `data[n]`) | -| `"file"` | string: path of file that will be read (nodejs only) | - -### Guessing File Type - -
- Implementation Details (click to show) - -Excel and other spreadsheet tools read the first few bytes and apply other -heuristics to determine a file type. This enables file type punning: renaming -files with the `.xls` extension will tell your computer to use Excel to open the -file but Excel will know how to handle it. This library applies similar logic: - -| Byte 0 | Raw File Type | Spreadsheet Types | -|:-------|:--------------|:----------------------------------------------------| -| `0xD0` | CFB Container | BIFF 5/8 or protected XLSX/XLSB or WQ3/QPW or XLR | -| `0x09` | BIFF Stream | BIFF 2/3/4/5 | -| `0x3C` | XML/HTML | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | -| `0x50` | ZIP Archive | XLSB or XLSX/M or ODS or UOS2 or NUMBERS or text | -| `0x49` | Plain Text | SYLK or plain text | -| `0x54` | Plain Text | DIF or plain text | -| `0xEF` | UTF8 Encoded | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | -| `0xFF` | UTF16 Encoded | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | -| `0x00` | Record Stream | Lotus WK\* or Quattro Pro or plain text | -| `0x7B` | Plain text | RTF or plain text | -| `0x0A` | Plain text | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | -| `0x0D` | Plain text | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | -| `0x20` | Plain text | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | - -DBF files are detected based on the first byte as well as the third and fourth -bytes (corresponding to month and day of the file date) - -Works for Windows files are detected based on the BOF record with type `0xFF` - -Plain text format guessing follows the priority order: - -| Format | Test | -|:-------|:--------------------------------------------------------------------| -| XML | ` - -
- Why are random text files valid? (click to show) - -Excel is extremely aggressive in reading files. Adding an XLS extension to any -display text file (where the only characters are ANSI display chars) tricks -Excel into thinking that the file is potentially a CSV or TSV file, even if it -is only one column! This library attempts to replicate that behavior. - -The best approach is to validate the desired worksheet and ensure it has the -expected number of rows or columns. Extracting the range is extremely simple: - -```js -var range = XLSX.utils.decode_range(worksheet['!ref']); -var ncols = range.e.c - range.s.c + 1, nrows = range.e.r - range.s.r + 1; -``` - -
- -## Writing Options - -The exported `write` and `writeFile` functions accept an options argument: - -| Option Name | Default | Description | -| :---------- | -------: | :-------------------------------------------------- | -|`type` | | Output data encoding (see Output Type below) | -|`cellDates` | `false` | Store dates as type `d` (default is `n`) | -|`bookSST` | `false` | Generate Shared String Table ** | -|`bookType` | `"xlsx"` | Type of Workbook (see below for supported formats) | -|`sheet` | `""` | Name of Worksheet for single-sheet formats ** | -|`compression`| `false` | Use ZIP compression for ZIP-based formats ** | -|`Props` | | Override workbook properties when writing ** | -|`themeXLSX` | | Override theme XML when writing XLSX/XLSB/XLSM ** | -|`ignoreEC` | `true` | Suppress "number as text" errors ** | -|`numbers` | | Payload for NUMBERS export ** | - -- `bookSST` is slower and more memory intensive, but has better compatibility - with older versions of iOS Numbers -- The raw data is the only thing guaranteed to be saved. Features not described - in this README may not be serialized. -- `cellDates` only applies to XLSX output and is not guaranteed to work with - third-party readers. Excel itself does not usually write cells with type `d` - so non-Excel tools may ignore the data or error in the presence of dates. -- `Props` is an object mirroring the workbook `Props` field. See the table from - the [Workbook File Properties](#workbook-file-properties) section. -- if specified, the string from `themeXLSX` will be saved as the primary theme - for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP) -- Due to a bug in the program, some features like "Text to Columns" will crash - Excel on worksheets where error conditions are ignored. The writer will mark - files to ignore the error by default. Set `ignoreEC` to `false` to suppress. -- Due to the size of the data, the NUMBERS data is not included by default. The - included `xlsx.zahl.js` and `xlsx.zahl.mjs` scripts include the data. - -### Supported Output Formats - -For broad compatibility with third-party tools, this library supports many -output formats. The specific file type is controlled with `bookType` option: - -| `bookType` | file ext | container | sheets | Description | -| :--------- | -------: | :-------: | :----- |:------------------------------- | -| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format | -| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format | -| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format | -| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format | -| `biff5` | `.xls` | CFB | multi | Excel 5.0/95 Workbook Format | -| `biff4` | `.xls` | none | single | Excel 4.0 Worksheet Format | -| `biff3` | `.xls` | none | single | Excel 3.0 Worksheet Format | -| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format | -| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) | -| `numbers` |`.numbers`| ZIP | single | Numbers 3.0+ Spreadsheet | -| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet | -| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet | -| `wk3` | `.wk3` | none | multi | Lotus Workbook (WK3) | -| `csv` | `.csv` | none | single | Comma Separated Values | -| `txt` | `.txt` | none | single | UTF-16 Unicode Text (TXT) | -| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) | -| `html` | `.html` | none | single | HTML Document | -| `dif` | `.dif` | none | single | Data Interchange Format (DIF) | -| `dbf` | `.dbf` | none | single | dBASE II + VFP Extensions (DBF) | -| `wk1` | `.wk1` | none | single | Lotus Worksheet (WK1) | -| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) | -| `prn` | `.prn` | none | single | Lotus Formatted Text | -| `eth` | `.eth` | none | single | Ethercalc Record Format (ETH) | - -- `compression` only applies to formats with ZIP containers. -- Formats that only support a single sheet require a `sheet` option specifying - the worksheet. If the string is empty, the first worksheet is used. -- `writeFile` will automatically guess the output file format based on the file - extension if `bookType` is not specified. It will choose the first format in - the aforementioned table that matches the extension. - -### Output Type - -The `type` argument for `write` mirrors the `type` argument for `read`: - -| `type` | output | -|------------|-----------------------------------------------------------------| -| `"base64"` | string: Base64 encoding of the file | -| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | -| `"string"` | string: JS string (characters interpreted as UTF8) | -| `"buffer"` | nodejs Buffer | -| `"array"` | ArrayBuffer, fallback array of 8-bit unsigned int | -| `"file"` | string: path of file that will be created (nodejs only) | - -- For compatibility with Excel, `csv` output will always include the UTF-8 byte - order mark. - -## Utility Functions - -The `sheet_to_*` functions accept a worksheet and an optional options object. - -The `*_to_sheet` functions accept a data object and an optional options object. - -The examples are based on the following worksheet: - -``` -XXX| A | B | C | D | E | F | G | ----+---+---+---+---+---+---+---+ - 1 | S | h | e | e | t | J | S | - 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | - 3 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -``` - -### Array of Arrays Input - -`XLSX.utils.aoa_to_sheet` takes an array of arrays of JS values and returns a -worksheet resembling the input data. Numbers, Booleans and Strings are stored -as the corresponding styles. Dates are stored as date or numbers. Array holes -and explicit `undefined` values are skipped. `null` values may be stubbed. All -other values are stored as strings. The function takes an options argument: - -| Option Name | Default | Description | -| :---------- | :-----: | :--------------------------------------------------- | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`cellDates` | false | Store dates as type `d` (default is `n`) | -|`sheetStubs` | false | Create cell objects of type `z` for `null` values | -|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | - -
- Examples (click to show) - -To generate the example sheet: - -```js -var ws = XLSX.utils.aoa_to_sheet([ - "SheetJS".split(""), - [1,2,3,4,5,6,7], - [2,3,4,5,6,7,8] -]); -``` -
- -`XLSX.utils.sheet_add_aoa` takes an array of arrays of JS values and updates an -existing worksheet object. It follows the same process as `aoa_to_sheet` and -accepts an options argument: - -| Option Name | Default | Description | -| :---------- | :-----: | :--------------------------------------------------- | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`cellDates` | false | Store dates as type `d` (default is `n`) | -|`sheetStubs` | false | Create cell objects of type `z` for `null` values | -|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | -|`origin` | | Use specified cell as starting point (see below) | - -`origin` is expected to be one of: - -| `origin` | Description | -| :--------------- | :-------------------------------------------------------- | -| (cell object) | Use specified cell (cell object) | -| (string) | Use specified cell (A1-style cell) | -| (number >= 0) | Start from the first column at specified row (0-indexed) | -| -1 | Append to bottom of worksheet starting on first column | -| (default) | Start from cell A1 | - - -
- Examples (click to show) - -Consider the worksheet: - -``` -XXX| A | B | C | D | E | F | G | ----+---+---+---+---+---+---+---+ - 1 | S | h | e | e | t | J | S | - 2 | 1 | 2 | | | 5 | 6 | 7 | - 3 | 2 | 3 | | | 6 | 7 | 8 | - 4 | 3 | 4 | | | 7 | 8 | 9 | - 5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | -``` - -This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: - -```js -/* Initial row */ -var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]); - -/* Write data starting at A2 */ -XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"}); - -/* Write data starting at E2 */ -XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}}); - -/* Append row */ -XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1}); -``` - -
- -### Array of Objects Input - -`XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet -with automatically-generated "headers" based on the keys of the objects. The -default column order is determined by the first appearance of the field using -`Object.keys`. The function accepts an options argument: - -| Option Name | Default | Description | -| :---------- | :-----: | :--------------------------------------------------- | -|`header` | | Use specified field order (default `Object.keys`) ** | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`cellDates` | false | Store dates as type `d` (default is `n`) | -|`skipHeader` | false | If true, do not include header row in output | -|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | - -- All fields from each row will be written. If `header` is an array and it does - not contain a particular field, the key will be appended to the array. -- Cell types are deduced from the type of each value. For example, a `Date` - object will generate a Date cell, while a string will generate a Text cell. -- Null values will be skipped by default. If `nullError` is true, an error cell - corresponding to `#NULL!` will be written to the worksheet. - -
- Examples (click to show) - -The original sheet cannot be reproduced using plain objects since JS object keys -must be unique. After replacing the second `e` and `S` with `e_1` and `S_1`: - -```js -var ws = XLSX.utils.json_to_sheet([ - { S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 }, - { S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 } -], {header:["S","h","e","e_1","t","J","S_1"]}); -``` - -Alternatively, the header row can be skipped: - -```js -var ws = XLSX.utils.json_to_sheet([ - { A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" }, - { A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7 }, - { A: 2, B: 3, C: 4, D: 5, E: 6, F: 7, G: 8 } -], {header:["A","B","C","D","E","F","G"], skipHeader:true}); -``` - -
- -`XLSX.utils.sheet_add_json` takes an array of objects and updates an existing -worksheet object. It follows the same process as `json_to_sheet` and accepts -an options argument: - -| Option Name | Default | Description | -| :---------- | :-----: | :--------------------------------------------------- | -|`header` | | Use specified column order (default `Object.keys`) | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`cellDates` | false | Store dates as type `d` (default is `n`) | -|`skipHeader` | false | If true, do not include header row in output | -|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | -|`origin` | | Use specified cell as starting point (see below) | - -`origin` is expected to be one of: - -| `origin` | Description | -| :--------------- | :-------------------------------------------------------- | -| (cell object) | Use specified cell (cell object) | -| (string) | Use specified cell (A1-style cell) | -| (number >= 0) | Start from the first column at specified row (0-indexed) | -| -1 | Append to bottom of worksheet starting on first column | -| (default) | Start from cell A1 | - - -
- Examples (click to show) - -Consider the worksheet: - -``` -XXX| A | B | C | D | E | F | G | ----+---+---+---+---+---+---+---+ - 1 | S | h | e | e | t | J | S | - 2 | 1 | 2 | | | 5 | 6 | 7 | - 3 | 2 | 3 | | | 6 | 7 | 8 | - 4 | 3 | 4 | | | 7 | 8 | 9 | - 5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | -``` - -This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: - -```js -/* Initial row */ -var ws = XLSX.utils.json_to_sheet([ - { A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" } -], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true}); - -/* Write data starting at A2 */ -XLSX.utils.sheet_add_json(ws, [ - { A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 } -], {skipHeader: true, origin: "A2"}); - -/* Write data starting at E2 */ -XLSX.utils.sheet_add_json(ws, [ - { A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 } -], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]}); - -/* Append row */ -XLSX.utils.sheet_add_json(ws, [ - { A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 } -], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1}); -``` - -
- -### HTML Table Input - -`XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet -resembling the input table. Numbers are parsed. All other data will be stored -as strings. - -`XLSX.utils.table_to_book` produces a minimal workbook based on the worksheet. - -Both functions accept options arguments: - -| Option Name | Default | Description | -| :---------- | :------: | :-------------------------------------------------- | -|`raw` | | If true, every cell will hold raw strings | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`cellDates` | false | Store dates as type `d` (default is `n`) | -|`sheetRows` | 0 | If >0, read the first `sheetRows` rows of the table | -|`display` | false | If true, hidden rows and cells will not be parsed | - - -
- Examples (click to show) - -To generate the example sheet, start with the HTML table: - -```html - - - - -
SheetJS
1234567
2345678
-``` - -To process the table: - -```js -var tbl = document.getElementById('sheetjs'); -var wb = XLSX.utils.table_to_book(tbl); -``` -
- -Note: `XLSX.read` can handle HTML represented as strings. - - -`XLSX.utils.sheet_add_dom` takes a table DOM element and updates an existing -worksheet object. It follows the same process as `table_to_sheet` and accepts -an options argument: - -| Option Name | Default | Description | -| :---------- | :------: | :-------------------------------------------------- | -|`raw` | | If true, every cell will hold raw strings | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`cellDates` | false | Store dates as type `d` (default is `n`) | -|`sheetRows` | 0 | If >0, read the first `sheetRows` rows of the table | -|`display` | false | If true, hidden rows and cells will not be parsed | - -`origin` is expected to be one of: - -| `origin` | Description | -| :--------------- | :-------------------------------------------------------- | -| (cell object) | Use specified cell (cell object) | -| (string) | Use specified cell (A1-style cell) | -| (number >= 0) | Start from the first column at specified row (0-indexed) | -| -1 | Append to bottom of worksheet starting on first column | -| (default) | Start from cell A1 | - - -
- Examples (click to show) - -A small helper function can create gap rows between tables: - -```js -function create_gap_rows(ws, nrows) { - var ref = XLSX.utils.decode_range(ws["!ref"]); // get original range - ref.e.r += nrows; // add to ending row - ws["!ref"] = XLSX.utils.encode_range(ref); // reassign row -} - -/* first table */ -var ws = XLSX.utils.table_to_sheet(document.getElementById('table1')); -create_gap_rows(ws, 1); // one row gap after first table - -/* second table */ -XLSX.utils.sheet_add_dom(ws, document.getElementById('table2'), {origin: -1}); -create_gap_rows(ws, 3); // three rows gap after second table - -/* third table */ -XLSX.utils.sheet_add_dom(ws, document.getElementById('table3'), {origin: -1}); -``` - -
- -### Formulae Output - -`XLSX.utils.sheet_to_formulae` generates an array of commands that represent -how a person would enter data into an application. Each entry is of the form -`A1-cell-address=formula-or-value`. String literals are prefixed with a `'` in -accordance with Excel. - -
- Examples (click to show) - -For the example sheet: - -```js -> var o = XLSX.utils.sheet_to_formulae(ws); -> [o[0], o[5], o[10], o[15], o[20]]; -[ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ] -``` -
- -### Delimiter-Separated Output - -As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also -produces CSV output. The function takes an options argument: - -| Option Name | Default | Description | -| :----------- | :------: | :------------------------------------------------- | -|`FS` | `","` | "Field Separator" delimiter between fields | -|`RS` | `"\n"` | "Record Separator" delimiter between rows | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`strip` | false | Remove trailing field separators in each record ** | -|`blankrows` | true | Include blank lines in the CSV output | -|`skipHidden` | false | Skips hidden rows/columns in the CSV output | -|`forceQuotes` | false | Force quotes around fields | - -- `strip` will remove trailing commas from each line under default `FS/RS` -- `blankrows` must be set to `false` to skip blank lines. -- Fields containing the record or field separator will automatically be wrapped - in double quotes; `forceQuotes` forces all cells to be wrapped in quotes. -- `XLSX.write` with `csv` type will always prepend the UTF-8 byte-order mark for - Excel compatibility. `sheet_to_csv` returns a JS string and omits the mark. - Using `XLSX.write` with type `string` will also skip the mark. - - -
- Examples (click to show) - -For the example sheet: - -```js -> console.log(XLSX.utils.sheet_to_csv(ws)); -S,h,e,e,t,J,S -1,2,3,4,5,6,7 -2,3,4,5,6,7,8 -> console.log(XLSX.utils.sheet_to_csv(ws, {FS:"\t"})); -S h e e t J S -1 2 3 4 5 6 7 -2 3 4 5 6 7 8 -> console.log(XLSX.utils.sheet_to_csv(ws,{FS:":",RS:"|"})); -S:h:e:e:t:J:S|1:2:3:4:5:6:7|2:3:4:5:6:7:8| -``` -
- -#### UTF-16 Unicode Text - -The `txt` output type uses the tab character as the field separator. If the -`codepage` library is available (included in full distribution but not core), -the output will be encoded in `CP1200` and the BOM will be prepended. - -`XLSX.utils.sheet_to_txt` takes the same arguments as `sheet_to_csv`. - -### HTML Output - -As an alternative to the `writeFile` HTML type, `XLSX.utils.sheet_to_html` also -produces HTML output. The function takes an options argument: - -| Option Name | Default | Description | -| :---------- | :------: | :-------------------------------------------------- | -|`id` | | Specify the `id` attribute for the `TABLE` element | -|`editable` | false | If true, set `contenteditable="true"` for every TD | -|`header` | | Override header (default `html body`) | -|`footer` | | Override footer (default `/body /html`) | - -
- Examples (click to show) - -For the example sheet: - -```js -> console.log(XLSX.utils.sheet_to_html(ws)); -// ... -``` -
- -### JSON - -`XLSX.utils.sheet_to_json` generates different types of JS objects. The function -takes an options argument: - -| Option Name | Default | Description | -| :---------- | :------: | :-------------------------------------------------- | -|`raw` | `true` | Use raw values (true) or formatted strings (false) | -|`range` | from WS | Override Range (see table below) | -|`header` | | Control output format (see table below) | -|`dateNF` | FMT 14 | Use specified date format in string output | -|`defval` | | Use specified value in place of null or undefined | -|`blankrows` | ** | Include blank lines in the output ** | - -- `raw` only affects cells which have a format code (`.z`) field or a formatted - text (`.w`) field. -- If `header` is specified, the first row is considered a data row; if `header` - is not specified, the first row is the header row and not considered data. -- When `header` is not specified, the conversion will automatically disambiguate - header entries by affixing `_` and a count starting at `1`. For example, if - three columns have header `foo` the output fields are `foo`, `foo_1`, `foo_2` -- `null` values are returned when `raw` is true but are skipped when false. -- If `defval` is not specified, null and undefined values are skipped normally. - If specified, all null and undefined points will be filled with `defval` -- When `header` is `1`, the default is to generate blank rows. `blankrows` must - be set to `false` to skip blank rows. -- When `header` is not `1`, the default is to skip blank rows. `blankrows` must - be true to generate blank rows - -`range` is expected to be one of: - -| `range` | Description | -| :--------------- | :-------------------------------------------------------- | -| (number) | Use worksheet range but set starting row to the value | -| (string) | Use specified range (A1-style bounded range string) | -| (default) | Use worksheet range (`ws['!ref']`) | - -`header` is expected to be one of: - -| `header` | Description | -| :--------------- | :-------------------------------------------------------- | -| `1` | Generate an array of arrays ("2D Array") | -| `"A"` | Row object keys are literal column labels | -| array of strings | Use specified strings as keys in row objects | -| (default) | Read and disambiguate first row as keys | - -- If header is not `1`, the row object will contain the non-enumerable property - `__rowNum__` that represents the row of the sheet corresponding to the entry. -- If header is an array, the keys will not be disambiguated. This can lead to - unexpected results if the array values are not unique! - - -
- Examples (click to show) - -For the example sheet: - -```js -> XLSX.utils.sheet_to_json(ws); -[ { S: 1, h: 2, e: 3, e_1: 4, t: 5, J: 6, S_1: 7 }, - { S: 2, h: 3, e: 4, e_1: 5, t: 6, J: 7, S_1: 8 } ] - -> XLSX.utils.sheet_to_json(ws, {header:"A"}); -[ { A: 'S', B: 'h', C: 'e', D: 'e', E: 't', F: 'J', G: 'S' }, - { A: '1', B: '2', C: '3', D: '4', E: '5', F: '6', G: '7' }, - { A: '2', B: '3', C: '4', D: '5', E: '6', F: '7', G: '8' } ] - -> XLSX.utils.sheet_to_json(ws, {header:["A","E","I","O","U","6","9"]}); -[ { '6': 'J', '9': 'S', A: 'S', E: 'h', I: 'e', O: 'e', U: 't' }, - { '6': '6', '9': '7', A: '1', E: '2', I: '3', O: '4', U: '5' }, - { '6': '7', '9': '8', A: '2', E: '3', I: '4', O: '5', U: '6' } ] - -> XLSX.utils.sheet_to_json(ws, {header:1}); -[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], - [ '1', '2', '3', '4', '5', '6', '7' ], - [ '2', '3', '4', '5', '6', '7', '8' ] ] -``` - -Example showing the effect of `raw`: - -```js -> ws['A2'].w = "3"; // set A2 formatted string value - -> XLSX.utils.sheet_to_json(ws, {header:1, raw:false}); -[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], - [ '3', '2', '3', '4', '5', '6', '7' ], // <-- A2 uses the formatted string - [ '2', '3', '4', '5', '6', '7', '8' ] ] - -> XLSX.utils.sheet_to_json(ws, {header:1}); -[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], - [ 1, 2, 3, 4, 5, 6, 7 ], // <-- A2 uses the raw value - [ 2, 3, 4, 5, 6, 7, 8 ] ] -``` -
- -## File Formats - -Despite the library name `xlsx`, it supports numerous spreadsheet file formats: - -| Format | Read | Write | -|:-------------------------------------------------------------|:-----:|:-----:| -| **Excel Worksheet/Workbook Formats** |:-----:|:-----:| -| Excel 2007+ XML Formats (XLSX/XLSM) | ✔ | ✔ | -| Excel 2007+ Binary Format (XLSB BIFF12) | ✔ | ✔ | -| Excel 2003-2004 XML Format (XML "SpreadsheetML") | ✔ | ✔ | -| Excel 97-2004 (XLS BIFF8) | ✔ | ✔ | -| Excel 5.0/95 (XLS BIFF5) | ✔ | ✔ | -| Excel 4.0 (XLS/XLW BIFF4) | ✔ | ✔ | -| Excel 3.0 (XLS BIFF3) | ✔ | ✔ | -| Excel 2.0/2.1 / Multiplan 4.x DOS (XLS BIFF2) | ✔ | ✔ | -| **Excel Supported Text Formats** |:-----:|:-----:| -| Delimiter-Separated Values (CSV/TXT) | ✔ | ✔ | -| Data Interchange Format (DIF) | ✔ | ✔ | -| Symbolic Link (SYLK/SLK) | ✔ | ✔ | -| Lotus Formatted Text (PRN) | ✔ | ✔ | -| UTF-16 Unicode Text (TXT) | ✔ | ✔ | -| **Other Workbook/Worksheet Formats** |:-----:|:-----:| -| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | ✔ | -| OpenDocument Spreadsheet (ODS) | ✔ | ✔ | -| Flat XML ODF Spreadsheet (FODS) | ✔ | ✔ | -| Uniform Office Format Spreadsheet (标文通 UOS1/UOS2) | ✔ | | -| dBASE II/III/IV / Visual FoxPro (DBF) | ✔ | ✔ | -| Lotus 1-2-3 (WK1/WK3) | ✔ | ✔ | -| Lotus 1-2-3 (WKS/WK2/WK4/123) | ✔ | | -| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | ✔ | | -| Works 1.x-3.x DOS / 2.x-5.x Windows Spreadsheet (WKS) | ✔ | | -| Works 6.x-9.x Spreadsheet (XLR) | ✔ | | -| **Other Common Spreadsheet Output Formats** |:-----:|:-----:| -| HTML Tables | ✔ | ✔ | -| Rich Text Format tables (RTF) | | ✔ | -| Ethercalc Record Format (ETH) | ✔ | ✔ | - -Features not supported by a given file format will not be written. Formats with -range limits will be silently truncated: - -| Format | Last Cell | Max Cols | Max Rows | -|:------------------------------------------|:-----------|---------:|---------:| -| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 | -| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 | -| Numbers 12.0 (NUMBERS) | ALL1000000 | 1000 | 1000000 | -| Quattro Pro 9+ (QPW) | IV1000000 | 256 | 1000000 | -| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 | -| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 | -| Excel 4.0 (XLS BIFF4) | IV16384 | 256 | 16384 | -| Excel 3.0 (XLS BIFF3) | IV16384 | 256 | 16384 | -| Excel 2.0/2.1 (XLS BIFF2) | IV16384 | 256 | 16384 | -| Lotus 1-2-3 R2 - R5 (WK1/WK3/WK4) | IV8192 | 256 | 8192 | -| Lotus 1-2-3 R1 (WKS) | IV2048 | 256 | 2048 | - -Excel 2003 SpreadsheetML range limits are governed by the version of Excel and -are not enforced by the writer. - -
- File Format Details (click to show) - -**Core Spreadsheet Formats** - -- **Excel 2007+ XML (XLSX/XLSM)** - -XLSX and XLSM files are ZIP containers containing a series of XML files in -accordance with the Open Packaging Conventions (OPC). The XLSM format, almost -identical to XLSX, is used for files containing macros. - -The format is standardized in ECMA-376 and later in ISO/IEC 29500. Excel does -not follow the specification, and there are additional documents discussing how -Excel deviates from the specification. - -- **Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)** - -BIFF 2/3 XLS are single-sheet streams of binary records. Excel 4 introduced -the concept of a workbook (`XLW` files) but also had single-sheet `XLS` format. -The structure is largely similar to the Lotus 1-2-3 file formats. BIFF5/8/12 -extended the format in various ways but largely stuck to the same record format. - -Multiplan 4 "Normal" files are identical in structure to BIFF2 and use the same -cell value records. There are some different record types for more advanced -features like Print Settings. The BIFF2 writer generates files that can be read -in Multiplan 4 and the parser can extract values from "Normal" files. - -There is no official specification for any of these formats. Excel 95 can write -files in these formats, so record lengths and fields were determined by writing -in all of the supported formats and comparing files. Excel 2016 can generate -BIFF5 files, enabling a full suite of file tests starting from XLSX or BIFF2. - -- **Excel 97-2004 Binary (BIFF8)** - -BIFF8 exclusively uses the Compound File Binary container format, splitting some -content into streams within the file. At its core, it still uses an extended -version of the binary record format from older versions of BIFF. - -The `MS-XLS` specification covers the basics of the file format, and other -specifications expand on serialization of features like properties. - -- **Excel 2003-2004 (SpreadsheetML)** - -Predating XLSX, SpreadsheetML files are simple XML files. There is no official -and comprehensive specification, although MS has released documentation on the -format. Since Excel 2016 can generate SpreadsheetML files, mapping features is -pretty straightforward. - -- **Excel 2007+ Binary (XLSB, BIFF12)** - -Introduced in parallel with XLSX, the XLSB format combines the BIFF architecture -with the content separation and ZIP container of XLSX. For the most part nodes -in an XLSX sub-file can be mapped to XLSB records in a corresponding sub-file. - -The `MS-XLSB` specification covers the basics of the file format, and other -specifications expand on serialization of features like properties. - -- **Delimiter-Separated Values (CSV/TXT)** - -Excel CSV deviates from RFC4180 in a number of important ways. The generated -CSV files should generally work in Excel although they may not work in RFC4180 -compatible readers. The parser should generally understand Excel CSV. The -writer proactively generates cells for formulae if values are unavailable. - -Excel TXT uses tab as the delimiter and code page 1200. - -Like in Excel, files starting with `0x49 0x44 ("ID")` are treated as Symbolic -Link files. Unlike Excel, if the file does not have a valid SYLK header, it -will be proactively reinterpreted as CSV. There are some files with semicolon -delimiter that align with a valid SYLK file. For the broadest compatibility, -all cells with the value of `ID` are automatically wrapped in double-quotes. - -**Miscellaneous Workbook Formats** - -Support for other formats is generally far behind XLS/XLSB/XLSX support, due in -part to a lack of publicly available documentation. Test files were produced in -the respective apps and compared to their XLS exports to determine structure. -The main focus is data extraction. - -- **Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123)** - -The Lotus formats consist of binary records similar to the BIFF structure. Lotus -did release a specification decades ago covering the original WK1 format. Other -features were deduced by producing files and comparing to Excel support. - -Generated WK1 worksheets are compatible with Lotus 1-2-3 R2 and Excel 5.0. - -Generated WK3 workbooks are compatible with Lotus 1-2-3 R9 and Excel 5.0. - -- **Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW)** - -The Quattro Pro formats use binary records in the same way as BIFF and Lotus. -Some of the newer formats (namely WB3 and QPW) use a CFB enclosure just like -BIFF8 XLS. - -- **Works for DOS / Windows Spreadsheet (WKS/XLR)** - -All versions of Works were limited to a single worksheet. - -Works for DOS 1.x - 3.x and Works for Windows 2.x extends the Lotus WKS format -with additional record types. - -Works for Windows 3.x - 5.x uses the same format and WKS extension. The BOF -record has type `FF` - -Works for Windows 6.x - 9.x use the XLR format. XLR is nearly identical to -BIFF8 XLS: it uses the CFB container with a Workbook stream. Works 9 saves the -exact Workbook stream for the XLR and the 97-2003 XLS export. Works 6 XLS -includes two empty worksheets but the main worksheet has an identical encoding. -XLR also includes a `WksSSWorkBook` stream similar to Lotus FM3/FMT files. - -- **Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS)** - -iWork 2013 (Numbers 3.0 / Pages 5.0 / Keynote 6.0) switched from a proprietary -XML-based format to the current file format based on the iWork Archive (IWA). -This format has been used up through the current release (Numbers 11.2). - -The parser focuses on extracting raw data from tables. Numbers technically -supports multiple tables in a logical worksheet, including custom titles. This -parser will generate one worksheet per Numbers table. - -The writer currently exports a small range from the first worksheet. - -- **OpenDocument Spreadsheet (ODS/FODS)** - -ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to -SpreadsheetML. Both are detailed in the OASIS standard, but tools like LO/OO -add undocumented extensions. The parsers and writers do not implement the full -standard, instead focusing on parts necessary to extract and store raw data. - -- **Uniform Office Spreadsheet (UOS1/2)** - -UOS is a very similar format, and it comes in 2 varieties corresponding to ODS -and FODS respectively. For the most part, the difference between the formats -is in the names of tags and attributes. - -**Miscellaneous Worksheet Formats** - -Many older formats supported only one worksheet: - -- **dBASE and Visual FoxPro (DBF)** - -DBF is really a typed table format: each column can only hold one data type and -each record omits type information. The parser generates a header row and -inserts records starting at the second row of the worksheet. The writer makes -files compatible with Visual FoxPro extensions. - -Multi-file extensions like external memos and tables are currently unsupported, -limited by the general ability to read arbitrary files in the web browser. The -reader understands DBF Level 7 extensions like DATETIME. - -- **Symbolic Link (SYLK)** - - is an informal specification based on our -experimentation and previous documentation efforts. - -- **Lotus Formatted Text (PRN)** - -There is no real documentation, and in fact Excel treats PRN as an output-only -file format. Nevertheless we can guess the column widths and reverse-engineer -the original layout. Excel's 240 character width limitation is not enforced. - -- **Data Interchange Format (DIF)** - -There is no unified definition. Visicalc DIF differs from Lotus DIF, and both -differ from Excel DIF. Where ambiguous, the parser/writer follows the expected -behavior from Excel. In particular, Excel extends DIF in incompatible ways: - -- Since Excel automatically converts numbers-as-strings to numbers, numeric - string constants are converted to formulae: `"0.3" -> "=""0.3""` -- DIF technically expects numeric cells to hold the raw numeric data, but Excel - permits formatted numbers (including dates) -- DIF technically has no support for formulae, but Excel will automatically - convert plain formulae. Array formulae are not preserved. - -- **HTML** - -Excel HTML worksheets include special metadata encoded in styles. For example, -`mso-number-format` is a localized string containing the number format. Despite -the metadata the output is valid HTML, although it does accept bare `&` symbols. - -The writer adds type metadata to the TD elements via the `t` tag. The parser -looks for those tags and overrides the default interpretation. For example, text -like `12345` will be parsed as numbers but `12345` will -be parsed as text. - -- **Rich Text Format (RTF)** - -Excel RTF worksheets are stored in clipboard when copying cells or ranges from a -worksheet. The supported codes are a subset of the Word RTF support. - -- **Ethercalc Record Format (ETH)** - -[Ethercalc](https://ethercalc.net/) is an open source web spreadsheet powered by -a record format reminiscent of SYLK wrapped in a MIME multi-part message. - -
- - -## Testing - -### Node - -
- (click to show) - -`make test` will run the node-based tests. By default it runs tests on files in -every supported format. To test a specific file type, set `FMTS` to the format -you want to test. Feature-specific tests are available with `make test_misc` - -```bash -$ make test_misc # run core tests -$ make test # run full tests -$ make test_xls # only use the XLS test files -$ make test_xlsx # only use the XLSX test files -$ make test_xlsb # only use the XLSB test files -$ make test_xml # only use the XML test files -$ make test_ods # only use the ODS test files -``` - -To enable all errors, set the environment variable `WTF=1`: - -```bash -$ make test # run full tests -$ WTF=1 make test # enable all error messages -``` - -`flow` and `eslint` checks are available: - -```bash -$ make lint # eslint checks -$ make flow # make lint + Flow checking -$ make tslint # check TS definitions -``` - -
- -### Browser - -
- (click to show) - -The core in-browser tests are available at `tests/index.html` within this repo. -Start a local server and navigate to that directory to run the tests. -`make ctestserv` will start a server on port 8000. - -`make ctest` will generate the browser fixtures. To add more files, edit the -`tests/fixtures.lst` file and add the paths. - -To run the full in-browser tests, clone the repo for -[`oss.sheetjs.com`](https://github.com/SheetJS/SheetJS.github.io) and replace -the `xlsx.js` file (then open a browser window and go to `stress.html`): - -```bash -$ cp xlsx.js ../SheetJS.github.io -$ cd ../SheetJS.github.io -$ simplehttpserver # or "python -mSimpleHTTPServer" or "serve" -$ open -a Chromium.app http://localhost:8000/stress.html -``` -
- -### Tested Environments - -
- (click to show) - - - NodeJS `0.8`, `0.10`, `0.12`, `4.x`, `5.x`, `6.x`, `7.x`, `8.x` - - IE 6/7/8/9/10/11 (IE 6-9 require shims) - - Chrome 24+ (including Android 4.0+) - - Safari 6+ (iOS and Desktop) - - Edge 13+, FF 18+, and Opera 12+ - -Tests utilize the mocha testing framework. - - - for XLS\* modules using Sauce Labs - -The test suite also includes tests for various time zones. To change -the timezone locally, set the TZ environment variable: - -```bash -$ env TZ="Asia/Kolkata" WTF=1 make test_misc -``` - -
- -### Test Files - -Test files are housed in [another repo](https://github.com/SheetJS/test_files). - -Running `make init` will refresh the `test_files` submodule and get the files. -Note that this requires `svn`, `git`, `hg` and other commands that may not be -available. If `make init` fails, please download the latest version of the test -files snapshot from [the repo](https://github.com/SheetJS/test_files/releases) - -
- Latest Snapshot (click to show) - -Latest test files snapshot: - - -(download and unzip to the `test_files` subdirectory) - -
- -## Contributing - -Due to the precarious nature of the Open Specifications Promise, it is very -important to ensure code is cleanroom. [Contribution Notes](CONTRIBUTING.md) - -
- File organization (click to show) - -At a high level, the final script is a concatenation of the individual files in -the `bits` folder. Running `make` should reproduce the final output on all -platforms. The README is similarly split into bits in the `docbits` folder. - -Folders: - -| folder | contents | -|:-------------|:--------------------------------------------------------------| -| `bits` | raw source files that make up the final script | -| `docbits` | raw markdown files that make up `README.md` | -| `bin` | server-side bin scripts (`xlsx.njs`) | -| `dist` | dist files for web browsers and nonstandard JS environments | -| `demos` | demo projects for platforms like ExtendScript and Webpack | -| `tests` | browser tests (run `make ctest` to rebuild) | -| `types` | typescript definitions and tests | -| `misc` | miscellaneous supporting scripts | -| `test_files` | test files (pulled from the test files repository) | - -
- -After cloning the repo, running `make help` will display a list of commands. - -### OSX/Linux - -
- (click to show) - -The `xlsx.js` file is constructed from the files in the `bits` subdirectory. The -build script (run `make`) will concatenate the individual bits to produce the -script. Before submitting a contribution, ensure that running make will produce -the `xlsx.js` file exactly. The simplest way to test is to add the script: - -```bash -$ git add xlsx.js -$ make clean -$ make -$ git diff xlsx.js -``` - -To produce the dist files, run `make dist`. The dist files are updated in each -version release and *should not be committed between versions*. -
- -### Windows - -
- (click to show) - -The included `make.cmd` script will build `xlsx.js` from the `bits` directory. -Building is as simple as: - -```cmd -> make -``` - -To prepare development environment: - -```cmd -> make init -``` - -The full list of commands available in Windows are displayed in `make help`: - -``` -make init -- install deps and global modules -make lint -- run eslint linter -make test -- run mocha test suite -make misc -- run smaller test suite -make book -- rebuild README and summary -make help -- display this message -``` - -As explained in [Test Files](#test-files), on Windows the release ZIP file must -be downloaded and extracted. If Bash on Windows is available, it is possible -to run the OSX/Linux workflow. The following steps prepares the environment: - -```bash -# Install support programs for the build and test commands -sudo apt-get install make git subversion mercurial - -# Install nodejs and NPM within the WSL -wget -qO- https://deb.nodesource.com/setup_8.x | sudo bash -sudo apt-get install nodejs - -# Install dev dependencies -sudo npm install -g mocha voc blanket xlsjs -``` - -
- -### Tests - -
- (click to show) - -The `test_misc` target (`make test_misc` on Linux/OSX / `make misc` on Windows) -runs the targeted feature tests. It should take 5-10 seconds to perform feature -tests without testing against the entire test battery. New features should be -accompanied with tests for the relevant file formats and features. - -For tests involving the read side, an appropriate feature test would involve -reading an existing file and checking the resulting workbook object. If a -parameter is involved, files should be read with different values to verify that -the feature is working as expected. - -For tests involving a new write feature which can already be parsed, appropriate -feature tests would involve writing a workbook with the feature and then opening -and verifying that the feature is preserved. - -For tests involving a new write feature without an existing read ability, please -add a feature test to the kitchen sink `tests/write.js`. -
- -## License - -Please consult the attached LICENSE file for details. All rights not explicitly -granted by the Apache 2.0 License are reserved by the Original Author. - - -## References - -
- OSP-covered Specifications (click to show) - - - `MS-CFB`: Compound File Binary File Format - - `MS-CTXLS`: Excel Custom Toolbar Binary File Format - - `MS-EXSPXML3`: Excel Calculation Version 2 Web Service XML Schema - - `MS-ODATA`: Open Data Protocol (OData) - - `MS-ODRAW`: Office Drawing Binary File Format - - `MS-ODRAWXML`: Office Drawing Extensions to Office Open XML Structure - - `MS-OE376`: Office Implementation Information for ECMA-376 Standards Support - - `MS-OFFCRYPTO`: Office Document Cryptography Structure - - `MS-OI29500`: Office Implementation Information for ISO/IEC 29500 Standards Support - - `MS-OLEDS`: Object Linking and Embedding (OLE) Data Structures - - `MS-OLEPS`: Object Linking and Embedding (OLE) Property Set Data Structures - - `MS-OODF3`: Office Implementation Information for ODF 1.2 Standards Support - - `MS-OSHARED`: Office Common Data Types and Objects Structures - - `MS-OVBA`: Office VBA File Format Structure - - `MS-XLDM`: Spreadsheet Data Model File Format - - `MS-XLS`: Excel Binary File Format (.xls) Structure Specification - - `MS-XLSB`: Excel (.xlsb) Binary File Format - - `MS-XLSX`: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format - - `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification - - `RTF`: Rich Text Format - -
- -- ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats" -- Open Document Format for Office Applications Version 1.2 (29 September 2011) -- Worksheet File Format (From Lotus) December 1984 +Hosted URL: diff --git a/docz/.gitignore b/docz/.gitignore new file mode 100644 index 0000000..b2d6de3 --- /dev/null +++ b/docz/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/docz/README.md b/docz/README.md new file mode 100644 index 0000000..01b4bc2 --- /dev/null +++ b/docz/README.md @@ -0,0 +1,3 @@ +# docs.sheetjs.com + + \ No newline at end of file diff --git a/docz/babel.config.js b/docz/babel.config.js new file mode 100644 index 0000000..e00595d --- /dev/null +++ b/docz/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/docz/blog/2019-05-28-first-blog-post.md b/docz/blog/2019-05-28-first-blog-post.md new file mode 100644 index 0000000..02f3f81 --- /dev/null +++ b/docz/blog/2019-05-28-first-blog-post.md @@ -0,0 +1,12 @@ +--- +slug: first-blog-post +title: First Blog Post +authors: + name: Gao Wei + title: Docusaurus Core Team + url: https://github.com/wgao19 + image_url: https://github.com/wgao19.png +tags: [hola, docusaurus] +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/docz/blog/2019-05-29-long-blog-post.md b/docz/blog/2019-05-29-long-blog-post.md new file mode 100644 index 0000000..26ffb1b --- /dev/null +++ b/docz/blog/2019-05-29-long-blog-post.md @@ -0,0 +1,44 @@ +--- +slug: long-blog-post +title: Long Blog Post +authors: endi +tags: [hello, docusaurus] +--- + +This is the summary of a very long blog post, + +Use a `` comment to limit blog post size in the list view. + + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/docz/blog/2021-08-01-mdx-blog-post.mdx b/docz/blog/2021-08-01-mdx-blog-post.mdx new file mode 100644 index 0000000..c04ebe3 --- /dev/null +++ b/docz/blog/2021-08-01-mdx-blog-post.mdx @@ -0,0 +1,20 @@ +--- +slug: mdx-blog-post +title: MDX Blog Post +authors: [slorber] +tags: [docusaurus] +--- + +Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). + +:::tip + +Use the power of React to create interactive blog posts. + +```js + +``` + + + +::: diff --git a/docz/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg b/docz/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..11bda0928456b12f8e53d0ba5709212a4058d449 GIT binary patch literal 96122 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 literal 0 HcmV?d00001 diff --git a/docz/blog/2021-08-26-welcome/index.md b/docz/blog/2021-08-26-welcome/index.md new file mode 100644 index 0000000..9455168 --- /dev/null +++ b/docz/blog/2021-08-26-welcome/index.md @@ -0,0 +1,25 @@ +--- +slug: welcome +title: Welcome +authors: [slorber, yangshun] +tags: [facebook, hello, docusaurus] +--- + +[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). + +Simply add Markdown files (or folders) to the `blog` directory. + +Regular blog authors can be added to `authors.yml`. + +The blog post date can be extracted from filenames, such as: + +- `2019-05-30-welcome.md` +- `2019-05-30-welcome/index.md` + +A blog post folder can be convenient to co-locate blog post images: + +![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) + +The blog supports tags as well! + +**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. diff --git a/docz/blog/authors.yml b/docz/blog/authors.yml new file mode 100644 index 0000000..bcb2991 --- /dev/null +++ b/docz/blog/authors.yml @@ -0,0 +1,17 @@ +endi: + name: Endilie Yacop Sucipto + title: Maintainer of Docusaurus + url: https://github.com/endiliey + image_url: https://github.com/endiliey.png + +yangshun: + name: Yangshun Tay + title: Front End Engineer @ Facebook + url: https://github.com/yangshun + image_url: https://github.com/yangshun.png + +slorber: + name: Sébastien Lorber + title: Docusaurus maintainer + url: https://sebastienlorber.com + image_url: https://github.com/slorber.png diff --git a/docz/docs/02-installation/01-standalone.mdx b/docz/docs/02-installation/01-standalone.mdx new file mode 100644 index 0000000..ea68334 --- /dev/null +++ b/docz/docs/02-installation/01-standalone.mdx @@ -0,0 +1,112 @@ +--- +sidebar_position: 1 +sidebar_custom_props: + summary: Classic pages with simple `} + + +The `latest` tag references the latest version and updates with each release: + +```html + + +``` + +**For production use, scripts should be downloaded and added to a public folder +alongside other scripts.** + +
+ Download using Bower (click to show) + +[Bower](https://bower.io/) plays nice with the CDN tarballs: + +
{`\
+$ npx bower install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+ +Bower will place the standalone scripts in `bower_components/js-xlsx/dist/` +
+ +
+ Browser builds (click to show) + +The complete single-file version is generated at `dist/xlsx.full.min.js` + +`dist/xlsx.core.min.js` omits codepage library (no support for XLS encodings) + +A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build: +- codepage library skipped (no support for XLS encodings) +- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers +- node stream utils removed + +These scripts are also available on the CDN: + +
{`\
+
+`}
+
+ +
+ +
+ Internet Explorer and ECMAScript 3 Compatibility (click to show) + +For broad compatibility with JavaScript engines, the library is written using +ECMAScript 3 language dialect as well as some ES5 features like `Array#forEach`. +Older browsers require shims to provide missing functions. + +To use the shim, add the shim before the script tag that loads `xlsx.js`: + +```html + + + + +``` + +Due to SSL certificate compatibility issues, it is highly recommended to save +the Standalone and Shim scripts from and add to a +public directory in the site. + +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. + +
+ +
+ ECMAScript Module Imports in a SCRIPT TAG (click to show) + +The ECMAScript Module build is saved to `xlsx.mjs` and can be directly added to +a page with a `script` tag using `type="module"`: + +
{`\
+`}
+
+ +If XLS support is required, `cpexcel.full.js` must be manually imported: + +
{`\
+`}
+
+ +
\ No newline at end of file diff --git a/docz/docs/02-installation/02-frameworks.md b/docz/docs/02-installation/02-frameworks.md new file mode 100644 index 0000000..aa0170b --- /dev/null +++ b/docz/docs/02-installation/02-frameworks.md @@ -0,0 +1,54 @@ +--- +sidebar_position: 2 +sidebar_custom_props: + summary: Angular, React, VueJS, Webpack, etc. +--- + +import current from '/version.js'; + +# Frameworks and Bundlers + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Each standalone release package is available at . The +NodeJS package is designed to be used with frameworks and bundlers. It is a +proper ECMAScript Module release which can be optimized with developer tools. + + + +
{`\
+$ npm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+ +
{`\
+$ pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+ +
{`\
+$ yarn add --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+ +Once installed, the library can be imported under the name `xlsx`: + +```js +import { read, writeFileXLSX } from "xlsx"; +``` + +
+ XLS Codepage support (click to show) + +If XLS support is required, `cpexcel.full.js` must be manually imported: + +```js +/* load the codepage support library for extended support with older formats */ +import { set_cptable } from "xlsx"; +import * as cptable from 'xlsx/dist/cpexcel.full.mjs'; +set_cptable(cptable); +``` + +
\ No newline at end of file diff --git a/docz/docs/02-installation/03-deno.md b/docz/docs/02-installation/03-deno.md new file mode 100644 index 0000000..6a1c83c --- /dev/null +++ b/docz/docs/02-installation/03-deno.md @@ -0,0 +1,31 @@ +--- +sidebar_position: 3 +sidebar_custom_props: + summary: Import ECMAScript Modules and TypeScript definitions +--- + +import current from '/version.js'; + +# Deno + +Each standalone release script is available at . + +Using the URL imports, `deno run` will automatically download scripts and types: + +
{`\
+// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
+import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';`}
+
+ +
+ XLS Codepage support (click to show) + +If XLS support is required, `cpexcel.full.js` must be manually imported: + +
{`\
+/* load the codepage support library for extended support with older formats  */
+import * as cptable from 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/cpexcel.full.mjs';
+XLSX.set_cptable(cptable);`}
+
+ +
\ No newline at end of file diff --git a/docz/docs/02-installation/04-nodejs.md b/docz/docs/02-installation/04-nodejs.md new file mode 100644 index 0000000..465843f --- /dev/null +++ b/docz/docs/02-installation/04-nodejs.md @@ -0,0 +1,104 @@ +--- +sidebar_position: 4 +sidebar_custom_props: + summary: Server-side and other frameworks using NodeJS modules +--- + +import current from '/version.js'; + +# NodeJS + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Tarballs are available on . + +
Each individual version can be referenced using a similar URL pattern. + +https://cdn.sheetjs.com/xlsx-{current}/xlsx-{current}.tgz is the URL for {current}
+ + is a link to the latest +version and will refresh on each release. + +## Installation + +Tarballs can be directly installed using a package manager: + + + +
{`\
+$ npm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+ +
{`\
+$ pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+ +
{`\
+$ yarn add --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+ +### Vendoring + +For general stability, "vendoring" modules is the recommended approach: + +
1) Download the tarball (xlsx-{current}.tgz) for the desired version. The current + version is available at https://cdn.sheetjs.com/xlsx-{current}/xlsx-{current}.tgz

+ +2) Create a `vendor` subdirectory at the root of your project and move the + tarball to that folder. Add it to your project repository. + +3) Install the tarball using a package manager: + + + +
{`\
+$ npm install --save file:vendor/xlsx-${current}.tgz`}
+
+
+ +
{`\
+$ pnpm install --save file:vendor/xlsx-${current}.tgz`}
+
+
+ +
{`\
+$ yarn add --save file:vendor/xlsx-0.18.7.tgz`}
+
+
+
+ +The package will be installed and accessible as `xlsx`. + +## Usage + +By default, the module supports `require` and it will automatically add support +for streams and filesystem access: + +```js +var XLSX = require("xlsx"); +``` + +The module also ships with `xlsx.mjs` for use with `import`. The `mjs` version +does not automatically load native node modules, so they must be added manually: + +```js +import * as XLSX from 'xlsx/xlsx.mjs'; + +/* load 'fs' for readFile and writeFile support */ +import * as fs from 'fs'; +XLSX.set_fs(fs); + +/* load 'stream' for stream support */ +import { Readable } from 'stream'; +XLSX.stream.set_readable(Readable); + +/* load the codepage support library for extended support with older formats */ +import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs'; +XLSX.set_cptable(cpexcel); +``` + diff --git a/docz/docs/02-installation/05-extendscript.md b/docz/docs/02-installation/05-extendscript.md new file mode 100644 index 0000000..0d1d9b3 --- /dev/null +++ b/docz/docs/02-installation/05-extendscript.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 5 +sidebar_custom_props: + summary: Photoshop, InDesign, and other Creative Cloud apps +--- + +import current from '/version.js'; + +# ExtendScript + +Each standalone release script is available at . + +`xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign. + +
+ +After downloading the script, it can be directly referenced with `#include`: + +```c +#include "xlsx.extendscript.js" +``` diff --git a/docz/docs/02-installation/_category_.json b/docz/docs/02-installation/_category_.json new file mode 100644 index 0000000..e111289 --- /dev/null +++ b/docz/docs/02-installation/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Installation", + "position": 2 +} diff --git a/docz/docs/02-installation/index.md b/docz/docs/02-installation/index.md new file mode 100644 index 0000000..56f86e0 --- /dev/null +++ b/docz/docs/02-installation/index.md @@ -0,0 +1,20 @@ +--- +hide_table_of_contents: true +--- + +# Installation + +import DocCardList from '@theme/DocCardList'; +import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; + + is the primary software distribution site. Please +read the installation instructions for your use case: + +
    {useCurrentSidebarCategory().items.map((item, index) => { + const listyle = (item.customProps?.icon) ? { + listStyleImage: `url("${item.customProps.icon}")` + } : {}; + return (
  • + {item.label}{item.customProps?.summary && (" - " + item.customProps.summary)} +
  • ); +})}
\ No newline at end of file diff --git a/docz/docs/03-example.mdx b/docz/docs/03-example.mdx new file mode 100644 index 0000000..69804b6 --- /dev/null +++ b/docz/docs/03-example.mdx @@ -0,0 +1,375 @@ +--- +sidebar_position: 3 +--- + +# Complete Example + +SheetJS presents a simple JS interface that works with "Array of Arrays" and +"Array of JS Objects". The API functions are building blocks that should be +combined with other JS APIs to solve problems. + +The discussion focuses on the problem solving mindset. API details are covered +in other parts of the documentation. + +The goal of this example is to generate a XLSB workbook of US President names +and birthdays. [Click here](#live-demo) to jump to the live demo + +## Acquire Data + +### Raw Data + +[The raw data is available in JSON form](https://theunitedstates.io/congress-legislators/executive.json). +For convenience, it has been [mirrored here](https://sheetjs.com/executive.json) + +The data result is an Array of objects. This is the data for John Adams: + +```js +{ + "id": { /* (data omitted) */ }, + "name": { + "first": "John", // <-- first name + "last": "Adams" // <-- last name + }, + "bio": { + "birthday": "1735-10-19", // <-- birthday + "gender": "M" + }, + "terms": [ + { "type": "viceprez", /* (other fields omitted) */ }, + { "type": "viceprez", /* (other fields omitted) */ }, + { "type": "prez", /* (other fields omitted) */ } + ] +} +``` + +### Filtering for Presidents + +The dataset includes Aaron Burr, a Vice President who was never President! + +`Array#filter` creates a new array with the desired rows. A President served +at least one term with `type` set to `"prez"`. To test if a particular row has +at least one `"prez"` term, `Array#some` is another native JS function. The +complete filter would be: + +```js +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); +``` + +### Reshaping the Array + +For this example, the name will be the first name combined with the last name +(`row.name.first + " " + row.name.last`) and the birthday will be the subfield +`row.bio.birthday`. Using `Array#map`, the dataset can be massaged in one call: + +```js +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); +``` + +The result is an array of "simple" objects with no nesting: + +```js +[ + { name: "George Washington", birthday: "1732-02-22" }, + { name: "John Adams", birthday: "1735-10-19" }, + // ... one row per President +] +``` + +## Create a Workbook + +With the cleaned dataset, `XLSX.utils.json_to_sheet` generates a worksheet: + +```js +const worksheet = XLSX.utils.json_to_sheet(rows); +``` + +`XLSX.utils.book_new` creates a new workbook and `XLSX.utils.book_append_sheet` +appends a worksheet to the workbook. The new worksheet will be called "Dates": + +```js +const workbook = XLSX.utils.book_new(); +XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); +``` + +## Clean up Workbook + +The data is in the workbook and can be exported. + +![Rough export](./img/rough.png) + +There are multiple opportunities for improvement: the headers can be renamed and +the column widths can be adjusted. [SheetJS Pro](https://sheetjs.com/pro) offers +additional styling options like cell styling and frozen rows. + +
Changing Header Names (click to show) + +By default, `json_to_sheet` creates a worksheet with a header row. In this case, +the headers come from the JS object keys: "name" and "birthday". + +The headers are in cells A1 and B1. `XLSX.utils.sheet_add_aoa` can write text +values to the existing worksheet starting at cell A1: + +```js +XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); +``` + +
+ +
Changing Column Widths (click to show) + +Some of the names are longer than the default column width. Column widths are +set by setting the `"!cols"` worksheet property. + +The following line sets the width of column A to approximately 10 characters: + +```js +worksheet["!cols"] = [ { wch: 10 } ]; // set column A width to 10 characters +``` + +One `Array#reduce` call over `rows` can calculate the maximum width: + +```js +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; +``` + +
+ +## Export a File + +`XLSX.writeFile` creates a spreadsheet file and tries to write it to the system. +In the browser, it will try to prompt the user to download the file. In NodeJS, +it will write to the local directory. + +```js +XLSX.writeFile(workbook, "Presidents.xlsb"); +``` + +![Final export](./img/final.png) + + +## Live Demo + +```jsx live +function Presidents() { return ( ); } +``` + +## Run the Demo Locally + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +Save the following script to `snippet.html` and open the page. The page must be +hosted (no `file:///` access). + + is a hosted version of the page. + +```html + + + + +``` + + + +Install the dependencies: + +```bash +$ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +``` + +Save the following script to `snippet.js` and run `node snippet.js`: + +```js +const XLSX = require("xlsx"); + +(async() => { + /* fetch JSON data and parse */ + const url = "https://sheetjs.com/executive.json"; + const raw_data = await (await fetch(url)).json(); + + /* filter for the Presidents */ + const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + + /* flatten objects */ + const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + })); + + /* generate worksheet and workbook */ + const worksheet = XLSX.utils.json_to_sheet(rows); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsb */ + XLSX.writeFile(workbook, "Presidents.xlsb"); +})(); +``` + +Native `fetch` support was added in NodeJS 18. For older versions of NodeJS, +the script will throw an error `fetch is not defined`. A third-party library +like `axios` presents a similar API for fetching data: + +
Example using axios (click to show) + +Install the dependencies: + +```bash +$ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +``` + +The differences in the script are highlighted below. + +```js +const XLSX = require("xlsx"); +// highlight-next-line +const axios = require("axios"); + +(async() => { + /* fetch JSON data and parse */ + const url = "https://sheetjs.com/executive.json"; + // highlight-next-line + const raw_data = (await axios(url, {responseType: "json"})).data; + + /* filter for the Presidents */ + const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + + /* flatten objects */ + const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + })); + + /* generate worksheet and workbook */ + const worksheet = XLSX.utils.json_to_sheet(rows); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsb */ + XLSX.writeFile(workbook, "Presidents.xlsb"); +})(); +``` + +
+ +
+ + +Save the following script to `snippet.ts` and run with +`deno run --allow-net --allow-write snippet.ts`: + +```js +// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts" +import * as XLSX from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs'; + +/* fetch JSON data and parse */ +const url = "https://sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter((row: any) => row.terms.some((term: any) => term.type === "prez")); + +/* flatten objects */ +const rows = prez.map((row: any) => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = XLSX.utils.json_to_sheet(rows); +const workbook = XLSX.utils.book_new(); +XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w: number, r: any) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsb */ +XLSX.writeFile(workbook, "Presidents.xlsb"); +``` + + +
\ No newline at end of file diff --git a/docz/docs/04-getting-started/01-roadmap.md b/docz/docs/04-getting-started/01-roadmap.md new file mode 100644 index 0000000..e98cae2 --- /dev/null +++ b/docz/docs/04-getting-started/01-roadmap.md @@ -0,0 +1,67 @@ +--- +sidebar_position: 1 +--- + +# Roadmap + +Most scenarios involving spreadsheets and data can be divided into 5 parts: + +1) **Acquire Data**: Data may be stored anywhere: local or remote files, + databases, HTML TABLE, or even generated programmatically in the web browser. + +2) **Extract Data**: For spreadsheet files, this involves parsing raw bytes to + read the cell data. For general JS data, this involves reshaping the data. + +3) **Process Data**: From generating summary statistics to cleaning data + records, this step is the heart of the problem. + +4) **Package Data**: This can involve making a new spreadsheet or serializing + with `JSON.stringify` or writing XML or simply flattening data for UI tools. + +5) **Release Data**: Spreadsheet files can be uploaded to a server or written + locally. Data can be presented to users in an HTML TABLE or data grid. + +A common problem involves generating a valid spreadsheet export from data stored +in an HTML table. In this example, an HTML TABLE on the page will be scraped, +a row will be added to the bottom with the date of the report, and a new file +will be generated and downloaded locally. `XLSX.writeFile` takes care of +packaging the data and attempting a local download: + +```js +// Acquire Data (reference to the HTML table) +var table_elt = document.getElementById("my-table-id"); + +// Extract Data (create a workbook object from the table) +var workbook = XLSX.utils.table_to_book(table_elt); + +// Process Data (add a new row) +var ws = workbook.Sheets["Sheet1"]; +XLSX.utils.sheet_add_aoa(ws, [["Created "+new Date().toISOString()]], {origin:-1}); + +// Package and Release Data (`writeFile` tries to write and save an XLSB file) +XLSX.writeFile(workbook, "Report.xlsb"); +``` + +This library tries to simplify steps 2 and 4 with functions to extract useful +data from spreadsheet files (`read` / `readFile`) and generate new spreadsheet +files from data (`write` / `writeFile`). Additional utility functions like +`table_to_book` work with other common data sources like HTML tables. + +This documentation and various demo projects cover a number of common scenarios +and approaches for steps 1 and 5. + +Utility functions help with step 3. + +## Highlights + +["Data Import"](../solutions/input) describes solutions for common data import +scenarios. + +["Data Export"](../solutions/output) describes solutions for common data export +scenarios. + +["Data Processing"](../solutions/processing) describes solutions for common +workbook processing and manipulation scenarios. + +["Utility Functions"](../api/utilities) details utility functions for +translating JSON Arrays and other common JS structures into worksheet objects. diff --git a/docz/docs/04-getting-started/02-zen.md b/docz/docs/04-getting-started/02-zen.md new file mode 100644 index 0000000..5d99fcb --- /dev/null +++ b/docz/docs/04-getting-started/02-zen.md @@ -0,0 +1,37 @@ +--- +sidebar_position: 2 +hide_table_of_contents: true +--- + +# Zen of SheetJS + +SheetJS design and development is guided by a few key principles. + +### Data processing should fit in any workflow + +The library does not impose a separate lifecycle. It fits nicely in websites +and apps built using any framework. The plain JS data objects play nice with +Web Workers and future APIs. + +### JavaScript is a powerful language for data processing + +The ["Common Spreadsheet Format"](../csf/general) is a simple object +representation of the core concepts of a workbook. The various functions in the +library provide low-level tools for working with the object. + +For friendly JS processing, there are utility functions for converting parts of +a worksheet to/from an Array of Arrays. The [Complete example](../03-example.mdx) +combines powerful JS Array methods with a network request library to download +data, select the information we want and create a workbook file: + +### File formats are implementation details + +The parser covers a wide gamut of common spreadsheet file formats to ensure that +"HTML-saved-as-XLS" files work as well as actual XLS or XLSX files. + +The writer supports a number of common output formats for broad compatibility +with the data ecosystem. + +To the greatest extent possible, data processing code should not have to worry +about the specific file formats involved. + diff --git a/docz/docs/04-getting-started/03-demos.md b/docz/docs/04-getting-started/03-demos.md new file mode 100644 index 0000000..7e544c9 --- /dev/null +++ b/docz/docs/04-getting-started/03-demos.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 3 +hide_table_of_contents: true +--- + +# Demo Projects + +The demo projects include small runnable examples and short explainers. + +### Frameworks and APIs + +- [`Angular.JS`](https://github.com/SheetJS/SheetJS/tree/master/demos/angular/) +- [`Angular 2+ and Ionic`](https://github.com/SheetJS/SheetJS/tree/master/demos/angular2/) +- [`Knockout`](https://github.com/SheetJS/SheetJS/tree/master/demos/knockout/) +- [`Meteor`](https://github.com/SheetJS/SheetJS/tree/master/demos/meteor/) +- [`React, React Native and NextJS`](https://github.com/SheetJS/SheetJS/tree/master/demos/react/) +- [`VueJS, WeeX, and NuxtJS`](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/) +- [`XMLHttpRequest and fetch`](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) +- [`NodeJS Server-Side Processing`](https://github.com/SheetJS/SheetJS/tree/master/demos/server/) +- [`Databases and Key/Value Stores`](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) +- [`Typed Arrays and Math`](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) + +### Front-End UI Components + +- [`canvas-datagrid`](https://github.com/SheetJS/SheetJS/tree/master/demos/datagrid/) +- [`x-spreadsheet`](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet/) +- [`react-data-grid`](https://github.com/SheetJS/SheetJS/tree/master/demos/react/modify/) +- [`vue3-table-light`](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/) + +### Platforms and Integrations +- [`Deno`](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) +- [`Electron`](https://github.com/SheetJS/SheetJS/tree/master/demos/electron/) +- [`NW.js`](https://github.com/SheetJS/SheetJS/tree/master/demos/nwjs/) +- [`Chrome / Chromium Extension`](https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/) +- [`Google Sheet export`](https://github.com/SheetJS/SheetJS/tree/master/demos/google-sheet/) +- [`ExtendScript for Adobe Apps`](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) +- [`Headless Browsers`](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) +- [`Other JavaScript Engines`](https://github.com/SheetJS/SheetJS/tree/master/demos/altjs/) +- [`"serverless" functions`](https://github.com/SheetJS/SheetJS/tree/master/demos/function/) +- [`Legacy Internet Explorer`](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) + +### Bundlers and Tooling +- [`browserify`](https://github.com/SheetJS/SheetJS/tree/master/demos/browserify/) +- [`fusebox`](https://github.com/SheetJS/SheetJS/tree/master/demos/fusebox/) +- [`parcel`](https://github.com/SheetJS/SheetJS/tree/master/demos/parcel/) +- [`requirejs`](https://github.com/SheetJS/SheetJS/tree/master/demos/requirejs/) +- [`rollup`](https://github.com/SheetJS/SheetJS/tree/master/demos/rollup/) +- [`systemjs`](https://github.com/SheetJS/SheetJS/tree/master/demos/systemjs/) +- [`typescript`](https://github.com/SheetJS/SheetJS/tree/master/demos/typescript/) +- [`webpack 2.x`](https://github.com/SheetJS/SheetJS/tree/master/demos/webpack/) diff --git a/docz/docs/04-getting-started/_category_.json b/docz/docs/04-getting-started/_category_.json new file mode 100644 index 0000000..4bd4025 --- /dev/null +++ b/docz/docs/04-getting-started/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Getting Started", + "position": 4 +} diff --git a/docz/docs/04-getting-started/img/docsVersionDropdown.png b/docz/docs/04-getting-started/img/docsVersionDropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..97e4164618b5f8beda34cfa699720aba0ad2e342 GIT binary patch literal 25427 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 literal 0 HcmV?d00001 diff --git a/docz/docs/04-getting-started/img/localeDropdown.png b/docz/docs/04-getting-started/img/localeDropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..e257edc1f932985396bf59584c7ccfaddf955779 GIT binary patch literal 27841 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 JrC|B>e*nH7H{}2T literal 0 HcmV?d00001 diff --git a/docz/docs/05-interface.md b/docz/docs/05-interface.md new file mode 100644 index 0000000..68a7aa4 --- /dev/null +++ b/docz/docs/05-interface.md @@ -0,0 +1,70 @@ +--- +sidebar_position: 5 +--- + +# Interface Summary + +`XLSX` is the exposed variable in the browser and the exported node variable + +`XLSX.version` is the version of the library (added by the build script). + +`XLSX.SSF` is an embedded version of the [format library](https://github.com/SheetJS/ssf). + +## Parsing functions + +`XLSX.read(data, read_opts)` attempts to parse `data`. + +`XLSX.readFile(filename, read_opts)` attempts to read `filename` and parse. + +Parse options are described in the [Parsing Options](./api/parse-options) section. + +## Writing functions + +`XLSX.write(wb, write_opts)` attempts to write the workbook `wb` + +`XLSX.writeFile(wb, filename, write_opts)` attempts to write `wb` to `filename`. +In browser-based environments, it will attempt to force a client-side download. + +`XLSX.writeFileAsync(filename, wb, o, cb)` attempts to write `wb` to `filename`. +If `o` is omitted, the writer will use the third argument as the callback. + +`XLSX.stream` contains a set of streaming write functions. + +Write options are described in the [Writing Options](./api/write-options) section. + +## Utilities + +Utilities are available in the `XLSX.utils` object and are described in the +[Utility Functions](./api/utilities) section: + +**Constructing:** + +- `book_new` creates an empty workbook +- `book_append_sheet` adds a worksheet to a workbook + +**Importing:** + +- `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. +- `json_to_sheet` converts an array of JS objects to a worksheet. +- `table_to_sheet` converts a DOM TABLE element to a worksheet. +- `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet. +- `sheet_add_json` adds an array of JS objects to an existing worksheet. + + +**Exporting:** + +- `sheet_to_json` converts a worksheet object to an array of JSON objects. +- `sheet_to_csv` generates delimiter-separated-values output. +- `sheet_to_txt` generates UTF16 formatted text. +- `sheet_to_html` generates HTML output. +- `sheet_to_formulae` generates a list of the formulae (with value fallbacks). + + +**Cell and cell address manipulation:** + +- `format_cell` generates the text value for a cell (using number formats). +- `encode_row / decode_row` converts between 0-indexed rows and 1-indexed rows. +- `encode_col / decode_col` converts between 0-indexed columns and column names. +- `encode_cell / decode_cell` converts cell addresses. +- `encode_range / decode_range` converts cell ranges. + diff --git a/docz/docs/06-solutions/01-input.md b/docz/docs/06-solutions/01-input.md new file mode 100644 index 0000000..69372bc --- /dev/null +++ b/docz/docs/06-solutions/01-input.md @@ -0,0 +1,782 @@ +--- +sidebar_position: 1 +--- + +# Data Import + +## Parsing Workbooks + +#### API + +_Extract data from spreadsheet bytes_ + +```js +var workbook = XLSX.read(data, opts); +``` + +The `read` method can extract data from spreadsheet bytes stored in a JS string, +"binary string", NodeJS buffer or typed array (`Uint8Array` or `ArrayBuffer`). + + +_Read spreadsheet bytes from a local file and extract data_ + +```js +var workbook = XLSX.readFile(filename, opts); +``` + +The `readFile` method attempts to read a spreadsheet file at the supplied path. +Browsers generally do not allow reading files in this way (it is deemed a +security risk), and attempts to read files in this way will throw an error. + +The second `opts` argument is optional. ["Parsing Options"](../api/parse-options) +covers the supported properties and behaviors. + +#### Examples + +Here are a few common scenarios (click on each subtitle to see the code): + +
+ Local file in a NodeJS server (click to show) + +`readFile` uses `fs.readFileSync` under the hood: + +```js +var XLSX = require("xlsx"); + +var workbook = XLSX.readFile("test.xlsx"); +``` + +For Node ESM, the `readFile` helper is not enabled. Instead, `fs.readFileSync` +should be used to read the file data as a `Buffer` for use with `XLSX.read`: + +```js +import { readFileSync } from "fs"; +import { read } from "xlsx/xlsx.mjs"; + +const buf = readFileSync("test.xlsx"); +/* buf is a Buffer */ +const workbook = read(buf); +``` + +
+ +
+ Local file in a Deno application (click to show) + +`readFile` uses `Deno.readFileSync` under the hood: + +```js +// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts" +import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs' + +const workbook = XLSX.readFile("test.xlsx"); +``` + +Applications reading files must be invoked with the `--allow-read` flag. The +[`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples + +
+ +
+ User-submitted file in a web page ("Drag-and-Drop") (click to show) + +For modern websites targeting Chrome 76+, `File#arrayBuffer` is recommended: + +```js +// XLSX is a global from the standalone script + +async function handleDropAsync(e) { + e.stopPropagation(); e.preventDefault(); + const f = e.dataTransfer.files[0]; + /* f is a File */ + const data = await f.arrayBuffer(); + /* data is an ArrayBuffer */ + const workbook = XLSX.read(data); + + /* DO SOMETHING WITH workbook HERE */ +} +drop_dom_element.addEventListener("drop", handleDropAsync, false); +``` + +For maximal compatibility, the `FileReader` API should be used: + +```js +function handleDrop(e) { + e.stopPropagation(); e.preventDefault(); + var f = e.dataTransfer.files[0]; + /* f is a File */ + var reader = new FileReader(); + reader.onload = function(e) { + var data = e.target.result; + /* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */ + var workbook = XLSX.read(data); + + /* DO SOMETHING WITH workbook HERE */ + }; + reader.readAsArrayBuffer(f); +} +drop_dom_element.addEventListener("drop", handleDrop, false); +``` + + demonstrates the FileReader technique. + +
+ +
+ User-submitted file with an HTML INPUT element (click to show) + +Starting with an HTML INPUT element with `type="file"`: + +```html + +``` + +For modern websites targeting Chrome 76+, `Blob#arrayBuffer` is recommended: + +```js +// XLSX is a global from the standalone script + +async function handleFileAsync(e) { + const file = e.target.files[0]; + const data = await file.arrayBuffer(); + /* data is an ArrayBuffer */ + const workbook = XLSX.read(data); + + /* DO SOMETHING WITH workbook HERE */ +} +input_dom_element.addEventListener("change", handleFileAsync, false); +``` + +For broader support (including IE10+), the `FileReader` approach is recommended: + +```js +function handleFile(e) { + var file = e.target.files[0]; + var reader = new FileReader(); + reader.onload = function(e) { + var data = e.target.result; + /* reader.readAsArrayBuffer(file) -> data will be an ArrayBuffer */ + var workbook = XLSX.read(e.target.result); + + /* DO SOMETHING WITH workbook HERE */ + }; + reader.readAsArrayBuffer(file); +} +input_dom_element.addEventListener("change", handleFile, false); +``` + +The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario. + +
+ +
+ Fetching a file in the web browser ("Ajax") (click to show) + +For modern websites targeting Chrome 42+, `fetch` is recommended: + +```js +// XLSX is a global from the standalone script + +(async() => { + const url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"; + const data = await (await fetch(url)).arrayBuffer(); + /* data is an ArrayBuffer */ + const workbook = XLSX.read(data); + + /* DO SOMETHING WITH workbook HERE */ +})(); +``` + +For broader support, the `XMLHttpRequest` approach is recommended: + +```js +var url = "http://oss.sheetjs.com/test_files/formula_stress_test.xlsx"; + +/* set up async GET request */ +var req = new XMLHttpRequest(); +req.open("GET", url, true); +req.responseType = "arraybuffer"; + +req.onload = function(e) { + var workbook = XLSX.read(req.response); + + /* DO SOMETHING WITH workbook HERE */ +}; + +req.send(); +``` + +The [`xhr` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xhr/) includes a longer discussion and more examples. + + shows fallback approaches for IE6+. + +
+ +
+ Local file in a PhotoShop or InDesign plugin (click to show) + +`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"); +``` + +The [`extendscript` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) includes a more complex example. + +
+ +
+ Local file in an Electron app (click to show) + +`readFile` can be used in the renderer process: + +```js +/* From the renderer process */ +var XLSX = require("xlsx"); + +var workbook = XLSX.readFile(path); +``` + +Electron APIs have changed over time. The [`electron` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/electron/) +shows a complete example and details the required version-specific settings. + +
+ +
+ Local file in a mobile app with React Native (click to show) + +The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes a sample React Native app. + +Since React Native does not provide a way to read files from the filesystem, a +third-party library must be used. The following libraries have been tested: + +- [`react-native-file-access`](https://npm.im/react-native-file-access) + +The `base64` encoding returns strings compatible with the `base64` type: + +```js +import XLSX from "xlsx"; +import { FileSystem } from "react-native-file-access"; + +const b64 = await FileSystem.readFile(path, "base64"); +/* b64 is a base64 string */ +const workbook = XLSX.read(b64, {type: "base64"}); +``` + +- [`react-native-fs`](https://npm.im/react-native-fs) + +The `ascii` encoding returns binary strings compatible with the `binary` type: + +```js +import XLSX from "xlsx"; +import { readFile } from "react-native-fs"; + +const bstr = await readFile(path, "ascii"); +/* bstr is a binary string */ +const workbook = XLSX.read(bstr, {type: "binary"}); +``` + +
+ +
+ NodeJS Server File Uploads (click to show) + +`read` can accept a NodeJS buffer. `readFile` can read files generated by a +HTTP POST request body parser like [`formidable`](https://npm.im/formidable): + +```js +const XLSX = require("xlsx"); +const http = require("http"); +const formidable = require("formidable"); + +const server = http.createServer((req, res) => { + const form = new formidable.IncomingForm(); + form.parse(req, (err, fields, files) => { + /* grab the first file */ + const f = Object.entries(files)[0][1]; + const path = f.filepath; + const workbook = XLSX.readFile(path); + + /* DO SOMETHING WITH workbook HERE */ + }); +}).listen(process.env.PORT || 7262); +``` + +The [`server` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/server) has more advanced examples. + +
+ +
+ Download files in a NodeJS process (click to show) + +Node 17.5 and 18.0 have native support for fetch: + +```js +const XLSX = require("xlsx"); + +const data = await (await fetch(url)).arrayBuffer(); +/* data is an ArrayBuffer */ +const workbook = XLSX.read(data); +``` + +For broader compatibility, third-party modules are recommended. + +[`request`](https://npm.im/request) requires a `null` encoding to yield Buffers: + +```js +var XLSX = require("xlsx"); +var request = require("request"); + +request({url: url, encoding: null}, function(err, resp, body) { + var workbook = XLSX.read(body); + + /* DO SOMETHING WITH workbook HERE */ +}); +``` + +[`axios`](https://npm.im/axios) works the same way in browser and in NodeJS: + +```js +const XLSX = require("xlsx"); +const axios = require("axios"); + +(async() => { + const res = await axios.get(url, {responseType: "arraybuffer"}); + /* res.data is a Buffer */ + const workbook = XLSX.read(res.data); + + /* DO SOMETHING WITH workbook HERE */ +})(); +``` + +
+ +
+ Download files in an Electron app (click to show) + +The `net` module in the main process can make HTTP/HTTPS requests to external +resources. Responses should be manually concatenated using `Buffer.concat`: + +```js +const XLSX = require("xlsx"); +const { net } = require("electron"); + +const req = net.request(url); +req.on("response", (res) => { + const bufs = []; // this array will collect all of the buffers + res.on("data", (chunk) => { bufs.push(chunk); }); + res.on("end", () => { + const workbook = XLSX.read(Buffer.concat(bufs)); + + /* DO SOMETHING WITH workbook HERE */ + }); +}); +req.end(); +``` + +
+ +
+ Readable Streams in NodeJS (click to show) + +When dealing with Readable Streams, the easiest approach is to buffer the stream +and process the whole thing at the end: + +```js +var fs = require("fs"); +var XLSX = require("xlsx"); + +function process_RS(stream, cb) { + 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); + }); +} +``` + +
+ +
+ ReadableStream in the browser (click to show) + +When dealing with `ReadableStream`, the easiest approach is to buffer the stream +and process the whole thing at the end: + +```js +// XLSX is a global from the standalone script + +async function process_RS(stream) { + /* collect data */ + const buffers = []; + const reader = stream.getReader(); + for(;;) { + const res = await reader.read(); + if(res.value) buffers.push(res.value); + if(res.done) break; + } + + /* concat */ + const out = new Uint8Array(buffers.reduce((acc, v) => acc + v.length, 0)); + + let off = 0; + for(const u8 of buffers) { + out.set(u8, off); + off += u8.length; + } + + return out; +} + +const data = await process_RS(stream); +/* data is Uint8Array */ +const workbook = XLSX.read(data, {type: 'array'}); +``` + +
+ +More detailed examples are covered in the [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) + +## Processing JSON and JS Data + +JSON and JS data tend to represent single worksheets. This section will use a +few utility functions to generate workbooks. + +_Create a new Workbook_ + +```js +var workbook = XLSX.utils.book_new(); +``` + +The `book_new` utility function creates an empty workbook with no worksheets. + +Spreadsheet software generally require at least one worksheet and enforce the +requirement in the user interface. This library enforces the requirement at +write time, throwing errors if an empty workbook is passed to write functions. + + +#### API + +_Create a worksheet from an array of arrays of JS values_ + +```js +var worksheet = XLSX.utils.aoa_to_sheet(aoa, opts); +``` + +The `aoa_to_sheet` utility function walks an "array of arrays" in row-major +order, generating a worksheet object. The following snippet generates a sheet +with cell `A1` set to the string `A1`, cell `B1` set to `B1`, etc: + +```js +var worksheet = XLSX.utils.aoa_to_sheet([ + ["A1", "B1", "C1"], + ["A2", "B2", "C2"], + ["A3", "B3", "C3"] +]); +``` + +["Array of Arrays Input"](../api/utilities#array-of-arrays-input) describes the function and the +optional `opts` argument in more detail. + + +_Create a worksheet from an array of JS objects_ + +```js +var worksheet = XLSX.utils.json_to_sheet(jsa, opts); +``` + +The `json_to_sheet` utility function walks an array of JS objects in order, +generating a worksheet object. By default, it will generate a header row and +one row per object in the array. The optional `opts` argument has settings to +control the column order and header output. + +["Array of Objects Input"](../api/utilities#array-of-objects-input) describes the function and +the optional `opts` argument in more detail. + +#### Examples + +["Complete Example"](../example) contains a detailed example "Get Data +from a JSON Endpoint and Generate a Workbook" + + +[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive +data grid for previewing and modifying structured data in the web browser. The +[`xspreadsheet` demo](https://github.com/sheetjs/sheetjs/tree/master/demos/xspreadsheet) includes a sample script with the +`xtos` function for converting from x-spreadsheet data object to a workbook. + is a live demo. + +
+ Records from a database query (SQL or no-SQL) (click to show) + +The [`database` demo](https://github.com/sheetjs/sheetjs/tree/master/demos/database/) includes examples of working with +databases and query results. + +
+ + +
+ Numerical Computations with TensorFlow.js (click to show) + +`@tensorflow/tfjs` and other libraries expect data in simple arrays, well-suited +for worksheets where each column is a data vector. That is the transpose of how +most people use spreadsheets, where each row is a vector. + +When recovering data from `tfjs`, the returned data points are stored in a typed +array. An array of arrays can be constructed with loops. `Array#unshift` can +prepend a title row before the conversion: + +```js +const XLSX = require("xlsx"); +const tf = require('@tensorflow/tfjs'); + +/* suppose xs and ys are vectors (1D tensors) -> tfarr will be a typed array */ +const tfdata = tf.stack([xs, ys]).transpose(); +const shape = tfdata.shape; +const tfarr = tfdata.dataSync(); + +/* construct the array of arrays */ +const aoa = []; +for(let j = 0; j < shape[0]; ++j) { + aoa[j] = []; + for(let i = 0; i < shape[1]; ++i) aoa[j][i] = tfarr[j * shape[1] + i]; +} +/* add headers to the top */ +aoa.unshift(["x", "y"]); + +/* generate worksheet */ +const worksheet = XLSX.utils.aoa_to_sheet(aoa); +``` + +The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) shows a complete example. + +
+ + +## Processing HTML Tables + +#### API + +_Create a worksheet by scraping an HTML TABLE in the page_ + +```js +var worksheet = XLSX.utils.table_to_sheet(dom_element, opts); +``` + +The `table_to_sheet` utility function takes a DOM TABLE element and iterates +through the rows to generate a worksheet. The `opts` argument is optional. +["HTML Table Input"](../api/utilities#html-table-input) describes the function in more detail. + + + +_Create a workbook by scraping an HTML TABLE in the page_ + +```js +var workbook = XLSX.utils.table_to_book(dom_element, opts); +``` + +The `table_to_book` utility function follows the same logic as `table_to_sheet`. +After generating a worksheet, it creates a blank workbook and appends the +spreadsheet. + +The options argument supports the same options as `table_to_sheet`, with the +addition of a `sheet` property to control the worksheet name. If the property +is missing or no options are specified, the default name `Sheet1` is used. + +#### Examples + +Here are a few common scenarios (click on each subtitle to see the code): + +
+ HTML TABLE element in a webpage (click to show) + +```html + + + + + + + + +
SheetJS
1234567
+ + + +``` + +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 sheet1 = XLSX.utils.table_to_sheet(document.getElementById("table1")); +XLSX.utils.book_append_sheet(workbook, sheet1, "Sheet1"); + +/* convert table "table2" to worksheet named "Sheet2" */ +var sheet2 = XLSX.utils.table_to_sheet(document.getElementById("table2")); +XLSX.utils.book_append_sheet(workbook, sheet2, "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"}); +``` + +
+ +
+ Chrome/Chromium Extension (click to show) + +The [`chrome` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/) shows a complete example and details the +required permissions and other settings. + +In an extension, it is recommended to generate the workbook in a content script +and pass the object back to the extension: + +```js +/* in the worker script */ +chrome.runtime.onMessage.addListener(function(msg, sender, cb) { + /* pass a message like { sheetjs: true } from the extension to scrape */ + if(!msg || !msg.sheetjs) return; + /* create a new workbook */ + var workbook = XLSX.utils.book_new(); + /* loop through each table element */ + var tables = document.getElementsByTagName("table") + for(var i = 0; i < tables.length; ++i) { + var worksheet = XLSX.utils.table_to_sheet(tables[i]); + XLSX.utils.book_append_sheet(workbook, worksheet, "Table" + i); + } + /* pass back to the extension */ + return cb(workbook); +}); +``` + +
+ +
+ Server-Side HTML Tables with Headless Chrome (click to show) + +The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML +files to XLSB workbooks. The core idea is to add the script to the page, parse +the table in the page context, generate a `base64` workbook and send it back +for further processing: + +```js +const XLSX = require("xlsx"); +const { readFileSync } = require("fs"), puppeteer = require("puppeteer"); + +const url = `https://sheetjs.com/demos/table`; + +/* get the standalone build source (node_modules/xlsx/dist/xlsx.full.min.js) */ +const lib = readFileSync(require.resolve("xlsx/dist/xlsx.full.min.js"), "utf8"); + +(async() => { + /* start browser and go to web page */ + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + await page.goto(url, {waitUntil: "networkidle2"}); + + /* inject library */ + await page.addScriptTag({content: lib}); + + /* this function `s5s` will be called by the script below, receiving the Base64-encoded file */ + await page.exposeFunction("s5s", async(b64) => { + const workbook = XLSX.read(b64, {type: "base64" }); + + /* DO SOMETHING WITH workbook HERE */ + }); + + /* generate XLSB file in webpage context and send back result */ + await page.addScriptTag({content: ` + /* call table_to_book on first table */ + var workbook = XLSX.utils.table_to_book(document.querySelector("TABLE")); + + /* generate XLSX file */ + var b64 = XLSX.write(workbook, {type: "base64", bookType: "xlsb"}); + + /* call "s5s" hook exposed from the node process */ + window.s5s(b64); + `}); + + /* cleanup */ + await browser.close(); +})(); +``` + +
+ +
+ Server-Side HTML Tables with Headless WebKit (click to show) + +The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML +files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). The core idea +is to add the script to the page, parse the table in the page context, generate +a `binary` workbook and send it back for further processing: + +```js +var XLSX = require('xlsx'); +var page = require('webpage').create(); + +/* this code will be run in the page */ +var code = [ "function(){", + /* call table_to_book on first table */ + "var wb = XLSX.utils.table_to_book(document.body.getElementsByTagName('table')[0]);", + + /* generate XLSB file and return binary string */ + "return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});", +"}" ].join(""); + +page.open('https://sheetjs.com/demos/table', function() { + /* Load the browser script from the UNPKG CDN */ + page.includeJs("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", function() { + /* The code will return an XLSB file encoded as binary string */ + var bin = page.evaluateJavaScript(code); + + var workbook = XLSX.read(bin, {type: "binary"}); + /* DO SOMETHING WITH workbook HERE */ + + phantom.exit(); + }); +}); +``` + +
+ +
+ NodeJS HTML Tables without a browser (click to show) + +NodeJS does not include a DOM implementation and Puppeteer requires a hefty +Chromium build. [`jsdom`](https://npm.im/jsdom) is a lightweight alternative: + +```js +const XLSX = require("xlsx"); +const { readFileSync } = require("fs"); +const { JSDOM } = require("jsdom"); + +/* obtain HTML string. This example reads from test.html */ +const html_str = fs.readFileSync("test.html", "utf8"); +/* get first TABLE element */ +const doc = new JSDOM(html_str).window.document.querySelector("table"); +/* generate workbook */ +const workbook = XLSX.utils.table_to_book(doc); +``` + +
diff --git a/docz/docs/06-solutions/03-processing.md b/docz/docs/06-solutions/03-processing.md new file mode 100644 index 0000000..1324970 --- /dev/null +++ b/docz/docs/06-solutions/03-processing.md @@ -0,0 +1,139 @@ +--- +sidebar_position: 3 +--- + +# Data Processing + +The ["Common Spreadsheet Format"](../csf/general) is a simple object +representation of the core concepts of a workbook. The utility functions work +with the object representation and are intended to handle common use cases. + +## Modifying Workbook Structure + +#### API + +_Append a Worksheet to a Workbook_ + +```js +XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name); +``` + +The `book_append_sheet` utility function appends a worksheet to the workbook. +The third argument specifies the desired worksheet name. Multiple worksheets can +be added to a workbook by calling the function multiple times. If the worksheet +name is already used in the workbook, it will throw an error. + +_Append a Worksheet to a Workbook and find a unique name_ + +```js +var new_name = XLSX.utils.book_append_sheet(workbook, worksheet, name, true); +``` + +If the fourth argument is `true`, the function will start with the specified +worksheet name. If the sheet name exists in the workbook, a new worksheet name +will be chosen by finding the name stem and incrementing the counter: + +```js +XLSX.utils.book_append_sheet(workbook, sheetA, "Sheet2", true); // Sheet2 +XLSX.utils.book_append_sheet(workbook, sheetB, "Sheet2", true); // Sheet3 +XLSX.utils.book_append_sheet(workbook, sheetC, "Sheet2", true); // Sheet4 +XLSX.utils.book_append_sheet(workbook, sheetD, "Sheet2", true); // Sheet5 +``` + +_List the Worksheet names in tab order_ + +```js +var wsnames = workbook.SheetNames; +``` + +The `SheetNames` property of the workbook object is a list of the worksheet +names in "tab order". API functions will look at this array. + +_Replace a Worksheet in place_ + +```js +workbook.Sheets[sheet_name] = new_worksheet; +``` + +The `Sheets` property of the workbook object is an object whose keys are names +and whose values are worksheet objects. By reassigning to a property of the +`Sheets` object, the worksheet object can be changed without disrupting the +rest of the worksheet structure. + +#### Examples + +
+ Add a new worksheet to a workbook (click to show) + +This example uses [`XLSX.utils.aoa_to_sheet`](../api/utilities#array-of-arrays-input). + +```js +var ws_name = "SheetJS"; + +/* Create worksheet */ +var ws_data = [ + [ "S", "h", "e", "e", "t", "J", "S" ], + [ 1 , 2 , 3 , 4 , 5 ] +]; +var ws = XLSX.utils.aoa_to_sheet(ws_data); + +/* Add the worksheet to the workbook */ +XLSX.utils.book_append_sheet(wb, ws, ws_name); +``` + +
+ +## Modifying Cell Values + +#### API + +_Modify a single cell value in a worksheet_ + +```js +XLSX.utils.sheet_add_aoa(worksheet, [[new_value]], { origin: address }); +``` + +_Modify multiple cell values in a worksheet_ + +```js +XLSX.utils.sheet_add_aoa(worksheet, aoa, opts); +``` + +The `sheet_add_aoa` utility function modifies cell values in a worksheet. The +first argument is the worksheet object. The second argument is an array of +arrays of values. The `origin` key of the third argument controls where cells +will be written. The following snippet sets `B3=1` and `E5="abc"`: + +```js +XLSX.utils.sheet_add_aoa(worksheet, [ + [1], // <-- Write 1 to cell B3 + , // <-- Do nothing in row 4 + [/*B5*/, /*C5*/, /*D5*/, "abc"] // <-- Write "abc" to cell E5 +], { origin: "B3" }); +``` + +["Array of Arrays Input"](../api/utilities#array-of-arrays-input) describes the +function and the optional `opts` argument in more detail. + +#### Examples + +
+ Appending rows to a worksheet (click to show) + +The special origin value `-1` instructs `sheet_add_aoa` to start in column A of +the row after the last row in the range, appending the data: + +```js +XLSX.utils.sheet_add_aoa(worksheet, [ + ["first row after data", 1], + ["second row after data", 2] +], { origin: -1 }); +``` + +
+ +## Modifying Other Worksheet / Workbook / Cell Properties + +The ["Common Spreadsheet Format"](../csf/general) section describes +the object structures in greater detail. + diff --git a/docz/docs/06-solutions/05-output.md b/docz/docs/06-solutions/05-output.md new file mode 100644 index 0000000..de35e6a --- /dev/null +++ b/docz/docs/06-solutions/05-output.md @@ -0,0 +1,624 @@ +--- +sidebar_position: 5 +--- + +# Data Export + +## Writing Workbooks + +#### API + +_Generate spreadsheet bytes (file) from data_ + +```js +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"](../api/write-options) +covers the supported properties and behaviors. + +_Generate and attempt to save file_ + +```js +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 `writeFile` method uses platform-specific APIs to initiate the file save. In +NodeJS, `fs.readFileSync` can create a file. In the web browser, a download is +attempted using the HTML5 `download` attribute, with fallbacks for IE. + +_Generate and attempt to save an XLSX file_ + +```js +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"](../api/write-options) +covers the supported properties and behaviors. + +#### Examples + +
+ Local file in a NodeJS server (click to show) + +`writeFile` uses `fs.writeFileSync` in server environments: + +```js +var XLSX = require("xlsx"); + +/* output format determined by filename */ +XLSX.writeFile(workbook, "out.xlsb"); +``` + +For Node ESM, the `writeFile` helper is not enabled. Instead, `fs.writeFileSync` +should be used to write the file data to a `Buffer` for use with `XLSX.write`: + +```js +import { writeFileSync } from "fs"; +import { write } from "xlsx/xlsx.mjs"; + +const buf = write(workbook, {type: "buffer", bookType: "xlsb"}); +/* buf is a Buffer */ +const workbook = writeFileSync("out.xlsb", buf); +``` + +
+ +
+ Local file in a Deno application (click to show) + +`writeFile` uses `Deno.writeFileSync` under the hood: + +```js +// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts" +import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs' + +XLSX.writeFile(workbook, "test.xlsx"); +``` + +Applications writing files must be invoked with the `--allow-write` flag. The +[`deno` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/deno/) has more examples + +
+ +
+ Local file in a PhotoShop or InDesign plugin (click to show) + +`writeFile` wraps the `File` logic in Photoshop and other ExtendScript targets. +The specified path should be an absolute path: + +```js +#include "xlsx.extendscript.js" + +/* output format determined by filename */ +XLSX.writeFile(workbook, "out.xlsx"); +/* at this point, out.xlsx is a file that you can distribute */ +``` + +The [`extendscript` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/extendscript/) includes a more complex example. + +
+ +
+ Download a file in the browser to the user machine (click to show) + +`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. + +```js +/* output format determined by filename */ +XLSX.writeFile(workbook, "out.xlsb"); +/* at this point, out.xlsb will have been downloaded */ +``` + +
+ +
+ Download a file in legacy browsers (click to show) + +`XLSX.writeFile` techniques work for most modern browsers as well as older IE. +For much older browsers, there are workarounds implemented by wrapper libraries. + +[`FileSaver.js`](https://github.com/eligrey/FileSaver.js/) implements `saveAs`. +Note: `XLSX.writeFile` will automatically call `saveAs` if available. + +```js +/* bookType can be any supported output type */ +var wopts = { bookType:"xlsx", bookSST:false, type:"array" }; + +var wbout = XLSX.write(workbook,wopts); + +/* the saveAs call downloads a file on the local machine */ +saveAs(new Blob([wbout],{type:"application/octet-stream"}), "test.xlsx"); +``` + +[`Downloadify`](https://github.com/dcneiner/downloadify) uses a Flash SWF button +to generate local files, suitable for environments where ActiveX is unavailable: + +```js +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](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario. + +
+ +
+ Browser upload file (ajax) (click to show) + +A complete example using XHR is [included in the XHR demo](https://github.com/SheetJS/SheetJS/tree/master/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); + +var req = new XMLHttpRequest(); +req.open("POST", "/upload", true); +var formdata = new FormData(); +formdata.append("file", "test.xlsx"); // <-- server expects `file` to hold name +formdata.append("data", wbout); // <-- `data` holds the base64-encoded data +req.send(formdata); +``` + +
+ +
+ PhantomJS (Headless Webkit) File Generation (click to show) + +The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML +files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). PhantomJS +`fs.write` supports writing files from the main process but has a different +interface from the NodeJS `fs` module: + +```js +var XLSX = require('xlsx'); +var fs = require('fs'); + +/* generate a binary string */ +var bin = XLSX.write(workbook, { type:"binary", bookType: "xlsx" }); +/* write to file */ +fs.write("test.xlsx", bin, "wb"); +``` + +Note: The section ["Processing HTML Tables"](./input#processing-html-tables) shows how +to generate a workbook from HTML tables in a page in "Headless WebKit". + +
+ + + +The [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/) cover mobile apps and other special deployments. + +### Writing Examples + +- exporting an HTML table +- generates a simple file + +### 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`. + +
+ nodejs convert to CSV and write file (click to show) + +```js +var output_file_name = "out.csv"; +var stream = XLSX.stream.to_csv(worksheet); +stream.pipe(fs.createWriteStream(output_file_name)); +``` + +
+ +
+ nodejs write JSON stream to screen (click to show) + +```js +/* to_json returns an object-mode stream */ +var stream = XLSX.stream.to_json(worksheet, {raw:true}); + +/* the following stream converts JS objects to text via JSON.stringify */ +var conv = new Transform({writableObjectMode:true}); +conv._transform = function(obj, e, cb){ cb(null, JSON.stringify(obj) + "\n"); }; + +stream.pipe(conv); conv.pipe(process.stdout); +``` + +
+ +
+ Exporting NUMBERS files (click to show) + +The NUMBERS writer requires a fairly large base. The supplementary `xlsx.zahl` +scripts provide support. `xlsx.zahl.js` is designed for standalone and NodeJS +use, while `xlsx.zahl.mjs` is suitable for ESM. + +_Browser_ + +```html + + + + +``` + +_Node_ + +```js +var XLSX = require("./xlsx.flow"); +var XLSX_ZAHL = require("./dist/xlsx.zahl"); +var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([ + ["SheetJS", "<3","விரிதாள்"], + [72,,"Arbeitsblätter"], + [,62,"数据"], + [true,false,], +]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); +XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true}); +``` + +_Deno_ + +```ts +import * as XLSX from './xlsx.mjs'; +import XLSX_ZAHL from './dist/xlsx.zahl.mjs'; + +var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([ + ["SheetJS", "<3","விரிதாள்"], + [72,,"Arbeitsblätter"], + [,62,"数据"], + [true,false,], +]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); +XLSX.writeFile(wb, "textports.numbers", {numbers: XLSX_ZAHL, compression: true}); +``` + +
+ + pipes write streams to nodejs response. + +### 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"](../csf/general) 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_ + +```js +var jsa = XLSX.utils.sheet_to_json(worksheet, opts); +``` + +_Create an array of arrays of JS values from a worksheet_ + +```js +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 +["JSON"](../api/utilities#json) section describes the argument in more detail. + +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 + +[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive +data grid for previewing and modifying structured data in the web browser. The +[`xspreadsheet` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet) includes a sample script with the +`stox` function for converting from a workbook to x-spreadsheet data object. + is a live demo. + +
+ Previewing data in a React data grid (click to show) + +[`react-data-grid`](https://npm.im/react-data-grid) is a data grid tailored for +react. It expects two properties: `rows` of data objects and `columns` which +describe the columns. For the purposes of massaging the data to fit the react +data grid API it is easiest to start from an array of arrays. + +This demo starts by fetching a remote file and using `XLSX.read` to extract: + +```js +import { useEffect, useState } from "react"; +import DataGrid from "react-data-grid"; +import { read, utils } from "xlsx"; + +const url = "https://oss.sheetjs.com/test_files/RkNumber.xls"; + +export default function App() { + const [columns, setColumns] = useState([]); + const [rows, setRows] = useState([]); + useEffect(() => {(async () => { + const wb = read(await (await fetch(url)).arrayBuffer(), { WTF: 1 }); + + /* use sheet_to_json with header: 1 to generate an array of arrays */ + const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 }); + + /* see react-data-grid docs to understand the shape of the expected data */ + setColumns(data[0].map((r) => ({ key: r, name: r }))); + setRows(data.slice(1).map((r) => r.reduce((acc, x, i) => { + acc[data[0][i]] = x; + return acc; + }, {}))); + })(); }); + + return ; +} +``` + +
+ +
+ Previewing data in a VueJS data grid (click to show) + +[`vue3-table-lite`](https://github.com/linmasahiro/vue3-table-lite) is a simple +VueJS 3 data table. It is featured [in the VueJS demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/). + +
+ +
+ Populating a database (SQL or no-SQL) (click to show) + +The [`database` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) includes examples of working with +databases and query results. + +
+ +
+ Numerical Computations with TensorFlow.js (click to show) + +`@tensorflow/tfjs` and other libraries expect data in simple arrays, well-suited +for worksheets where each column is a data vector. That is the transpose of how +most people use spreadsheets, where each row is a vector. + +A single `Array#map` can pull individual named rows from `sheet_to_json` export: + +```js +const XLSX = require("xlsx"); +const tf = require('@tensorflow/tfjs'); + +const key = "age"; // this is the field we want to pull +const ages = XLSX.utils.sheet_to_json(worksheet).map(r => r[key]); +const tf_data = tf.tensor1d(ages); +``` + +All fields can be processed at once using a transpose of the 2D tensor generated +with the `sheet_to_json` export with `header: 1`. The first row, if it contains +header labels, should be removed with a slice: + +```js +const XLSX = require("xlsx"); +const tf = require('@tensorflow/tfjs'); + +/* array of arrays of the data starting on the second row */ +const aoa = XLSX.utils.sheet_to_json(worksheet, {header: 1}).slice(1); +/* dataset in the "correct orientation" */ +const tf_dataset = tf.tensor2d(aoa).transpose(); +/* pull out each dataset with a slice */ +const tf_field0 = tf_dataset.slice([0,0], [1,tensor.shape[1]]).flatten(); +const tf_field1 = tf_dataset.slice([1,0], [1,tensor.shape[1]]).flatten(); +``` + +The [`array` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/array/) shows a complete example. + +
+ + +### Generating HTML Tables + +#### API + +_Generate HTML Table from Worksheet_ + +```js +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 `` 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`: + +```js +var container = document.getElementById("tavolo"); +container.innerHTML = XLSX.utils.sheet_to_html(worksheet); +``` + +Combining with `fetch`, constructing a site from a workbook is straightforward: + +
+ Vanilla JS + HTML fetch workbook and generate table previews (click to show) + +```html + + +
+ + + +``` + +
+ +
+ React fetch workbook and generate HTML table previews (click to show) + +It is generally recommended to use a React-friendly workflow, but it is possible +to generate HTML and use it in React with `dangerouslySetInnerHTML`: + +```jsx +function Tabeller(props) { + /* the workbook object is the state */ + const [workbook, setWorkbook] = React.useState(XLSX.utils.book_new()); + + /* fetch and update the workbook with an effect */ + React.useEffect(() => { (async() => { + /* fetch and parse workbook -- see the fetch example for details */ + const wb = XLSX.read(await (await fetch("sheetjs.xlsx")).arrayBuffer()); + setWorkbook(wb); + })(); }); + + return workbook.SheetNames.map(name => (<> +

name

+
+ )); +} +``` + +The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes more React examples. + +
+ +
+ VueJS fetch workbook and generate HTML table previews (click to show) + +It is generally recommended to use a VueJS-friendly workflow, but it is possible +to generate HTML and use it in VueJS with the `v-html` directive: + +```jsx +import { read, utils } from 'xlsx'; +import { reactive } from 'vue'; + +const S5SComponent = { + mounted() { (async() => { + /* fetch and parse workbook -- see the fetch example for details */ + const workbook = read(await (await fetch("sheetjs.xlsx")).arrayBuffer()); + /* loop through the worksheet names in order */ + workbook.SheetNames.forEach(name => { + /* generate HTML from the corresponding worksheets */ + const html = utils.sheet_to_html(workbook.Sheets[name]); + /* add to state */ + this.wb.wb.push({ name, html }); + }); + })(); }, + /* this state mantra is required for array updates to work */ + setup() { return { wb: reactive({ wb: [] }) }; }, + template: ` +
+

{{ ws.name }}

+
+
` +}; +``` + +The [`vuejs` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue) includes more React examples. + +
+ +### Generating Single-Worksheet Snapshots + +The `sheet_to_*` functions accept a worksheet object. + +#### API + +_Generate a CSV from a single worksheet_ + +```js +var csv = XLSX.utils.sheet_to_csv(worksheet, opts); +``` + +This snapshot is designed to replicate the "CSV UTF8 (`.csv`)" output type. +["Delimiter-Separated Output"](../api/utilities#delimiter-separated-output) describes the +function and the optional `opts` argument in more detail. + +_Generate "Text" from a single worksheet_ + +```js +var txt = XLSX.utils.sheet_to_txt(worksheet, opts); +``` + +This snapshot is designed to replicate the "UTF16 Text (`.txt`)" output type. +["Delimiter-Separated Output"](../api/utilities#delimiter-separated-output) describes the +function and the optional `opts` argument in more detail. + +_Generate a list of formulae from a single worksheet_ + +```js +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"](../api/utilities#formulae-output) describes the function in more detail. diff --git a/docz/docs/06-solutions/_category_.json b/docz/docs/06-solutions/_category_.json new file mode 100644 index 0000000..aa99f52 --- /dev/null +++ b/docz/docs/06-solutions/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Common Use Cases", + "position": 6 +} diff --git a/docz/docs/07-csf/01-general.md b/docz/docs/07-csf/01-general.md new file mode 100644 index 0000000..24400af --- /dev/null +++ b/docz/docs/07-csf/01-general.md @@ -0,0 +1,150 @@ +--- +sidebar_position: 1 +--- + +# Core Concepts + +The "Common Spreadsheet Format" (CSF) is the object model used by SheetJS. + +## Cell Addresses and Ranges + +Cell address objects are stored as `{c:C, r:R}` where `C` and `R` are 0-indexed +column and row numbers, respectively. For example, the cell address `B5` is +represented by the object `{c:1, r:4}`. + +Cell range objects are stored as `{s:S, e:E}` where `S` is the first cell and +`E` is the last cell in the range. The ranges are inclusive. For example, the +range `A3:B7` is represented by the object `{s:{c:0, r:2}, e:{c:1, r:6}}`. +Utility functions perform a row-major order walk traversal of a sheet range: + +```js +for(var R = range.s.r; R <= range.e.r; ++R) { + for(var C = range.s.c; C <= range.e.c; ++C) { + var cell_address = {c:C, r:R}; + /* if an A1-style address is needed, encode the address */ + var cell_ref = XLSX.utils.encode_cell(cell_address); + } +} +``` + +## Cell Object + +Cell objects are plain JS objects with keys and values following the convention: + +| Key | Description | +| --- | ---------------------------------------------------------------------- | +| `v` | raw value (see [Data Types](#data-types) section for more info) | +| `w` | formatted text (if applicable) | +| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub | +| `f` | cell formula encoded as an A1-style string (if applicable) | +| `F` | range of enclosing array if formula is array formula (if applicable) | +| `D` | if true, array formula is dynamic (if applicable) | +| `r` | rich text encoding (if applicable) | +| `h` | HTML rendering of the rich text (if applicable) | +| `c` | comments associated with the cell | +| `z` | number format string associated with the cell (if requested) | +| `l` | cell hyperlink object (`.Target` holds link, `.Tooltip` is tooltip) | +| `s` | the style/theme of the cell (if applicable) | + +Built-in export utilities (such as the CSV exporter) will use the `w` text if it +is available. To change a value, be sure to delete `cell.w` (or set it to +`undefined`) before attempting to export. The utilities will regenerate the `w` +text from the number format (`cell.z`) and the raw value if possible. + +The actual array formula is stored in the `f` field of the first cell in the +array range. Other cells in the range will omit the `f` field. + +### Data Types + +The raw value is stored in the `v` value property, interpreted based on the `t` +type property. This separation allows for representation of numbers as well as +numeric text. There are 6 valid cell types: + +| Type | Description | +| :--: | :-------------------------------------------------------------------- | +| `b` | Boolean: value interpreted as JS `boolean` | +| `e` | Error: value is a numeric code and `w` property stores common name ** | +| `n` | Number: value is a JS `number` ** | +| `d` | Date: value is a JS `Date` object or string to be parsed as Date ** | +| `s` | Text: value interpreted as JS `string` and written as text ** | +| `z` | Stub: blank stub cell that is ignored by data processing utilities ** | + +
+ Error values and interpretation (click to show) + +| Value | Error Meaning | +| -----: | :-------------- | +| `0x00` | `#NULL!` | +| `0x07` | `#DIV/0!` | +| `0x0F` | `#VALUE!` | +| `0x17` | `#REF!` | +| `0x1D` | `#NAME?` | +| `0x24` | `#NUM!` | +| `0x2A` | `#N/A` | +| `0x2B` | `#GETTING_DATA` | + +
+ +Type `n` is the Number type. This includes all forms of data that Excel stores +as numbers, such as dates/times and Boolean fields. Excel exclusively uses data +that can be fit in an IEEE754 floating point number, just like JS Number, so the +`v` field holds the raw number. The `w` field holds formatted text. Dates are +stored as numbers by default and converted with `XLSX.SSF.parse_date_code`. + +Type `d` is the Date type, generated only when the option `cellDates` is passed. +Since JSON does not have a natural Date type, parsers are generally expected to +store ISO 8601 Date strings like you would get from `date.toISOString()`. On +the other hand, writers and exporters should be able to handle date strings and +JS Date objects. Note that Excel disregards timezone modifiers and treats all +dates in the local timezone. The library does not correct for this error. + +Type `s` is the String type. Values are explicitly stored as text. Excel will +interpret these cells as "number stored as text". Generated Excel files +automatically suppress that class of error, but other formats may elicit errors. + +Type `z` represents blank stub cells. They are generated in cases where cells +have no assigned value but hold comments or other metadata. They are ignored by +the core library data processing utility functions. By default these cells are +not generated; the parser `sheetStubs` option must be set to `true`. + + +#### Dates + +
+ Excel Date Code details (click to show) + +By default, Excel stores dates as numbers with a format code that specifies date +processing. For example, the date `19-Feb-17` is stored as the number `42785` +with a number format of `d-mmm-yy`. The `SSF` module understands number formats +and performs the appropriate conversion. + +XLSX also supports a special date type `d` where the data is an ISO 8601 date +string. The formatter converts the date back to a number. + +The default behavior for all parsers is to generate number cells. Setting +`cellDates` to true will force the generators to store dates. + +
+ +
+ Time Zones and Dates (click to show) + +Excel has no native concept of universal time. All times are specified in the +local time zone. Excel limitations prevent specifying true absolute dates. + +Following Excel, this library treats all dates as relative to local time zone. + +
+ +
+ Epochs: 1900 and 1904 (click to show) + +Excel supports two epochs (January 1 1900 and January 1 1904). +The workbook's epoch can be determined by examining the workbook's +`wb.Workbook.WBProps.date1904` property: + +```js +!!(((wb.Workbook||{}).WBProps||{}).date1904) +``` + +
diff --git a/docz/docs/07-csf/02-sheet.md b/docz/docs/07-csf/02-sheet.md new file mode 100644 index 0000000..9d5e6a3 --- /dev/null +++ b/docz/docs/07-csf/02-sheet.md @@ -0,0 +1,144 @@ +--- +sidebar_position: 2 +--- + +# Sheet Objects + +Excel supports 4 different types of "sheets": +- "worksheets": normal sheets +- "chartsheets": full-tab charts +- "macrosheets": legacy (pre-VBA) macros +- "dialogsheets": legacy (pre-VBA) dialogs + +## Generic Sheet Object + +Generic sheets are plain JavaScript objects. Each key that does not start with +`!` is an `A1`-style address whose corresponding value is a cell object. + +`sheet[address]` returns the cell object for the specified address. + +### Sheet Properties + +Each key starts with `!`. The properties are accessible as `sheet[key]`. + +- `sheet['!ref']`: A-1 based range representing the sheet range. Functions that + work with sheets should use this parameter to determine the range. Cells that + are assigned outside of the range are not processed. In particular, when + writing a sheet by hand, cells outside of the range are not included + + Functions that handle sheets should test for the presence of `!ref` field. + If the `!ref` is omitted or is not a valid range, functions are free to treat + the sheet as empty or attempt to guess the range. The standard utilities that + ship with this library treat sheets as empty (for example, the CSV output is + empty string). + + When reading a worksheet with the `sheetRows` property set, the ref parameter + will use the restricted range. The original range is set at `ws['!fullref']` + +- `sheet['!margins']`: Object representing the page margins. The default values + follow Excel's "normal" preset. Excel also has a "wide" and a "narrow" preset + but they are stored as raw measurements. The main properties are listed below: + +
+ Page margin details (click to show) + +| key | description | "normal" | "wide" | "narrow" | +|----------|------------------------|:---------|:-------|:-------- | +| `left` | left margin (inches) | `0.7` | `1.0` | `0.25` | +| `right` | right margin (inches) | `0.7` | `1.0` | `0.25` | +| `top` | top margin (inches) | `0.75` | `1.0` | `0.75` | +| `bottom` | bottom margin (inches) | `0.75` | `1.0` | `0.75` | +| `header` | header margin (inches) | `0.3` | `0.5` | `0.3` | +| `footer` | footer margin (inches) | `0.3` | `0.5` | `0.3` | + +```js +/* Set worksheet sheet to "normal" */ +ws["!margins"]={left:0.7, right:0.7, top:0.75,bottom:0.75,header:0.3,footer:0.3} +/* Set worksheet sheet to "wide" */ +ws["!margins"]={left:1.0, right:1.0, top:1.0, bottom:1.0, header:0.5,footer:0.5} +/* Set worksheet sheet to "narrow" */ +ws["!margins"]={left:0.25,right:0.25,top:0.75,bottom:0.75,header:0.3,footer:0.3} +``` +
+ +## Worksheet Object + +In addition to the aforementioned sheet keys, worksheets also add: + +- `ws['!cols']`: array of column properties objects. Column widths are actually + stored in files in a normalized manner, measured in terms of the "Maximum + Digit Width" (the largest width of the rendered digits 0-9, in pixels). When + parsed, the column objects store the pixel width in the `wpx` field, character + width in the `wch` field, and the maximum digit width in the `MDW` field. + +- `ws['!rows']`: array of row properties objects as explained later in the docs. + Each row object encodes properties including row height and visibility. + +- `ws['!merges']`: array of range objects corresponding to the merged cells in + the worksheet. Plain text formats do not support merge cells. CSV export + will write all cells in the merge range if they exist, so be sure that only + the first cell (upper-left) in the range is set. + +- `ws['!outline']`: configure how outlines should behave. Options default to + the default settings in Excel 2019: + +| key | Excel feature | default | +|:----------|:----------------------------------------------|:--------| +| `above` | Uncheck "Summary rows below detail" | `false` | +| `left` | Uncheck "Summary rows to the right of detail" | `false` | + +- `ws['!protect']`: object of write sheet protection properties. The `password` + key specifies the password for formats that support password-protected sheets + (XLSX/XLSB/XLS). The writer uses the XOR obfuscation method. The following + keys control the sheet protection -- set to `false` to enable a feature when + sheet is locked or set to `true` to disable a feature: + +
+ Worksheet Protection Details (click to show) + +| key | feature (true=disabled / false=enabled) | default | +|:----------------------|:----------------------------------------|:-----------| +| `selectLockedCells` | Select locked cells | enabled | +| `selectUnlockedCells` | Select unlocked cells | enabled | +| `formatCells` | Format cells | disabled | +| `formatColumns` | Format columns | disabled | +| `formatRows` | Format rows | disabled | +| `insertColumns` | Insert columns | disabled | +| `insertRows` | Insert rows | disabled | +| `insertHyperlinks` | Insert hyperlinks | disabled | +| `deleteColumns` | Delete columns | disabled | +| `deleteRows` | Delete rows | disabled | +| `sort` | Sort | disabled | +| `autoFilter` | Filter | disabled | +| `pivotTables` | Use PivotTable reports | disabled | +| `objects` | Edit objects | enabled | +| `scenarios` | Edit scenarios | enabled | +
+ +- `ws['!autofilter']`: AutoFilter object following the schema: + +```typescript +type AutoFilter = { + ref:string; // A-1 based range representing the AutoFilter table range +} +``` + +## Other Sheet Types + +### Chartsheet Object + +Chartsheets are represented as standard sheets. They are distinguished with the +`!type` property set to `"chart"`. + +The underlying data and `!ref` refer to the cached data in the chartsheet. The +first row of the chartsheet is the underlying header. + +### Macrosheet Object + +Macrosheets are represented as standard sheets. They are distinguished with the +`!type` property set to `"macro"`. + +### Dialogsheet Object + +Dialogsheets are represented as standard sheets. They are distinguished with the +`!type` property set to `"dialog"`. diff --git a/docz/docs/07-csf/03-book.md b/docz/docs/07-csf/03-book.md new file mode 100644 index 0000000..c7de881 --- /dev/null +++ b/docz/docs/07-csf/03-book.md @@ -0,0 +1,107 @@ +--- +sidebar_position: 3 +--- + +# Workbook Object + +`workbook.SheetNames` is an ordered list of the sheets in the workbook + +`wb.Sheets[sheetname]` returns an object representing the worksheet. + +`wb.Props` is an object storing the standard properties. `wb.Custprops` stores +custom properties. Since the XLS standard properties deviate from the XLSX +standard, XLS parsing stores core properties in both places. + +`wb.Workbook` stores [workbook-level attributes](#workbook-level-attributes). + +## File Properties + +The various file formats use different internal names for file properties. The +workbook `Props` object normalizes the names: + +
+ File Properties (click to show) + +| JS Name | Excel Description | +|:--------------|:-------------------------------| +| `Title` | Summary tab "Title" | +| `Subject` | Summary tab "Subject" | +| `Author` | Summary tab "Author" | +| `Manager` | Summary tab "Manager" | +| `Company` | Summary tab "Company" | +| `Category` | Summary tab "Category" | +| `Keywords` | Summary tab "Keywords" | +| `Comments` | Summary tab "Comments" | +| `LastAuthor` | Statistics tab "Last saved by" | +| `CreatedDate` | Statistics tab "Created" | + +
+ +For example, to set the workbook title property: + +```js +if(!wb.Props) wb.Props = {}; +wb.Props.Title = "Insert Title Here"; +``` + +Custom properties are added in the workbook `Custprops` object: + +```js +if(!wb.Custprops) wb.Custprops = {}; +wb.Custprops["Custom Property"] = "Custom Value"; +``` + +Writers will process the `Props` key of the options object: + +```js +/* force the Author to be "SheetJS" */ +XLSX.write(wb, {Props:{Author:"SheetJS"}}); +``` + +## Workbook-Level Attributes + +`wb.Workbook` stores workbook-level attributes. + +### Defined Names + +
+ Format Support (click to show) + +**Defined Names**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK + +**Unicode Defined Names**: XLSX/M, XLSB, BIFF8 XLS, XLML + +**Defined Name Comment**: XLSX/M, XLSB, BIFF8 XLS + +
+ +`wb.Workbook.Names` is an array of defined name objects which have the keys: + +| Key | Description | +|:----------|:-----------------------------------------------------------------| +| `Sheet` | Name scope. Sheet Index (0 = first sheet) or `null` (Workbook) | +| `Name` | Case-sensitive name. Standard rules apply ** | +| `Ref` | A1-style Reference (`"Sheet1!$A$1:$D$20"`) | +| `Comment` | Comment (only applicable for XLS/XLSX/XLSB) | + +Excel allows two sheet-scoped defined names to share the same name. However, a +sheet-scoped name cannot collide with a workbook-scope name. Workbook writers +may not enforce this constraint. + +### Workbook Views + +`wb.Workbook.Views` is an array of workbook view objects which have the keys: + +| Key | Description | +|:----------------|:----------------------------------------------------| +| `RTL` | If true, display right-to-left | + +### Miscellaneous Workbook Properties + +`wb.Workbook.WBProps` holds other workbook properties: + +| Key | Description | +|:----------------|:----------------------------------------------------| +| `CodeName` | [VBA Workbook Code Name](./features#vba-and-macros) | +| `date1904` | epoch: 0/false for 1900 system, 1/true for 1904 | +| `filterPrivacy` | Warn or strip personally identifying info on save | diff --git a/docz/docs/07-csf/07-features.md b/docz/docs/07-csf/07-features.md new file mode 100644 index 0000000..6ec46bb --- /dev/null +++ b/docz/docs/07-csf/07-features.md @@ -0,0 +1,701 @@ +--- +sidebar_position: 7 +--- + +# Spreadsheet Features + +Even for basic features like date storage, the official Excel formats store the +same content in different ways. The parsers are expected to convert from the +underlying file format representation to the Common Spreadsheet Format. Writers +are expected to convert from CSF back to the underlying file format. + +## Formulae + +The A1-style formula string is stored in the `f` field. Even though different +file formats store the formulae in different ways, the formats are translated. +Even though some formats store formulae with a leading equal sign, CSF formulae +do not start with `=`. + +
+ Formulae File Format Support (click to show) + +| Storage Representation | Formats | Read | Write | +|:-----------------------|:-------------------------|:-----:|:-----:| +| A1-style strings | XLSX | ✔ | ✔ | +| RC-style strings | XLML and plain text | ✔ | ✔ | +| BIFF Parsed formulae | XLSB and all XLS formats | ✔ | | +| OpenFormula formulae | ODS/FODS/UOS | ✔ | ✔ | +| Lotus Parsed formulae | All Lotus WK_ formats | ✔ | | + +Since Excel prohibits named cells from colliding with names of A1 or RC style +cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed +formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula +formulae can be converted with regular expressions. + +Shared formulae are decompressed and each cell has the formula corresponding to +its cell. Writers generally do not attempt to generate shared formulae. +
+ +### Single-Cell Formulae + +For simple formulae, the `f` key of the desired cell can be set to the actual +formula text. This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`: + +```js +var worksheet = { + "!ref": "A1:A3", + A1: { t:'n', v:1 }, + A2: { t:'n', v:2 }, + A3: { t:'n', v:3, f:'A1+A2' } +}; +``` + +Utilities like `aoa_to_sheet` will accept cell objects in lieu of values: + +```js +var worksheet = XLSX.utils.aoa_to_sheet([ + [ 1 ], // A1 + [ 2 ], // A2 + [ {t: "n", v: 3, f: "A1+A2"} ] // A3 +]); +``` + +Cells with formula entries but no value will be serialized in a way that Excel +and other spreadsheet tools will recognize. This library will not automatically +compute formula results! For example, the following worksheet will include the +`BESSELJ` function but the result will not be available in JavaScript: + +```js +var worksheet = XLSX.utils.aoa_to_sheet([ + [ 3.14159, 2 ], // Row "1" + [ { t:'n', f:'BESSELJ(A1,B1)' } ] // Row "2" will be calculated on file open +} +``` + +If the actual results are needed in JS, [SheetJS Pro](https://sheetjs.com/pro) +offers a formula calculator component for evaluating expressions, updating +values and dependent cells, and refreshing entire workbooks. + + +### Array Formulae + +_Assign an array formula_ + +```js +XLSX.utils.sheet_set_array_formula(worksheet, range, formula); +``` + +Array formulae are stored in the top-left cell of the array block. All cells +of an array formula have a `F` field corresponding to the range. A single-cell +formula can be distinguished from a plain formula by the presence of `F` field. + +For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`: + +```js +// API function +XLSX.utils.sheet_set_array_formula(worksheet, "C1", "SUM(A1:A3*B1:B3)"); + +// ... OR raw operations +worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" }; +``` + +For a multi-cell array formula, every cell has the same array range but only the +first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`: + +```js +// API function +XLSX.utils.sheet_set_array_formula(worksheet, "D1:D3", "A1:A3*B1:B3"); + +// ... OR raw operations +worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" }; +worksheet['D2'] = { t:'n', F:"D1:D3" }; +worksheet['D3'] = { t:'n', F:"D1:D3" }; +``` + +Utilities and writers are expected to check for the presence of a `F` field and +ignore any possible formula element `f` in cells other than the starting cell. +They are not expected to perform validation of the formulae! + + +### Dynamic Arrays + +_Assign a dynamic array formula_ + +```js +XLSX.utils.sheet_set_array_formula(worksheet, range, formula, true); +``` + +Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB +file formats. They are represented like normal array formulae but have special +cell metadata indicating that the formula should be allowed to adjust the range. + +An array formula can be marked as dynamic by setting the cell's `D` property to +true. The `F` range is expected but can be the set to the current cell: + +```js +// API function +XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1); + +// ... OR raw operations +worksheet['C1'] = { t: "s", f: "_xlfn.UNIQUE(A1:A3)", F:"C1", D: 1 }; // dynamic +``` + +### Localization + +SheetJS operates at the file level. Excel stores formula expressions using the +English (United States) function names. For non-English users, Excel uses a +localized set of function names. + +For example, when the computer language and region is set to French (France), +Excel interprets `=SOMME(A1:C3)` as if `SOMME` is the `SUM` function. However, +in the actual file, Excel stores `SUM(A1:C3)`. + +**Prefixed "Future Functions"** + +Functions introduced in newer versions of Excel are prefixed with `_xlfn.` when +stored in files. When writing formula expressions using these functions, the +prefix is required for maximal compatibility: + +```js +// Broadest compatibility +XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1); + +// Can cause errors in spreadsheet software +XLSX.utils.sheet_set_array_formula(worksheet, "C1", "UNIQUE(A1:A3)", 1); +``` + +When reading a file, the `xlfn` option preserves the prefixes. + +
+ Functions requiring `_xlfn.` prefix (click to show) + +This list is growing with each Excel release. + +``` +ACOT +ACOTH +AGGREGATE +ARABIC +BASE +BETA.DIST +BETA.INV +BINOM.DIST +BINOM.DIST.RANGE +BINOM.INV +BITAND +BITLSHIFT +BITOR +BITRSHIFT +BITXOR +BYCOL +BYROW +CEILING.MATH +CEILING.PRECISE +CHISQ.DIST +CHISQ.DIST.RT +CHISQ.INV +CHISQ.INV.RT +CHISQ.TEST +COMBINA +CONFIDENCE.NORM +CONFIDENCE.T +COT +COTH +COVARIANCE.P +COVARIANCE.S +CSC +CSCH +DAYS +DECIMAL +ERF.PRECISE +ERFC.PRECISE +EXPON.DIST +F.DIST +F.DIST.RT +F.INV +F.INV.RT +F.TEST +FIELDVALUE +FILTERXML +FLOOR.MATH +FLOOR.PRECISE +FORMULATEXT +GAMMA +GAMMA.DIST +GAMMA.INV +GAMMALN.PRECISE +GAUSS +HYPGEOM.DIST +IFNA +IMCOSH +IMCOT +IMCSC +IMCSCH +IMSEC +IMSECH +IMSINH +IMTAN +ISFORMULA +ISOMITTED +ISOWEEKNUM +LAMBDA +LET +LOGNORM.DIST +LOGNORM.INV +MAKEARRAY +MAP +MODE.MULT +MODE.SNGL +MUNIT +NEGBINOM.DIST +NORM.DIST +NORM.INV +NORM.S.DIST +NORM.S.INV +NUMBERVALUE +PDURATION +PERCENTILE.EXC +PERCENTILE.INC +PERCENTRANK.EXC +PERCENTRANK.INC +PERMUTATIONA +PHI +POISSON.DIST +QUARTILE.EXC +QUARTILE.INC +QUERYSTRING +RANDARRAY +RANK.AVG +RANK.EQ +REDUCE +RRI +SCAN +SEC +SECH +SEQUENCE +SHEET +SHEETS +SKEW.P +SORTBY +STDEV.P +STDEV.S +T.DIST +T.DIST.2T +T.DIST.RT +T.INV +T.INV.2T +T.TEST +UNICHAR +UNICODE +UNIQUE +VAR.P +VAR.S +WEBSERVICE +WEIBULL.DIST +XLOOKUP +XOR +Z.TEST +``` + +
+ +## Row and Column Properties + +
+ Format Support (click to show) + +**Row Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM, ODS + +**Column Properties**: XLSX/M, XLSB, BIFF8 XLS, XLML, SYLK, DOM + +
+ + +Row and Column properties are not extracted by default when reading from a file +and are not persisted by default when writing to a file. The option +`cellStyles: true` must be passed to the relevant read or write function. + +_Column Properties_ + +The `!cols` array in each worksheet, if present, is a collection of `ColInfo` +objects which have the following properties: + +```typescript +type ColInfo = { + /* visibility */ + hidden?: boolean; // if true, the column is hidden + + /* column width is specified in one of the following ways: */ + wpx?: number; // width in screen pixels + width?: number; // width in Excel's "Max Digit Width", width*256 is integral + wch?: number; // width in characters + + /* other fields for preserving features from files */ + level?: number; // 0-indexed outline / group level + MDW?: number; // Excel's "Max Digit Width" unit, always integral +}; +``` + +_Row Properties_ + +The `!rows` array in each worksheet, if present, is a collection of `RowInfo` +objects which have the following properties: + +```typescript +type RowInfo = { + /* visibility */ + hidden?: boolean; // if true, the row is hidden + + /* row height is specified in one of the following ways: */ + hpx?: number; // height in screen pixels + hpt?: number; // height in points + + level?: number; // 0-indexed outline / group level +}; +``` + +_Outline / Group Levels Convention_ + +The Excel UI displays the base outline level as `1` and the max level as `8`. +Following JS conventions, SheetJS uses 0-indexed outline levels wherein the base +outline level is `0` and the max level is `7`. + +
+ Why are there three width types? (click to show) + +There are three different width types corresponding to the three different ways +spreadsheets store column widths: + +SYLK and other plain text formats use raw character count. Contemporaneous tools +like Visicalc and Multiplan were character based. Since the characters had the +same width, it sufficed to store a count. This tradition was continued into the +BIFF formats. + +SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel +count throughout the file. Column widths, row heights, and other measures use +pixels. When the pixel and character counts do not align, Excel rounds values. + +XLSX internally stores column widths in a nebulous "Max Digit Width" form. The +Max Digit Width is the width of the largest digit when rendered (generally the +"0" character is the widest). The internal width must be an integer multiple of +the the width divided by 256. ECMA-376 describes a formula for converting +between pixels and the internal width. This represents a hybrid approach. + +Read functions attempt to populate all three properties. Write functions will +try to cycle specified values to the desired type. In order to avoid potential +conflicts, manipulation should delete the other properties first. For example, +when changing the pixel width, delete the `wch` and `width` properties. +
+ +
+ Implementation details (click to show) + +_Row Heights_ + +Excel internally stores row heights in points. The default resolution is 72 DPI +or 96 PPI, so the pixel and point size should agree. For different resolutions +they may not agree, so the library separates the concepts. + +Even though all of the information is made available, writers are expected to +follow the priority order: + +1) use `hpx` pixel height if available +2) use `hpt` point height if available + +_Column Widths_ + +Given the constraints, it is possible to determine the MDW without actually +inspecting the font! The parsers guess the pixel width by converting from width +to pixels and back, repeating for all possible MDW and selecting the MDW that +minimizes the error. XLML actually stores the pixel width, so the guess works +in the opposite direction. + +Even though all of the information is made available, writers are expected to +follow the priority order: + +1) use `width` field if available +2) use `wpx` pixel width if available +3) use `wch` character count if available + +
+ +## Number Formats + +The `cell.w` formatted text for each cell is produced from `cell.v` and `cell.z` +format. If the format is not specified, the Excel `General` format is used. +The format can either be specified as a string or as an index into the format +table. Parsers are expected to populate `workbook.SSF` with the number format +table. Writers are expected to serialize the table. + +Custom tools should ensure that the local table has each used format string +somewhere in the table. Excel convention mandates that the custom formats start +at index 164. The following example creates a custom format from scratch: + +
+ New worksheet with custom format (click to show) + +```js +var wb = { + SheetNames: ["Sheet1"], + Sheets: { + Sheet1: { + "!ref":"A1:C1", + A1: { t:"n", v:10000 }, // <-- General format + B1: { t:"n", v:10000, z: "0%" }, // <-- Builtin format + C1: { t:"n", v:10000, z: "\"T\"\ #0.00" } // <-- Custom format + } + } +} +``` +
+ +The rules are slightly different from how Excel displays custom number formats. +In particular, literal characters must be wrapped in double quotes or preceded +by a backslash. For more info, see the Excel documentation article +`Create or delete a custom number format` or ECMA-376 18.8.31 (Number Formats) + + +
+ Default Number Formats (click to show) + +The default formats are listed in ECMA-376 18.8.30: + +| ID | Format | +|---:|:---------------------------| +| 0 | `General` | +| 1 | `0` | +| 2 | `0.00` | +| 3 | `#,##0` | +| 4 | `#,##0.00` | +| 9 | `0%` | +| 10 | `0.00%` | +| 11 | `0.00E+00` | +| 12 | `# ?/?` | +| 13 | `# ??/??` | +| 14 | `m/d/yy` (see below) | +| 15 | `d-mmm-yy` | +| 16 | `d-mmm` | +| 17 | `mmm-yy` | +| 18 | `h:mm AM/PM` | +| 19 | `h:mm:ss AM/PM` | +| 20 | `h:mm` | +| 21 | `h:mm:ss` | +| 22 | `m/d/yy h:mm` | +| 37 | `#,##0 ;(#,##0)` | +| 38 | `#,##0 ;[Red](#,##0)` | +| 39 | `#,##0.00;(#,##0.00)` | +| 40 | `#,##0.00;[Red](#,##0.00)` | +| 45 | `mm:ss` | +| 46 | `[h]:mm:ss` | +| 47 | `mmss.0` | +| 48 | `##0.0E+0` | +| 49 | `@` | + +
+ +Format 14 (`m/d/yy`) is localized by Excel: even though the file specifies that +number format, it will be drawn differently based on system settings. It makes +sense when the producer and consumer of files are in the same locale, but that +is not always the case over the Internet. To get around this ambiguity, parse +functions accept the `dateNF` option to override the interpretation of that +specific format string. + +## Hyperlinks + +
+ Format Support (click to show) + +**Cell Hyperlinks**: XLSX/M, XLSB, BIFF8 XLS, XLML, ODS + +**Tooltips**: XLSX/M, XLSB, BIFF8 XLS, XLML + +
+ +Hyperlinks are stored in the `l` key of cell objects. The `Target` field of the +hyperlink object is the target of the link, including the URI fragment. Tooltips +are stored in the `Tooltip` field and are displayed when you move your mouse +over the text. + +For example, the following snippet creates a link from cell `A3` to + with the tip `"Find us @ SheetJS.com!"`: + +```js +ws['A1'].l = { Target:"https://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" }; +``` + +Note that Excel does not automatically style hyperlinks -- they will generally +be displayed as normal text. + +_Remote Links_ + +HTTP / HTTPS links can be used directly: + +```js +ws['A2'].l = { Target:"https://docs.sheetjs.com/#hyperlinks" }; +ws['A3'].l = { Target:"http://localhost:7262/yes_localhost_works" }; +``` + +Excel also supports `mailto` email links with subject line: + +```js +ws['A4'].l = { Target:"mailto:ignored@dev.null" }; +ws['A5'].l = { Target:"mailto:ignored@dev.null?subject=Test Subject" }; +``` + +_Local Links_ + +Links to absolute paths should use the `file://` URI scheme: + +```js +ws['B1'].l = { Target:"file:///SheetJS/t.xlsx" }; /* Link to /SheetJS/t.xlsx */ +ws['B2'].l = { Target:"file:///c:/SheetJS.xlsx" }; /* Link to c:\SheetJS.xlsx */ +``` + +Links to relative paths can be specified without a scheme: + +```js +ws['B3'].l = { Target:"SheetJS.xlsb" }; /* Link to SheetJS.xlsb */ +ws['B4'].l = { Target:"../SheetJS.xlsm" }; /* Link to ../SheetJS.xlsm */ +``` + +Relative Paths have undefined behavior in the SpreadsheetML 2003 format. Excel +2019 will treat a `..\` parent mark as two levels up. + +_Internal Links_ + +Links where the target is a cell or range or defined name in the same workbook +("Internal Links") are marked with a leading hash character: + +```js +ws['C1'].l = { Target:"#E2" }; /* Link to cell E2 */ +ws['C2'].l = { Target:"#Sheet2!E2" }; /* Link to cell E2 in sheet Sheet2 */ +ws['C3'].l = { Target:"#SomeDefinedName" }; /* Link to Defined Name */ +``` + +## Cell Comments + +Cell comments are objects stored in the `c` array of cell objects. The actual +contents of the comment are split into blocks based on the comment author. The +`a` field of each comment object is the author of the comment and the `t` field +is the plain text representation. + +For example, the following snippet appends a cell comment into cell `A1`: + +```js +if(!ws.A1.c) ws.A1.c = []; +ws.A1.c.push({a:"SheetJS", t:"I'm a little comment, short and stout!"}); +``` + +Note: XLSB enforces a 54 character limit on the Author name. Names longer than +54 characters may cause issues with other formats. + +To mark a comment as normally hidden, set the `hidden` property: + +```js +if(!ws.A1.c) ws.A1.c = []; +ws.A1.c.push({a:"SheetJS", t:"This comment is visible"}); + +if(!ws.A2.c) ws.A2.c = []; +ws.A2.c.hidden = true; +ws.A2.c.push({a:"SheetJS", t:"This comment will be hidden"}); +``` + + +_Threaded Comments_ + +Introduced in Excel 365, threaded comments are plain text comment snippets with +author metadata and parent references. They are supported in XLSX and XLSB. + +To mark a comment as threaded, each comment part must have a true `T` property: + +```js +if(!ws.A1.c) ws.A1.c = []; +ws.A1.c.push({a:"SheetJS", t:"This is not threaded"}); + +if(!ws.A2.c) ws.A2.c = []; +ws.A2.c.hidden = true; +ws.A2.c.push({a:"SheetJS", t:"This is threaded", T: true}); +ws.A2.c.push({a:"JSSheet", t:"This is also threaded", T: true}); +``` + +There is no Active Directory or Office 365 metadata associated with authors in a thread. + +## Sheet Visibility + +Excel enables hiding sheets in the lower tab bar. The sheet data is stored in +the file but the UI does not readily make it available. Standard hidden sheets +are revealed in the "Unhide" menu. Excel also has "very hidden" sheets which +cannot be revealed in the menu. It is only accessible in the VB Editor! + +The visibility setting is stored in the `Hidden` property of sheet props array. + +
+ More details (click to show) + +| Value | Definition | +|:-----:|:------------| +| 0 | Visible | +| 1 | Hidden | +| 2 | Very Hidden | + +With : + +```js +> wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] }) +[ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ] +``` + +Non-Excel formats do not support the Very Hidden state. The best way to test +if a sheet is visible is to check if the `Hidden` property is logical truth: + +```js +> wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] }) +[ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ] +``` +
+ +## VBA and Macros + +VBA Macros are stored in a special data blob that is exposed in the `vbaraw` +property of the workbook object when the `bookVBA` option is `true`. They are +supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats. The supported format +writers automatically insert the data blobs if it is present in the workbook and +associate with the worksheet names. + +
+ Custom Code Names (click to show) + +The workbook code name is stored in `wb.Workbook.WBProps.CodeName`. By default, +Excel will write `ThisWorkbook` or a translated phrase like `DieseArbeitsmappe`. +Worksheet and Chartsheet code names are in the worksheet properties object at +`wb.Workbook.Sheets[i].CodeName`. Macrosheets and Dialogsheets are ignored. + +The readers and writers preserve the code names, but they have to be manually +set when adding a VBA blob to a different workbook. + +
+ +
+ Macrosheets (click to show) + +Older versions of Excel also supported a non-VBA "macrosheet" sheet type that +stored automation commands. These are exposed in objects with the `!type` +property set to `"macro"`. + +
+ +
+ Detecting macros in workbooks (click to show) + +The `vbaraw` field will only be set if macros are present, so testing is simple: + +```js +function wb_has_macro(wb/*:workbook*/)/*:boolean*/ { + if(!!wb.vbaraw) return true; + const sheets = wb.SheetNames.map((n) => wb.Sheets[n]); + return sheets.some((ws) => !!ws && ws['!type']=='macro'); +} +``` + +
+ diff --git a/docz/docs/07-csf/_category_.json b/docz/docs/07-csf/_category_.json new file mode 100644 index 0000000..c73cfc9 --- /dev/null +++ b/docz/docs/07-csf/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Common Spreadsheet Format", + "position": 7 +} diff --git a/docz/docs/08-api/05-parse-options.md b/docz/docs/08-api/05-parse-options.md new file mode 100644 index 0000000..4fea085 --- /dev/null +++ b/docz/docs/08-api/05-parse-options.md @@ -0,0 +1,155 @@ +--- +sidebar_position: 5 +hide_table_of_contents: true +title: Reading Files +--- + +# Parsing Options + +`XLSX.read(data, read_opts)` attempts to parse `data`. + +`XLSX.readFile(filename, read_opts)` attempts to read `filename` and parse. + +The read functions accept an options argument: + +| Option Name | Default | Description | +| :---------- | ------: | :--------------------------------------------------- | +|`type` | | Input data encoding (see Input Type below) | +|`raw` | false | If true, plain text parsing will not parse values ** | +|`codepage` | | If specified, use code page when appropriate ** | +|`cellFormula`| true | Save formulae to the .f field | +|`cellHTML` | true | Parse rich text and save HTML to the `.h` field | +|`cellNF` | false | Save number format string to the `.z` field | +|`cellStyles` | false | Save style/theme info to the `.s` field | +|`cellText` | true | Generated formatted text to the `.w` field | +|`cellDates` | false | Store dates as type `d` (default is `n`) | +|`dateNF` | | If specified, use the string for date code 14 ** | +|`sheetStubs` | false | Create cell objects of type `z` for stub cells | +|`sheetRows` | 0 | If >0, read the first `sheetRows` rows ** | +|`bookDeps` | false | If true, parse calculation chains | +|`bookFiles` | false | If true, add raw files to book object ** | +|`bookProps` | false | If true, only parse enough to get book metadata ** | +|`bookSheets` | false | If true, only parse enough to get the sheet names | +|`bookVBA` | false | If true, copy VBA blob to `vbaraw` field ** | +|`password` | "" | If defined and file is encrypted, use password ** | +|`WTF` | false | If true, throw errors on unexpected file features ** | +|`sheets` | | If specified, only parse specified sheets ** | +|`PRN` | false | If true, allow parsing of PRN files ** | +|`xlfn` | false | If true, preserve `_xlfn.` prefixes in formulae ** | +|`FS` | | DSV Field Separator override | + +- Even if `cellNF` is false, formatted text will be generated and saved to `.w` +- In some cases, sheets may be parsed even if `bookSheets` is false. +- Excel aggressively tries to interpret values from CSV and other plain text. + This leads to surprising behavior! The `raw` option suppresses value parsing. +- `bookSheets` and `bookProps` combine to give both sets of information +- `Deps` will be an empty object if `bookDeps` is false +- `bookFiles` behavior depends on file type: + * `keys` array (paths in the ZIP) for ZIP-based formats + * `files` hash (mapping paths to objects representing the files) for ZIP + * `cfb` object for formats using CFB containers +- `sheetRows-1` rows will be generated when looking at the JSON object output + (since the header row is counted as a row when parsing the data) +- By default all worksheets are parsed. `sheets` restricts based on input type: + * number: zero-based index of worksheet to parse (`0` is first worksheet) + * string: name of worksheet to parse (case insensitive) + * array of numbers and strings to select multiple worksheets. +- `bookVBA` merely exposes the raw VBA CFB object. It does not parse the data. + XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`. BIFF8 XLS mixes + the VBA entries alongside the core Workbook entry, so the library generates a + new XLSB-compatible blob from the XLS CFB container. +- `codepage` is applied to BIFF2 - BIFF5 files without `CodePage` records and to + CSV files without BOM in `type:"binary"`. BIFF8 XLS always defaults to 1200. +- `PRN` affects parsing of text files without a common delimiter character. +- Currently only XOR encryption is supported. Unsupported error will be thrown + for files employing other encryption methods. +- Newer Excel functions are serialized with the `_xlfn.` prefix, hidden from the + user. SheetJS will strip `_xlfn.` normally. The `xlfn` option preserves them. +- WTF is mainly for development. By default, the parser will suppress read + errors on single worksheets, allowing you to read from the worksheets that do + parse properly. Setting `WTF:true` forces those errors to be thrown. + +### Input Type + +Strings can be interpreted in multiple ways. The `type` parameter for `read` +tells the library how to parse the data argument: + +| `type` | expected input | +|------------|-----------------------------------------------------------------| +| `"base64"` | string: Base64 encoding of the file | +| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | +| `"string"` | string: JS string (characters interpreted as UTF8) | +| `"buffer"` | nodejs Buffer | +| `"array"` | array: array of 8-bit unsigned int (byte `n` is `data[n]`) | +| `"file"` | string: path of file that will be read (nodejs only) | + +### Guessing File Type + +
+ Implementation Details (click to show) + +Excel and other spreadsheet tools read the first few bytes and apply other +heuristics to determine a file type. This enables file type punning: renaming +files with the `.xls` extension will tell your computer to use Excel to open the +file but Excel will know how to handle it. This library applies similar logic: + +| Byte 0 | Raw File Type | Spreadsheet Types | +|:-------|:--------------|:----------------------------------------------------| +| `0xD0` | CFB Container | BIFF 5/8 or protected XLSX/XLSB or WQ3/QPW or XLR | +| `0x09` | BIFF Stream | BIFF 2/3/4/5 | +| `0x3C` | XML/HTML | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | +| `0x50` | ZIP Archive | XLSB or XLSX/M or ODS or UOS2 or NUMBERS or text | +| `0x49` | Plain Text | SYLK or plain text | +| `0x54` | Plain Text | DIF or plain text | +| `0xEF` | UTF8 Encoded | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | +| `0xFF` | UTF16 Encoded | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | +| `0x00` | Record Stream | Lotus WK\* or Quattro Pro or plain text | +| `0x7B` | Plain text | RTF or plain text | +| `0x0A` | Plain text | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | +| `0x0D` | Plain text | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | +| `0x20` | Plain text | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text | + +DBF files are detected based on the first byte as well as the third and fourth +bytes (corresponding to month and day of the file date) + +Works for Windows files are detected based on the BOF record with type `0xFF` + +Plain text format guessing follows the priority order: + +| Format | Test | +|:-------|:--------------------------------------------------------------------| +| XML | ` + +
+ Why are random text files valid? (click to show) + +Excel is extremely aggressive in reading files. Adding an XLS extension to any +display text file (where the only characters are ANSI display chars) tricks +Excel into thinking that the file is potentially a CSV or TSV file, even if it +is only one column! This library attempts to replicate that behavior. + +The best approach is to validate the desired worksheet and ensure it has the +expected number of rows or columns. Extracting the range is extremely simple: + +```js +var range = XLSX.utils.decode_range(worksheet['!ref']); +var ncols = range.e.c - range.s.c + 1, nrows = range.e.r - range.s.r + 1; +``` + +
+ diff --git a/docz/docs/08-api/07-write-options.md b/docz/docs/08-api/07-write-options.md new file mode 100644 index 0000000..5103e65 --- /dev/null +++ b/docz/docs/08-api/07-write-options.md @@ -0,0 +1,102 @@ +--- +sidebar_position: 7 +hide_table_of_contents: true +title: Writing Files +--- + +# Writing Options + +`XLSX.write(wb, write_opts)` attempts to write the workbook `wb` + +`XLSX.writeFile(wb, filename, write_opts)` attempts to write `wb` to `filename`. +In browser-based environments, it will attempt to force a client-side download. + +`XLSX.writeFileAsync(filename, wb, o, cb)` attempts to write `wb` to `filename`. +If `o` is omitted, the writer will use the third argument as the callback. + +The write functions accept an options argument: + +| Option Name | Default | Description | +| :---------- | -------: | :-------------------------------------------------- | +|`type` | | Output data encoding (see Output Type below) | +|`cellDates` | `false` | Store dates as type `d` (default is `n`) | +|`bookSST` | `false` | Generate Shared String Table ** | +|`bookType` | `"xlsx"` | Type of Workbook (see below for supported formats) | +|`sheet` | `""` | Name of Worksheet for single-sheet formats ** | +|`compression`| `false` | Use ZIP compression for ZIP-based formats ** | +|`Props` | | Override workbook properties when writing ** | +|`themeXLSX` | | Override theme XML when writing XLSX/XLSB/XLSM ** | +|`ignoreEC` | `true` | Suppress "number as text" errors ** | +|`numbers` | | Payload for NUMBERS export ** | + +- `bookSST` is slower and more memory intensive, but has better compatibility + with older versions of iOS Numbers +- The raw data is the only thing guaranteed to be saved. Features not described + in this README may not be serialized. +- `cellDates` only applies to XLSX output and is not guaranteed to work with + third-party readers. Excel itself does not usually write cells with type `d` + so non-Excel tools may ignore the data or error in the presence of dates. +- `Props` is an object mirroring the workbook `Props` field. See the table from + the [Workbook File Properties](../csf/book#file-properties) section. +- if specified, the string from `themeXLSX` will be saved as the primary theme + for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP) +- Due to a bug in the program, some features like "Text to Columns" will crash + Excel on worksheets where error conditions are ignored. The writer will mark + files to ignore the error by default. Set `ignoreEC` to `false` to suppress. +- Due to the size of the data, the NUMBERS data is not included by default. The + included `xlsx.zahl.js` and `xlsx.zahl.mjs` scripts include the data. + +## Supported Output Formats + +For broad compatibility with third-party tools, this library supports many +output formats. The specific file type is controlled with `bookType` option: + +| `bookType` | file ext | container | sheets | Description | +| :--------- | -------: | :-------: | :----- |:------------------------------- | +| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format | +| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format | +| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format | +| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format | +| `biff5` | `.xls` | CFB | multi | Excel 5.0/95 Workbook Format | +| `biff4` | `.xls` | none | single | Excel 4.0 Worksheet Format | +| `biff3` | `.xls` | none | single | Excel 3.0 Worksheet Format | +| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format | +| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) | +| `numbers` |`.numbers`| ZIP | single | Numbers 3.0+ Spreadsheet | +| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet | +| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet | +| `wk3` | `.wk3` | none | multi | Lotus Workbook (WK3) | +| `csv` | `.csv` | none | single | Comma Separated Values | +| `txt` | `.txt` | none | single | UTF-16 Unicode Text (TXT) | +| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) | +| `html` | `.html` | none | single | HTML Document | +| `dif` | `.dif` | none | single | Data Interchange Format (DIF) | +| `dbf` | `.dbf` | none | single | dBASE II + VFP Extensions (DBF) | +| `wk1` | `.wk1` | none | single | Lotus Worksheet (WK1) | +| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) | +| `prn` | `.prn` | none | single | Lotus Formatted Text | +| `eth` | `.eth` | none | single | Ethercalc Record Format (ETH) | + +- `compression` only applies to formats with ZIP containers. +- Formats that only support a single sheet require a `sheet` option specifying + the worksheet. If the string is empty, the first worksheet is used. +- `writeFile` will automatically guess the output file format based on the file + extension if `bookType` is not specified. It will choose the first format in + the aforementioned table that matches the extension. + +## Output Type + +The `type` argument for `write` mirrors the `type` argument for `read`: + +| `type` | output | +|------------|-----------------------------------------------------------------| +| `"base64"` | string: Base64 encoding of the file | +| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | +| `"string"` | string: JS string (characters interpreted as UTF8) | +| `"buffer"` | nodejs Buffer | +| `"array"` | ArrayBuffer, fallback array of 8-bit unsigned int | +| `"file"` | string: path of file that will be created (nodejs only) | + +- For compatibility with Excel, `csv` output will always include the UTF-8 byte + order mark. + diff --git a/docz/docs/08-api/09-utilities.md b/docz/docs/08-api/09-utilities.md new file mode 100644 index 0000000..5e6ada9 --- /dev/null +++ b/docz/docs/08-api/09-utilities.md @@ -0,0 +1,497 @@ +--- +sidebar_position: 9 +--- + + +# Utility Functions + +The `sheet_to_*` functions accept a worksheet and an optional options object. + +The `*_to_sheet` functions accept a data object and an optional options object. + +The examples are based on the following worksheet: + +``` +XXX| A | B | C | D | E | F | G | +---+---+---+---+---+---+---+---+ + 1 | S | h | e | e | t | J | S | + 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | + 3 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | +``` + +### Array of Arrays Input + +`XLSX.utils.aoa_to_sheet` takes an array of arrays of JS values and returns a +worksheet resembling the input data. Numbers, Booleans and Strings are stored +as the corresponding styles. Dates are stored as date or numbers. Array holes +and explicit `undefined` values are skipped. `null` values may be stubbed. All +other values are stored as strings. The function takes an options argument: + +| Option Name | Default | Description | +| :---------- | :-----: | :--------------------------------------------------- | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`cellDates` | false | Store dates as type `d` (default is `n`) | +|`sheetStubs` | false | Create cell objects of type `z` for `null` values | +|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | + +
+ Examples (click to show) + +To generate the example sheet: + +```js +var ws = XLSX.utils.aoa_to_sheet([ + "SheetJS".split(""), + [1,2,3,4,5,6,7], + [2,3,4,5,6,7,8] +]); +``` +
+ +`XLSX.utils.sheet_add_aoa` takes an array of arrays of JS values and updates an +existing worksheet object. It follows the same process as `aoa_to_sheet` and +accepts an options argument: + +| Option Name | Default | Description | +| :---------- | :-----: | :--------------------------------------------------- | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`cellDates` | false | Store dates as type `d` (default is `n`) | +|`sheetStubs` | false | Create cell objects of type `z` for `null` values | +|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | +|`origin` | | Use specified cell as starting point (see below) | + +`origin` is expected to be one of: + +| `origin` | Description | +| :--------------- | :-------------------------------------------------------- | +| (cell object) | Use specified cell (cell object) | +| (string) | Use specified cell (A1-style cell) | +| (number >= 0) | Start from the first column at specified row (0-indexed) | +| -1 | Append to bottom of worksheet starting on first column | +| (default) | Start from cell A1 | + + +
+ Examples (click to show) + +Consider the worksheet: + +``` +XXX| A | B | C | D | E | F | G | +---+---+---+---+---+---+---+---+ + 1 | S | h | e | e | t | J | S | + 2 | 1 | 2 | | | 5 | 6 | 7 | + 3 | 2 | 3 | | | 6 | 7 | 8 | + 4 | 3 | 4 | | | 7 | 8 | 9 | + 5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | +``` + +This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: + +```js +/* Initial row */ +var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]); + +/* Write data starting at A2 */ +XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"}); + +/* Write data starting at E2 */ +XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}}); + +/* Append row */ +XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1}); +``` + +
+ +### Array of Objects Input + +`XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet +with automatically-generated "headers" based on the keys of the objects. The +default column order is determined by the first appearance of the field using +`Object.keys`. The function accepts an options argument: + +| Option Name | Default | Description | +| :---------- | :-----: | :--------------------------------------------------- | +|`header` | | Use specified field order (default `Object.keys`) ** | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`cellDates` | false | Store dates as type `d` (default is `n`) | +|`skipHeader` | false | If true, do not include header row in output | +|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | + +- All fields from each row will be written. If `header` is an array and it does + not contain a particular field, the key will be appended to the array. +- Cell types are deduced from the type of each value. For example, a `Date` + object will generate a Date cell, while a string will generate a Text cell. +- Null values will be skipped by default. If `nullError` is true, an error cell + corresponding to `#NULL!` will be written to the worksheet. + +
+ Examples (click to show) + +The original sheet cannot be reproduced using plain objects since JS object keys +must be unique. After replacing the second `e` and `S` with `e_1` and `S_1`: + +```js +var ws = XLSX.utils.json_to_sheet([ + { S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 }, + { S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 } +], {header:["S","h","e","e_1","t","J","S_1"]}); +``` + +Alternatively, the header row can be skipped: + +```js +var ws = XLSX.utils.json_to_sheet([ + { A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" }, + { A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7 }, + { A: 2, B: 3, C: 4, D: 5, E: 6, F: 7, G: 8 } +], {header:["A","B","C","D","E","F","G"], skipHeader:true}); +``` + +
+ +`XLSX.utils.sheet_add_json` takes an array of objects and updates an existing +worksheet object. It follows the same process as `json_to_sheet` and accepts +an options argument: + +| Option Name | Default | Description | +| :---------- | :-----: | :--------------------------------------------------- | +|`header` | | Use specified column order (default `Object.keys`) | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`cellDates` | false | Store dates as type `d` (default is `n`) | +|`skipHeader` | false | If true, do not include header row in output | +|`nullError` | false | If true, emit `#NULL!` error cells for `null` values | +|`origin` | | Use specified cell as starting point (see below) | + +`origin` is expected to be one of: + +| `origin` | Description | +| :--------------- | :-------------------------------------------------------- | +| (cell object) | Use specified cell (cell object) | +| (string) | Use specified cell (A1-style cell) | +| (number >= 0) | Start from the first column at specified row (0-indexed) | +| -1 | Append to bottom of worksheet starting on first column | +| (default) | Start from cell A1 | + + +
+ Examples (click to show) + +Consider the worksheet: + +``` +XXX| A | B | C | D | E | F | G | +---+---+---+---+---+---+---+---+ + 1 | S | h | e | e | t | J | S | + 2 | 1 | 2 | | | 5 | 6 | 7 | + 3 | 2 | 3 | | | 6 | 7 | 8 | + 4 | 3 | 4 | | | 7 | 8 | 9 | + 5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | +``` + +This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: + +```js +/* Initial row */ +var ws = XLSX.utils.json_to_sheet([ + { A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" } +], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true}); + +/* Write data starting at A2 */ +XLSX.utils.sheet_add_json(ws, [ + { A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 } +], {skipHeader: true, origin: "A2"}); + +/* Write data starting at E2 */ +XLSX.utils.sheet_add_json(ws, [ + { A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 } +], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]}); + +/* Append row */ +XLSX.utils.sheet_add_json(ws, [ + { A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 } +], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1}); +``` + +
+ +### HTML Table Input + +`XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet +resembling the input table. Numbers are parsed. All other data will be stored +as strings. + +`XLSX.utils.table_to_book` produces a minimal workbook based on the worksheet. + +Both functions accept options arguments: + +| Option Name | Default | Description | +| :---------- | :------: | :-------------------------------------------------- | +|`raw` | | If true, every cell will hold raw strings | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`cellDates` | false | Store dates as type `d` (default is `n`) | +|`sheetRows` | 0 | If >0, read the first `sheetRows` rows of the table | +|`display` | false | If true, hidden rows and cells will not be parsed | + + +
+ Examples (click to show) + +To generate the example sheet, start with the HTML table: + +```html + + + + +
SheetJS
1234567
2345678
+``` + +To process the table: + +```js +var tbl = document.getElementById('sheetjs'); +var wb = XLSX.utils.table_to_book(tbl); +``` +
+ +Note: `XLSX.read` can handle HTML represented as strings. + + +`XLSX.utils.sheet_add_dom` takes a table DOM element and updates an existing +worksheet object. It follows the same process as `table_to_sheet` and accepts +an options argument: + +| Option Name | Default | Description | +| :---------- | :------: | :-------------------------------------------------- | +|`raw` | | If true, every cell will hold raw strings | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`cellDates` | false | Store dates as type `d` (default is `n`) | +|`sheetRows` | 0 | If >0, read the first `sheetRows` rows of the table | +|`display` | false | If true, hidden rows and cells will not be parsed | + +`origin` is expected to be one of: + +| `origin` | Description | +| :--------------- | :-------------------------------------------------------- | +| (cell object) | Use specified cell (cell object) | +| (string) | Use specified cell (A1-style cell) | +| (number >= 0) | Start from the first column at specified row (0-indexed) | +| -1 | Append to bottom of worksheet starting on first column | +| (default) | Start from cell A1 | + + +
+ Examples (click to show) + +A small helper function can create gap rows between tables: + +```js +function create_gap_rows(ws, nrows) { + var ref = XLSX.utils.decode_range(ws["!ref"]); // get original range + ref.e.r += nrows; // add to ending row + ws["!ref"] = XLSX.utils.encode_range(ref); // reassign row +} + +/* first table */ +var ws = XLSX.utils.table_to_sheet(document.getElementById('table1')); +create_gap_rows(ws, 1); // one row gap after first table + +/* second table */ +XLSX.utils.sheet_add_dom(ws, document.getElementById('table2'), {origin: -1}); +create_gap_rows(ws, 3); // three rows gap after second table + +/* third table */ +XLSX.utils.sheet_add_dom(ws, document.getElementById('table3'), {origin: -1}); +``` + +
+ +### Formulae Output + +`XLSX.utils.sheet_to_formulae` generates an array of commands that represent +how a person would enter data into an application. Each entry is of the form +`A1-cell-address=formula-or-value`. String literals are prefixed with a `'` in +accordance with Excel. + +
+ Examples (click to show) + +For the example sheet: + +```js +> var o = XLSX.utils.sheet_to_formulae(ws); +> [o[0], o[5], o[10], o[15], o[20]]; +[ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ] +``` +
+ +### Delimiter-Separated Output + +As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also +produces CSV output. The function takes an options argument: + +| Option Name | Default | Description | +| :----------- | :------: | :------------------------------------------------- | +|`FS` | `","` | "Field Separator" delimiter between fields | +|`RS` | `"\n"` | "Record Separator" delimiter between rows | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`strip` | false | Remove trailing field separators in each record ** | +|`blankrows` | true | Include blank lines in the CSV output | +|`skipHidden` | false | Skips hidden rows/columns in the CSV output | +|`forceQuotes` | false | Force quotes around fields | + +- `strip` will remove trailing commas from each line under default `FS/RS` +- `blankrows` must be set to `false` to skip blank lines. +- Fields containing the record or field separator will automatically be wrapped + in double quotes; `forceQuotes` forces all cells to be wrapped in quotes. +- `XLSX.write` with `csv` type will always prepend the UTF-8 byte-order mark for + Excel compatibility. `sheet_to_csv` returns a JS string and omits the mark. + Using `XLSX.write` with type `string` will also skip the mark. + + +
+ Examples (click to show) + +For the example sheet: + +```js +> console.log(XLSX.utils.sheet_to_csv(ws)); +S,h,e,e,t,J,S +1,2,3,4,5,6,7 +2,3,4,5,6,7,8 +> console.log(XLSX.utils.sheet_to_csv(ws, {FS:"\t"})); +S h e e t J S +1 2 3 4 5 6 7 +2 3 4 5 6 7 8 +> console.log(XLSX.utils.sheet_to_csv(ws,{FS:":",RS:"|"})); +S:h:e:e:t:J:S|1:2:3:4:5:6:7|2:3:4:5:6:7:8| +``` +
+ +#### UTF-16 Unicode Text + +The `txt` output type uses the tab character as the field separator. If the +`codepage` library is available (included in full distribution but not core), +the output will be encoded in `CP1200` and the BOM will be prepended. + +`XLSX.utils.sheet_to_txt` takes the same arguments as `sheet_to_csv`. + +### HTML Output + +As an alternative to the `writeFile` HTML type, `XLSX.utils.sheet_to_html` also +produces HTML output. The function takes an options argument: + +| Option Name | Default | Description | +| :---------- | :------: | :-------------------------------------------------- | +|`id` | | Specify the `id` attribute for the `TABLE` element | +|`editable` | false | If true, set `contenteditable="true"` for every TD | +|`header` | | Override header (default `html body`) | +|`footer` | | Override footer (default `/body /html`) | + +
+ Examples (click to show) + +For the example sheet: + +```js +> console.log(XLSX.utils.sheet_to_html(ws)); +// ... +``` +
+ +### JSON + +`XLSX.utils.sheet_to_json` generates different types of JS objects. The function +takes an options argument: + +| Option Name | Default | Description | +| :---------- | :------: | :-------------------------------------------------- | +|`raw` | `true` | Use raw values (true) or formatted strings (false) | +|`range` | from WS | Override Range (see table below) | +|`header` | | Control output format (see table below) | +|`dateNF` | FMT 14 | Use specified date format in string output | +|`defval` | | Use specified value in place of null or undefined | +|`blankrows` | ** | Include blank lines in the output ** | + +- `raw` only affects cells which have a format code (`.z`) field or a formatted + text (`.w`) field. +- If `header` is specified, the first row is considered a data row; if `header` + is not specified, the first row is the header row and not considered data. +- When `header` is not specified, the conversion will automatically disambiguate + header entries by affixing `_` and a count starting at `1`. For example, if + three columns have header `foo` the output fields are `foo`, `foo_1`, `foo_2` +- `null` values are returned when `raw` is true but are skipped when false. +- If `defval` is not specified, null and undefined values are skipped normally. + If specified, all null and undefined points will be filled with `defval` +- When `header` is `1`, the default is to generate blank rows. `blankrows` must + be set to `false` to skip blank rows. +- When `header` is not `1`, the default is to skip blank rows. `blankrows` must + be true to generate blank rows + +`range` is expected to be one of: + +| `range` | Description | +| :--------------- | :-------------------------------------------------------- | +| (number) | Use worksheet range but set starting row to the value | +| (string) | Use specified range (A1-style bounded range string) | +| (default) | Use worksheet range (`ws['!ref']`) | + +`header` is expected to be one of: + +| `header` | Description | +| :--------------- | :-------------------------------------------------------- | +| `1` | Generate an array of arrays ("2D Array") | +| `"A"` | Row object keys are literal column labels | +| array of strings | Use specified strings as keys in row objects | +| (default) | Read and disambiguate first row as keys | + +- If header is not `1`, the row object will contain the non-enumerable property + `__rowNum__` that represents the row of the sheet corresponding to the entry. +- If header is an array, the keys will not be disambiguated. This can lead to + unexpected results if the array values are not unique! + + +
+ Examples (click to show) + +For the example sheet: + +```js +> XLSX.utils.sheet_to_json(ws); +[ { S: 1, h: 2, e: 3, e_1: 4, t: 5, J: 6, S_1: 7 }, + { S: 2, h: 3, e: 4, e_1: 5, t: 6, J: 7, S_1: 8 } ] + +> XLSX.utils.sheet_to_json(ws, {header:"A"}); +[ { A: 'S', B: 'h', C: 'e', D: 'e', E: 't', F: 'J', G: 'S' }, + { A: '1', B: '2', C: '3', D: '4', E: '5', F: '6', G: '7' }, + { A: '2', B: '3', C: '4', D: '5', E: '6', F: '7', G: '8' } ] + +> XLSX.utils.sheet_to_json(ws, {header:["A","E","I","O","U","6","9"]}); +[ { '6': 'J', '9': 'S', A: 'S', E: 'h', I: 'e', O: 'e', U: 't' }, + { '6': '6', '9': '7', A: '1', E: '2', I: '3', O: '4', U: '5' }, + { '6': '7', '9': '8', A: '2', E: '3', I: '4', O: '5', U: '6' } ] + +> XLSX.utils.sheet_to_json(ws, {header:1}); +[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], + [ '1', '2', '3', '4', '5', '6', '7' ], + [ '2', '3', '4', '5', '6', '7', '8' ] ] +``` + +Example showing the effect of `raw`: + +```js +> ws['A2'].w = "3"; // set A2 formatted string value + +> XLSX.utils.sheet_to_json(ws, {header:1, raw:false}); +[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], + [ '3', '2', '3', '4', '5', '6', '7' ], // <-- A2 uses the formatted string + [ '2', '3', '4', '5', '6', '7', '8' ] ] + +> XLSX.utils.sheet_to_json(ws, {header:1}); +[ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], + [ 1, 2, 3, 4, 5, 6, 7 ], // <-- A2 uses the raw value + [ 2, 3, 4, 5, 6, 7, 8 ] ] +``` +
diff --git a/docz/docs/08-api/_category_.json b/docz/docs/08-api/_category_.json new file mode 100644 index 0000000..2c5d9f1 --- /dev/null +++ b/docz/docs/08-api/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "API Functions", + "position": 8 +} diff --git a/docz/docs/09-miscellany/01-formats.md b/docz/docs/09-miscellany/01-formats.md new file mode 100644 index 0000000..1baa638 --- /dev/null +++ b/docz/docs/09-miscellany/01-formats.md @@ -0,0 +1,255 @@ +--- +sidebar_position: 1 +--- + +# File Formats + +![circo graph of format support](../img/formats.png) + +![graph legend](../img/legend.png) + + +| Format | Read | Write | +|:-------------------------------------------------------------|:-----:|:-----:| +| **Excel Worksheet/Workbook Formats** |:-----:|:-----:| +| Excel 2007+ XML Formats (XLSX/XLSM) | ✔ | ✔ | +| Excel 2007+ Binary Format (XLSB BIFF12) | ✔ | ✔ | +| Excel 2003-2004 XML Format (XML "SpreadsheetML") | ✔ | ✔ | +| Excel 97-2004 (XLS BIFF8) | ✔ | ✔ | +| Excel 5.0/95 (XLS BIFF5) | ✔ | ✔ | +| Excel 4.0 (XLS/XLW BIFF4) | ✔ | ✔ | +| Excel 3.0 (XLS BIFF3) | ✔ | ✔ | +| Excel 2.0/2.1 / Multiplan 4.x DOS (XLS BIFF2) | ✔ | ✔ | +| **Excel Supported Text Formats** |:-----:|:-----:| +| Delimiter-Separated Values (CSV/TXT) | ✔ | ✔ | +| Data Interchange Format (DIF) | ✔ | ✔ | +| Symbolic Link (SYLK/SLK) | ✔ | ✔ | +| Lotus Formatted Text (PRN) | ✔ | ✔ | +| UTF-16 Unicode Text (TXT) | ✔ | ✔ | +| **Other Workbook/Worksheet Formats** |:-----:|:-----:| +| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | ✔ | +| OpenDocument Spreadsheet (ODS) | ✔ | ✔ | +| Flat XML ODF Spreadsheet (FODS) | ✔ | ✔ | +| Uniform Office Format Spreadsheet (标文通 UOS1/UOS2) | ✔ | | +| dBASE II/III/IV / Visual FoxPro (DBF) | ✔ | ✔ | +| Lotus 1-2-3 (WK1/WK3) | ✔ | ✔ | +| Lotus 1-2-3 (WKS/WK2/WK4/123) | ✔ | | +| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | ✔ | | +| Works 1.x-3.x DOS / 2.x-5.x Windows Spreadsheet (WKS) | ✔ | | +| Works 6.x-9.x Spreadsheet (XLR) | ✔ | | +| **Other Common Spreadsheet Output Formats** |:-----:|:-----:| +| HTML Tables | ✔ | ✔ | +| Rich Text Format tables (RTF) | | ✔ | +| Ethercalc Record Format (ETH) | ✔ | ✔ | + +Features not supported by a given file format will not be written. Formats with +range limits will be silently truncated: + +| Format | Last Cell | Max Cols | Max Rows | +|:------------------------------------------|:-----------|---------:|---------:| +| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 | +| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 | +| Numbers 12.0 (NUMBERS) | ALL1000000 | 1000 | 1000000 | +| Quattro Pro 9+ (QPW) | IV1000000 | 256 | 1000000 | +| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 | +| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 | +| Excel 4.0 (XLS BIFF4) | IV16384 | 256 | 16384 | +| Excel 3.0 (XLS BIFF3) | IV16384 | 256 | 16384 | +| Excel 2.0/2.1 (XLS BIFF2) | IV16384 | 256 | 16384 | +| Lotus 1-2-3 R2 - R5 (WK1/WK3/WK4) | IV8192 | 256 | 8192 | +| Lotus 1-2-3 R1 (WKS) | IV2048 | 256 | 2048 | + +Excel 2003 SpreadsheetML range limits are governed by the version of Excel and +are not enforced by the writer. + +### Excel 2007+ XML (XLSX/XLSM) + +XLSX and XLSM files are ZIP containers containing a series of XML files in +accordance with the Open Packaging Conventions (OPC). The XLSM format, almost +identical to XLSX, is used for files containing macros. + +The format is standardized in ECMA-376 and later in ISO/IEC 29500. Excel does +not follow the specification, and there are additional documents discussing how +Excel deviates from the specification. + +### Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5) + +BIFF 2/3 XLS are single-sheet streams of binary records. Excel 4 introduced +the concept of a workbook (`XLW` files) but also had single-sheet `XLS` format. +The structure is largely similar to the Lotus 1-2-3 file formats. BIFF5/8/12 +extended the format in various ways but largely stuck to the same record format. + +Multiplan 4 "Normal" files are identical in structure to BIFF2 and use the same +cell value records. There are some different record types for more advanced +features like Print Settings. The BIFF2 writer generates files that can be read +in Multiplan 4 and the parser can extract values from "Normal" files. + +There is no official specification for any of these formats. Excel 95 can write +files in these formats, so record lengths and fields were determined by writing +in all of the supported formats and comparing files. Excel 2016 can generate +BIFF5 files, enabling a full suite of file tests starting from XLSX or BIFF2. + +### Excel 97-2004 Binary (BIFF8) + +BIFF8 exclusively uses the Compound File Binary container format, splitting some +content into streams within the file. At its core, it still uses an extended +version of the binary record format from older versions of BIFF. + +The `MS-XLS` specification covers the basics of the file format, and other +specifications expand on serialization of features like properties. + +### Excel 2003-2004 (SpreadsheetML) + +Predating XLSX, SpreadsheetML files are simple XML files. There is no official +and comprehensive specification, although MS has released documentation on the +format. Since Excel 2016 can generate SpreadsheetML files, mapping features is +pretty straightforward. + +### Excel 2007+ Binary (XLSB, BIFF12) + +Introduced in parallel with XLSX, the XLSB format combines the BIFF architecture +with the content separation and ZIP container of XLSX. For the most part nodes +in an XLSX sub-file can be mapped to XLSB records in a corresponding sub-file. + +The `MS-XLSB` specification covers the basics of the file format, and other +specifications expand on serialization of features like properties. + +### Delimiter-Separated Values (CSV/TXT) + +Excel CSV deviates from RFC4180 in a number of important ways. The generated +CSV files should generally work in Excel although they may not work in RFC4180 +compatible readers. The parser should generally understand Excel CSV. The +writer proactively generates cells for formulae if values are unavailable. + +Excel TXT uses tab as the delimiter and code page 1200. + +Like in Excel, files starting with `0x49 0x44 ("ID")` are treated as Symbolic +Link files. Unlike Excel, if the file does not have a valid SYLK header, it +will be proactively reinterpreted as CSV. There are some files with semicolon +delimiter that align with a valid SYLK file. For the broadest compatibility, +all cells with the value of `ID` are automatically wrapped in double-quotes. + +### Miscellaneous Workbook Formats + +Support for other formats is generally far behind XLS/XLSB/XLSX support, due in +part to a lack of publicly available documentation. Test files were produced in +the respective apps and compared to their XLS exports to determine structure. +The main focus is data extraction. + +#### Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123) + +The Lotus formats consist of binary records similar to the BIFF structure. Lotus +did release a specification decades ago covering the original WK1 format. Other +features were deduced by producing files and comparing to Excel support. + +Generated WK1 worksheets are compatible with Lotus 1-2-3 R2 and Excel 5.0. + +Generated WK3 workbooks are compatible with Lotus 1-2-3 R9 and Excel 5.0. + +#### Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW) + +The Quattro Pro formats use binary records in the same way as BIFF and Lotus. +Some of the newer formats (namely WB3 and QPW) use a CFB enclosure just like +BIFF8 XLS. + +#### Works for DOS / Windows Spreadsheet (WKS/XLR) + +All versions of Works were limited to a single worksheet. + +Works for DOS 1.x - 3.x and Works for Windows 2.x extends the Lotus WKS format +with additional record types. + +Works for Windows 3.x - 5.x uses the same format and WKS extension. The BOF +record has type `FF` + +Works for Windows 6.x - 9.x use the XLR format. XLR is nearly identical to +BIFF8 XLS: it uses the CFB container with a Workbook stream. Works 9 saves the +exact Workbook stream for the XLR and the 97-2003 XLS export. Works 6 XLS +includes two empty worksheets but the main worksheet has an identical encoding. +XLR also includes a `WksSSWorkBook` stream similar to Lotus FM3/FMT files. + +#### Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) + +iWork 2013 (Numbers 3.0 / Pages 5.0 / Keynote 6.0) switched from a proprietary +XML-based format to the current file format based on the iWork Archive (IWA). +This format has been used up through the current release (Numbers 11.2). + +The parser focuses on extracting raw data from tables. Numbers technically +supports multiple tables in a logical worksheet, including custom titles. This +parser will generate one worksheet per Numbers table. + +The writer currently exports a small range from the first worksheet. + +#### OpenDocument Spreadsheet (ODS/FODS) + +ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to +SpreadsheetML. Both are detailed in the OASIS standard, but tools like LO/OO +add undocumented extensions. The parsers and writers do not implement the full +standard, instead focusing on parts necessary to extract and store raw data. + +#### Uniform Office Spreadsheet (UOS1/2) + +UOS is a very similar format, and it comes in 2 varieties corresponding to ODS +and FODS respectively. For the most part, the difference between the formats +is in the names of tags and attributes. + +### Miscellaneous Worksheet Formats + +Many older formats supported only one worksheet: + +#### dBASE and Visual FoxPro (DBF) + +DBF is really a typed table format: each column can only hold one data type and +each record omits type information. The parser generates a header row and +inserts records starting at the second row of the worksheet. The writer makes +files compatible with Visual FoxPro extensions. + +Multi-file extensions like external memos and tables are currently unsupported, +limited by the general ability to read arbitrary files in the web browser. The +reader understands DBF Level 7 extensions like DATETIME. + +#### Symbolic Link (SYLK) + + is an informal specification based on our +experimentation and previous documentation efforts. + +#### Lotus Formatted Text (PRN) + +There is no real documentation, and in fact Excel treats PRN as an output-only +file format. Nevertheless we can guess the column widths and reverse-engineer +the original layout. Excel's 240 character width limitation is not enforced. + +#### Data Interchange Format (DIF) + +There is no unified definition. Visicalc DIF differs from Lotus DIF, and both +differ from Excel DIF. Where ambiguous, the parser/writer follows the expected +behavior from Excel. In particular, Excel extends DIF in incompatible ways: + +- Since Excel automatically converts numbers-as-strings to numbers, numeric + string constants are converted to formulae: `"0.3" -> "=""0.3""` +- DIF technically expects numeric cells to hold the raw numeric data, but Excel + permits formatted numbers (including dates) +- DIF technically has no support for formulae, but Excel will automatically + convert plain formulae. Array formulae are not preserved. + +#### HTML + +Excel HTML worksheets include special metadata encoded in styles. For example, +`mso-number-format` is a localized string containing the number format. Despite +the metadata the output is valid HTML, although it does accept bare `&` symbols. + +The writer adds type metadata to the TD elements via the `t` tag. The parser +looks for those tags and overrides the default interpretation. For example, text +like `12345` will be parsed as numbers but `12345` will +be parsed as text. + +#### Rich Text Format (RTF) + +Excel RTF worksheets are stored in clipboard when copying cells or ranges from a +worksheet. The supported codes are a subset of the Word RTF support. + +#### Ethercalc Record Format (ETH) + +[Ethercalc](https://ethercalc.net/) is an open source web spreadsheet powered by +a record format reminiscent of SYLK wrapped in a MIME multi-part message. + diff --git a/docz/docs/09-miscellany/06-testing.md b/docz/docs/09-miscellany/06-testing.md new file mode 100644 index 0000000..f93ef6a --- /dev/null +++ b/docz/docs/09-miscellany/06-testing.md @@ -0,0 +1,111 @@ +--- +sidebar_position: 6 +hide_table_of_contents: true +--- + +# Testing + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +`make test` will run the node-based tests. By default it runs tests on files in +every supported format. To test a specific file type, set `FMTS` to the format +you want to test. Feature-specific tests are available with `make test_misc` + +```bash +$ make test_misc # run core tests +$ make test # run full tests +$ make test_xls # only use the XLS test files +$ make test_xlsx # only use the XLSX test files +$ make test_xlsb # only use the XLSB test files +$ make test_xml # only use the XML test files +$ make test_ods # only use the ODS test files +``` + +To enable all errors, set the environment variable `WTF=1`: + +```bash +$ make test # run full tests +$ WTF=1 make test # enable all error messages +``` + +`flow` and `eslint` checks are available: + +```bash +$ make lint # eslint checks +$ make flow # make lint + Flow checking +$ make tslint # check TS definitions +``` + + + + +The core in-browser tests are available at `tests/index.html` within this repo. +Start a local server and navigate to that directory to run the tests. +`make ctestserv` will start a server on port 8000. + +`make ctest` will generate the browser fixtures. To add more files, edit the +`tests/fixtures.lst` file and add the paths. + +To run the full in-browser tests, clone the repo for +[`oss.sheetjs.com`](https://github.com/SheetJS/SheetJS.github.io) and replace +the `xlsx.js` file (then open a browser window and go to `stress.html`): + +```bash +$ cp xlsx.js ../SheetJS.github.io +$ cd ../SheetJS.github.io +$ simplehttpserver # or "python -mSimpleHTTPServer" or "serve" +$ open -a Chromium.app http://localhost:8000/stress.html +``` + + + + +`make test-deno` will run the full Deno test suite and `make test-deno_misc` +will run the smaller feature-specific tests. + + + + +### Tested Environments + +
+ (click to show) + + - NodeJS `0.8`, `0.10`, `0.12`, `4.x`, `5.x`, `6.x`, `7.x`, `8.x` + - IE 6/7/8/9/10/11 (IE 6-9 require shims) + - Chrome 24+ (including Android 4.0+) + - Safari 6+ (iOS and Desktop) + - Edge 13+, FF 18+, and Opera 12+ + +Tests utilize the mocha testing framework. + + - for XLS\* modules using Sauce Labs + +The test suite also includes tests for various time zones. To change +the timezone locally, set the TZ environment variable: + +```bash +$ env TZ="Asia/Kolkata" WTF=1 make test_misc +``` + +
+ +### Test Files + +Test files are housed in [another repo](https://github.com/SheetJS/test_files). + +Running `make init` will refresh the `test_files` submodule and get the files. +Note that this requires `svn`, `git`, `hg` and other commands that may not be +available. If `make init` fails, please download the latest version of the test +files snapshot from [the repo](https://github.com/SheetJS/test_files/releases) + +#### Latest Snapshot + + + +(download and unzip to the `test_files` subdirectory) + diff --git a/docz/docs/09-miscellany/07-contributing.md b/docz/docs/09-miscellany/07-contributing.md new file mode 100644 index 0000000..81105a2 --- /dev/null +++ b/docz/docs/09-miscellany/07-contributing.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 7 +hide_table_of_contents: true +--- + +# Contributing + +Due to the precarious nature of the Open Specifications Promise, it is very +important to ensure code is cleanroom. [Contribution Notes](https://raw.githubusercontent.com/SheetJS/sheetjs/master/CONTRIBUTING.md) + +
+ File organization (click to show) + +At a high level, the final script is a concatenation of the individual files in +the `bits` folder. Running `make` should reproduce the final output on all +platforms. + +Folders: + +| folder | contents | +|:-------------|:--------------------------------------------------------------| +| `bits` | raw source files that make up the final script | +| `bin` | server-side bin scripts (`xlsx.njs`) | +| `dist` | dist files for web browsers and nonstandard JS environments | +| `demos` | demo projects for platforms like ExtendScript and Webpack | +| `tests` | browser tests (run `make ctest` to rebuild) | +| `types` | typescript definitions and tests | +| `misc` | miscellaneous supporting scripts | +| `test_files` | test files (pulled from the test files repository) | + +
+ +After cloning the repo, running `make help` will display a list of commands. + +## Platform-Specific Details + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +The `xlsx.js` file is constructed from the files in the `bits` subdirectory. The +build script (run `make`) will concatenate the individual bits to produce the +script. Before submitting a contribution, ensure that running make will produce +the `xlsx.js` file exactly. The simplest way to test is to add the script: + +```bash +$ git add xlsx.js +$ make clean +$ make +$ git diff xlsx.js +``` + +To produce the dist files, run `make dist`. The dist files are updated in each +version release and *should not be committed between versions*. + + + + +The included `make.cmd` script will build `xlsx.js` from the `bits` directory. +Building is as simple as: + +```cmd +> make +``` + +To prepare development environment: + +```cmd +> make init +``` + +The full list of commands available in Windows are displayed in `make help`: + +``` +make init -- install deps and global modules +make lint -- run eslint linter +make test -- run mocha test suite +make misc -- run smaller test suite +make book -- rebuild README and summary +make help -- display this message +``` + +As explained in [Test Files](./testing#test-files), on Windows the release ZIP file must +be downloaded and extracted. If Bash on Windows is available, it is possible +to run the OSX/Linux workflow. The following steps prepares the environment: + +```bash +# Install support programs for the build and test commands +sudo apt-get install make git subversion mercurial + +# Install nodejs and NPM within the WSL +wget -qO- https://deb.nodesource.com/setup_8.x | sudo bash +sudo apt-get install nodejs + +# Install dev dependencies +sudo npm install -g mocha voc blanket xlsjs +``` + + + + +### Tests + +The `test_misc` target (`make test_misc` on Linux/OSX / `make misc` on Windows) +runs the targeted feature tests. It should take 5-10 seconds to perform feature +tests without testing against the entire test battery. New features should be +accompanied with tests for the relevant file formats and features. + +For tests involving the read side, an appropriate feature test would involve +reading an existing file and checking the resulting workbook object. If a +parameter is involved, files should be read with different values to verify that +the feature is working as expected. + +For tests involving a new write feature which can already be parsed, appropriate +feature tests would involve writing a workbook with the feature and then opening +and verifying that the feature is preserved. + +For tests involving a new write feature without an existing read ability, please +add a feature test to the kitchen sink `tests/write.js`. + diff --git a/docz/docs/09-miscellany/08-license.md b/docz/docs/09-miscellany/08-license.md new file mode 100644 index 0000000..9892c43 --- /dev/null +++ b/docz/docs/09-miscellany/08-license.md @@ -0,0 +1,218 @@ +--- +sidebar_position: 8 +hide_table_of_contents: true +--- + +# License + +SheetJS Community Edition is licensed under the "Apache 2.0 License". All rights +not explicitly granted by the Apache 2.0 License are reserved by SheetJS LLC. + +
License (click to show) + +``` + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (C) 2012-present SheetJS LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +``` + +
+ diff --git a/docz/docs/09-miscellany/09-references.md b/docz/docs/09-miscellany/09-references.md new file mode 100644 index 0000000..00238ae --- /dev/null +++ b/docz/docs/09-miscellany/09-references.md @@ -0,0 +1,46 @@ +--- +sidebar_position: 9 +hide_table_of_contents: true +--- + +# References + +Some of our original research is documented at + +The specifications list is non-exhaustive. + +- ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats" +- Open Document Format for Office Applications Version 1.2 (29 September 2011) +- Worksheet File Format (From Lotus) December 1984 + + +## Open Specifications Promise + +Lotus released their "Worksheet File Format" documentation into the Public +Domain. Microsoft opted for the "Open Specifications Promise", a covenant not +to sue. The documentation that falls under the promise are listed below. + +
Specifications (click to show) + + - `MS-CFB`: Compound File Binary File Format + - `MS-CTXLS`: Excel Custom Toolbar Binary File Format + - `MS-EXSPXML3`: Excel Calculation Version 2 Web Service XML Schema + - `MS-ODATA`: Open Data Protocol (OData) + - `MS-ODRAW`: Office Drawing Binary File Format + - `MS-ODRAWXML`: Office Drawing Extensions to Office Open XML Structure + - `MS-OE376`: Office Implementation Information for ECMA-376 Standards Support + - `MS-OFFCRYPTO`: Office Document Cryptography Structure + - `MS-OI29500`: Office Implementation Information for ISO/IEC 29500 Standards Support + - `MS-OLEDS`: Object Linking and Embedding (OLE) Data Structures + - `MS-OLEPS`: Object Linking and Embedding (OLE) Property Set Data Structures + - `MS-OODF3`: Office Implementation Information for ODF 1.2 Standards Support + - `MS-OSHARED`: Office Common Data Types and Objects Structures + - `MS-OVBA`: Office VBA File Format Structure + - `MS-XLDM`: Spreadsheet Data Model File Format + - `MS-XLS`: Excel Binary File Format (.xls) Structure Specification + - `MS-XLSB`: Excel (.xlsb) Binary File Format + - `MS-XLSX`: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format + - `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification + - `RTF`: Rich Text Format + +
\ No newline at end of file diff --git a/docz/docs/09-miscellany/_category_.json b/docz/docs/09-miscellany/_category_.json new file mode 100644 index 0000000..b36045f --- /dev/null +++ b/docz/docs/09-miscellany/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Miscellany", + "position": 9 +} diff --git a/docz/docs/img/final.png b/docz/docs/img/final.png new file mode 100644 index 0000000000000000000000000000000000000000..1faf0531d16d6d0c35c870f4edd095265512d80a GIT binary patch literal 32461 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\|seXq!!I7v{RyF`!{+lL=745GV( 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 literal 0 HcmV?d00001 diff --git a/docz/docs/img/legend.png b/docz/docs/img/legend.png new file mode 100644 index 0000000000000000000000000000000000000000..686a7518d665fdb2270508bed42fa7ca2e8af880 GIT binary patch literal 33608 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docz/docs/index.md b/docz/docs/index.md new file mode 100644 index 0000000..31016d8 --- /dev/null +++ b/docz/docs/index.md @@ -0,0 +1,223 @@ +--- +sidebar_position: 1 +hide_table_of_contents: true +--- + +# SheetJS CE + +![License](https://img.shields.io/github/license/SheetJS/sheetjs) +[![Build Status](https://img.shields.io/github/workflow/status/sheetjs/sheetjs/Tests:%20node.js)](https://github.com/SheetJS/sheetjs/actions) +[![Snyk Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/SheetJS/sheetjs)](https://snyk.io/test/github/SheetJS/sheetjs) +[![npm Downloads](https://img.shields.io/npm/dm/xlsx.svg)](https://npmjs.org/package/xlsx) + +SheetJS Community Edition offers battle-tested open-source solutions for +extracting useful data from almost any complex spreadsheet and generating new +spreadsheets that will work with legacy and modern software alike. + +[SheetJS Pro](https://sheetjs.com/pro) offers solutions beyond data processing: +Edit complex templates with ease; let out your inner Picasso with styling; make +custom sheets with images/graphs/PivotTables; evaluate formula expressions and +port calculations to web apps; automate common spreadsheet tasks, and much more! + +## Simple Examples + +The code editors are live -- feel free to edit! Due to technical limitations, +they showcase ReactJS patterns. Other parts of the documentation will cover +more common use cases including plain JavaScript. + +### Export an HTML Table to Excel XLSX + +

How to add to your site (click to show) + +1) Make sure your table has an ID: + +```html + +``` + +2) Include a reference to the SheetJS Library in your page: + +```html + +``` + +3) Add a button that users will click to generate an export + +```html + +``` + +4) Add an event handler for the `click` event to create a workbook and download: + +```js +document.getElementById("TableToExport").addEventListener('click', function() { + /* Create worksheet from HTML DOM TABLE */ + var wb = XLSX.utils.table_to_book(document.getElementById("TableToExport")); + /* Export to file (start a download) */ + XLSX.writeFile(wb, "SheetJSTable.xlsx"); +}); +``` + + + +
Live Example (click to show) + +```jsx live +/* The live editor requires this function wrapper */ +function Table2XLSX(props) { + + /* Callback invoked when the button is clicked */ + const xport = React.useCallback(() => { + /* Create worksheet from HTML DOM TABLE */ + const table = document.getElementById("Table2XLSX"); + const wb = XLSX.utils.table_to_book(table); + + /* Export to file (start a download) */ + XLSX.writeFile(wb, "SheetJSTable.xlsx"); + }); + + return (<> +
+ + + + +
SheetJS Table Export
AuthorIDNote
SheetJS7262Hi!
+ Powered by SheetJS +
+ + ); +} +``` + +
SheetJS Pro Basic extends this export with +support for CSS styling and rich text. + +
+ +### Download and Preview a Numbers workbook + +
How to add to your site (click to show) + +1) Create a container DIV for the table: + +```html +
+``` + +2) Include a reference to the SheetJS Library in your page: + +```html + +``` + +3) Add a script block to download and update the page: + +```html + +``` + +
+ +
Live Example (click to hide) + +```jsx live +/* The live editor requires this function wrapper */ +function Numbers2HTML(props) { + const [html, setHTML] = React.useState(""); + + /* Fetch and update HTML */ + React.useEffect(async() => { + /* Fetch file */ + const f = await fetch("https://sheetjs.com/pres.numbers"); + const ab = await f.arrayBuffer(); + + /* Parse file */ + const wb = XLSX.read(ab); + const ws = wb.Sheets[wb.SheetNames[0]]; + + /* Generate HTML */ + setHTML(XLSX.utils.sheet_to_html(ws)); + }); + + return (
); +} +``` + +SheetJS Pro Basic extends this import with +support for CSS styling and rich text. + +
+ +### Convert a CSV file to HTML Table and Excel XLSX + +
Live Example (click to show) + +```jsx live +/* The live editor requires this function wrapper */ +function Tabeller(props) { + + /* Starting CSV data -- change data here */ + const csv = `\ +This,is,a,Test +வணக்கம்,สวัสดี,你好,가지마 +1,2,3,4`; + + /* Parse CSV into a workbook object */ + const wb = XLSX.read(csv, {type: "string"}); + + /* Get the worksheet (default name "Sheet1") */ + const ws = wb.Sheets.Sheet1; + + /* Create HTML table */ + const id = "tabeller"; // HTML TABLE ID + const __html = XLSX.utils.sheet_to_html(ws, { id }); + + return (<> + + {/* Show HTML preview */} +
+ + {/* Export Button */} + + + ); + +} +``` + +
+ + +### Browser Testing + +[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs) + +### Supported File Formats + +![circo graph of format support](./img/formats.png) + +![graph legend](./img/legend.png) diff --git a/docz/docusaurus.config.js b/docz/docusaurus.config.js new file mode 100644 index 0000000..a59f6f7 --- /dev/null +++ b/docz/docusaurus.config.js @@ -0,0 +1,161 @@ +// @ts-check +// Note: type annotations allow type checking and IDEs autocompletion + +const lightCodeTheme = require('prism-react-renderer/themes/github'); +const darkCodeTheme = require('prism-react-renderer/themes/dracula'); + +/** @type {import('@docusaurus/types').Config} */ +const config = { + title: 'SheetJS Community Edition', + tagline: 'Get Sheet Done', + url: 'https://docs.sheetjs.com', + baseUrl: '/', + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'warn', + favicon: 'img/favicon.ico', + + // GitHub pages deployment config. + // If you aren't using GitHub pages, you don't need these. + //organizationName: 'sheetjs', // Usually your GitHub org/user name. + //projectName: 'sheetjs', // Usually your repo name. + + // Even if you don't use internalization, you can use this field to set useful + // metadata like html lang. For example, if your site is Chinese, you may want + // to replace "en" with "zh-Hans". + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + presets: [ + [ + 'classic', + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + sidebarPath: require.resolve('./sidebars.js'), + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + // editUrl: + // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + }, + //blog: { + // showReadingTime: true, + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + // editUrl: + // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + //}, + theme: { + customCss: require.resolve('./src/css/custom.css'), + }, + googleAnalytics: { + trackingID: 'UA-36810333-1', + anonymizeIP: true + } + }), + ], + ], + + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + navbar: { + title: 'SheetJS CE Docs', + logo: { + alt: 'SheetJS Logo', + src: 'img/logo.svg', + }, + items: [ + { + type: 'doc', + docId: 'index', + position: 'left', + label: 'Docs', + }, + //{to: '/blog', label: 'Blog', position: 'left'}, + { + href: 'https://sheetjs.com', + label: 'SheetJS', + position: 'right', + }, + { + href: 'https://github.com/sheetjs/sheetjs', + label: 'Source', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { + label: 'Intro', + to: '/docs', + }, + { + label: 'Example', + to: '/docs/example', + }, + ], + }, + { + title: 'Community', + items: [ + //{ + // label: 'Stack Overflow', + // href: 'https://stackoverflow.com/questions/tagged/sheetjs', + //}, + //{ + // label: 'Discord', + // href: 'https://discordapp.com/invite/sheetjs', + //}, + { + label: 'Twitter', + href: 'https://twitter.com/sheetjs', + }, + ], + }, + { + title: 'More', + items: [ + //{ + // label: 'Blog', + // to: '/blog', + //}, + { + label: 'SheetJS Pro', + href: 'https://sheetjs.com/pro', + }, + { + label: 'Source', + href: 'https://github.com/sheetjs/sheetjs', + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} SheetJS LLC.`, + }, + prism: { + theme: lightCodeTheme, + darkTheme: darkCodeTheme, + }, + liveCodeBlock: { + playgroundPosition: 'top' + } + }), + themes: [ + "@docusaurus/theme-live-codeblock" + ], + scripts: [ + { + src: "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", + async: true + } + ] +}; + +module.exports = config; diff --git a/docz/package.json b/docz/package.json new file mode 100644 index 0000000..61fb77c --- /dev/null +++ b/docz/package.json @@ -0,0 +1,43 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids" + }, + "dependencies": { + "@docusaurus/core": "2.0.0-beta.20", + "@docusaurus/preset-classic": "2.0.0-beta.20", + "@docusaurus/theme-common": "^2.0.0-beta.20", + "@docusaurus/theme-live-codeblock": "^2.0.0-beta.20", + "@mdx-js/react": "^1.6.22", + "clsx": "^1.1.1", + "prism-react-renderer": "^1.3.1", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "2.0.0-beta.20" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/docz/sidebars.js b/docz/sidebars.js new file mode 100644 index 0000000..fd342f2 --- /dev/null +++ b/docz/sidebars.js @@ -0,0 +1,31 @@ +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ + +// @ts-check + +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const sidebars = { + // By default, Docusaurus generates a sidebar from the docs folder structure + tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], + + // But you can create a sidebar manually + /* + tutorialSidebar: [ + { + type: 'category', + label: 'Tutorial', + items: ['hello'], + }, + ], + */ +}; + +module.exports = sidebars; diff --git a/docz/src/components/HomepageFeatures/index.js b/docz/src/components/HomepageFeatures/index.js new file mode 100644 index 0000000..473ba08 --- /dev/null +++ b/docz/src/components/HomepageFeatures/index.js @@ -0,0 +1,93 @@ +import React from 'react'; +import clsx from 'clsx'; +import styles from './styles.module.css'; +import Link from '@docusaurus/Link'; + +const FeatureList = [ + { + title: 'All the Data', + Svg: require('@site/static/img/data.svg').default, + description: ( + <> + SheetJS presents a unified interface to every Excel file format as well + as Lotus 1-2-3, Numbers, and Quattro Pro. Process all the data! + + ), + denouement: ( +
+ + File Details + +
+ ), + }, + { + title: 'All the Tools', + Svg: require('@site/static/img/tools.svg').default, + description: ( + <> + SheetJS offers solutions for common data problems. Unlock the power of + JavaScript to wrangle data and effortlessly solve problems. + + ), + denouement: ( +
+ + Complete Example + +
+ ), + }, + { + title: 'All the Places', + Svg: require('@site/static/img/places.svg').default, + description: ( + <> + SheetJS runs everywhere: web browsers, servers, desktop apps, mobile + apps, SalesForce and Photoshop plugins, even within Excel! + + ), + denouement: ( +
+ + Demo Projects + +
+ ), + }, +]; + +function Feature({Svg, title, description, denouement}) { + return ( +
+
+ +
+
+

{title}

+

{description}

+
+ {denouement && (
{denouement}
)} +
+ ); +} + +export default function HomepageFeatures() { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/docz/src/components/HomepageFeatures/styles.module.css b/docz/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 0000000..b248eb2 --- /dev/null +++ b/docz/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/docz/src/components/Playground.tsx b/docz/src/components/Playground.tsx new file mode 100644 index 0000000..917c7f2 --- /dev/null +++ b/docz/src/components/Playground.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +import { CodePreview } from 'docusaurus-plugin-code-preview'; + +/* +export default function Playground(props) { + return ( + + ); +} +*/ + +export default function Playground(props) { + return ; +} diff --git a/docz/src/css/custom.css b/docz/src/css/custom.css new file mode 100644 index 0000000..8764628 --- /dev/null +++ b/docz/src/css/custom.css @@ -0,0 +1,39 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #40b48a; + --ifm-color-primary-darker: #3c9e7a; + --ifm-color-primary-darkest: #3c9e7a; + --ifm-color-primary-light: #58e0ae; + --ifm-color-primary-lighter: #8ef5cf; + --ifm-color-primary-lightest: #8ef5cf; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #4db69f; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} + +.content-pack::before { + content: "\1f4e6"; + margin-left: -20px; + margin-right: 4px; +} +.content-pack { + position: relative; +} \ No newline at end of file diff --git a/docz/src/pages/index.js b/docz/src/pages/index.js new file mode 100644 index 0000000..f736379 --- /dev/null +++ b/docz/src/pages/index.js @@ -0,0 +1,40 @@ +import React from 'react'; +import clsx from 'clsx'; +import Layout from '@theme/Layout'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import styles from './index.module.css'; +import HomepageFeatures from '@site/src/components/HomepageFeatures'; + +function HomepageHeader() { + const {siteConfig} = useDocusaurusContext(); + return ( +
+
+

{siteConfig.title}

+

{siteConfig.tagline}

+
+ + Get Started + +
+
+
+ ); +} + +export default function Home() { + const {siteConfig} = useDocusaurusContext(); + return ( + + +
+ +
+
+ ); +} diff --git a/docz/src/pages/index.module.css b/docz/src/pages/index.module.css new file mode 100644 index 0000000..9f71a5d --- /dev/null +++ b/docz/src/pages/index.module.css @@ -0,0 +1,23 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/docz/static/.nojekyll b/docz/static/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docz/static/data.json b/docz/static/data.json new file mode 100644 index 0000000..6de5155 --- /dev/null +++ b/docz/static/data.json @@ -0,0 +1,2364 @@ +[ + { + "id": { + "bioguide": "W000178", + "govtrack": 411351, + "icpsr_prez": 99869 + }, + "name": { + "first": "George", + "last": "Washington" + }, + "bio": { + "birthday": "1732-02-22", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1789-04-30", + "end": "1793-03-04", + "party": "no party", + "how": "election" + }, + { + "type": "prez", + "start": "1793-03-04", + "end": "1797-03-04", + "party": "no party", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "A000039", + "govtrack": 400699, + "icpsr_prez": 99870 + }, + "name": { + "first": "John", + "last": "Adams" + }, + "bio": { + "birthday": "1735-10-19", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1789-04-21", + "end": "1793-03-04", + "party": "Federalist", + "how": "election" + }, + { + "type": "viceprez", + "start": "1793-03-04", + "end": "1797-03-04", + "party": "Federalist", + "how": "election" + }, + { + "type": "prez", + "start": "1797-03-04", + "end": "1801-03-04", + "party": "Federalist", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "J000069", + "govtrack": 405974, + "icpsr_prez": 99871 + }, + "name": { + "first": "Thomas", + "last": "Jefferson" + }, + "bio": { + "birthday": "1743-04-13", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1797-03-04", + "end": "1801-03-04", + "party": "Democratic-Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1801-03-04", + "end": "1805-03-04", + "party": "Democratic-Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1805-03-04", + "end": "1809-03-04", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "B001133", + "govtrack": 402077, + "icpsr": 1302 + }, + "name": { + "first": "Aaron", + "last": "Burr", + "suffix": "Jr." + }, + "bio": { + "birthday": "1756-02-06", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1801-03-04", + "end": "1805-03-04", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "C000527", + "govtrack": 412587 + }, + "name": { + "first": "George", + "last": "Clinton" + }, + "bio": { + "birthday": "1739-07-26", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1805-03-04", + "end": "1809-03-04", + "party": "Democratic-Republican", + "how": "election" + }, + { + "type": "viceprez", + "start": "1809-03-04", + "end": "1812-04-20", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "G000139", + "govtrack": 404507, + "icpsr": 3541 + }, + "name": { + "first": "Elbridge", + "last": "Gerry" + }, + "bio": { + "birthday": "1744-07-17", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1813-03-04", + "end": "1814-11-23", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "M000043", + "govtrack": 407071, + "icpsr": 5903, + "icpsr_prez": 99872 + }, + "name": { + "first": "James", + "last": "Madison" + }, + "bio": { + "birthday": "1751-03-16", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1809-03-04", + "end": "1813-03-04", + "party": "Democratic-Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1813-03-04", + "end": "1817-03-04", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "T000306", + "govtrack": 412588 + }, + "name": { + "first": "Daniel", + "middle": "D.", + "last": "Tompkins" + }, + "bio": { + "birthday": "1774-06-21", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1817-03-04", + "end": "1821-03-05", + "party": "Democratic-Republican", + "how": "election" + }, + { + "type": "viceprez", + "start": "1821-03-05", + "end": "1825-03-04", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "M000858", + "govtrack": 407829, + "icpsr": 6594, + "icpsr_prez": 99873 + }, + "name": { + "first": "James", + "last": "Monroe" + }, + "bio": { + "birthday": "1758-04-28", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1817-03-04", + "end": "1821-03-05", + "party": "Democratic-Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1821-03-05", + "end": "1825-03-04", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "A000041", + "govtrack": 400702, + "icpsr": 34, + "icpsr_prez": 99874 + }, + "name": { + "first": "John", + "middle": "Quincy", + "last": "Adams" + }, + "bio": { + "birthday": "1767-07-11", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1825-03-04", + "end": "1829-03-04", + "party": "Democratic-Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "C000044", + "govtrack": 402205, + "icpsr": 1418 + }, + "name": { + "first": "John", + "middle": "Caldwell", + "last": "Calhoun" + }, + "bio": { + "birthday": "1782-03-18", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1825-03-04", + "end": "1829-03-04", + "party": "Democratic-Republican", + "how": "election" + }, + { + "type": "viceprez", + "start": "1829-03-04", + "end": "1832-12-28", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "J000005", + "govtrack": 405913, + "icpsr": 4843, + "icpsr_prez": 99875 + }, + "name": { + "first": "Andrew", + "last": "Jackson" + }, + "bio": { + "birthday": "1767-03-15", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1829-03-04", + "end": "1833-03-04", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1833-03-04", + "end": "1837-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "J000170", + "govtrack": 406067, + "icpsr": 4988 + }, + "name": { + "first": "Richard", + "middle": "Mentor", + "last": "Johnson" + }, + "bio": { + "birthday": "1780-10-17", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1837-03-04", + "end": "1841-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "V000009", + "govtrack": 411074, + "icpsr": 9595, + "icpsr_prez": 99876 + }, + "name": { + "first": "Martin", + "last": "Van Buren" + }, + "bio": { + "birthday": "1782-12-05", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1833-03-04", + "end": "1837-03-04", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1837-03-04", + "end": "1841-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H000279", + "govtrack": 405153, + "icpsr": 4138, + "icpsr_prez": 99877 + }, + "name": { + "first": "William", + "middle": "Henry", + "last": "Harrison" + }, + "bio": { + "birthday": "1773-02-09", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1841-03-04", + "end": "1841-04-04", + "party": "Whig", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "T000450", + "govtrack": 411018, + "icpsr": 9542, + "icpsr_prez": 99878 + }, + "name": { + "first": "John", + "last": "Tyler" + }, + "bio": { + "birthday": "1790-03-29", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1841-03-04", + "end": "1841-04-04", + "party": "Whig", + "how": "election" + }, + { + "type": "prez", + "start": "1841-04-04", + "end": "1845-03-04", + "party": "Whig", + "how": "succession" + } + ] + }, + { + "id": { + "bioguide": "D000011", + "govtrack": 403154, + "icpsr": 2305 + }, + "name": { + "first": "George", + "middle": "Mifflin", + "last": "Dallas" + }, + "bio": { + "birthday": "1792-07-10", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1845-03-04", + "end": "1849-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "P000409", + "govtrack": 408802, + "icpsr": 7507, + "icpsr_prez": 99879 + }, + "name": { + "first": "James", + "middle": "Knox", + "last": "Polk" + }, + "bio": { + "birthday": "1795-11-02", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1845-03-04", + "end": "1849-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412344, + "icpsr_prez": 99880 + }, + "name": { + "first": "Zachary", + "last": "Taylor" + }, + "bio": { + "birthday": "1784-11-24", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1849-03-04", + "end": "1850-07-09", + "party": "Whig", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "F000115", + "govtrack": 404072, + "icpsr": 3140, + "icpsr_prez": 99881 + }, + "name": { + "first": "Millard", + "last": "Fillmore" + }, + "bio": { + "birthday": "1800-01-07", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1849-03-04", + "end": "1850-07-09", + "party": "Whig", + "how": "election" + }, + { + "type": "prez", + "start": "1850-07-09", + "end": "1853-03-04", + "party": "Whig", + "how": "succession" + } + ] + }, + { + "id": { + "bioguide": "K000217", + "govtrack": 406377, + "icpsr": 5275 + }, + "name": { + "first": "William", + "middle": "Rufus de Vane", + "last": "King" + }, + "bio": { + "birthday": "1786-04-07", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1853-03-04", + "end": "1853-04-18", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "P000333", + "govtrack": 408730, + "icpsr": 7435, + "icpsr_prez": 99882 + }, + "name": { + "first": "Franklin", + "last": "Pierce" + }, + "bio": { + "birthday": "1804-11-23", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1853-03-04", + "end": "1857-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "B000789", + "govtrack": 401746, + "icpsr": 995, + "icpsr_prez": 99883 + }, + "name": { + "first": "John", + "middle": "Cabell", + "last": "Breckinridge" + }, + "bio": { + "birthday": "1821-01-16", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1857-03-04", + "end": "1861-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "B001005", + "govtrack": 401954, + "icpsr": 1186, + "icpsr_prez": 99883 + }, + "name": { + "first": "James", + "last": "Buchanan" + }, + "bio": { + "birthday": "1791-04-23", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1857-03-04", + "end": "1861-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H000121", + "govtrack": 405003, + "icpsr": 4001 + }, + "name": { + "first": "Hannibal", + "last": "Hamlin" + }, + "bio": { + "birthday": "1809-08-27", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1861-03-04", + "end": "1865-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "L000313", + "govtrack": 406807, + "icpsr": 5666, + "icpsr_prez": 99884 + }, + "name": { + "first": "Abraham", + "last": "Lincoln" + }, + "bio": { + "birthday": "1809-02-12", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1861-03-04", + "end": "1865-03-04", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1865-03-04", + "end": "1865-04-15", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "J000116", + "govtrack": 406017, + "icpsr": 4940, + "icpsr_prez": 99885 + }, + "name": { + "first": "Andrew", + "last": "Johnson" + }, + "bio": { + "birthday": "1808-12-29", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1865-03-04", + "end": "1865-04-15", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1865-04-15", + "end": "1869-03-04", + "party": "Democratic", + "how": "succession" + } + ] + }, + { + "id": { + "bioguide": "C000626", + "govtrack": 402755, + "icpsr": 1938 + }, + "name": { + "first": "Schuyler", + "last": "Colfax" + }, + "bio": { + "birthday": "1823-03-23", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1869-03-04", + "end": "1873-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "W000585", + "govtrack": 411739, + "icpsr": 10225 + }, + "name": { + "first": "Henry", + "last": "Wilson" + }, + "bio": { + "birthday": "1812-02-16", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1873-03-04", + "end": "1875-11-22", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412350, + "icpsr_prez": 99886 + }, + "name": { + "first": "Ulysses", + "middle": "Simpson", + "last": "Grant" + }, + "bio": { + "birthday": "1822-04-27", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1869-03-04", + "end": "1873-03-04", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1873-03-04", + "end": "1877-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "W000341", + "govtrack": 411503, + "icpsr": 9995 + }, + "name": { + "first": "William", + "middle": "Almon", + "last": "Wheeler" + }, + "bio": { + "birthday": "1819-06-30", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1877-03-04", + "end": "1881-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H000393", + "govtrack": 405261, + "icpsr": 4232, + "icpsr_prez": 99887 + }, + "name": { + "first": "Rutherford", + "middle": "Birchard", + "last": "Hayes" + }, + "bio": { + "birthday": "1822-10-04", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1877-03-04", + "end": "1881-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "G000063", + "govtrack": 404436, + "icpsr": 3473, + "icpsr_prez": 99888 + }, + "name": { + "first": "James", + "middle": "Abram", + "last": "Garfield" + }, + "bio": { + "birthday": "1831-11-19", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1881-03-04", + "end": "1881-09-19", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "A000303", + "govtrack": 400945, + "icpsr_prez": 99889 + }, + "name": { + "first": "Chester", + "middle": "Alan", + "last": "Arthur" + }, + "bio": { + "birthday": "1829-10-05", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1881-03-04", + "end": "1881-09-19", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1881-09-19", + "end": "1885-03-04", + "party": "Republican", + "how": "succession" + } + ] + }, + { + "id": { + "bioguide": "H000493", + "govtrack": 405356, + "icpsr": 4319 + }, + "name": { + "first": "Thomas", + "middle": "Andrews", + "last": "Hendricks" + }, + "bio": { + "birthday": "1819-09-07", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1885-03-04", + "end": "1885-11-25", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "M001018", + "govtrack": 407985, + "icpsr": 6742 + }, + "name": { + "first": "Levi", + "middle": "Parsons", + "last": "Morton" + }, + "bio": { + "birthday": "1824-05-16", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1889-03-04", + "end": "1893-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H000263", + "govtrack": 405139, + "icpsr": 4124, + "icpsr_prez": 99891 + }, + "name": { + "first": "Benjamin", + "last": "Harrison" + }, + "bio": { + "birthday": "1833-08-20", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1889-03-04", + "end": "1893-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "S000889", + "govtrack": 410350, + "icpsr": 8918 + }, + "name": { + "first": "Adlai", + "middle": "Ewing", + "last": "Stevenson" + }, + "bio": { + "birthday": "1835-10-23", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1893-03-04", + "end": "1897-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412354, + "icpsr_prez": 99890 + }, + "name": { + "first": "Grover", + "last": "Cleveland" + }, + "bio": { + "birthday": "1837-03-18", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1885-03-04", + "end": "1889-03-04", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1893-03-04", + "end": "1897-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H000660", + "govtrack": 412589 + }, + "name": { + "first": "Garret", + "middle": "Augustus", + "last": "Hobart" + }, + "bio": { + "birthday": "1844-06-03", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1897-03-04", + "end": "1899-11-21", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "M000522", + "govtrack": 407515, + "icpsr": 6312, + "icpsr_prez": 99892 + }, + "name": { + "first": "William", + "last": "McKinley", + "suffix": "Jr." + }, + "bio": { + "birthday": "1843-01-29", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1897-03-04", + "end": "1901-03-04", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1901-03-04", + "end": "1901-09-14", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "F000003", + "govtrack": 403965, + "icpsr": 3046 + }, + "name": { + "first": "Charles", + "middle": "Warren", + "last": "Fairbanks" + }, + "bio": { + "birthday": "1852-05-11", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1905-03-04", + "end": "1909-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "R000429", + "govtrack": 409394, + "icpsr_prez": 99893 + }, + "name": { + "first": "Theodore", + "last": "Roosevelt" + }, + "bio": { + "birthday": "1858-10-27", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1901-03-04", + "end": "1901-09-14", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1901-09-14", + "end": "1905-03-04", + "party": "Republican", + "how": "succession" + }, + { + "type": "prez", + "start": "1905-03-04", + "end": "1909-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "S000345", + "govtrack": 409841, + "icpsr": 8453 + }, + "name": { + "first": "James", + "middle": "Schoolcraft", + "last": "Sherman" + }, + "bio": { + "birthday": "1855-10-24", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1909-03-04", + "end": "1912-10-30", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412359, + "icpsr_prez": 99894 + }, + "name": { + "first": "William", + "middle": "Howard", + "last": "Taft" + }, + "bio": { + "birthday": "1857-09-15", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1909-03-04", + "end": "1913-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "M000164", + "govtrack": 412590 + }, + "name": { + "first": "Thomas", + "middle": "Riley", + "last": "Marshall" + }, + "bio": { + "birthday": "1854-03-14", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1913-03-04", + "end": "1917-03-04", + "party": "Democratic", + "how": "election" + }, + { + "type": "viceprez", + "start": "1917-03-04", + "end": "1921-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412360, + "icpsr_prez": 99895 + }, + "name": { + "first": "Woodrow", + "last": "Wilson" + }, + "bio": { + "birthday": "1856-12-28", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1913-03-04", + "end": "1917-03-04", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1917-03-04", + "end": "1921-03-04", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H000192", + "govtrack": 405073, + "icpsr": 4059, + "icpsr_prez": 99896 + }, + "name": { + "first": "Warren", + "middle": "Gamaliel", + "last": "Harding" + }, + "bio": { + "birthday": "1865-11-02", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1921-03-04", + "end": "1923-08-02", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "D000147", + "govtrack": 412591 + }, + "name": { + "first": "Charles", + "middle": "Gates", + "last": "Dawes" + }, + "bio": { + "birthday": "1865-08-27", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1925-03-04", + "end": "1929-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "C000738", + "govtrack": 402859, + "icpsr_prez": 99897 + }, + "name": { + "first": "Calvin", + "last": "Coolidge" + }, + "bio": { + "birthday": "1872-07-04", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1921-03-04", + "end": "1923-08-02", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1923-08-02", + "end": "1925-03-04", + "party": "Republican", + "how": "succession" + }, + { + "type": "prez", + "start": "1925-03-04", + "end": "1929-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "C001008", + "govtrack": 403115, + "icpsr": 2269 + }, + "name": { + "first": "Charles", + "last": "Curtis" + }, + "bio": { + "birthday": "1860-01-25", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1929-03-04", + "end": "1933-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412363, + "icpsr_prez": 99898 + }, + "name": { + "first": "Herbert", + "middle": "Clark", + "last": "Hoover" + }, + "bio": { + "birthday": "1874-08-10", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1929-03-04", + "end": "1933-03-04", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "G000074", + "govtrack": 404446, + "icpsr": 3482 + }, + "name": { + "first": "John", + "middle": "Nance", + "last": "Garner" + }, + "bio": { + "birthday": "1868-11-22", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1933-03-04", + "end": "1937-01-20", + "party": "Democratic", + "how": "election" + }, + { + "type": "viceprez", + "start": "1937-01-20", + "end": "1941-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "W000077", + "govtrack": 412592 + }, + "name": { + "first": "Henry", + "middle": "Agard", + "last": "Wallace" + }, + "bio": { + "birthday": "1888-10-07", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1941-01-20", + "end": "1945-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412364, + "icpsr_prez": 99899 + }, + "name": { + "first": "Franklin", + "middle": "Delano", + "last": "Roosevelt" + }, + "bio": { + "birthday": "1882-01-30", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1933-03-04", + "end": "1937-01-20", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1937-01-20", + "end": "1941-01-20", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1941-01-20", + "end": "1945-01-20", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1945-01-20", + "end": "1945-04-12", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "B000145", + "govtrack": 401146, + "icpsr": 437 + }, + "name": { + "first": "Alben", + "middle": "William", + "last": "Barkley" + }, + "bio": { + "birthday": "1877-11-24", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1949-01-20", + "end": "1953-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "T000387", + "govtrack": 410956, + "icpsr": 9487, + "icpsr_prez": 99900 + }, + "name": { + "first": "Harry", + "middle": "S.", + "last": "Truman" + }, + "bio": { + "birthday": "1884-05-08", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1945-01-20", + "end": "1945-04-12", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1945-04-12", + "end": "1949-01-20", + "party": "Democratic", + "how": "succession" + }, + { + "type": "prez", + "start": "1949-01-20", + "end": "1953-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412366, + "icpsr_prez": 99901 + }, + "name": { + "first": "Dwight", + "middle": "David", + "last": "Eisenhower" + }, + "bio": { + "birthday": "1890-10-14", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1953-01-20", + "end": "1957-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1957-01-20", + "end": "1961-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "K000107", + "govtrack": 406274, + "icpsr": 5180, + "icpsr_prez": 99902 + }, + "name": { + "first": "John", + "middle": "Fitzgerald", + "last": "Kennedy" + }, + "bio": { + "birthday": "1917-05-29", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1961-01-20", + "end": "1963-11-22", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H000953", + "thomas": "01366", + "govtrack": 405797, + "icpsr": 4728 + }, + "name": { + "first": "Hubert", + "middle": "Horatio", + "last": "Humphrey", + "suffix": "Jr." + }, + "bio": { + "birthday": "1911-05-27", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1965-01-20", + "end": "1969-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "J000160", + "govtrack": 406058, + "icpsr": 4979, + "icpsr_prez": 99903 + }, + "name": { + "first": "Lyndon", + "middle": "Baines", + "last": "Johnson" + }, + "bio": { + "birthday": "1908-08-27", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1961-01-20", + "end": "1963-11-22", + "party": "Democratic", + "how": "election" + }, + { + "type": "prez", + "start": "1963-11-22", + "end": "1965-01-20", + "party": "Democratic", + "how": "succession" + }, + { + "type": "prez", + "start": "1965-01-20", + "end": "1969-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "A000059", + "govtrack": 412593 + }, + "name": { + "first": "Spiro", + "middle": "Theodore", + "last": "Agnew" + }, + "bio": { + "birthday": "1918-11-09", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1969-01-20", + "end": "1973-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "viceprez", + "start": "1973-01-20", + "end": "1973-10-10", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "N000116", + "govtrack": 408200, + "icpsr": 6939, + "icpsr_prez": 99904 + }, + "name": { + "first": "Richard", + "middle": "Milhous", + "last": "Nixon" + }, + "bio": { + "birthday": "1913-01-09", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1953-01-20", + "end": "1957-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "viceprez", + "start": "1957-01-20", + "end": "1961-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1969-01-20", + "end": "1973-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1973-01-20", + "end": "1974-08-09", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "F000260", + "thomas": "00399", + "govtrack": 404212, + "icpsr": 3268, + "icpsr_prez": 99905 + }, + "name": { + "first": "Gerald", + "middle": "Rudolph", + "last": "Ford", + "suffix": "Jr." + }, + "bio": { + "birthday": "1913-07-14", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1973-12-06", + "end": "1974-08-09", + "party": "Republican", + "how": "appointment" + }, + { + "type": "prez", + "start": "1974-08-09", + "end": "1977-01-20", + "party": "Republican", + "how": "succession" + } + ] + }, + { + "id": { + "bioguide": "R000363", + "govtrack": 412594 + }, + "name": { + "first": "Nelson", + "middle": "Aldrich", + "last": "Rockefeller" + }, + "bio": { + "birthday": "1908-07-08", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1974-12-19", + "end": "1977-01-20", + "party": "Republican", + "how": "appointment" + } + ] + }, + { + "id": { + "bioguide": "M000851", + "thomas": "01402", + "govtrack": 407824, + "icpsr": 10813 + }, + "name": { + "first": "Walter", + "middle": "Frederick", + "last": "Mondale" + }, + "bio": { + "birthday": "1928-01-05", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1977-01-20", + "end": "1981-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412371, + "icpsr_prez": 99906 + }, + "name": { + "first": "James", + "middle": "Earl", + "last": "Carter", + "nickname": "Jimmy" + }, + "bio": { + "birthday": "1924-10-01", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1977-01-20", + "end": "1981-01-20", + "party": "Democratic", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412372, + "icpsr_prez": 99907 + }, + "name": { + "first": "Ronald", + "middle": "Wilson", + "last": "Reagan" + }, + "bio": { + "birthday": "1911-02-06", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1981-01-20", + "end": "1985-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1985-01-20", + "end": "1989-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "Q000007", + "thomas": "00935", + "govtrack": 408970, + "icpsr": 14447 + }, + "name": { + "first": "James", + "middle": "Danforth", + "last": "Quayle", + "nickname": "Dan" + }, + "bio": { + "birthday": "1947-02-04", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1989-01-20", + "end": "1993-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "B001166", + "govtrack": 402108, + "icpsr": 11008, + "icpsr_prez": 99908 + }, + "name": { + "first": "George", + "middle": "Herbert Walker", + "last": "Bush" + }, + "bio": { + "birthday": "1924-06-12", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1981-01-20", + "end": "1985-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "viceprez", + "start": "1985-01-20", + "end": "1989-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "1989-01-20", + "end": "1993-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "G000321", + "thomas": "00449", + "lis": "S170", + "govtrack": 404679, + "icpsr": 14423 + }, + "name": { + "first": "Albert", + "middle": "Arnold", + "last": "Gore", + "suffix": "Jr.", + "nickname": "Al" + }, + "bio": { + "birthday": "1948-03-31", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "1993-01-20", + "end": "1997-01-20", + "party": "Democrat", + "how": "election" + }, + { + "type": "viceprez", + "start": "1997-01-20", + "end": "2001-01-20", + "party": "Democrat", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412374, + "icpsr_prez": 99909 + }, + "name": { + "first": "William", + "middle": "Jefferson", + "last": "Clinton", + "nickname": "Bill" + }, + "bio": { + "birthday": "1946-08-19", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "1993-01-20", + "end": "1997-01-20", + "party": "Democrat", + "how": "election" + }, + { + "type": "prez", + "start": "1997-01-20", + "end": "2001-01-20", + "party": "Democrat", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "C000344", + "thomas": "00193", + "govtrack": 402484, + "icpsr": 14611 + }, + "name": { + "first": "Richard", + "middle": "Bruce", + "last": "Cheney", + "nickname": "Dick" + }, + "bio": { + "birthday": "1941-01-30", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "2001-01-20", + "end": "2005-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "viceprez", + "start": "2005-01-20", + "end": "2009-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412375 + }, + "name": { + "first": "George", + "middle": "Walker", + "last": "Bush" + }, + "bio": { + "birthday": "1946-07-06", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "2001-01-20", + "end": "2005-01-20", + "party": "Republican", + "how": "election" + }, + { + "type": "prez", + "start": "2005-01-20", + "end": "2009-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "B000444", + "thomas": "01284", + "lis": "S010", + "govtrack": 300008, + "opensecrets": "N00001669", + "votesmart": 53279, + "icpsr": 14101, + "fec": [ + "S8DE00012" + ], + "cspan": 34, + "wikipedia": "Joe Biden", + "wikidata": "Q6279", + "google_entity_id": "kg:/m/012gx2", + "ballotpedia": "Joe Biden" + }, + "name": { + "first": "Joseph", + "middle": "Robinette", + "last": "Biden", + "suffix": "Jr.", + "nickname": "Joe" + }, + "bio": { + "birthday": "1942-11-20", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "2009-01-20", + "end": "2013-01-20", + "party": "Democrat", + "how": "election" + }, + { + "type": "viceprez", + "start": "2013-01-20", + "end": "2017-01-20", + "party": "Democrat", + "how": "election" + }, + { + "type": "prez", + "start": "2021-01-20", + "end": "2025-01-20", + "party": "Democrat", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "O000167", + "thomas": "01763", + "lis": "S298", + "govtrack": 400629, + "opensecrets": "N00009638", + "votesmart": 9490 + }, + "name": { + "first": "Barack", + "middle": "Hussein", + "last": "Obama" + }, + "bio": { + "birthday": "1961-08-04", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "2009-01-20", + "end": "2013-01-20", + "party": "Democrat", + "how": "election" + }, + { + "type": "prez", + "start": "2013-01-20", + "end": "2017-01-20", + "party": "Democrat", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "P000587", + "thomas": "01649", + "govtrack": 400315, + "opensecrets": "N00003765", + "votesmart": 34024, + "fec": [ + "H8IN02060" + ], + "wikipedia": "Mike Pence", + "house_history": 20013, + "icpsr": 20117, + "wikidata": "Q24313", + "google_entity_id": "kg:/m/022r9r" + }, + "name": { + "first": "Mike", + "last": "Pence" + }, + "bio": { + "birthday": "1959-06-07", + "gender": "M" + }, + "terms": [ + { + "type": "viceprez", + "start": "2017-01-20", + "end": "2021-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "govtrack": 412733, + "opensecrets": "N00023864", + "votesmart": 15723, + "fec": [ + "P80001571" + ], + "wikipedia": "Donald Trump" + }, + "name": { + "first": "Donald", + "middle": "J.", + "last": "Trump" + }, + "bio": { + "birthday": "1946-06-14", + "gender": "M" + }, + "terms": [ + { + "type": "prez", + "start": "2017-01-20", + "end": "2021-01-20", + "party": "Republican", + "how": "election" + } + ] + }, + { + "id": { + "bioguide": "H001075", + "fec": [ + "S6CA00584" + ], + "govtrack": 412678, + "votesmart": 120012, + "wikipedia": "Kamala Harris", + "ballotpedia": "Kamala Harris", + "lis": "S387", + "wikidata": "Q10853588", + "google_entity_id": "kg:/m/08sry2", + "opensecrets": "N00036915", + "maplight": 2190, + "cspan": 1018696, + "icpsr": 41701 + }, + "name": { + "first": "Kamala", + "middle": "D.", + "last": "Harris", + "official_full": "Kamala D. Harris" + }, + "bio": { + "gender": "F", + "birthday": "1964-10-20" + }, + "terms": [ + { + "type": "viceprez", + "start": "2021-01-20", + "end": "2025-01-20", + "party": "Democrat", + "how": "election" + } + ] + } +] \ No newline at end of file diff --git a/docz/static/img/data.svg b/docz/static/img/data.svg new file mode 100644 index 0000000..192bc9b --- /dev/null +++ b/docz/static/img/data.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docz/static/img/favicon.ico b/docz/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3eb2306654c1c10ea5b1ebd313b7148c74e2f113 GIT binary patch literal 65931 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 literal 0 HcmV?d00001 diff --git a/docz/static/img/formats.svg b/docz/static/img/formats.svg new file mode 100644 index 0000000..08f30e9 --- /dev/null +++ b/docz/static/img/formats.svg @@ -0,0 +1,534 @@ + + + + + + +G + + + +csf + + +Common +Spreadsheet +Format +(JS Object) + + + +xls2 + +XLS +BIFF2 + + + +csf->xls2 + + + + + +xls3 + +XLS +BIFF3 + + + +csf->xls3 + + + + + +xls4 + +XLS +BIFF4 + + + +csf->xls4 + + + + + +xls5 + +XLS +BIFF5 + + + +csf->xls5 + + + + + +xls8 + +XLS +BIFF8 + + + +csf->xls8 + + + + + +xlml + +SSML +(2003/4) + + + +csf->xlml + + + + + +xlsx + +XLSX +XLSM + + + +csf->xlsx + + + + + +xlsb + +XLSB +BIFF12 + + + +csf->xlsb + + + + + +nums + +NUMBERS + + + +csf->nums + + + + + +ods + +ODS + + + +csf->ods + + + + + +fods + +FODS + + + +csf->fods + + + + + +html + +HTML +Table + + + +csf->html + + + + + +csv + +CSV + + + +csf->csv + + + + + +txt + +TXT +UTF-16 + + + +csf->txt + + + + + +dbf + +DBF + + + +csf->dbf + + + + + +dif + +DIF + + + +csf->dif + + + + + +slk + +SYLK + + + +csf->slk + + + + + +prn + +PRN + + + +csf->prn + + + + + +rtf + +RTF + + + +csf->rtf + + + + + +wk1 + +WK1 + + + +csf->wk1 + + + + + +wk3 + +WK3 + + + +csf->wk3 + + + + + +eth + +ETH + + + +csf->eth + + + + + +xls2->csf + + + + + +xls3->csf + + + + + +xls4->csf + + + + + +xls5->csf + + + + + +xls8->csf + + + + + +xlml->csf + + + + + +xlsx->csf + + + + + +xlsb->csf + + + + + +nums->csf + + + + + +ods->csf + + + + + +fods->csf + + + + + +uos + +UOS + + + +uos->csf + + + + + +html->csf + + + + + +csv->csf + + + + + +txt->csf + + + + + +dbf->csf + + + + + +dif->csf + + + + + +slk->csf + + + + + +prn->csf + + + + + +wk1->csf + + + + + +wksl + +WKS +Lotus + + + +wksl->csf + + + + + +wk3->csf + + + + + +wk4 + +WK4 + + + +wk4->csf + + + + + +123 + +123 + + + +123->csf + + + + + +wksm + +WKS +Works + + + +wksm->csf + + + + + +xlr + +XLR + + + +xlr->csf + + + + + +wq1 + +WQ1 + + + +wq1->csf + + + + + +wq2 + +WQ2 +WB* + + + +wq2->csf + + + + + +qpw + +QPW + + + +qpw->csf + + + + + +eth->csf + + + + + diff --git a/docz/static/img/logo.svg b/docz/static/img/logo.svg new file mode 100644 index 0000000..5fe8eb5 --- /dev/null +++ b/docz/static/img/logo.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docz/static/img/places.svg b/docz/static/img/places.svg new file mode 100644 index 0000000..5618105 --- /dev/null +++ b/docz/static/img/places.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docz/static/img/tools.svg b/docz/static/img/tools.svg new file mode 100644 index 0000000..5cfdc5c --- /dev/null +++ b/docz/static/img/tools.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docz/version.js b/docz/version.js new file mode 100644 index 0000000..6453a5d --- /dev/null +++ b/docz/version.js @@ -0,0 +1,2 @@ +const current = "0.18.7"; +export default current;