Compare commits

...

104 Commits

Author SHA1 Message Date
Pieter Sheth-Voss
8f7a29464d
Merge pull request #151 from oosswwaalldd/patch-1
Fixed horizontal alignment values
2020-08-27 22:46:48 -04:00
Oswald Reyes
6d0f51fc98
Fixed horizontal alignment values
Replaced current values for `left`, `center` and `right`
2020-08-27 19:11:51 -04:00
Pieter Sheth-Voss
6226e1afe8 Undo last commit 2019-09-18 09:46:57 -04:00
Pieter Sheth-Voss
92333227c4 Add examples 2019-04-01 17:34:29 -04:00
Pieter Sheth-Voss
c86472d281 Merge branch 'master' of https://github.com/protobi/js-xlsx 2017-05-31 15:51:21 -04:00
Pieter Sheth-Voss
f2520b7223 Freeze columns 2017-05-31 15:50:29 -04:00
Pieter Sheth-Voss
68ba4e8f58 Merge pull request #64 from zeg-io/patch-1
Fixed Style Table in README.md
2017-04-04 11:21:56 -04:00
Tony
c224819b16 Fixed Style Table in README.md
Table had an extra column defined that did not exist and was trashing the conversion to a table
2017-04-04 09:46:28 -05:00
Pieter Sheth-Voss
a03dc219ab Add freeze panes 2017-04-03 00:43:27 -04:00
Pieter Sheth-Voss
f959b02ae9 Add freeze panes 2017-04-03 00:43:05 -04:00
Pieter Sheth-Voss
9edf279467 Add freeze pane option 2017-04-02 22:53:03 -04:00
Pieter Sheth-Voss
1903cff791 Merge remote-tracking branch 'origin/master' 2016-10-11 09:12:12 -04:00
Pieter Sheth-Voss
6e6678960c PR #40 - Skip cells with incorrect link to shared strings 2016-10-11 09:11:45 -04:00
protobi
d5092b42cb Merge pull request #46 from noodoo/fix/lower-case-files
Fix file getter: letter case not match
2016-09-28 21:35:57 -04:00
Georgy Chikhladze
d3f63434a0 Apply letter case issue fix to the source code 2016-09-10 12:55:46 +03:00
Georgy Chikhladze
796fbb515a Fix file getter: letter case not match 2016-07-14 18:56:31 +03:00
Pieter Sheth-Voss
3c7f807bfa Revert package name 2016-05-25 00:27:49 -04:00
Pieter Sheth-Voss
34d618c8fe Update tests; add feature to freeze headerrow 2016-05-24 23:30:56 -04:00
Pieter Sheth-Voss
245ffb895a Update tests; add feature to freeze headerrow 2016-05-24 23:26:43 -04:00
Pieter Sheth-Voss
8198744d58 merge from beta 2016-05-24 22:50:24 -04:00
Pieter Sheth-Voss
2424890518 Merge remote-tracking branch 'origin/beta' into beta 2016-05-24 17:28:06 -04:00
Pieter Sheth-Voss
0b8e5386bb Add repeating print headers 2016-05-24 17:27:37 -04:00
Pieter Sheth-Voss
eef7da3099 Merge branch 'master' of https://github.com/protobi/js-xlsx 2016-04-05 23:17:18 -04:00
Pieter Sheth-Voss
876c4a0552 Set tabSelected to 0 per issue #26 2016-04-05 23:17:01 -04:00
Pieter Sheth-Voss
bed6327d22 Set tabSelected to 0 per issue #26 2016-04-05 23:09:20 -04:00
protobi
2ec18e96ba Update README.md 2016-03-08 13:27:38 -05:00
protobi
050b74edbf Update README.md 2016-03-08 13:27:03 -05:00
protobi
0e62411e83 Update README.md 2016-03-08 13:26:42 -05:00
protobi
aceebf4690 Update README.md 2016-03-08 13:06:00 -05:00
protobi
9407fe8aeb Update README.md 2016-03-08 13:05:12 -05:00
protobi
166d0e33bf Update README.md 2016-03-08 13:04:54 -05:00
protobi
fe748adc01 Copy README from beta 2016-03-08 12:57:04 -05:00
Pieter Sheth-Voss
f984bd6479 Add rowBreaks, colBreaks, scale, showGridLines 2015-12-05 16:45:13 -05:00
Pieter Sheth-Voss
7de41c2657 Add doc props 2015-12-04 23:15:03 -05:00
Pieter Sheth-Voss
0bf1153da5 Add page scale and orientation 2015-12-04 21:53:47 -05:00
Pieter Sheth-Voss
376096b151 Add page setup 2015-12-04 21:23:19 -05:00
Pieter Sheth-Voss
bbeec3edfd Add row/col breaks 2015-12-04 21:02:05 -05:00
Pieter Sheth-Voss
43f569884a Add row and column breaks 2015-12-04 20:57:48 -05:00
Pieter Sheth-Voss
d4e0b8b172 Bump bower version to 0.87 2015-12-04 09:56:10 -05:00
Pieter Sheth-Voss
634699fb16 Merge branch 'master' of https://github.com/protobi/js-xlsx into beta 2015-12-04 09:54:41 -05:00
Pieter Sheth-Voss
2886195440 Merge branch 'master' of https://github.com/protobi/js-xlsx 2015-12-04 09:53:53 -05:00
Pieter Sheth-Voss
8b1add6659 Add showGridLines as option 2015-12-04 09:53:43 -05:00
Pieter Sheth-Voss
fd83f20b40 Merge branch 'master' of https://github.com/protobi/js-xlsx into beta 2015-12-04 09:49:24 -05:00
Pieter Sheth-Voss
03b755b3ae Add showGridlines 2015-12-04 09:49:11 -05:00
protobi
d00f36f94f Merge pull request #10 from CoorpAcademy/fix-ref-styles
Breaks references in style objects
2015-08-13 13:12:41 -04:00
godu
599f285dfd Breaks ref in style object 2015-08-13 16:46:31 +02:00
godu
905c51206b Adds tests 2015-08-13 16:43:29 +02:00
godu
7461389d49 Adds cheerio dependencie for tests/test-style.js 2015-08-13 16:34:02 +02:00
Pieter Sheth-Voss
57b6fd4662 Pull changes to persist styles with blank cells; increment versions for bower and npm; run cp node_modules/codepage/dist/cpexcel.full.js dist/cpexcel.js
cp jszip.js dist/jszip.js
cp ods.js dist/ods.js
cp xlsx.js dist/
cp LICENSE dist/
uglifyjs xlsx.js -o dist/xlsx.min.js --source-map dist/xlsx.min.map --preamble "$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/xlsx.min.js
uglifyjs jszip.js xlsx.js -o dist/xlsx.core.min.js --source-map dist/xlsx.core.min.map --preamble "$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/xlsx.core.min.js
uglifyjs jszip.js dist/cpexcel.js xlsx.js -o dist/xlsx.full.min.js --source-map dist/xlsx.full.min.map --preamble "$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/xlsx.full.min.js
2015-08-11 17:40:53 -04:00
Pieter Sheth-Voss
348c533f6c Update bower version to 0.8.5 2015-08-11 17:32:56 -04:00
Pieter Sheth-Voss
3e3633ad52 Merge master to preserve blank style; increment version number 2015-08-11 17:30:32 -04:00
Pieter Sheth-Voss
d76234ae80 Merge remote-tracking branch 'origin/master' into beta 2015-08-11 17:28:32 -04:00
Pieter Sheth-Voss
0d1281cc94 Added test files 2015-08-11 17:23:56 -04:00
Pieter Sheth-Voss
dcf6f17455 Retain styles for blank cells 2015-08-11 17:20:09 -04:00
Pieter Sheth-Voss
f52c80eef6 Remove lab, .idea, test-csv, test-acid, etc. from repo 2015-06-26 13:10:56 -04:00
Pieter Sheth-Voss
e7b06d7a62 Remove lab, .idea, test-csv, test-acid, etc. from repo 2015-06-26 13:07:56 -04:00
Pieter Sheth-Voss
1ca3c3e6b5 Remove lab, .idea, test-csv, test-acid, etc. from repo 2015-06-26 13:04:45 -04:00
Pieter Sheth-Voss
c034eda675 Update README, bower, package 2015-06-12 21:22:05 -04:00
Pieter Sheth-Voss
3010d93f40 Update README, bower, package 2015-06-12 21:00:21 -04:00
Pieter Sheth-Voss
d60a0a5b89 Update README, bower, package 2015-06-12 20:58:07 -04:00
Pieter Sheth-Voss
a6023550ee Update README, bower, package 2015-06-12 20:56:36 -04:00
Pieter Sheth-Voss
9145958b40 Update README, bower, package 2015-06-12 20:35:36 -04:00
Pieter Sheth-Voss
0096c09dd3 Update README, bower, package 2015-06-12 20:32:58 -04:00
Pieter Sheth-Voss
8801e76e3f Make dist and update package name 2015-06-12 20:19:05 -04:00
Pieter Sheth-Voss
0255a05f14 Remove temp example files from repo 2015-06-11 23:31:42 -04:00
Pieter Sheth-Voss
4099a24cfa Default gray125 style per pull request #3 2015-06-04 12:05:26 -04:00
Pieter Sheth-Voss
ed0cd9b2c1 Add alignment; update README 2015-05-21 15:52:24 -04:00
Pieter Sheth-Voss
858abf1103 Remove requirement that require, module or jquery be defined before using StyleBuilder 2015-05-12 09:01:24 -04:00
Pieter Sheth-Voss
21e1976f82 Merge branch 'master' of https://github.com/protobi/js-xlsx 2015-05-08 09:14:48 -04:00
Pieter Sheth-Voss
40cfb0cf8f Document wrapText 2015-05-08 09:09:20 -04:00
Pieter Sheth-Voss
acf60c22bc Merge pull request #2 from knownasilya/patch-2
Add syntax highlighting to readme examples
2015-04-20 15:37:36 -04:00
Ilya Radchenko
c2873831ca Add syntax highlighting to readme examples 2015-04-20 15:25:10 -04:00
Pieter Sheth-Voss
5dbf215c9c Correct hex2RGB coding, apply tints 2015-04-17 13:15:13 -04:00
Pieter Sheth-Voss
89066b45b6 Save fill color to .rgb but not tint 2015-04-17 11:18:51 -04:00
Pieter Sheth-Voss
51b7cabd2c Parse raw_rgb 2015-04-17 10:21:48 -04:00
Pieter Sheth-Voss
08e648bbb5 Update tests to reflect change in spec for fills 2015-04-16 10:40:46 -04:00
Pieter Sheth-Voss
0b1a0408cb Merge changes from upsteam 2015-04-15 16:40:26 -04:00
Pieter Sheth-Voss
5f9576a6d2 Read borders and alignments 2015-04-15 15:07:45 -04:00
Pieter Sheth-Voss
114f257ce4 Merge remote-tracking branch 'origin/master' 2015-04-15 09:52:35 -04:00
Pieter Sheth-Voss
9102c8214d Added round-trip test for styles 2015-03-29 15:21:11 -04:00
Pieter Sheth-Voss
8da3738378 Update README.md
Add additional font style options
2015-03-28 13:12:54 -04:00
Pieter Sheth-Voss
995f5e89bf Parse font bold-italic-strike-outline-shadow-superscript-subscript 2015-03-28 13:05:53 -04:00
Pieter Sheth-Voss
37a031caee Parse font bold-italic-strike-outline-shadow-superscript-subscript 2015-03-28 13:04:20 -04:00
Pieter Sheth-Voss
27a300b862 Read styles - font, fill and numFmt 2015-03-28 12:32:46 -04:00
Pieter Sheth-Voss
33c32f0647 Merge remote-tracking branch 'origin/master' 2015-03-19 22:50:22 -04:00
Pieter Sheth-Voss
4f4f7fc6bc Fix issue exporting font color 2015-03-19 22:49:24 -04:00
Pieter Sheth-Voss
ad2a1203f1 Update README.md
Add notes for bordering merged cells
2015-03-12 23:47:02 -04:00
Pieter Sheth-Voss
0e2b8a499d Merge pull request #1 from knownasilya/patch-2
Remove broken link
2015-03-12 11:16:25 -04:00
Ilya Radchenko
1a51c40423 Remove broken link 2015-03-12 10:47:35 -04:00
Pieter Sheth-Voss
9b76f6b1f5 Update README for textRotation 2015-03-12 09:54:59 -04:00
Pieter Sheth-Voss
aa8f3a759f Add support for textRotation 2015-03-12 09:52:30 -04:00
Pieter Sheth-Voss
33dc7b883d Update README.md 2015-03-09 10:05:20 -04:00
Pieter Sheth-Voss
97d4001343 Update Style specifications in README.md 2015-03-09 10:04:34 -04:00
Pieter Sheth-Voss
c3af249415 Add styles to README.md 2015-03-09 09:59:31 -04:00
Pieter Sheth-Voss
5e443310f8 Remove stray console.log() calls 2015-03-07 00:02:18 -05:00
Pieter Sheth-Voss
91ec052ae6 Added support for borders 2015-03-06 23:55:50 -05:00
Pieter Sheth-Voss
1f02e5bea2 Handle embedded quotes in number formats 2015-03-05 12:18:36 -05:00
Pieter Sheth-Voss
05b58d839a Escape embedded quotes 2015-03-03 14:27:28 -05:00
Pieter Sheth-Voss
576b59f96a Fix issue with custom formats 2015-03-02 00:28:11 -05:00
Pieter Sheth-Voss
cd2b20f7e5 Remove stray logs 2015-03-01 23:27:00 -05:00
Pieter Sheth-Voss
5f7a0f2ad2 Removed dependence on cheerio, jquery; added xmlbuilder; 2015-03-01 23:18:10 -05:00
Pieter Sheth-Voss
a562150b96 Use jQuery parseXML to preserve case in XML 2015-03-01 00:39:47 -05:00
Pieter Sheth-Voss
845d2a8880 Added support for alignment 2015-02-28 11:55:15 -05:00
Pieter Sheth-Voss
0227496616 Add ability to save cell styles to .xlsx 2015-02-28 01:42:41 -05:00
47 changed files with 9611 additions and 1419 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

6
.gitignore vendored

@ -19,3 +19,9 @@ tmp
*.htm
*.html
*.sheetjs
lab/
test_files
example.js
example2.js
.idea

197
README.md

@ -1,7 +1,18 @@
# xlsx
# xlsx-style
Parser and writer for various spreadsheet formats. Pure-JS cleanroom
implementation from official specifications and related documents.
Parser and writer for various spreadsheet formats. Pure-JS cleanroom implementation from official specifications and related documents.
# About this fork
**NOTE:** [This project](https://github.com/SheetJS/js-xlsx/tree/beta) is a fork of the original (and awesome) [SheetJS/xlsx](https://github.com/SheetJS/js-xlsx) project.
It is extended to enable cell formats to be read from and written to .xlsx workbooks.
The intent is to provide a temporary means of using these features in practice, and ultimately to merge this into the primary project.
Report any issues to https://github.com/protobi/js-xlsx/issues.
For those contributing to this fork:
* `master` is the main branch, which follows the original repo to enable a future pull request.
* `beta` branch is published to npm and bower to make this fork available for use.
# Supported formats
Supported read formats:
@ -24,17 +35,23 @@ Source: <http://git.io/xlsx>
## Installation
With [npm](https://www.npmjs.org/package/xlsx):
With [npm](https://www.npmjs.org/package/xlsx-style):
npm install xlsx
```sh
npm install xlsx-style --save
```
In the browser:
<script lang="javascript" src="dist/xlsx.core.min.js"></script>
```html
<script lang="javascript" src="dist/xlsx.core.min.js"></script>
```
With [bower](http://bower.io/search/?q=js-xlsx):
bower install js-xlsx
```sh
bower install js-xlsx-style#beta
```
CDNjs automatically pulls the latest version and makes all versions available at
<http://cdnjs.com/libraries/xlsx>
@ -46,10 +63,12 @@ of these modules are rather large in size and are only needed in special
circumstances, so they do not ship with the core. For browser use, they must
be included directly:
<!-- international support from https://github.com/sheetjs/js-codepage -->
<script src="dist/cpexcel.js"></script>
<!-- ODS support -->
<script src="dist/ods.js"></script>
```html
<!-- international support from https://github.com/sheetjs/js-codepage -->
<script src="dist/cpexcel.js"></script>
<!-- ODS support -->
<script src="dist/ods.js"></script>
```
An appropriate version for each dependency is included in the dist/ directory.
@ -63,7 +82,9 @@ Since xlsx.js uses ES5 functions like `Array#forEach`, older browsers require
To use the shim, add the shim before the script tag that loads xlsx.js:
<script type="text/javascript" src="/path/to/shim.js"></script>
```html
<script type="text/javascript" src="/path/to/shim.js"></script>
```
## Parsing Workbooks
@ -72,7 +93,7 @@ data and feeding it into the library. Here are a few common scenarios:
- node readFile:
```
```js
if(typeof require !== 'undefined') XLSX = require('xlsx');
var workbook = XLSX.readFile('test.xlsx');
/* DO SOMETHING WITH workbook HERE */
@ -81,10 +102,11 @@ var workbook = XLSX.readFile('test.xlsx');
- ajax (for a more complete example that works in older browsers, check the demo
at <http://oss.sheetjs.com/js-xlsx/ajax.html>):
```
```js
/* set up XMLHttpRequest */
var url = "test_files/formula_stress_test_ajax.xlsx";
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
@ -108,13 +130,14 @@ oReq.send();
- HTML5 drag-and-drop using readAsBinaryString:
```
```js
/* set up drag-and-drop event */
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
var i,f;
var i, f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
@ -134,10 +157,11 @@ drop_dom_element.addEventListener('drop', handleDrop, false);
- HTML5 input file element using readAsBinaryString:
```
```js
function handleFile(e) {
var files = e.target.files;
var i,f;
var i, f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
@ -160,7 +184,7 @@ The full object format is described later in this README.
This example extracts the value stored in cell A1 from the first worksheet:
```
```js
var first_sheet_name = workbook.SheetNames[0];
var address_of_cell = 'A1';
@ -176,8 +200,9 @@ var desired_value = desired_cell.v;
This example iterates through every nonempty of every sheet and dumps values:
```
```js
var sheet_name_list = workbook.SheetNames;
sheet_name_list.forEach(function(y) { /* iterate through sheets */
var worksheet = workbook.Sheets[y];
for (z in worksheet) {
@ -195,7 +220,9 @@ Complete examples:
Note that older versions of IE does not support HTML5 File API, so the base64
mode is provided for testing. On OSX you can get the base64 encoding with:
$ <target_file.xlsx base64 | pbcopy
```sh
$ <target_file.xlsx base64 | pbcopy
```
- <http://oss.sheetjs.com/js-xlsx/ajax.html> XMLHttpRequest
@ -220,7 +247,7 @@ Assuming `workbook` is a workbook object:
- nodejs write to file:
```
```js
/* output format determined by filename */
XLSX.writeFile(workbook, 'out.xlsx');
/* at this point, out.xlsx is a file that you can distribute */
@ -228,7 +255,7 @@ XLSX.writeFile(workbook, 'out.xlsx');
- write to binary string (using FileSaver.js):
```
```js
/* bookType can be 'xlsx' or 'xlsm' or 'xlsb' */
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
@ -303,7 +330,7 @@ Cell range objects are stored as `{s:S, e:E}` where `S` is the first cell and
range `A3:B7` is represented by the object `{s:{c:0, r:2}, e:{c:1, r:6}}`. Utils
use the following pattern to walk each of the cells in a 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};
@ -331,6 +358,9 @@ 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.
**Note**: The .z attribute is now deprecated. Use the `.s` attribute to specify cell styles including number formats.
To specify a number format, use `s.numFmt`, e.g. `{v: 42145.822, s: { numFmt: "m/dd/yy"}}` described below.
### Data Types
The raw value is stored in the `v` field, interpreted based on the `t` field.
@ -400,14 +430,39 @@ Special worksheet keys (accessible as `worksheet[key]`, each starting with `!`):
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['!printHeader']`: array of row indices for repeating row headers on print, e.g. `[1:1]` to repeat just the first row.
The following properties are currently used when generating an XLSX file, but not yet parsed:
- `ws['!rowBreaks']`: array of row break points, e.g. `[16,32]`
- `ws['!colBreaks']`: array of col break points, e.g. `[8,16]`
- `ws['!pageSetup']`: `{scale: '100', orientation: 'portrait'||'landscape'}
- `ws['!printHeader']`: array of first and last row indexes for repeat header on printing, e.g. `[1,1]` to repeat just first row
- `ws['!freeze']`: string cell reference for breakpoint, e.g. the following will freeze the first row and first column:
{
xSplit: "1",
ySplit: "1",
topLeftCell: "B2",
activePane: "bottomRight",
state: "frozen"
}
### 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
`wb.Props` is an object storing the standard properties. The following properties are currently used when
generating an XLSX file, but not yet parsed:
- `title`
- `subject`
- `description`
- `keywords`
- `creator`
`wb.Custprops` stores custom properties. Since the XLS standard properties deviate from the XLSX
standard, XLS parsing stores core properties in both places. .
@ -459,6 +514,12 @@ The exported `write` and `writeFile` functions accept an options argument:
| cellDates | false | Store dates as type `d` (default is `n`) |
| bookSST | false | Generate Shared String Table ** |
| bookType | 'xlsx' | Type of Workbook ("xlsx" or "xlsm" or "xlsb") |
| showGridLines | true | Show gridlines on all pages |
| tabSelected | '1' | Initial tab selected |
| Props | null | Workbook properties |
- `bookSST` is slower and more memory intensive, but has better compatibility
with older versions of iOS Numbers
@ -468,6 +529,84 @@ The exported `write` and `writeFile` functions accept an options argument:
- `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 blow up in the presence of dates.
- showGridLines and tabSelected are currently used when generating an XLSX file but not yet parse.
- Props specifies workbook properties
## Cell Styles
Cell styles are specified by a style object that roughly parallels the OpenXML structure. The style object has five
top-level attributes: `fill`, `font`, `numFmt`, `alignment`, and `border`.
| Style Attribute | Sub Attributes | Values |
| :-------------- | :------------- | :------------- |
| fill | patternType | `"solid"` or `"none"`
| | fgColor | `COLOR_SPEC`
| | bgColor | `COLOR_SPEC`
| font | name | `"Calibri"` // default
| | sz | `"11"` // font size in points
| | color | `COLOR_SPEC`
| | bold | `true` or `false`
| | underline | `true` or `false`
| | italic | `true` or `false`
| | strike | `true` or `false`
| | outline | `true` or `false`
| | shadow | `true` or `false`
| | vertAlign | `true` or `false`
| numFmt | | `"0"` // integer index to built in formats, see StyleBuilder.SSF property
| | | `"0.00%"` // string matching a built-in format, see StyleBuilder.SSF
| | | `"0.0%"` // string specifying a custom format
| | | `"0.00%;\\(0.00%\\);\\-;@"` // string specifying a custom format, escaping special characters
| | | `"m/dd/yy"` // string a date format using Excel's format notation
| alignment | vertical | `"bottom"` or `"center"` or `"top"`
| | horizontal | `"left"` or `"center"` or `"right"`
| | wrapText | `true ` or ` false`
| | readingOrder | `2` // for right-to-left
| | textRotation | Number from `0` to `180` or `255` (default is `0`)
| | | `90` is rotated up 90 degrees
| | | `45` is rotated up 45 degrees
| | | `135` is rotated down 45 degrees
| | | `180` is rotated down 180 degrees
| | | `255` is special, aligned vertically
| border | top | `{ style: BORDER_STYLE, color: COLOR_SPEC }`
| | bottom | `{ style: BORDER_STYLE, color: COLOR_SPEC }`
| | left | `{ style: BORDER_STYLE, color: COLOR_SPEC }`
| | right | `{ style: BORDER_STYLE, color: COLOR_SPEC }`
| | diagonal | `{ style: BORDER_STYLE, color: COLOR_SPEC }`
| | diagonalUp | `true` or `false`
| | diagonalDown | `true` or `false`
**COLOR_SPEC**: Colors for `fill`, `font`, and `border` are specified as objects, either:
* `{ auto: 1}` specifying automatic values
* `{ rgb: "FFFFAA00" }` specifying a hex ARGB value
* `{ theme: "1", tint: "-0.25"}` specifying an integer index to a theme color and a tint value (default 0)
* `{ indexed: 64}` default value for `fill.bgColor`
**BORDER_STYLE**: Border style is a string value which may take on one of the following values:
* `thin`
* `medium`
* `thick`
* `dotted`
* `hair`
* `dashed`
* `mediumDashed`
* `dashDot`
* `mediumDashDot`
* `dashDotDot`
* `mediumDashDotDot`
* `slantDashDot`
Borders for merged areas are specified for each cell within the merged area. So to apply a box border to a merged area of 3x3 cells, border styles would need to be specified for eight different cells:
* left borders for the three cells on the left,
* right borders for the cells on the right
* top borders for the cells on the top
* bottom borders for the cells on the left
## Tested Environments
@ -494,7 +633,7 @@ Running `make init` will refresh the `test_files` submodule and get the files.
[the oss.sheetjs.com repo](https://github.com/SheetJS/SheetJS.github.io) and
replace the xlsx.js file (then fire up the browser and go to `stress.html`):
```
```sh
$ cp xlsx.js ../SheetJS.github.io
$ cd ../SheetJS.github.io
$ simplehttpserver # or "python -mSimpleHTTPServer" or "serve"
@ -513,7 +652,7 @@ 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 move the script:
```
```sh
$ mv xlsx.js xlsx.new.js
$ make
$ diff xlsx.js xlsx.new.js
@ -564,5 +703,3 @@ Open Document Format for Office Applications Version 1.2 (29 September 2011)
[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/ed5bb2c4c4346a474fef270f847f3f78 "githalytics.com")](http://githalytics.com/SheetJS/js-xlsx)

@ -1 +1 @@
XLSX.version = '0.8.0';
XLSX.version = '0.8.20';

@ -15,8 +15,14 @@ function getdata(data) {
function safegetzipfile(zip, file) {
var f = file; if(zip.files[f]) return zip.files[f];
f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
var lowerCaseFiles = {};
for (var key in zip.files) {
lowerCaseFiles[key.toLowerCase()] = zip.files[key];
}
f = file.toLowerCase(); if(lowerCaseFiles[f]) return lowerCaseFiles[f];
f = f.replace(/\//g,'\\'); if(lowerCaseFiles[f]) return lowerCaseFiles[f];
return null;
}

@ -60,13 +60,20 @@ function cp_doit(f, g, h, o, p) {
function write_core_props(cp, opts) {
var o = [XML_HEADER, CORE_PROPS_XML_ROOT], p = {};
if(!cp) return o.join("");
if (opts && opts.Props) {
if (opts.Props.title) o[o.length] = '<dc:title>' + opts.Props.title + '</dc:title>';
if (opts.Props.subject) o[o.length] = '<dc:subject>' + opts.Props.subject + '</dc:subject>';
if (opts.Props.creator) o[o.length] = '<dc:creator>' + opts.Props.creator + '</dc:creator>';
if (opts.Props.keywords) o[o.length] = '<cp:keywords>' + opts.Props.keywords + '</cp:keywords>';
if (opts.Props.description) o[o.length] = '<dc:description>' + opts.Props.description + '</dc:description>';
}
if(cp) {
if(cp.CreatedDate != null) cp_doit("dcterms:created", typeof cp.CreatedDate === "string" ? cp.CreatedDate : write_w3cdtf(cp.CreatedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
if(cp.ModifiedDate != null) cp_doit("dcterms:modified", typeof cp.ModifiedDate === "string" ? cp.ModifiedDate : write_w3cdtf(cp.ModifiedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
if(cp.CreatedDate != null) cp_doit("dcterms:created", typeof cp.CreatedDate === "string" ? cp.CreatedDate : write_w3cdtf(cp.CreatedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
if(cp.ModifiedDate != null) cp_doit("dcterms:modified", typeof cp.ModifiedDate === "string" ? cp.ModifiedDate : write_w3cdtf(cp.ModifiedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
for(var i = 0; i != CORE_PROPS.length; ++i) { var f = CORE_PROPS[i]; cp_doit(f[0], cp[f[1]], null, o, p); }
if(o.length>2){ o[o.length] = ('</cp:coreProperties>'); o[1]=o[1].replace("/>",">"); }
return o.join("");
for(var i = 0; i != CORE_PROPS.length; ++i) { var f = CORE_PROPS[i]; cp_doit(f[0], cp[f[1]], null, o, p); }
}
if(o.length>2){ o[o.length] = ('</cp:coreProperties>'); o[1]=o[1].replace("/>",">"); }
return o.join("");
}

@ -1,6 +1,6 @@
function hex2RGB(h) {
var o = h.substr(h[0]==="#"?1:0,6);
return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
}
function rgb2Hex(rgb) {
for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]);
@ -42,11 +42,12 @@ function hsl2RGB(hsl){
/* 18.8.3 bgColor tint algorithm */
function rgb_tint(hex, tint) {
if(tint === 0) return hex;
if(tint == 0) return hex;
var hsl = rgb2HSL(hex2RGB(hex));
if (tint < 0) hsl[2] = hsl[2] * (1 + tint);
else hsl[2] = 1 - (1 - hsl[2]) * (1 - tint);
return rgb2Hex(hsl2RGB(hsl));
var rev =rgb2Hex(hsl2RGB(hsl))
return rev;
}
/* 18.3.1.13 width calculations */

@ -1,169 +1,400 @@
/* 18.8.21 fills CT_Fills */
function parse_fills(t, opts) {
styles.Fills = [];
var fill = {};
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<fills': case '<fills>': case '</fills>': break;
styles.Fills = [];
var fill = {};
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<fills':
case '<fills>':
case '</fills>':
break;
/* 18.8.20 fill CT_Fill */
case '<fill>': break;
case '</fill>': styles.Fills.push(fill); fill = {}; break;
/* 18.8.20 fill CT_Fill */
case '<fill>':
break;
case '</fill>':
styles.Fills.push(fill);
fill = {};
break;
/* 18.8.32 patternFill CT_PatternFill */
case '<patternFill':
if(y.patternType) fill.patternType = y.patternType;
break;
case '<patternFill/>': case '</patternFill>': break;
/* 18.8.32 patternFill CT_PatternFill */
case '<patternFill':
if (y.patternType) fill.patternType = y.patternType;
break;
case '<patternFill/>':
case '</patternFill>':
break;
/* 18.8.3 bgColor CT_Color */
case '<bgColor':
if(!fill.bgColor) fill.bgColor = {};
if(y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
if(y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.bgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.bgColor.rgb = y.rgb.substring(y.rgb.length - 6);
break;
case '<bgColor/>': case '</bgColor>': break;
/* 18.8.3 bgColor CT_Color */
case '<bgColor':
if (!fill.bgColor) fill.bgColor = {};
if (y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
if (y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
if (y.tint) fill.bgColor.tint = parseFloat(y.tint);
/* 18.8.19 fgColor CT_Color */
case '<fgColor':
if(!fill.fgColor) fill.fgColor = {};
if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.fgColor.rgb = y.rgb.substring(y.rgb.length - 6);
break;
case '<fgColor/>': case '</fgColor>': break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
}
});
if (y.theme && themes.themeElements && themes.themeElements.clrScheme) {
fill.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[fill.bgColor.theme].rgb, fill.bgColor.tint || 0);
if (opts.WTF) fill.bgColor.raw_rgb = rgb_tint(themes.themeElements.clrScheme[fill.bgColor.theme].rgb,0);
}
/* Excel uses ARGB strings */
if (y.rgb) fill.bgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<bgColor/>':
case '</bgColor>':
break;
/* 18.8.19 fgColor CT_Color */
case '<fgColor':
if (!fill.fgColor) fill.fgColor = {};
if (y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if (y.tint) fill.fgColor.tint = parseFloat(y.tint);
if (y.theme && themes.themeElements && themes.themeElements.clrScheme) {
fill.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[fill.fgColor.theme].rgb, fill.fgColor.tint || 0);
if (opts.WTF) fill.fgColor.raw_rgb = rgb_tint(themes.themeElements.clrScheme[fill.fgColor.theme].rgb,0);
}
/* Excel uses ARGB strings */
if (y.rgb) fill.fgColor.rgb = y.rgb;//.substring(y.rgb.length - 6);
break;
case '<fgColor/>':
case '</fgColor>':
break;
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
}
});
}
function parse_fonts(t, opts) {
styles.Fonts = [];
var font = {};
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<fonts':
case '<fonts>':
case '</fonts>':
break;
case '<font':
break;
case '</font>':
styles.Fonts.push(font);
;
font = {};
break;
case '<name':
if (y.val) font.name = y.val;
break;
case '<name/>':
case '</name>':
break;
case '<b/>':
font.bold = true;
break;
case '<u/>':
font.underline = true;
break;
case '<i/>':
font.italic = true;
break;
case '<strike/>':
font.strike = true;
break;
case '<outline/>':
font.outline = true;
break;
case '<shadow/>':
font.shadow = true;
break;
case '<sz':
if (y.val) font.sz = y.val;
break;
case '<sz/>':
case '</sz>':
break;
case '<vertAlign':
if (y.val) font.vertAlign = y.val;
break;
case '<vertAlign/>':
case '</vertAlign>':
break;
case '<color':
if (!font.color) font.color = {};
if (y.theme) font.color.theme = y.theme;
if (y.tint) font.color.tint = y.tint;
if (y.theme && themes.themeElements && themes.themeElements.clrScheme) {
font.color.rgb = rgb_tint(themes.themeElements.clrScheme[font.color.theme].rgb, font.color.tint || 0);
}
if (y.rgb) font.color.rgb = y.rgb;
break;
case '<color/>':
case '</color>':
break;
}
});
}
function parse_borders(t, opts) {
styles.Borders = [];
var border = {}, sub_border = {};
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<borders':
case '<borders>':
case '</borders>':
break;
case '<border':
case '<border>':
border = {};
if (y.diagonalUp) { border.diagonalUp = y.diagonalUp; }
if (y.diagonalDown) { border.diagonalDown = y.diagonalDown; }
styles.Borders.push(border);
break;
break;
case '</border>':
break;
case '<left':
sub_border = border.left = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<right':
sub_border = border.right = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<top':
sub_border = border.top = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<bottom':
sub_border = border.bottom = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<diagonal':
sub_border = border.diagonal = {};
if (y.style) {
sub_border.style = y.style;
}
break;
case '<color':
sub_border.color = {};
if (y.theme) sub_border.color.theme = y.theme;
if (y.theme && themes.themeElements && themes.themeElements.clrScheme) {
sub_border.color.rgb = rgb_tint(themes.themeElements.clrScheme[sub_border.color.theme].rgb, sub_border.color.tint || 0);
}
if (y.tint) sub_border.color.tint = y.tint;
if (y.rgb) sub_border.color.rgb = y.rgb;
if (y.auto) sub_border.color.auto = y.auto;
break;
case '<name/>':
case '</name>':
break;
default:
break;
}
});
}
/* 18.8.31 numFmts CT_NumFmts */
function parse_numFmts(t, opts) {
styles.NumberFmt = [];
var k = keys(SSF._table);
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
case '<numFmt': {
var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
}
}
styles.NumberFmt = [];
var k = keys(SSF._table);
for (var i = 0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for (i = 0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch (y[0]) {
case '<numFmts':
case '</numFmts>':
case '<numFmts/>':
case '<numFmts>':
break;
case '<numFmt':
{
var f = unescapexml(utf8read(y.formatCode)), j = parseInt(y.numFmtId, 10);
styles.NumberFmt[j] = f;
if (j > 0) SSF.load(f, j);
}
break;
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
}
}
}
function write_numFmts(NF, opts) {
var o = ["<numFmts>"];
[[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
});
if(o.length === 1) return "";
o[o.length] = ("</numFmts>");
o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
return o.join("");
var o = ["<numFmts>"];
[
[5, 8],
[23, 26],
[41, 44],
[63, 66],
[164, 392]
].forEach(function (r) {
for (var i = r[0]; i <= r[1]; ++i) if (NF[i] !== undefined) o[o.length] = (writextag('numFmt', null, {numFmtId: i, formatCode: escapexml(NF[i])}));
});
if (o.length === 1) return "";
o[o.length] = ("</numFmts>");
o[0] = writextag('numFmts', null, { count: o.length - 2 }).replace("/>", ">");
return o.join("");
}
/* 18.8.10 cellXfs CT_CellXfs */
function parse_cellXfs(t, opts) {
styles.CellXf = [];
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
styles.CellXf = [];
var xf;
t[0].match(tagregex).forEach(function (x) {
var y = parsexmltag(x);
switch (y[0]) {
case '<cellXfs':
case '<cellXfs>':
case '<cellXfs/>':
case '</cellXfs>':
break;
/* 18.8.45 xf CT_Xf */
case '<xf': delete y[0];
if(y.numFmtId) y.numFmtId = parseInt(y.numFmtId, 10);
if(y.fillId) y.fillId = parseInt(y.fillId, 10);
styles.CellXf.push(y); break;
case '</xf>': break;
/* 18.8.45 xf CT_Xf */
case '<xf':
xf = y;
delete xf[0];
delete y[0];
if (xf.numFmtId) xf.numFmtId = parseInt(xf.numFmtId, 10);
if (xf.fillId) xf.fillId = parseInt(xf.fillId, 10);
styles.CellXf.push(xf);
break;
case '</xf>':
break;
/* 18.8.1 alignment CT_CellAlignment */
case '<alignment': case '<alignment/>': break;
/* 18.8.1 alignment CT_CellAlignment */
case '<alignment':
case '<alignment/>':
var alignment = {}
if (y.vertical) { alignment.vertical = y.vertical;}
if (y.horizontal) { alignment.horizontal = y.horizontal;}
if (y.textRotation != undefined) { alignment.textRotation = y.textRotation; }
if (y.indent) { alignment.indent = y.indent; }
if (y.wrapText) { alignment.wrapText = y.wrapText; }
xf.alignment = alignment;
/* 18.8.33 protection CT_CellProtection */
case '<protection': case '</protection>': case '<protection/>': break;
break;
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in cellXfs';
}
});
/* 18.8.33 protection CT_CellProtection */
case '<protection':
case '</protection>':
case '<protection/>':
break;
case '<extLst':
case '</extLst>':
break;
case '<ext':
break;
default:
if (opts.WTF) throw 'unrecognized ' + y[0] + ' in cellXfs';
}
});
}
function write_cellXfs(cellXfs) {