diff --git a/.eslintrc b/.eslintrc
index 686a33ea3ddef0f45c9d285ce65bafa6ce8004e0..d30937062ed979ba70e6cafd2e88af2a01a4e84a 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -5,10 +5,12 @@
"ecmaVersion": 3,
},
"plugins": [ "html", "json" ],
+ "!extends": "eslint:recommended",
"rules": {
"no-use-before-define": [ 1, {
"functions":false, "classes":true, "variables":false
}],
+ "no-console": 0,
"no-bitwise": 0,
"curly": 0,
"comma-style": [ 2, "last" ],
diff --git a/README.md b/README.md
index d56ea686455f960fe0dc1d1ef0e07e67a17d0c20..eb293aecb8dffbfd01de2104a71aa8341a0af6c6 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,8 @@ Emphasis on parsing and writing robustness, cross-format feature compatibility
with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.
This is the community version. We also offer a pro version with performance
-enhancements and additional features by request.
+enhancements, additional features by request, and dedicated support.
+
[**Pro Version**](http://sheetjs.com/pro)
@@ -18,17 +19,33 @@ enhancements and additional features by request.
[**Source Code**](http://git.io/xlsx)
-[**File format support for known spreadsheet data formats:**](#file-formats)
+[**Issues and Bug Reports**](https://github.com/sheetjs/js-xlsx/issues)
-![circo graph of format support](formats.png)
+[**Other General Support Issues**](https://discourse.sheetjs.com)
+
+[**File format support for known spreadsheet data formats:**](#file-formats)
- Graph Legend
+ Graph of supported formats (click to show)
+
+![circo graph of format support](formats.png)
![graph legend](legend.png)
+[**Browser Test**](http://oss.sheetjs.com/js-xlsx/tests/)
+
+[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
+
+[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
+[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
+[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
+[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
+[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
+[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
+[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
+
## Table of Contents
@@ -40,6 +57,7 @@ enhancements and additional features by request.
* [JS Ecosystem Demos](#js-ecosystem-demos)
* [Optional Modules](#optional-modules)
* [ECMAScript 5 Compatibility](#ecmascript-5-compatibility)
+- [Philosophy](#philosophy)
- [Parsing Workbooks](#parsing-workbooks)
* [Complete Examples](#complete-examples)
* [Note on Streaming Read](#note-on-streaming-read)
@@ -114,7 +132,6 @@ enhancements and additional features by request.
* [Windows](#windows)
- [License](#license)
- [References](#references)
-- [Badges](#badges)
@@ -122,16 +139,16 @@ enhancements and additional features by request.
## Installation
-With [npm](https://www.npmjs.org/package/xlsx):
+In the browser, just add a script tag:
-```bash
-$ npm install xlsx
+```html
+
```
-In the browser:
+With [npm](https://www.npmjs.org/package/xlsx):
-```html
-
+```bash
+$ npm install xlsx
```
With [bower](http://bower.io/search/?q=js-xlsx):
@@ -194,6 +211,41 @@ To use the shim, add the shim before the script tag that loads xlsx.js:
```
+## Philosophy
+
+
+ Philosophy (click to show)
+
+Prior to SheetJS, APIs for processing spreadsheet files were format-specific.
+Third-party libraries either supported one format, or they involved a separate
+set of classes for each supported file type. Even though XLSB was introduced in
+Excel 2007, nothing outside of SheetJS or Excel supported the format.
+
+To promote a format-agnostic view, js-xlsx starts from a pure-JS representation
+that we call the ["Common Spreadsheet Format"](#common-spreadsheet-format).
+Emphasizing a uniform object representation enables radical features like format
+conversion (e.g. reading an XLSX template and saving as XLS) and circumvents the
+"class trap". By abstracting the complexities of the various formats, tools
+need not worry about the specific file type!
+
+A simple object representation combined with careful coding practices enables
+use cases in older browsers and in alternative environments like ExtendScript
+and Web Workers. It is always tempting to use the latest and greatest features,
+but they tend to require the latest versions of browsers, limiting usability.
+
+Utility functions capture common use cases like generating JS objects or HTML.
+Most simple operations should only require a few lines of code. More complex
+operations generally should be straightforward to implement.
+
+Excel pushes the XLSX format as default starting in Excel 2007. However, there
+are other formats with more appealing properties. For example, the XLSB format
+is spiritually similar to XLSX but files often tend up taking less than half the
+space and open much faster! Even though an XLSX writer is available, other
+format writers are available so users can take advantage of the unique
+characteristics of each format.
+
+
+
## Parsing Workbooks
For parsing, the first step is to read the file. This involves acquiring the
@@ -505,7 +557,6 @@ Utilities are available in the `XLSX.utils` object:
**Exporting:**
- `sheet_to_json` converts a worksheet object to an array of JSON objects.
- `sheet_to_row_object_array` is an alias that will be removed in the future.
- `sheet_to_csv` generates delimiter-separated-values output.
- `sheet_to_formulae` generates a list of the formulae (with value fallbacks).
@@ -1008,17 +1059,14 @@ at index 164. The following example creates a custom format from scratch:
```js
var tbl = {};
-XLSX.SSF.init_table(tbl); // <-- load builtin formats
-tbl[164] = "\"T\"\ #0.00";
var wb = {
- SSF: tbl,
SheetNames: ["Sheet1"],
Sheets: {
Sheet1: {
"!ref":"A1:C1",
- A1: { t:"n", v:10000 }, // <-- General format
- B1: { t:"n", v:10000, z: tbl[4] }, // <-- Builtin format
- C1: { t:"n", v:10000, z: tbl[164] } // <-- Custom format
+ 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
}
}
}
@@ -1439,8 +1487,8 @@ the output will be encoded in codepage `1200` and the BOM will be prepended.
### JSON
-`XLSX.utils.sheet_to_json` and the alias `XLSX.utils.sheet_to_row_object_array`
-generate different types of JS objects. The function takes an options argument:
+`XLSX.utils.sheet_to_json` generates different types of JS objects. The function
+takes an options argument:
| Option Name | Default | Description |
| :---------- | :------: | :-------------------------------------------------- |
@@ -1834,6 +1882,9 @@ $ open -a Chromium.app http://localhost:8000/stress.html
### Tested Environments
+
+ (click to show)
+
- NodeJS 0.8, 0.9, 0.10, 0.11, 0.12, 4.x, 5.x, 6.x, 7.x
- IE 6/7/8/9/10/11 (IE6-9 browsers require shims for interacting with client)
- Chrome 24+
@@ -1847,6 +1898,8 @@ Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:
- for XLS\* modules
- for XLS\* modules using Sauce Labs
+
+
### Test Files
Test files are housed in [another repo](https://github.com/SheetJS/test_files).
@@ -1980,20 +2033,3 @@ granted by the Apache 2.0 License are reserved by the Original Author.
- Worksheet File Format (From Lotus) December 1984
-## Badges
-
-[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
-
-[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
-
-[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
-
-[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
-
-[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
-
-[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
-
-[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
-
-[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/bin/xlsx.njs b/bin/xlsx.njs
index 9e1befc1687e7d4644ae1e0a605f3de68b19e2b5..9b10895ade33c7b44e6716d3c407f5e386388b3b 100755
--- a/bin/xlsx.njs
+++ b/bin/xlsx.njs
@@ -1,5 +1,6 @@
#!/usr/bin/env node
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
+/* eslint-env node */
var n = "xlsx";
/* vim: set ts=2 ft=javascript: */
var X = require('../');
@@ -176,9 +177,9 @@ var oo = "";
var strm = false;
if(!program.quiet) console.error(target_sheet);
if(program.formulae) oo = X.utils.get_formulae(ws).join("\n");
-else if(program.json) oo = JSON.stringify(X.utils.sheet_to_row_object_array(ws));
-else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_row_object_array(ws,{raw:true}));
-else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_row_object_array(ws,{raw:true, header:1}));
+else if(program.json) oo = JSON.stringify(X.utils.sheet_to_json(ws));
+else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true}));
+else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true, header:1}));
else {
strm = true;
var stream = X.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep});
diff --git a/bits/00_header.js b/bits/00_header.js
index 8eefc1d8c4eb1ef04ab15f4e0a32a79d3688a1a7..634a2d1b3b970f9b5d3f22b509b21966c5691c7d 100644
--- a/bits/00_header.js
+++ b/bits/00_header.js
@@ -3,5 +3,6 @@
/*jshint -W041 */
/*jshint funcscope:true, eqnull:true */
/*exported XLSX */
+/*global exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
diff --git a/bits/01_version.js b/bits/01_version.js
index ddea91c9123f236d8a41370350a1b52fa596c0a8..566412f6531aadc263c6efe6c263eae76804d2cc 100644
--- a/bits/01_version.js
+++ b/bits/01_version.js
@@ -1 +1 @@
-XLSX.version = '0.9.13';
+XLSX.version = '0.10.0';
diff --git a/bits/02_codepage.js b/bits/02_codepage.js
index 862803c555d737862dc784a0966778db14774201..2d7e77ebaa2115ed715f9ea7e4880d4c654407ef 100644
--- a/bits/02_codepage.js
+++ b/bits/02_codepage.js
@@ -1,8 +1,8 @@
-var current_codepage = 1200, current_cptable;
+var current_codepage = 1200;
/*:: declare var cptable:any; */
+/*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js');
- current_cptable = cptable[current_codepage];
}
function reset_cp() { set_cp(1200); }
var set_cp = function(cp) { current_codepage = cp; };
@@ -18,7 +18,7 @@ var debom = function(data/*:string*/)/*:string*/ {
var _getchar = function _gc1(x) { return String.fromCharCode(x); };
if(typeof cptable !== 'undefined') {
- set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
+ set_cp = function(cp) { current_codepage = cp; };
debom = function(data) {
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
return data;
diff --git a/bits/04_base64.js b/bits/04_base64.js
index 2fc0636a600a53d7844e05bac6025e2cddf714d1..7050f436b3be269080bc75886385bd0ba06422d7 100644
--- a/bits/04_base64.js
+++ b/bits/04_base64.js
@@ -1,7 +1,7 @@
var Base64 = (function make_b64(){
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
return {
- encode: function(input/*:string*/, utf8)/*:string*/ {
+ encode: function(input/*:string*/)/*:string*/ {
var o = "";
var c1, c2, c3, e1, e2, e3, e4;
for(var i = 0; i < input.length; ) {
@@ -18,7 +18,7 @@ var Base64 = (function make_b64(){
}
return o;
},
- decode: function b64_decode(input/*:string*/, utf8)/*:string*/ {
+ decode: function b64_decode(input/*:string*/)/*:string*/ {
var o = "";
var c1, c2, c3;
var e1, e2, e3, e4;
diff --git a/bits/10_ssf.js b/bits/10_ssf.js
index ccd13426fc40e6fc64aeb516c26073dba9c184e1..c179063e9c184584bb71217991d8ff4ff530889f 100644
--- a/bits/10_ssf.js
+++ b/bits/10_ssf.js
@@ -2,7 +2,7 @@
/*jshint -W041 */
var SSF = {};
var make_ssf = function make_ssf(SSF){
-SSF.version = '0.9.1';
+SSF.version = '0.9.2';
function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; }
function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; }
function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
@@ -270,12 +270,14 @@ function write_num_exp(fmt/*:string*/, val/*:number*/)/*:string*/{
var o/*:string*/;
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
if(fmt.match(/^#+0.0E\+0$/)) {
+ if(val == 0) return "0.0E+0";
+ else if(val < 0) return "-" + write_num_exp(fmt, -val);
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
- var ee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;
+ var ee = Math.floor(Math.log(val)*Math.LOG10E)%period;
if(ee < 0) ee += period;
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
if(o.indexOf("e") === -1) {
- var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
+ var fakee = Math.floor(Math.log(val)*Math.LOG10E);
if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
else o += "E+" + (fakee - ee);
while(o.substr(0,2) === "0.") {
@@ -353,7 +355,7 @@ function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
if((r = fmt.match(/^(0*)\.(#*)$/))) {
return sign + rnd(aval, r[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
}
- if((r = fmt.match(/^#,##0(\.?)$/))) return sign + commaify(pad0r(aval,0));
+ if((r = fmt.match(/^#{1,3},##0(\.?)$/))) return sign + commaify(pad0r(aval,0));
if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(""+(Math.floor(val) + carry(val, r[1].length))) + "." + pad0(dec(val, r[1].length),r[1].length);
}
@@ -401,7 +403,12 @@ function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(flr(val)).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(ri,r[1].length);
}
switch(fmt) {
+ case "###,##0.00": return write_num_flt(type, "#,##0.00", val);
+ case "###,###":
+ case "##,###":
case "#,###": var x = commaify(pad0r(aval,0)); return x !== "0" ? sign + x : "";
+ case "###,###.00": return write_num_flt(type, "###,##0.00",val).replace(/^0\./,".");
+ case "#,###.00": return write_num_flt(type, "#,##0.00",val).replace(/^0\./,".");
default:
}
throw new Error("unsupported format |" + fmt + "|");
@@ -419,12 +426,14 @@ function write_num_exp2(fmt/*:string*/, val/*:number*/)/*:string*/{
var o/*:string*/;
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
if(fmt.match(/^#+0.0E\+0$/)) {
+ if(val == 0) return "0.0E+0";
+ else if(val < 0) return "-" + write_num_exp2(fmt, -val);
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
- var ee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;
+ var ee = Math.floor(Math.log(val)*Math.LOG10E)%period;
if(ee < 0) ee += period;
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
if(!o.match(/[Ee]/)) {
- var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
+ var fakee = Math.floor(Math.log(val)*Math.LOG10E);
if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
else o += "E+" + (fakee - ee);
o = o.replace(/\+-/,"-");
@@ -446,7 +455,7 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
if(fmt.indexOf('E') !== -1) return write_num_exp2(fmt, val);
if(fmt.charCodeAt(0) === 36) return "$"+write_num_int(type,fmt.substr(fmt.charAt(1)==' '?2:1),val);
var o;
- var r, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
+ var r/*:?Array*/, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
if(fmt.match(/^00+$/)) return sign + pad0(aval,fmt.length);
if(fmt.match(/^[#?]+$/)) {
o = (""+val); if(val === 0) o = "";
@@ -466,7 +475,7 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
if((r = fmt.match(/^(0*)\.(#*)$/))) {
return sign + (""+aval).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
}
- if((r = fmt.match(/^#,##0(\.?)$/))) return sign + commaify((""+aval));
+ if((r = fmt.match(/^#{1,3},##0(\.?)$/))) return sign + commaify((""+aval));
if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify((""+val)) + "." + fill('0',r[1].length);
}
@@ -482,12 +491,12 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
}
var oa = "";
if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))) {
- ri = Math.min(r[4].length,7);
+ ri = Math.min(/*::String(*/r[4]/*::)*/.length,7);
ff = frac(aval, Math.pow(10,ri)-1, false);
o = "" + sign;
- oa = write_num("n", r[1], ff[1]);
+ oa = write_num("n", /*::String(*/r[1]/*::)*/, ff[1]);
if(oa.charAt(oa.length-1) == " ") oa = oa.substr(0,oa.length-1) + "0";
- o += oa + r[2] + "/" + r[3];
+ o += oa + /*::String(*/r[2]/*::)*/ + "/" + /*::String(*/r[3]/*::)*/;
oa = rpad_(ff[2],ri);
if(oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length-oa.length)) + oa;
o += oa;
@@ -513,8 +522,12 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify(""+val).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(0,r[1].length);
}
switch(fmt) {
+ case "###,###":
+ case "##,###":
case "#,###": var x = commaify(""+aval); return x !== "0" ? sign + x : "";
default:
+ if(fmt.slice(-3) == ".00") return write_num_int(type, fmt.slice(0,-3), val) + ".00";
+ if(fmt.slice(-2) == ".0") return write_num_int(type, fmt.slice(0,-2), val) + ".0";
}
throw new Error("unsupported format |" + fmt + "|");
}
@@ -610,7 +623,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
if(v < 0) return "";
if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
o = c; while(++i -1) {
o = (o.match(/\$([^-\[\]]*)/)||[])[1]||"$";
if(!fmt_is_date(fmt)) out[out.length] = {t:'t',v:o};
@@ -641,7 +655,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
}
/* falls through */
case '0': case '#':
- o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1 || c=='\\' && fmt.charAt(i+1) == "-" && "0#".indexOf(fmt.charAt(i+2))>-1) o += c;
+ o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1 || c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1) o += c;
out[out.length] = {t:'n', v:o}; break;
case '?':
o = c; while(fmt.charAt(++i) === c) o+=c;
@@ -705,7 +719,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
(c=out[jj].t) === "?" || c === "D" ||
(c === " " || c === "t") && out[jj+1] != null && (out[jj+1].t === '?' || out[jj+1].t === "t" && out[jj+1].v === '/') ||
out[i].t === '(' && (c === ' ' || c === 'n' || c === ')') ||
- c === 't' && (out[jj].v === '/' || '$€'.indexOf(out[jj].v) > -1 || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?')
+ c === 't' && (out[jj].v === '/' || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?')
)) {
out[i].v += out[jj].v;
out[jj] = {v:"", t:";"}; ++jj;
@@ -819,7 +833,6 @@ function choose_fmt(f/*:string*/, v) {
}
function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(o == null) o = {};
- //fixopts(o != null ? o : (o=[]));
var sfmt = "";
switch(typeof fmt) {
case "string":
diff --git a/bits/21_ziputils.js b/bits/21_ziputils.js
index 13f30849e591efd97414b2de9a742aa295a0d77b..14aa2d3c15a185120913bd78372493431730e8d3 100644
--- a/bits/21_ziputils.js
+++ b/bits/21_ziputils.js
@@ -53,6 +53,7 @@ function getzipstr(zip, file/*:string*/, safe/*:?boolean*/)/*:?string*/ {
var _fs, jszip;
/*:: declare var JSZip:any; */
+/*global JSZip:true */
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
diff --git a/bits/22_xmlutils.js b/bits/22_xmlutils.js
index 7925da14e7f59ca68229c75d7a0538fbb1e50181..557729ad98f52a9742a35d9cf35243593649db0a 100644
--- a/bits/22_xmlutils.js
+++ b/bits/22_xmlutils.js
@@ -37,7 +37,7 @@ var encodings = {
'&': '&'
};
var rencoding = evert(encodings);
-var rencstr = "&<>'\"".split("");
+//var rencstr = "&<>'\"".split("");
// TODO: CP remap (need to read file version to determine OS)
var unescapexml/*:StringConv*/ = (function() {
diff --git a/bits/26_crypto.js b/bits/26_crypto.js
index 937d78d12eb510af64d4b3195d3925a2bfd698df..c41f62c9f52bdfa71a37b75f376c487e51bff1de 100644
--- a/bits/26_crypto.js
+++ b/bits/26_crypto.js
@@ -33,5 +33,6 @@ var make_offcrypto = function(O, _crypto) {
};
};
/*:: declare var crypto:any; */
+/*global crypto:true */
make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined);
diff --git a/bits/28_binstructs.js b/bits/28_binstructs.js
index 684c6bc8aeef34ec1d5a10343cc19a534735a63b..40631056920da53ebbdd62d190559e2d1f2493f9 100644
--- a/bits/28_binstructs.js
+++ b/bits/28_binstructs.js
@@ -1,8 +1,31 @@
+function write_UInt32LE(x/*:number*/, o) {
+ if(!o) o = new_buf(4);
+ o.write_shift(4, x);
+ return o;
+}
+
+/* [MS-XLSB] 2.5.168 */
+function parse_XLWideString(data)/*:string*/ {
+ var cchCharacters = data.read_shift(4);
+ return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
+}
+function write_XLWideString(data/*:string*/, o) {
+ var _null = false; if(o == null) { _null = true; o = new_buf(4+2*data.length); }
+ o.write_shift(4, data.length);
+ if(data.length > 0) o.write_shift(0, data, 'dbcs');
+ return _null ? o.slice(0, o.l) : o;
+}
/* [MS-XLSB] 2.5.143 */
function parse_StrRun(data, length/*:?number*/) {
return { ich: data.read_shift(2), ifnt: data.read_shift(2) };
}
+function write_StrRun(run, o) {
+ if(!o) o = new_buf(4);
+ o.write_shift(2, run.ich || 0);
+ o.write_shift(2, run.ifnt || 0);
+ return o;
+}
/* [MS-XLSB] 2.1.7.121 */
function parse_RichStr(data, length/*:number*/)/*:XLString*/ {
@@ -31,6 +54,17 @@ function write_RichStr(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
write_XLWideString(str.t, o);
return _null ? o.slice(0, o.l) : o;
}
+/* [MS-XLSB] 2.4.325 BrtCommentText (RichStr w/1 run) */
+var parse_BrtCommentText = parse_RichStr;
+function write_BrtCommentText(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
+ /* TODO: formatted string */
+ var _null = false; if(o == null) { _null = true; o = new_buf(23+4*str.t.length); }
+ o.write_shift(1,1);
+ write_XLWideString(str.t, o);
+ o.write_shift(4,1);
+ write_StrRun({ich:0,ifnt:0}, o);
+ return _null ? o.slice(0, o.l) : o;
+}
/* [MS-XLSB] 2.5.9 */
function parse_XLSBCell(data)/*:any*/ {
@@ -65,18 +99,6 @@ function write_XLNullableWideString(data/*:string*/, o) {
return _null ? o.slice(0, o.l) : o;
}
-/* [MS-XLSB] 2.5.168 */
-function parse_XLWideString(data)/*:string*/ {
- var cchCharacters = data.read_shift(4);
- return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
-}
-function write_XLWideString(data/*:string*/, o) {
- var _null = false; if(o == null) { _null = true; o = new_buf(4+2*data.length); }
- o.write_shift(4, data.length);
- if(data.length > 0) o.write_shift(0, data, 'dbcs');
- return _null ? o.slice(0, o.l) : o;
-}
-
/* [MS-XLSB] 2.5.165 */
var parse_XLNameWideString = parse_XLWideString;
var write_XLNameWideString = write_XLWideString;
@@ -153,23 +175,75 @@ var RBErr = evert_num(BErr);
function parse_BrtColor(data, length/*:number*/) {
var out = {};
var d = data.read_shift(1);
- out.fValidRGB = d & 1;
- out.xColorType = d >>> 1;
- out.index = data.read_shift(1);
- out.nTintAndShade = data.read_shift(2, 'i');
- out.bRed = data.read_shift(1);
- out.bGreen = data.read_shift(1);
- out.bBlue = data.read_shift(1);
- out.bAlpha = data.read_shift(1);
+
+ var fValidRGB = d & 1;
+ var xColorType = d >>> 1;
+
+ var index = data.read_shift(1);
+ var nTS = data.read_shift(2, 'i');
+ var bR = data.read_shift(1);
+ var bG = data.read_shift(1);
+ var bB = data.read_shift(1);
+ var bAlpha = data.read_shift(1);
+
+ switch(xColorType) {
+ case 0: out.auto = 1; break;
+ case 1:
+ out.index = index;
+ var icv = XLSIcv[index];
+ /* automatic pseudo index 81 */
+ if(icv) out.rgb = icv[0].toString(16) + icv[1].toString(16) + icv[2].toString(16);
+ break;
+ case 2:
+ /* if(!fValidRGB) throw new Error("invalid"); */
+ out.rgb = bR.toString(16) + bG.toString(16) + bB.toString(16);
+ break;
+ case 3: out.theme = index; break;
+ }
+ if(nTS != 0) out.tint = nTS > 0 ? nTS / 32767 : nTS / 32768;
+
+ return out;
+}
+function write_BrtColor(color, o) {
+ if(!o) o = new_buf(8);
+ if(!color||color.auto) { o.write_shift(4, 0); o.write_shift(4, 0); return o; }
+ if(color.index) {
+ o.write_shift(1, 0x02);
+ o.write_shift(1, color.index);
+ } else if(color.theme) {
+ o.write_shift(1, 0x06);
+ o.write_shift(1, color.theme);
+ } else {
+ o.write_shift(1, 0x05);
+ o.write_shift(1, 0);
+ }
+ var nTS = color.tint || 0;
+ if(nTS > 0) nTS *= 32767;
+ else if(nTS < 0) nTS *= 32768;
+ o.write_shift(2, nTS);
+ if(!color.rgb) {
+ o.write_shift(2, 0);
+ o.write_shift(1, 0);
+ o.write_shift(1, 0);
+ } else {
+ var rgb = (color.rgb || 'FFFFFF');
+ o.write_shift(1, parseInt(rgb.substr(0,2),16));
+ o.write_shift(1, parseInt(rgb.substr(2,2),16));
+ o.write_shift(1, parseInt(rgb.substr(4,2),16));
+ o.write_shift(1, 0xFF);
+ }
+ return o;
}
/* [MS-XLSB] 2.5.52 */
-function parse_FontFlags(data, length/*:number*/) {
+function parse_FontFlags(data, length/*:number*/, opts) {
var d = data.read_shift(1);
data.l++;
var out = {
- fItalic: d & 0x2,
- fStrikeout: d & 0x8,
+ /* fBold: d & 0x01 */
+ fItalic: d & 0x02,
+ /* fUnderline: d & 0x04 */
+ fStrikeout: d & 0x08,
fOutline: d & 0x10,
fShadow: d & 0x20,
fCondense: d & 0x40,
@@ -177,3 +251,17 @@ function parse_FontFlags(data, length/*:number*/) {
};
return out;
}
+function write_FontFlags(font, o) {
+ if(!o) o = new_buf(2);
+ var grbit =
+ (font.italic ? 0x02 : 0) |
+ (font.strike ? 0x08 : 0) |
+ (font.outline ? 0x10 : 0) |
+ (font.shadow ? 0x20 : 0) |
+ (font.condense ? 0x40 : 0) |
+ (font.extend ? 0x80 : 0);
+ o.write_shift(1, grbit);
+ o.write_shift(1, 0);
+ return o;
+}
+
diff --git a/bits/29_xlsenum.js b/bits/29_xlsenum.js
index 2dcd187d3d8aaf4ae39e411de8cfa7eb757b2adb..7cc5004c3fd1d4173f58da66c4e83eb488c352e2 100644
--- a/bits/29_xlsenum.js
+++ b/bits/29_xlsenum.js
@@ -1,40 +1,40 @@
/* [MS-OLEPS] 2.2 PropertyType */
{
- var VT_EMPTY = 0x0000;
- var VT_NULL = 0x0001;
+ //var VT_EMPTY = 0x0000;
+ //var VT_NULL = 0x0001;
var VT_I2 = 0x0002;
var VT_I4 = 0x0003;
- var VT_R4 = 0x0004;
- var VT_R8 = 0x0005;
- var VT_CY = 0x0006;
- var VT_DATE = 0x0007;
- var VT_BSTR = 0x0008;
- var VT_ERROR = 0x000A;
+ //var VT_R4 = 0x0004;
+ //var VT_R8 = 0x0005;
+ //var VT_CY = 0x0006;
+ //var VT_DATE = 0x0007;
+ //var VT_BSTR = 0x0008;
+ //var VT_ERROR = 0x000A;
var VT_BOOL = 0x000B;
var VT_VARIANT = 0x000C;
- var VT_DECIMAL = 0x000E;
- var VT_I1 = 0x0010;
- var VT_UI1 = 0x0011;
- var VT_UI2 = 0x0012;
+ //var VT_DECIMAL = 0x000E;
+ //var VT_I1 = 0x0010;
+ //var VT_UI1 = 0x0011;
+ //var VT_UI2 = 0x0012;
var VT_UI4 = 0x0013;
- var VT_I8 = 0x0014;
+ //var VT_I8 = 0x0014;
var VT_UI8 = 0x0015;
- var VT_INT = 0x0016;
- var VT_UINT = 0x0017;
+ //var VT_INT = 0x0016;
+ //var VT_UINT = 0x0017;
var VT_LPSTR = 0x001E;
- var VT_LPWSTR = 0x001F;
+ //var VT_LPWSTR = 0x001F;
var VT_FILETIME = 0x0040;
- var VT_BLOB = 0x0041;
- var VT_STREAM = 0x0042;
- var VT_STORAGE = 0x0043;
- var VT_STREAMED_Object = 0x0044;
- var VT_STORED_Object = 0x0045;
- var VT_BLOB_Object = 0x0046;
+ //var VT_BLOB = 0x0041;
+ //var VT_STREAM = 0x0042;
+ //var VT_STORAGE = 0x0043;
+ //var VT_STREAMED_Object = 0x0044;
+ //var VT_STORED_Object = 0x0045;
+ //var VT_BLOB_Object = 0x0046;
var VT_CF = 0x0047;
- var VT_CLSID = 0x0048;
- var VT_VERSIONED_STREAM = 0x0049;
+ //var VT_CLSID = 0x0048;
+ //var VT_VERSIONED_STREAM = 0x0049;
var VT_VECTOR = 0x1000;
- var VT_ARRAY = 0x2000;
+ //var VT_ARRAY = 0x2000;
var VT_STRING = 0x0050; // 2.3.3.1.11 VtString
var VT_USTR = 0x0051; // 2.3.3.1.12 VtUnalignedString
@@ -186,6 +186,7 @@ var XLSFillPattern = [
function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
/* [MS-XLS] 2.5.161 */
+/* [MS-XLSB] 2.5.75 */
var XLSIcv = rgbify([
/* Color Constants */
0x000000,
@@ -197,7 +198,7 @@ var XLSIcv = rgbify([
0xFF00FF,
0x00FFFF,
- /* Defaults */
+ /* Overridable Defaults */
0x000000,
0xFFFFFF,
0xFF0000,
@@ -258,8 +259,24 @@ var XLSIcv = rgbify([
0x333399,
0x333333,
- /* Sheet */
- 0xFFFFFF,
- 0x000000
+ /* Other entries to appease BIFF8/12 */
+ 0xFFFFFF, /* 0x40 icvForeground ?? */
+ 0x000000, /* 0x41 icvBackground ?? */
+ 0x000000, /* 0x42 icvFrame ?? */
+ 0x000000, /* 0x43 icv3D ?? */
+ 0x000000, /* 0x44 icv3DText ?? */
+ 0x000000, /* 0x45 icv3DHilite ?? */
+ 0x000000, /* 0x46 icv3DShadow ?? */
+ 0x000000, /* 0x47 icvHilite ?? */
+ 0x000000, /* 0x48 icvCtlText ?? */
+ 0x000000, /* 0x49 icvCtlScrl ?? */
+ 0x000000, /* 0x4A icvCtlInv ?? */
+ 0x000000, /* 0x4B icvCtlBody ?? */
+ 0x000000, /* 0x4C icvCtlFrame ?? */
+ 0x000000, /* 0x4D icvCtlFore ?? */
+ 0x000000, /* 0x4E icvCtlBack ?? */
+ 0x000000, /* 0x4F icvCtlNeutral */
+ 0x000000, /* 0x50 icvInfoBk ?? */
+ 0x000000 /* 0x51 icvInfoText ?? */
]);
diff --git a/bits/31_rels.js b/bits/31_rels.js
index 86c70889fa932f6cf19a99290b59161ff8e64a07..195bbce4643956121a975511ff9d79fedb622d64 100644
--- a/bits/31_rels.js
+++ b/bits/31_rels.js
@@ -55,7 +55,7 @@ function write_rels(rels)/*:string*/ {
function add_rels(rels, rId, f, type, relobj)/*:number*/ {
if(!relobj) relobj = {};
if(!rels['!id']) rels['!id'] = {};
- if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){}
+ if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
relobj.Id = 'rId' + rId;
relobj.Type = type;
relobj.Target = f;
diff --git a/bits/35_custprops.js b/bits/35_custprops.js
index 68f300b96f58e9e468525bfa77bfc66ba60ea7b1..8efcd1f6c67b15da535ec016004784fad4618b60 100644
--- a/bits/35_custprops.js
+++ b/bits/35_custprops.js
@@ -39,7 +39,7 @@ function parse_cust_props(data/*:string*/, opts) {
default:
if(opts.WTF && typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
}
- } else if(x.substr(0,2) === "") {
+ } else if(x.substr(0,2) === "") {/* empty */
} else if(opts.WTF) throw new Error(x);
}
}
diff --git a/bits/38_xlstypes.js b/bits/38_xlstypes.js
index 26628ae25a503ba8b5d81e13c60801f32b42262b..84c87dd499b2a1568ba4c927c9f5b879bb0e67c0 100644
--- a/bits/38_xlstypes.js
+++ b/bits/38_xlstypes.js
@@ -174,28 +174,25 @@ function parse_PropertySet(blob, PIDSI) {
if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
case 0: PropH[piddsi.n] = 1252;
/* falls through */
- case 10000: // OSX Roman
- case 1252: // Windows Latin
-
- case 874: // SB Windows Thai
- case 1250: // SB Windows Central Europe
- case 1251: // SB Windows Cyrillic
- case 1253: // SB Windows Greek
- case 1254: // SB Windows Turkish
- case 1255: // SB Windows Hebrew
- case 1256: // SB Windows Arabic
- case 1257: // SB Windows Baltic
- case 1258: // SB Windows Vietnam
-
- case 932: // DB Windows Japanese Shift-JIS
- case 936: // DB Windows Simplified Chinese GBK
- case 949: // DB Windows Korean
- case 950: // DB Windows Traditional Chinese Big5
-
- case 1200: // UTF16LE
- case 1201: // UTF16BE
- case 65000: case -536: // UTF-7
- case 65001: case -535: // UTF-8
+ case 874:
+ case 932:
+ case 936:
+ case 949:
+ case 950:
+ case 1250:
+ case 1251:
+ case 1253:
+ case 1254:
+ case 1255:
+ case 1256:
+ case 1257:
+ case 1258:
+ case 10000:
+ case 1200:
+ case 1201:
+ case 1252:
+ case 65000: case -536:
+ case 65001: case -535:
set_cp(CodePage = PropH[piddsi.n]); break;
default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
}
@@ -262,7 +259,7 @@ function parse_PropertySetStream(file, PIDSI) {
if(NumSets === 1) return rval;
if(blob.l !== Offset1) throw new Error("Length mismatch 2: " + blob.l + " !== " + Offset1);
var PSet1;
- try { PSet1 = parse_PropertySet(blob, null); } catch(e) { }
+ try { PSet1 = parse_PropertySet(blob, null); } catch(e) {/* empty */}
for(y in PSet1) rval[y] = PSet1[y];
rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
return rval;
@@ -363,7 +360,7 @@ function parse_XLUnicodeString2(blob, length, opts) {
var parse_ControlInfo = parsenoop;
/* [MS-OSHARED] 2.3.7.6 URLMoniker TODO: flags */
-var parse_URLMoniker = function(blob, length) {
+var parse_URLMoniker = function(blob/*, length, opts*/) {
var len = blob.read_shift(4), start = blob.l;
var extra = false;
if(len > 24) {
diff --git a/bits/39_xlsbiff.js b/bits/39_xlsbiff.js
index cddd7e047cbc649f7db0f1e433fc1f36d3c3335c..38e3237ab48dfef75fff1f86711c6510f31f1ca2 100644
--- a/bits/39_xlsbiff.js
+++ b/bits/39_xlsbiff.js
@@ -21,7 +21,7 @@ function parse_frtHeader(blob) {
function parse_OptXLUnicodeString(blob, length, opts) { return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts); }
/* 2.5.158 */
-var HIDEOBJENUM = ['SHOWALL', 'SHOWPLACEHOLDER', 'HIDEALL'];
+//var HIDEOBJENUM = ['SHOWALL', 'SHOWPLACEHOLDER', 'HIDEALL'];
var parse_HideObjEnum = parseuint16;
/* 2.5.344 */
@@ -99,35 +99,39 @@ function parse_FtCf(blob, length) {
}
/* 2.5.140 - 2.5.154 and friends */
+function parse_FtSkip(blob, length) { blob.l += 2; blob.l += blob.read_shift(2); }
var FtTab = {
- /*::[*/0x15/*::]*/: parse_FtCmo,
- /*::[*/0x13/*::]*/: parsenoop, /* FtLbsData */
- /*::[*/0x12/*::]*/: function(blob, length) { blob.l += 12; }, /* FtCblsData */
- /*::[*/0x11/*::]*/: function(blob, length) { blob.l += 8; }, /* FtRboData */
- /*::[*/0x10/*::]*/: parsenoop, /* FtEdoData */
- /*::[*/0x0F/*::]*/: parsenoop, /* FtGboData */
- /*::[*/0x0D/*::]*/: parse_FtNts, /* FtNts */
- /*::[*/0x0C/*::]*/: function(blob, length) { blob.l += 24; }, /* FtSbs */
- /*::[*/0x0B/*::]*/: function(blob, length) { blob.l += 10; }, /* FtRbo */
- /*::[*/0x0A/*::]*/: function(blob, length) { blob.l += 16; }, /* FtCbls */
- /*::[*/0x09/*::]*/: parsenoop, /* FtPictFmla */
- /*::[*/0x08/*::]*/: function(blob, length) { blob.l += 6; }, /* FtPioGrbit */
- /*::[*/0x07/*::]*/: parse_FtCf, /* FtCf */
- /*::[*/0x06/*::]*/: function(blob, length) { blob.l += 6; }, /* FtGmo */
- /*::[*/0x04/*::]*/: parsenoop, /* FtMacro */
- /*::[*/0x00/*::]*/: function(blob, length) { blob.l += 4; } /* FtEnding */
+ /*::[*/0x00/*::]*/: parse_FtSkip, /* FtEnd */
+ /*::[*/0x04/*::]*/: parse_FtSkip, /* FtMacro */
+ /*::[*/0x05/*::]*/: parse_FtSkip, /* FtButton */
+ /*::[*/0x06/*::]*/: parse_FtSkip, /* FtGmo */
+ /*::[*/0x07/*::]*/: parse_FtCf, /* FtCf */
+ /*::[*/0x08/*::]*/: parse_FtSkip, /* FtPioGrbit */
+ /*::[*/0x09/*::]*/: parse_FtSkip, /* FtPictFmla */
+ /*::[*/0x0A/*::]*/: parse_FtSkip, /* FtCbls */
+ /*::[*/0x0B/*::]*/: parse_FtSkip, /* FtRbo */
+ /*::[*/0x0C/*::]*/: parse_FtSkip, /* FtSbs */
+ /*::[*/0x0D/*::]*/: parse_FtNts, /* FtNts */
+ /*::[*/0x0E/*::]*/: parse_FtSkip, /* FtSbsFmla */
+ /*::[*/0x0F/*::]*/: parse_FtSkip, /* FtGboData */
+ /*::[*/0x10/*::]*/: parse_FtSkip, /* FtEdoData */
+ /*::[*/0x11/*::]*/: parse_FtSkip, /* FtRboData */
+ /*::[*/0x12/*::]*/: parse_FtSkip, /* FtCblsData */
+ /*::[*/0x13/*::]*/: parse_FtSkip, /* FtLbsData */
+ /*::[*/0x14/*::]*/: parse_FtSkip, /* FtCblsFmla */
+ /*::[*/0x15/*::]*/: parse_FtCmo
};
function parse_FtArray(blob, length, ot) {
- var s = blob.l;
+ var tgt = blob.l + length;
var fts = [];
- while(blob.l < s + length) {
+ while(blob.l < tgt) {
var ft = blob.read_shift(2);
blob.l-=2;
try {
- fts.push(FtTab[ft](blob, s + length - blob.l));
- } catch(e) { blob.l = s + length; return fts; }
+ fts.push(FtTab[ft](blob, tgt - blob.l));
+ } catch(e) { blob.l = tgt; return fts; }
}
- if(blob.l != s + length) blob.l = s + length; //throw new Error("bad Object Ft-sequence");
+ if(blob.l != tgt) blob.l = tgt; //throw new Error("bad Object Ft-sequence");
return fts;
}
@@ -158,7 +162,7 @@ function parse_BOF(blob, length) {
function parse_InterfaceHdr(blob, length) {
if(length === 0) return 0x04b0;
var q;
- if((q=blob.read_shift(2))!==0x04b0){}
+ if((q=blob.read_shift(2))!==0x04b0){/* empty */}
return 0x04b0;
}
@@ -246,11 +250,16 @@ function parse_RecalcId(blob, length) {
}
/* 2.4.87 */
-function parse_DefaultRowHeight(blob, length) {
- var f = blob.read_shift(2);
- var fl = {Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3};
- /* char is misleading, miyRw and miyRwHidden overlap */
+function parse_DefaultRowHeight(blob, length, opts) {
+ var f = 0;
+ if(!(opts && opts.biff == 2)) {
+ f = blob.read_shift(2);
+ }
var miyRw = blob.read_shift(2);
+ if((opts && opts.biff == 2)) {
+ f = 1 - (miyRw >> 15); miyRw &= 0x7fff;
+ }
+ var fl = {Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3};
return [fl, miyRw];
}
@@ -265,9 +274,17 @@ function parse_Window1(blob, length) {
/* 2.4.122 TODO */
function parse_Font(blob, length, opts) {
- blob.l += 14;
- var name = parse_ShortXLUnicodeString(blob, 0, opts);
- return name;
+ var o = {
+ dyHeight: blob.read_shift(2),
+ fl: blob.read_shift(2)
+ };
+ switch(opts && opts.biff || 8) {
+ case 2: break;
+ case 3: case 4: blob.l += 2; break;
+ default: blob.l += 10; break;
+ }
+ o.name = parse_ShortXLUnicodeString(blob, 0, opts);
+ return o;
}
/* 2.4.149 */
@@ -299,8 +316,8 @@ var parse_BIFF2Format = parse_XLUnicodeString2;
function parse_Dimensions(blob, length, opts) {
var end = blob.l + length;
var w = opts.biff == 8 || !opts.biff ? 4 : 2;
- var r = blob.read_shift(w), R = blob.read_shift(w),
- c = blob.read_shift(2), C = blob.read_shift(2);
+ var r = blob.read_shift(w), R = blob.read_shift(w);
+ var c = blob.read_shift(2), C = blob.read_shift(2);
blob.l = end;
return {s: {r:r, c:c}, e: {r:R, c:C}};
}
@@ -549,11 +566,49 @@ function parse_MergeCells(blob, length) {
}
/* 2.4.181 TODO: parse all the things! */
-function parse_Obj(blob, length) {
+function parse_Obj(blob, length, opts) {
+ if(opts && opts.biff < 8) return parse_BIFF5Obj(blob, length, opts);
var cmo = parse_FtCmo(blob, 22); // id, ot, flags
var fts = parse_FtArray(blob, length-22, cmo[1]);
return { cmo: cmo, ft:fts };
}
+/* from older spec */
+var parse_BIFF5OT = [];
+parse_BIFF5OT[0x08] = function(blob, length, opts) {
+ var tgt = blob.l + length;
+ blob.l += 10; // todo
+ var cf = blob.read_shift(2);
+ blob.l += 4;
+ var cbPictFmla = blob.read_shift(2);
+ blob.l += 2;
+ var grbit = blob.read_shift(2);
+ blob.l += 4;
+ var cchName = blob.read_shift(1);
+ blob.l += cchName; // TODO: stName
+ blob.l = tgt; // TODO: fmla
+ return { fmt:cf };
+};
+
+function parse_BIFF5Obj(blob, length, opts) {
+ var cnt = blob.read_shift(4);
+ var ot = blob.read_shift(2);
+ var id = blob.read_shift(2);
+ var grbit = blob.read_shift(2);
+ var colL = blob.read_shift(2);
+ var dxL = blob.read_shift(2);
+ var rwT = blob.read_shift(2);
+ var dyT = blob.read_shift(2);
+ var colR = blob.read_shift(2);
+ var dxR = blob.read_shift(2);
+ var rwB = blob.read_shift(2);
+ var dyB = blob.read_shift(2);
+ var cbMacro = blob.read_shift(2);
+ blob.l += 6;
+ length -= 36;
+ var fts = [];
+ fts.push((parse_BIFF5OT[ot]||parsenoop)(blob, length, opts));
+ return { cmo: [id, ot, grbit], ft:fts };
+}
/* 2.4.329 TODO: parse properly */
function parse_TxO(blob, length, opts) {
@@ -684,7 +739,6 @@ var parse_StyleExt = parsenoop;
var parse_Window2 = parsenoop;
-
var parse_Backup = parsebool; /* 2.4.14 */
var parse_Blank = parse_XLSCell; /* 2.4.20 Just the cell */
var parse_BottomMargin = parse_Xnum; /* 2.4.27 */
@@ -991,6 +1045,16 @@ var parse_BopPopCustom = parsenoop;
var parse_Fbi2 = parsenoop;
/* --- Specific to versions before BIFF8 --- */
+function parse_ImData(blob, length, opts) {
+ var tgt = blob.l + length;
+ var cf = blob.read_shift(2);
+ var env = blob.read_shift(2);
+ var lcb = blob.read_shift(4);
+ var o = {fmt:cf, env:env, len:lcb, data:blob.slice(blob.l,blob.l+lcb)};
+ blob.l += lcb;
+ return o;
+}
+
function parse_BIFF5String(blob) {
var len = blob.read_shift(1);
return blob.read_shift(len, 'sbcs-cont');
@@ -1037,7 +1101,7 @@ function parse_BIFF2FONTXTRA(blob, length) {
blob.l += 1; // charset
blob.l += 3; // unknown
blob.l += 1; // font family
- blob.l += length - 9;
+ blob.l += length - 13;
}
/* TODO: parse rich text runs */
diff --git a/bits/40_harb.js b/bits/40_harb.js
index b9898a919dee2dcdab534b14e6aa10cf7bb27579..5066631844fc25cea005564ed39c41a521d57df0 100644
--- a/bits/40_harb.js
+++ b/bits/40_harb.js
@@ -210,17 +210,23 @@ var SYLK = (function() {
var Mval = 0, j;
for (; ri !== records.length; ++ri) {
Mval = 0;
- var record = records[ri].trim().split(";");
- var RT = record[0], val;
- switch(RT) {
- case 'P': if(record[1].charAt(0) == 'P') formats.push(records[ri].trim().substr(3).replace(/;;/g, ";"));
+ var rstr=records[ri].trim(), record=rstr.split(";"), RT=record[0], val;
+ if(rstr.length > 0) switch(RT) {
+ case 'ID': break; /* header */
+ case 'E': break; /* EOF */
+ case 'B': break; /* dimensions */
+ case 'O': break; /* options? */
+ case 'P':
+ if(record[1].charAt(0) == 'P')
+ formats.push(rstr.substr(3).replace(/;;/g, ";"));
break;
- case 'C': case 'F': for(rj=1; rj 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
else if(Mval == 0) rowinfo[R].hidden = true;
+ break;
+ default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
} break;
- default: break;
+ default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
}
}
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
@@ -297,7 +319,7 @@ var SYLK = (function() {
});
}
- function write_ws_rows_sylk(out, rows) {
+ function write_ws_rows_sylk(out/*:Array*/, rows/*:Array*/) {
rows.forEach(function(row, i) {
var rec = "F;";
if(row.hidden) rec += "M0;";
@@ -318,6 +340,7 @@ var SYLK = (function() {
if(ws['!cols']) write_ws_cols_sylk(preamble, ws['!cols']);
if(ws['!rows']) write_ws_rows_sylk(preamble, ws['!rows']);
+ preamble.push("B;Y" + (r.e.r - r.s.r + 1) + ";X" + (r.e.c - r.s.c + 1) + ";D" + [r.s.c,r.s.r,r.e.c,r.e.r].join(" "));
for(var R = r.s.r; R <= r.e.r; ++R) {
for(var C = r.s.c; C <= r.e.c; ++C) {
var coord = encode_cell({r:R,c:C});
@@ -447,7 +470,7 @@ var PRN = (function() {
function set_text_arr(data/*:string*/, arr/*:AOA*/, R/*:number*/, C/*:number*/) {
if(data === 'TRUE') arr[R][C] = true;
else if(data === 'FALSE') arr[R][C] = false;
- else if(data === ""){}
+ else if(data === ""){/* empty */}
else if(+data == +data) arr[R][C] = +data;
else arr[R][C] = data;
}
@@ -485,29 +508,36 @@ var PRN = (function() {
/* known sep */
if(str.substr(0,4) == "sep=" && str.charCodeAt(5) == 10) { sep = str.charAt(4); str = str.substr(6); }
- /* TODO: actually determine the separator */
- if(str.substr(0,1024).indexOf("\t") == -1) sep = ","; else sep = "\t";
+ else if(str.substr(0,1024).indexOf("\t") == -1) sep = ","; else sep = "\t";
var R = 0, C = 0, v = 0;
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0;
- str = str.replace(/\r\n/g, "\n");
- for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
- case 0x22: instr = !instr; break;
- case sepcc: case 0x0a: if(instr) break;
+ str = str.replace(/\r\n/mg, "\n");
+ function finish_cell() {
var s = str.slice(start, end);
var cell = ({}/*:any*/);
if(s.charCodeAt(0) == 0x3D) { cell.t = 'n'; cell.f = s.substr(1); }
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
- else if(!isNaN(v = parseFloat(s))) { cell.t = 'n'; cell.w = s; cell.v = v; }
- else { cell.t = 's'; cell.v = s.replace(/^"/,"").replace(/"$/,"").replace(/""/g,'"'); }
+ else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; }
+ else if(!isNaN(new Date(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); }
+ else {
+ cell.t = 's';
+ if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
+ cell.v = s;
+ }
if(o.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = cell; }
else ws[encode_cell({c:C,r:R})] = cell;
start = end+1;
if(range.e.c < C) range.e.c = C;
if(range.e.r < R) range.e.r = R;
- if(cc == sepcc) ++C; else { C = 0; ++R; } break;
+ if(cc == sepcc) ++C; else { C = 0; ++R; }
+ }
+ for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
+ case 0x22: if(instr || (end - start == 0)) instr = !instr; break;
+ case sepcc: case 0x0a: case 0x0d: if(!instr) finish_cell(); break;
default: break;
}
+ if(end - start > 0) finish_cell();
ws['!ref'] = encode_range(range);
return ws;
diff --git a/bits/43_sstbin.js b/bits/43_sstbin.js
index 9d158acf60ff27895e244c1fe4b32f4b759e9b52..7904ad40b49623b04b731b8ed6254be642932557 100644
--- a/bits/43_sstbin.js
+++ b/bits/43_sstbin.js
@@ -22,8 +22,8 @@ function parse_sst_bin(data, opts)/*:SST*/ {
pass = false; break;
default:
- if(R_n.indexOf("Begin") > 0){}
- else if(R_n.indexOf("End") > 0){}
+ if(R_n.indexOf("Begin") > 0){/* empty */}
+ else if(R_n.indexOf("End") > 0){/* empty */}
if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
}
});
diff --git a/bits/47_styxml.js b/bits/47_styxml.js
index 61894ab15d93eb369db4e618a196838300b214d3..e9b7df34c79a42f2b6712251500e6689e3b93dd4 100644
--- a/bits/47_styxml.js
+++ b/bits/47_styxml.js
@@ -138,30 +138,47 @@ function parse_fonts(t, styles, themes, opts) {
case '': case '': break;
- /* 18.8.2 b CT_BooleanProperty */
- case '': font.bold = true; break;
+ /* 18.8.2 b CT_BooleanProperty */
+ case '': font.bold = 1; break;
/* 18.8.26 i CT_BooleanProperty */
- case '': font.italic = true; break;
+ case '': font.italic = 1; break;
/* 18.4.13 u CT_UnderlineProperty */
- case '': font.underline = true; break;
+ case '': font.underline = 1; break;
/* 18.4.10 strike CT_BooleanProperty */
- case '': font.strike = true; break;
+ case '': font.strike = 1; break;
- /* 18.4.2 outline CT_BooleanProperty */
- case '': font.outline = true; break;
+ /* 18.4.2 outline CT_BooleanProperty */
+ case '': font.outline = 1; break;
/* 18.8.36 shadow CT_BooleanProperty */
- case '': font.shadow = true; break;
+ case '': font.shadow = 1; break;
+
+ /* 18.8.12 condense CT_BooleanProperty */
+ case '': font.condense = 1; break;
+
+ /* 18.8.17 extend CT_BooleanProperty */
+ case '': font.extend = 1; break;
/* 18.4.11 sz CT_FontSize */
- case '': case '': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
@@ -169,28 +186,39 @@ function parse_fonts(t, styles, themes, opts) {
case '': case '': break;
/* 18.8.18 family CT_FontFamily */
- case '': case '': break;
/* 18.8.35 scheme CT_FontScheme */
case '': case '': break;
- /* 18.4.1 charset CT_IntProperty TODO */
+ /* 18.4.1 charset CT_IntProperty */
case '': case '': break;
@@ -302,17 +330,18 @@ return function parse_sty_xml(data, themes, opts) {
/* 18.8.23 fonts CT_Fonts ? */
if((t=data.match(fontsRegex))) parse_fonts(t, styles, themes, opts);
- /* 18.8.21 fills CT_Fills */
+ /* 18.8.21 fills CT_Fills ? */
if((t=data.match(fillsRegex))) parse_fills(t, styles, themes, opts);
- /* 18.8.5 borders CT_Borders ? */
+ /* 18.8.5 borders CT_Borders ? */
if((t=data.match(bordersRegex))) parse_borders(t, styles, themes, opts);
- /* 18.8.9 cellStyleXfs CT_CellStyleXfs ? */
+ /* 18.8.9 cellStyleXfs CT_CellStyleXfs ? */
/* 18.8.10 cellXfs CT_CellXfs ? */
if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
+ /* 18.8.8 cellStyles CT_CellStyles ? */
/* 18.8.15 dxfs CT_Dxfs ? */
/* 18.8.42 tableStyles CT_TableStyles ? */
/* 18.8.11 colors CT_Colors ? */
diff --git a/bits/48_stybin.js b/bits/48_stybin.js
index 987ad9bd31da4271f6fca8da6390b5f90c9ab69d..bed89fc8467b318664403cd4d93012b558a13eba 100644
--- a/bits/48_stybin.js
+++ b/bits/48_stybin.js
@@ -4,33 +4,132 @@ function parse_BrtFmt(data, length/*:number*/) {
var stFmtCode = parse_XLWideString(data,length-2);
return [ifmt, stFmtCode];
}
+function write_BrtFmt(i/*:number*/, f/*:string*/, o) {
+ if(!o) o = new_buf(6 + 4 * f.length);
+ o.write_shift(2, i);
+ write_XLWideString(f, o);
+ return o.length > o.l ? o.slice(0, o.l) : o;
+}
/* [MS-XLSB] 2.4.653 BrtFont TODO */
-function parse_BrtFont(data, length/*:number*/) {
- var out = ({flags:{}}/*:any*/);
- out.dyHeight = data.read_shift(2);
- out.grbit = parse_FontFlags(data, 2);
- out.bls = data.read_shift(2);
- out.sss = data.read_shift(2);
- out.uls = data.read_shift(1);
- out.bFamily = data.read_shift(1);
- out.bCharSet = data.read_shift(1);
+function parse_BrtFont(data, length/*:number*/, opts) {
+ var out = ({}/*:any*/);
+
+ out.sz = data.read_shift(2) / 20;
+
+ var grbit = parse_FontFlags(data, 2, opts);
+ if(grbit.fCondense) out.condense = 1;
+ if(grbit.fExtend) out.extend = 1;
+ if(grbit.fShadow) out.shadow = 1;
+ if(grbit.fOutline) out.outline = 1;
+ if(grbit.fStrikeout) out.strike = 1;
+ if(grbit.fItalic) out.italic = 1;
+
+ var bls = data.read_shift(2);
+ if(bls === 0x02BC) out.bold = 1;
+
+ switch(data.read_shift(2)) {
+ /* case 0: out.vertAlign = "baseline"; break; */
+ case 1: out.vertAlign = "superscript"; break;
+ case 2: out.vertAlign = "subscript"; break;
+ }
+
+ var underline = data.read_shift(1);
+ if(underline != 0) out.underline = underline;
+
+ var family = data.read_shift(1);
+ if(family > 0) out.family = family;
+
+ var bCharSet = data.read_shift(1);
+ if(bCharSet > 0) out.charset = bCharSet;
+
data.l++;
- out.brtColor = parse_BrtColor(data, 8);
- out.bFontScheme = data.read_shift(1);
+ out.color = parse_BrtColor(data, 8);
+
+ switch(data.read_shift(1)) {
+ /* case 0: out.scheme = "none": break; */
+ case 1: out.scheme = "major"; break;
+ case 2: out.scheme = "minor"; break;
+ }
+
out.name = parse_XLWideString(data, length - 21);
- out.flags.Bold = out.bls === 0x02BC;
- out.flags.Italic = out.grbit.fItalic;
- out.flags.Strikeout = out.grbit.fStrikeout;
- out.flags.Outline = out.grbit.fOutline;
- out.flags.Shadow = out.grbit.fShadow;
- out.flags.Condense = out.grbit.fCondense;
- out.flags.Extend = out.grbit.fExtend;
- out.flags.Sub = out.sss & 0x2;
- out.flags.Sup = out.sss & 0x1;
return out;
}
+function write_BrtFont(font, o) {
+ if(!o) o = new_buf(25+4*32);
+ o.write_shift(2, font.sz * 20);
+ write_FontFlags(font, o);
+ o.write_shift(2, font.bold ? 0x02BC : 0x0190);
+ var sss = 0;
+ if(font.vertAlign == "superscript") sss = 1;
+ else if(font.vertAlign == "subscript") sss = 2;
+ o.write_shift(2, sss);
+ o.write_shift(1, font.underline || 0);
+ o.write_shift(1, font.family || 0);
+ o.write_shift(1, font.charset || 0);
+ o.write_shift(1, 0);
+ write_BrtColor(font.color, o);
+ var scheme = 0;
+ if(font.scheme == "major") scheme = 1;
+ if(font.scheme == "minor") scheme = 2;
+ o.write_shift(1, scheme);
+ write_XLWideString(font.name, o);
+ return o.length > o.l ? o.slice(0, o.l) : o;
+}
+
+/* [MS-XLSB] 2.4.644 BrtFill */
+var XLSBFillPTNames = [
+ "none",
+ "solid",
+ "mediumGray",
+ "darkGray",
+ "lightGray",
+ "darkHorizontal",
+ "darkVertical",
+ "darkDown",
+ "darkUp",
+ "darkGrid",
+ "darkTrellis",
+ "lightHorizontal",
+ "lightVertical",
+ "lightDown",
+ "lightUp",
+ "lightGrid",
+ "lightTrellis",
+ "gray125",
+ "gray0625"
+];
+var rev_XLSBFillPTNames = evert(XLSBFillPTNames);
+/* TODO: gradient fill representation */
+function write_BrtFill(fill, o) {
+ if(!o) o = new_buf(4*3 + 8*7 + 16*1);
+ var fls = rev_XLSBFillPTNames[fill.patternType];
+ if(fls == null) fls = 0x28;
+ o.write_shift(4, fls);
+ var j = 0;
+ if(fls != 0x28) {
+ /* TODO: custom FG Color */
+ write_BrtColor({auto:1}, o);
+ /* TODO: custom BG Color */
+ write_BrtColor({auto:1}, o);
+
+ for(; j < 12; ++j) o.write_shift(4, 0);
+ } else {
+ for(; j < 4; ++j) o.write_shift(4, 0);
+
+ for(; j < 12; ++j) o.write_shift(4, 0); /* TODO */
+ /* iGradientType */
+ /* xnumDegree */
+ /* xnumFillToLeft */
+ /* xnumFillToRight */
+ /* xnumFillToTop */
+ /* xnumFillToBottom */
+ /* cNumStop */
+ /* xfillGradientStop */
+ }
+ return o.length > o.l ? o.slice(0, o.l) : o;
+}
/* [MS-XLSB] 2.4.816 BrtXF */
function parse_BrtXF(data, length/*:number*/) {
@@ -39,6 +138,62 @@ function parse_BrtXF(data, length/*:number*/) {
parsenoop(data, length-4);
return {ixfe:ixfeParent, ifmt:ifmt };
}
+function write_BrtXF(data, ixfeP, o) {
+ if(!o) o = new_buf(16);
+ o.write_shift(2, ixfeP||0);
+ o.write_shift(2, data.numFmtId||0);
+ o.write_shift(2, 0); /* iFont */
+ o.write_shift(2, 0); /* iFill */
+ o.write_shift(2, 0); /* ixBorder */
+ o.write_shift(1, 0); /* trot */
+ o.write_shift(1, 0); /* indent */
+ o.write_shift(1, 0); /* flags */
+ o.write_shift(1, 0); /* flags */
+ o.write_shift(1, 0); /* xfGrbitAtr */
+ o.write_shift(1, 0);
+ return o;
+}
+
+/* [MS-XLSB] 2.5.4 Blxf TODO */
+function write_Blxf(data, o) {
+ if(!o) o = new_buf(10);
+ o.write_shift(1, 0); /* dg */
+ o.write_shift(1, 0);
+ o.write_shift(4, 0); /* color */
+ o.write_shift(4, 0); /* color */
+ return o;
+}
+/* [MS-XLSB] 2.4.299 BrtBorder TODO */
+function write_BrtBorder(border, o) {
+ if(!o) o = new_buf(51);
+ o.write_shift(1, 0); /* diagonal */
+ write_Blxf(null, o); /* top */
+ write_Blxf(null, o); /* bottom */
+ write_Blxf(null, o); /* left */
+ write_Blxf(null, o); /* right */
+ write_Blxf(null, o); /* diag */
+ return o.length > o.l ? o.slice(0, o.l) : o;
+}
+
+/* [MS-XLSB] 2.4.755 BrtStyle TODO */
+function write_BrtStyle(style, o) {
+ if(!o) o = new_buf(12+4*10);
+ o.write_shift(4, style.xfId);
+ o.write_shift(2, 1);
+ o.write_shift(1, +style.builtinId);
+ o.write_shift(1, 0); /* iLevel */
+ write_XLNullableWideString(style.name || "", o);
+ return o.length > o.l ? o.slice(0, o.l) : o;
+}
+
+/* [MS-XLSB] 2.4.269 BrtBeginTableStyles */
+function write_BrtBeginTableStyles(cnt, defTableStyle, defPivotStyle) {
+ var o = new_buf(4+256*2*4);
+ o.write_shift(4, cnt);
+ write_XLNullableWideString(defTableStyle, o);
+ write_XLNullableWideString(defPivotStyle, o);
+ return o.length > o.l ? o.slice(0, o.l) : o;
+}
/* [MS-XLSB] 2.1.7.50 Styles */
function parse_sty_bin(data, themes, opts) {
@@ -57,6 +212,9 @@ function parse_sty_bin(data, themes, opts) {
break;
case 0x002B: /* 'BrtFont' */
styles.Fonts.push(val);
+ if(val.color.theme != null && themes && themes.themeElements && themes.themeElements.clrScheme) {
+ val.color.rgb = rgb_tint(themes.themeElements.clrScheme[val.color.theme].rgb, val.color.tint || 0);
+ }
break;
case 0x0401: /* 'BrtKnownFonts' */ break;
case 0x002D: /* 'BrtFill' */ break;
@@ -98,20 +256,126 @@ function parse_sty_bin(data, themes, opts) {
return styles;
}
+function write_FMTS_bin(ba, NF) {
+ if(!NF) return;
+ var cnt = 0;
+ [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) {
+ for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt;
+ });
+
+ if(cnt == 0) return;
+ write_record(ba, "BrtBeginFmts", write_UInt32LE(cnt));
+ [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) {
+ for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i]));
+ });
+ write_record(ba, "BrtEndFmts");
+}
+
+function write_FONTS_bin(ba, data) {
+ var cnt = 1;
+
+ if(cnt == 0) return;
+ write_record(ba, "BrtBeginFonts", write_UInt32LE(cnt));
+ write_record(ba, "BrtFont", write_BrtFont({
+ sz:12,
+ color: {theme:1},
+ name: "Calibri",
+ family: 2,
+ scheme: "minor"
+ }));
+ /* 1*65491BrtFont [ACFONTS] */
+ write_record(ba, "BrtEndFonts");
+}
+
+function write_FILLS_bin(ba, data) {
+ var cnt = 2;
+
+ if(cnt == 0) return;
+ write_record(ba, "BrtBeginFills", write_UInt32LE(cnt));
+ write_record(ba, "BrtFill", write_BrtFill({patternType:"none"}));
+ write_record(ba, "BrtFill", write_BrtFill({patternType:"gray125"}));
+ /* 1*65431BrtFill */
+ write_record(ba, "BrtEndFills");
+}
+
+function write_BORDERS_bin(ba, data) {
+ var cnt = 1;
+
+ if(cnt == 0) return;
+ write_record(ba, "BrtBeginBorders", write_UInt32LE(cnt));
+ write_record(ba, "BrtBorder", write_BrtBorder({}));
+ /* 1*65430BrtBorder */
+ write_record(ba, "BrtEndBorders");
+}
+
+function write_CELLSTYLEXFS_bin(ba, data) {
+ var cnt = 1;
+ write_record(ba, "BrtBeginCellStyleXFs", write_UInt32LE(cnt));
+ write_record(ba, "BrtXF", write_BrtXF({
+ numFmtId:0,
+ fontId:0,
+ fillId:0,
+ borderId:0
+ }, 0xFFFF));
+ /* 1*65430(BrtXF *FRT) */
+ write_record(ba, "BrtEndCellStyleXFs");
+}
+
+function write_CELLXFS_bin(ba, data) {
+ write_record(ba, "BrtBeginCellXFs", write_UInt32LE(data.length));
+ data.forEach(function(c) { write_record(ba, "BrtXF", write_BrtXF(c,0)); });
+ /* 1*65430(BrtXF *FRT) */
+ write_record(ba, "BrtEndCellXFs");
+}
+
+function write_STYLES_bin(ba, data) {
+ var cnt = 1;
+
+ write_record(ba, "BrtBeginStyles", write_UInt32LE(1));
+ write_record(ba, "BrtStyle", write_BrtStyle({
+ xfId:0,
+ builtinId:0,
+ name:"Normal"
+ }));
+ /* 1*65430(BrtStyle *FRT) */
+ write_record(ba, "BrtEndStyles");
+}
+
+function write_DXFS_bin(ba, data) {
+ var cnt = 0;
+
+ write_record(ba, "BrtBeginDXFs", write_UInt32LE(cnt));
+ /* *2147483647(BrtDXF *FRT) */
+ write_record(ba, "BrtEndDXFs");
+}
+
+function write_TABLESTYLES_bin(ba, data) {
+ var cnt = 0;
+
+ write_record(ba, "BrtBeginTableStyles", write_BrtBeginTableStyles(cnt, "TableStyleMedium9", "PivotStyleMedium4"));
+ /* *TABLESTYLE */
+ write_record(ba, "BrtEndTableStyles");
+}
+
+function write_COLORPALETTE_bin(ba, data) {
+ return;
+ /* BrtBeginColorPalette [INDEXEDCOLORS] [MRUCOLORS] BrtEndColorPalette */
+}
+
/* [MS-XLSB] 2.1.7.50 Styles */
-function write_sty_bin(data, opts) {
+function write_sty_bin(wb, opts) {
var ba = buf_array();
write_record(ba, "BrtBeginStyleSheet");
- /* [FMTS] */
- /* [FONTS] */
- /* [FILLS] */
- /* [BORDERS] */
- /* CELLSTYLEXFS */
- /* CELLXFS*/
- /* STYLES */
- /* DXFS */
- /* TABLESTYLES */
- /* [COLORPALETTE] */
+ write_FMTS_bin(ba, wb.SSF);
+ write_FONTS_bin(ba, wb);
+ write_FILLS_bin(ba, wb);
+ write_BORDERS_bin(ba, wb);
+ write_CELLSTYLEXFS_bin(ba, wb);
+ write_CELLXFS_bin(ba, opts.cellXfs);
+ write_STYLES_bin(ba, wb);
+ write_DXFS_bin(ba, wb);
+ write_TABLESTYLES_bin(ba, wb);
+ write_COLORPALETTE_bin(ba, wb);
/* FRTSTYLESHEET*/
write_record(ba, "BrtEndStyleSheet");
return ba.end();
diff --git a/bits/49_theme.js b/bits/49_theme.js
index 26b897881dfb4b3ea1a0c7f8db932b20d7f195c3..4590dffdf226352772800012a017121cc97d07a9 100644
--- a/bits/49_theme.js
+++ b/bits/49_theme.js
@@ -7,50 +7,41 @@ function parse_clrScheme(t, themes, opts) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
+ /* 20.1.6.2 clrScheme (Color Scheme) CT_ColorScheme */
case '': break;
/* 20.1.2.3.32 srgbClr CT_SRgbColor */
- case '':
- case '':
- /* 20.1.4.1.10 dk2 (Dark 2) */
- case '':
- case '':
- /* 20.1.4.1.22 lt1 (Light 1) */
- case '':
- case '':
- /* 20.1.4.1.23 lt2 (Light 2) */
- case '':
- case '':
/* 20.1.4.1.1 accent1 (Accent 1) */
- case '':
- case '':
/* 20.1.4.1.2 accent2 (Accent 2) */
- case '':
- case '':
/* 20.1.4.1.3 accent3 (Accent 3) */
- case '':
- case '':
/* 20.1.4.1.4 accent4 (Accent 4) */
- case '':
- case '':
/* 20.1.4.1.5 accent5 (Accent 5) */
- case '':
- case '':
/* 20.1.4.1.6 accent6 (Accent 6) */
- case '':
- case '':
- /* 20.1.4.1.19 hlink (Hyperlink) */
- case '':
- case '':
+ /* 20.1.4.1.9 dk1 (Dark 1) */
+ /* 20.1.4.1.10 dk2 (Dark 2) */
/* 20.1.4.1.15 folHlink (Followed Hyperlink) */
- case '':
- case '':
+ /* 20.1.4.1.19 hlink (Hyperlink) */
+ /* 20.1.4.1.22 lt1 (Light 1) */
+ /* 20.1.4.1.23 lt2 (Light 2) */
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
+ case '': case '':
if (y[0][1] === '/') {
themes.themeElements.clrScheme.push(color);
color = {};
diff --git a/bits/53_ccbin.js b/bits/53_ccbin.js
index ac71efa16b48db198c834b1bc96c517405a1126b..7e8cd0561475f15ea8e14d25460845c827e9479c 100644
--- a/bits/53_ccbin.js
+++ b/bits/53_ccbin.js
@@ -22,8 +22,8 @@ function parse_cc_bin(data, opts) {
out.push(val); break;
default:
- if((R_n||"").indexOf("Begin") > 0){}
- else if((R_n||"").indexOf("End") > 0){}
+ if((R_n||"").indexOf("Begin") > 0){/* empty */}
+ else if((R_n||"").indexOf("End") > 0){/* empty */}
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
}
});
diff --git a/bits/55_vml.js b/bits/55_vml.js
index 2c81891c1b08c649445949e426a2b1042a5510ed..e0bd8963b7cf00e9c50d49eb8a7c4b342e6cb75e 100644
--- a/bits/55_vml.js
+++ b/bits/55_vml.js
@@ -34,6 +34,7 @@ function write_comments_vml(rId, comments) {
writetag('x:AutoFill', "False"),
writetag('x:Row', String(c.r)),
writetag('x:Column', String(c.c)),
+ '',
'',
''
]); });
diff --git a/bits/58_cmntbin.js b/bits/58_cmntbin.js
index c7b2cf0c6a7ca4f9c74f85ad9576cfaf782e8983..82ca18a56efe8a877c7a4e17178728882bad2b82 100644
--- a/bits/58_cmntbin.js
+++ b/bits/58_cmntbin.js
@@ -22,9 +22,6 @@ function write_BrtBeginComment(data, o) {
/* [MS-XLSB] 2.4.324 BrtCommentAuthor */
var parse_BrtCommentAuthor = parse_XLWideString;
-/* [MS-XLSB] 2.4.325 BrtCommentText */
-var parse_BrtCommentText = parse_RichStr;
-
/* [MS-XLSB] 2.1.7.8 Comments */
function parse_comments_bin(data, opts) {
var out = [];
@@ -57,8 +54,8 @@ function parse_comments_bin(data, opts) {
default:
- if((R_n||"").indexOf("Begin") > 0){}
- else if((R_n||"").indexOf("End") > 0){}
+ if((R_n||"").indexOf("Begin") > 0){/* empty */}
+ else if((R_n||"").indexOf("End") > 0){/* empty */}
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
}
});
@@ -87,7 +84,7 @@ function write_comments_bin(data, opts) {
c.iauthor = iauthor.indexOf(c.a);
var range = {s:decode_cell(comment[0]),e:decode_cell(comment[0])};
write_record(ba, "BrtBeginComment", write_BrtBeginComment([range, c]));
- if(c.t && c.t.length > 0) write_record(ba, "BrtCommentText", write_RichStr(c));
+ if(c.t && c.t.length > 0) write_record(ba, "BrtCommentText", write_BrtCommentText(c));
write_record(ba, "BrtEndComment");
delete c.iauthor;
});
diff --git a/bits/62_fxls.js b/bits/62_fxls.js
index 569f45713379c1120924e9e85c57b0e328cacd83..a681db4cbf8f3e65375d567d56723eb8a241ba12 100644
--- a/bits/62_fxls.js
+++ b/bits/62_fxls.js
@@ -1,7 +1,7 @@
/* --- formula references point to MS-XLS --- */
/* Small helpers */
function parseread(l) { return function(blob, length) { blob.l+=l; return; }; }
-function parseread1(blob, length) { blob.l+=1; return; }
+function parseread1(blob) { blob.l+=1; return; }
/* Rgce Helpers */
@@ -25,7 +25,7 @@ function parse_RgceArea(blob, length, opts) {
return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} };
}
/* BIFF 2-5 encodes flags in the row field */
-function parse_RgceArea_BIFF2(blob, length, opts) {
+function parse_RgceArea_BIFF2(blob/*, length, opts*/) {
var r=parse_ColRelU(blob, 2), R=parse_ColRelU(blob, 2);
var c=blob.read_shift(1);
var C=blob.read_shift(1);
@@ -33,7 +33,7 @@ function parse_RgceArea_BIFF2(blob, length, opts) {
}
/* 2.5.198.105 TODO */
-function parse_RgceAreaRel(blob, length, opts) {
+function parse_RgceAreaRel(blob, length/*, opts*/) {
var r=blob.read_shift(length == 12 ? 4 : 2), R=blob.read_shift(length == 12 ? 4 : 2);
var c=parse_ColRelU(blob, 2);
var C=parse_ColRelU(blob, 2);
@@ -701,12 +701,12 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
var f = formula[0][ff];
//console.log("++",f, stack)
switch(f[0]) {
- /* 2.5.198.93 */
- case 'PtgUminus': stack.push("-" + stack.pop()); break;
- /* 2.5.198.95 */
- case 'PtgUplus': stack.push("+" + stack.pop()); break;
- /* 2.5.198.81 */
- case 'PtgPercent': stack.push(stack.pop() + "%"); break;
+ case 'PtgUminus': /* 2.5.198.93 */
+ stack.push("-" + stack.pop()); break;
+ case 'PtgUplus': /* 2.5.198.95 */
+ stack.push("+" + stack.pop()); break;
+ case 'PtgPercent': /* 2.5.198.81 */
+ stack.push(stack.pop() + "%"); break;
case 'PtgAdd': /* 2.5.198.26 */
case 'PtgConcat': /* 2.5.198.43 */
@@ -723,10 +723,12 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
e1 = stack.pop(); e2 = stack.pop();
if(last_sp >= 0) {
switch(formula[0][last_sp][1][0]) {
- // $FlowIgnore
- case 0: sp = fill(" ", formula[0][last_sp][1][1]); break;
- // $FlowIgnore
- case 1: sp = fill("\r", formula[0][last_sp][1][1]); break;
+ case 0:
+ // $FlowIgnore
+ sp = fill(" ", formula[0][last_sp][1][1]); break;
+ case 1:
+ // $FlowIgnore
+ sp = fill("\r", formula[0][last_sp][1][1]); break;
default:
sp = "";
// $FlowIgnore
@@ -738,51 +740,46 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
stack.push(e2+PtgBinOp[f[0]]+e1);
break;
- /* 2.5.198.67 */
- case 'PtgIsect':
+ case 'PtgIsect': /* 2.5.198.67 */
e1 = stack.pop(); e2 = stack.pop();
stack.push(e2+" "+e1);
break;
- case 'PtgUnion':
+ case 'PtgUnion': /* 2.5.198.94 */
e1 = stack.pop(); e2 = stack.pop();
stack.push(e2+","+e1);
break;
- case 'PtgRange':
+ case 'PtgRange': /* 2.5.198.83 */
e1 = stack.pop(); e2 = stack.pop();
stack.push(e2+":"+e1);
break;
- /* 2.5.198.34 */
- case 'PtgAttrChoose': break;
- /* 2.5.198.35 */
- case 'PtgAttrGoto': break;
- /* 2.5.198.36 */
- case 'PtgAttrIf': break;
- /* [MS-XLSB] 2.5.97.28 */
- case 'PtgAttrIfError': break;
+ case 'PtgAttrChoose': /* 2.5.198.34 */
+ break;
+ case 'PtgAttrGoto': /* 2.5.198.35 */
+ break;
+ case 'PtgAttrIf': /* 2.5.198.36 */
+ break;
+ case 'PtgAttrIfError': /* [MS-XLSB] 2.5.97.28 */
+ break;
- /* 2.5.198.84 */
- case 'PtgRef':
+ case 'PtgRef': /* 2.5.198.84 */
type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts);
stack.push(encode_cell_xls(c));
break;
- /* 2.5.198.88 */
- case 'PtgRefN':
+ case 'PtgRefN': /* 2.5.198.88 */
type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1];
stack.push(encode_cell_xls(c));
break;
- case 'PtgRef3d': // TODO: lots of stuff
+ case 'PtgRef3d': /* 2.5.198.85 */
type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls(f[1][2], _range, opts);
sname = supbooks.SheetNames[ixti];
var w = sname; /* IE9 fails on defined names */
stack.push(sname + "!" + encode_cell_xls(c));
break;
- /* 2.5.198.62 */
- case 'PtgFunc':
- /* 2.5.198.63 */
- case 'PtgFuncVar':
+ case 'PtgFunc': /* 2.5.198.62 */
+ case 'PtgFuncVar': /* 2.5.198.63 */
//console.log(f[1]);
/* f[1] = [argc, func, type] */
var argc/*:number*/ = f[1][0], func/*:string*/ = f[1][1];
@@ -793,43 +790,38 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
stack.push(func + "(" + args.join(",") + ")");
break;
- /* 2.5.198.42 */
- case 'PtgBool': stack.push(f[1] ? "TRUE" : "FALSE"); break;
- /* 2.5.198.66 */
- case 'PtgInt': stack.push(/*::String(*/f[1]/*::)*/); break;
- /* 2.5.198.79 TODO: precision? */
- case 'PtgNum': stack.push(String(f[1])); break;
- /* 2.5.198.89 */
- // $FlowIgnore
- case 'PtgStr': stack.push('"' + f[1] + '"'); break;
- /* 2.5.198.57 */
- case 'PtgErr': stack.push(/*::String(*/f[1]/*::)*/); break;
- /* 2.5.198.31 TODO */
- case 'PtgAreaN':
+ case 'PtgBool': /* 2.5.198.42 */
+ stack.push(f[1] ? "TRUE" : "FALSE"); break;
+ case 'PtgInt': /* 2.5.198.66 */
+ stack.push(/*::String(*/f[1]/*::)*/); break;
+ case 'PtgNum': /* 2.5.198.79 TODO: precision? */
+ stack.push(String(f[1])); break;
+ case 'PtgStr': /* 2.5.198.89 */
+ // $FlowIgnore
+ stack.push('"' + f[1] + '"'); break;
+ case 'PtgErr': /* 2.5.198.57 */
+ stack.push(/*::String(*/f[1]/*::)*/); break;
+ case 'PtgAreaN': /* 2.5.198.31 TODO */
type = f[1][0]; r = shift_range_xls(f[1][1], _range, opts);
stack.push(encode_range_xls((r/*:any*/), opts));
break;
- /* 2.5.198.27 TODO: fixed points */
- case 'PtgArea':
+ case 'PtgArea': /* 2.5.198.27 TODO: fixed points */
type = f[1][0]; r = shift_range_xls(f[1][1], _range, opts);
stack.push(encode_range_xls((r/*:any*/), opts));
break;
- /* 2.5.198.28 */
- case 'PtgArea3d': // TODO: lots of stuff
+ case 'PtgArea3d': /* 2.5.198.28 TODO */
type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; r = f[1][2];
sname = (supbooks && supbooks[1] ? supbooks[1][ixti+1] : "**MISSING**");
stack.push(sname + "!" + encode_range((r/*:any*/)));
break;
- /* 2.5.198.41 */
- case 'PtgAttrSum':
+ case 'PtgAttrSum': /* 2.5.198.41 */
stack.push("SUM(" + stack.pop() + ")");
break;
- /* 2.5.198.37 */
- case 'PtgAttrSemi': break;
+ case 'PtgAttrSemi': /* 2.5.198.37 */
+ break;
- /* 2.5.97.60 TODO: do something different for revisions */
- case 'PtgName':
+ case 'PtgName': /* 2.5.97.60 TODO: revisions */
/* f[1] = type, 0, nameindex */
nameidx = f[1][2];
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
@@ -838,8 +830,7 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
stack.push(name);
break;
- /* 2.5.97.61 TODO: do something different for revisions */
- case 'PtgNameX':
+ case 'PtgNameX': /* 2.5.97.61 TODO: revisions */
/* f[1] = type, ixti, nameindex */
var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = f[1][2]; var externbook;
/* TODO: Properly handle missing values */
@@ -850,7 +841,7 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
} else {
var pnxname = supbooks.SheetNames[bookidx];
var o = "";
- if(((supbooks[bookidx]||[])[0]||[])[0] == 0x3A01){}
+ if(((supbooks[bookidx]||[])[0]||[])[0] == 0x3A01){/* empty */}
else if(((supbooks[bookidx]||[])[0]||[])[0] == 0x0401){
if(supbooks[bookidx][nameidx] && supbooks[bookidx][nameidx].itab > 0) {
o = supbooks.SheetNames[supbooks[bookidx][nameidx].itab-1] + "!";
@@ -867,8 +858,7 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
stack.push(externbook.Name);
break;
- /* 2.5.198.80 */
- case 'PtgParen':
+ case 'PtgParen': /* 2.5.198.80 */
var lp = '(', rp = ')';
if(last_sp >= 0) {
sp = "";
@@ -889,15 +879,13 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
}
stack.push(lp + stack.pop() + rp); break;
- /* 2.5.198.86 */
- case 'PtgRefErr': stack.push('#REF!'); break;
+ case 'PtgRefErr': /* 2.5.198.86 */
+ stack.push('#REF!'); break;
- /* 2.5.198.87 */
- case 'PtgRefErr3d': stack.push('#REF!'); break;
+ case 'PtgRefErr3d': /* 2.5.198.87 */
+ stack.push('#REF!'); break;
- /* */
- /* 2.5.198.58 TODO */
- case 'PtgExp':
+ case 'PtgExp': /* 2.5.198.58 TODO */
c = {c:f[1][1],r:f[1][0]};
var q = ({c: cell.c, r:cell.r}/*:any*/);
if(supbooks.sharedf[encode_cell(c)]) {
@@ -919,42 +907,37 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
}
break;
- /* 2.5.198.32 TODO */
- case 'PtgArray':
+ case 'PtgArray': /* 2.5.198.32 TODO */
stack.push("{" + stringify_array(f[1]) + "}");
break;
- /* 2.5.198.70 TODO: confirm this is a non-display */
- case 'PtgMemArea':
+ case 'PtgMemArea': /* 2.5.198.70 TODO: confirm this is a non-display */
//stack.push("(" + f[2].map(encode_range).join(",") + ")");
break;
- /* 2.5.198.38 */
- case 'PtgAttrSpace':
- /* 2.5.198.39 */
- case 'PtgAttrSpaceSemi':
+ case 'PtgAttrSpace': /* 2.5.198.38 */
+ case 'PtgAttrSpaceSemi': /* 2.5.198.39 */
last_sp = ff;
break;
- /* 2.5.198.92 TODO */
- case 'PtgTbl': break;
+ case 'PtgTbl': /* 2.5.198.92 TODO */
+ break;
- /* 2.5.198.71 */
- case 'PtgMemErr': break;
+ case 'PtgMemErr': /* 2.5.198.71 */
+ break;
- /* 2.5.198.74 */
- case 'PtgMissArg':
+ case 'PtgMissArg': /* 2.5.198.74 */
stack.push("");
break;
- /* 2.5.198.29 */
- case 'PtgAreaErr': stack.push("#REF!"); break;
+ case 'PtgAreaErr': /* 2.5.198.29 */
+ stack.push("#REF!"); break;
- /* 2.5.198.30 */
- case 'PtgAreaErr3d': stack.push("#REF!"); break;
+ case 'PtgAreaErr3d': /* 2.5.198.30 */
+ stack.push("#REF!"); break;
- /* 2.5.198.72 TODO */
- case 'PtgMemFunc': break;
+ case 'PtgMemFunc': /* 2.5.198.72 TODO */
+ break;
default: throw new Error('Unrecognized Formula Token: ' + String(f));
}
@@ -966,12 +949,14 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks,
/* note: some bad XLSB files omit the PtgParen */
case 4: _left = false;
/* falls through */
- // $FlowIgnore
- case 0: sp = fill(" ", f[1][1]); break;
+ case 0:
+ // $FlowIgnore
+ sp = fill(" ", f[1][1]); break;
case 5: _left = false;
/* falls through */
- // $FlowIgnore
- case 1: sp = fill("\r", f[1][1]); break;
+ case 1:
+ // $FlowIgnore
+ sp = fill("\r", f[1][1]); break;
default:
sp = "";
// $FlowIgnore
diff --git a/bits/66_wscommon.js b/bits/66_wscommon.js
index d7ce1ebf188bc711e74358ea6be6cba53a2b4192..0e415bb2fc5af4d55dfa021e05f1e6faa7ce7fee 100644
--- a/bits/66_wscommon.js
+++ b/bits/66_wscommon.js
@@ -39,7 +39,16 @@ function default_margins(margins, mode) {
function get_cell_style(styles, cell, opts) {
var z = opts.revssf[cell.z != null ? cell.z : "General"];
- for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i;
+ var i = 0x3c, len = styles.length;
+ if(z == null && opts.ssf) {
+ for(; i < 0x188; ++i) if(opts.ssf[i] == null) {
+ SSF.load(cell.z, i);
+ opts.ssf[i] = cell.z;
+ opts.revssf[cell.z] = z = i;
+ break;
+ }
+ }
+ for(i = 0; i != len; ++i) if(styles[i].numFmtId === z) return i;
styles[len] = {
numFmtId:z,
fontId:0,
@@ -77,7 +86,7 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
} catch(e) { if(opts.WTF) throw e; }
if(fillid) try {
p.s = styles.Fills[fillid];
- if (p.s.fgColor && p.s.fgColor.theme) {
+ if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
if(opts.WTF) p.s.fgColor.raw_rgb = themes.themeElements.clrScheme[p.s.fgColor.theme].rgb;
}
diff --git a/bits/68_wsbin.js b/bits/68_wsbin.js
index 6f4a02aa595c605e078d8cb823b2de2781fdec15..6bd2cb5525201ac9149d4036a7411e528a83fc91 100644
--- a/bits/68_wsbin.js
+++ b/bits/68_wsbin.js
@@ -69,6 +69,9 @@ function write_row_header(ba, ws, range, R) {
var parse_BrtWsDim = parse_UncheckedRfX;
var write_BrtWsDim = write_UncheckedRfX;
+/* [MS-XLSB] 2.4.813 BrtWsFmtInfo */
+//function write_BrtWsFmtInfo(ws, o) { }
+
/* [MS-XLSB] 2.4.815 BrtWsProp */
function parse_BrtWsProp(data, length) {
var z = {};
@@ -78,8 +81,9 @@ function parse_BrtWsProp(data, length) {
return z;
}
function write_BrtWsProp(str, o) {
- if(o == null) o = new_buf(80+4*str.length);
- for(var i = 0; i < 11; ++i) o.write_shift(1,0);
+ if(o == null) o = new_buf(84+4*str.length);
+ for(var i = 0; i < 3; ++i) o.write_shift(1,0);
+ write_BrtColor({auto:1}, o);
o.write_shift(-4,-1);
o.write_shift(-4,-1);
write_XLSBCodeName(str, o);
@@ -260,8 +264,8 @@ function write_BrtHLink(l, rId, o) {
write_UncheckedRfX({s:decode_cell(l[0]), e:decode_cell(l[0])}, o);
write_RelID("rId" + rId, o);
var locidx = l[1].Target.indexOf("#");
- var location = locidx == -1 ? "" : l[1].Target.substr(locidx+1);
- write_XLWideString(location || "", o);
+ var loc = locidx == -1 ? "" : l[1].Target.substr(locidx+1);
+ write_XLWideString(loc || "", o);
write_XLWideString(l[1].Tooltip || "", o);
write_XLWideString("", o);
return o.slice(0, o.l);
@@ -536,6 +540,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
s['!margins'] = val;
break;
+ /* case 'BrtUid' */
case 0x00AF: /* 'BrtAFilterDateGroupItem' */
case 0x0284: /* 'BrtActiveX' */
case 0x0271: /* 'BrtBigName' */
@@ -585,7 +590,6 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
case 0x0413: /* 'BrtSparkline' */
case 0x01AC: /* 'BrtTable' */
case 0x00AA: /* 'BrtTop10Filter' */
- /* case 'BrtUid' */
case 0x0032: /* 'BrtValueMeta' */
case 0x0816: /* 'BrtWebExtension' */
case 0x01E5: /* 'BrtWsFmtInfo' */
@@ -601,8 +605,8 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
case 0x0026: /* 'BrtACEnd' */ break;
default:
- if((R_n||"").indexOf("Begin") > 0){}
- else if((R_n||"").indexOf("End") > 0){}
+ if((R_n||"").indexOf("Begin") > 0){/* empty */}
+ else if((R_n||"").indexOf("End") > 0){/* empty */}
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
}
}, opts);
@@ -646,7 +650,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
}
var o/*:any*/ = ({r:R, c:C}/*:any*/);
/* TODO: cell style */
- //o.s = get_cell_style(opts.cellXfs, cell, opts);
+ o.s = get_cell_style(opts.cellXfs, cell, opts);
if(cell.l) ws['!links'].push([encode_cell(o), cell.l]);
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
switch(cell.t) {
@@ -753,6 +757,11 @@ function write_WSVIEWS2(ba, ws) {
write_record(ba, "BrtEndWsViews");
}
+function write_WSFMTINFO(ba, ws) {
+ /* [ACWSFMTINFO] */
+ //write_record(ba, "BrtWsFmtInfo", write_BrtWsFmtInfo(ws));
+}
+
function write_SHEETPROTECT(ba, ws) {
if(!ws['!protect']) return;
/* [BrtSheetProtectionIso] */
@@ -770,7 +779,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
write_record(ba, "BrtWsProp", write_BrtWsProp(s));
write_record(ba, "BrtWsDim", write_BrtWsDim(r));
write_WSVIEWS2(ba, ws);
- /* [WSFMTINFO] */
+ write_WSFMTINFO(ba, ws);
write_COLINFOS(ba, ws, idx, opts, wb);
write_CELLTABLE(ba, ws, idx, opts, wb);
/* [BrtSheetCalcProp] */
diff --git a/bits/73_wbbin.js b/bits/73_wbbin.js
index 8a8a8051953c89c5e92224080f735429b5f512ca..23610d2222e5c35affe08738b92d353e7646b165 100644
--- a/bits/73_wbbin.js
+++ b/bits/73_wbbin.js
@@ -24,7 +24,7 @@ function parse_BrtWbProp(data, length) {
return [dwThemeVersion, strName];
}
function write_BrtWbProp(data, o) {
- if(!o) o = new_buf(68);
+ if(!o) o = new_buf(72);
o.write_shift(4, 0);
o.write_shift(4, 0);
write_XLSBCodeName("ThisWorkbook", o);
@@ -85,6 +85,9 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
break;
case 0x040C: /* 'BrtNameExt' */ break;
+ /* case 'BrtModelTimeGroupingCalcCol' */
+ /* case 'BrtRevisionPtr' */
+ /* case 'BrtUid' */
case 0x0817: /* 'BrtAbsPath15' */
case 0x0216: /* 'BrtBookProtection' */
case 0x02A5: /* 'BrtBookProtectionIso' */
@@ -100,11 +103,9 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
case 0x0299: /* 'BrtFnGroup' */
case 0x0850: /* 'BrtModelRelationship' */
case 0x084D: /* 'BrtModelTable' */
- /* case 'BrtModelTimeGroupingCalcCol' */
case 0x0225: /* 'BrtOleSize' */
case 0x0805: /* 'BrtPivotTableRef' */
case 0x0169: /* 'BrtPlaceholderName' */
- /* case 'BrtRevisionPtr' */
case 0x0254: /* 'BrtSmartTagType' */
case 0x029B: /* 'BrtSupAddin' */
case 0x0163: /* 'BrtSupBookSrc' */
@@ -113,7 +114,6 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
case 0x081C: /* 'BrtTableSlicerCacheID' */
case 0x081B: /* 'BrtTableSlicerCacheIDs' */
case 0x0822: /* 'BrtTimelineCachePivotCacheID' */
- /* case 'BrtUid' */
case 0x018D: /* 'BrtUserBookView' */
case 0x009A: /* 'BrtWbFactoid' */
case 0x0099: /* 'BrtWbProp' */
@@ -132,8 +132,8 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
case 0x0010: /* 'BrtFRTArchID$' */ break;
default:
- if((R_n||"").indexOf("Begin") > 0){}
- else if((R_n||"").indexOf("End") > 0){}
+ if((R_n||"").indexOf("Begin") > 0){/* empty */}
+ else if((R_n||"").indexOf("End") > 0){/* empty */}
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
}
}, opts);
diff --git a/bits/75_xlml.js b/bits/75_xlml.js
index 3ec8e8c564405263385080a65dbebe44d693d7c0..07fab4c8a69b1e8827e370e306a87b1e095bd82c 100644
--- a/bits/75_xlml.js
+++ b/bits/75_xlml.js
@@ -530,7 +530,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
/* WorksheetOptions */
case 'WorksheetOptions': switch(Rn[3]) {
case 'Visible':
- if(Rn[0].slice(-2) === "/>"){}
+ if(Rn[0].slice(-2) === "/>"){/* empty */}
else if(Rn[1]==="/") switch(str.slice(pidx, Rn.index)) {
case "SheetHidden": wsprops.Hidden = 1; break;
case "SheetVeryHidden": wsprops.Hidden = 2; break;
@@ -729,12 +729,10 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
default: seen = false;
} break;
- /* Sorting */
case 'Sorting':
- /* ConditionalFormatting */
case 'ConditionalFormatting':
- /* DataValidation */
- case 'DataValidation': switch(Rn[3]) {
+ case 'DataValidation':
+ switch(Rn[3]) {
case 'Range': break;
case 'Type': break;
case 'Min': break;
@@ -889,7 +887,7 @@ function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workb
if(wb && wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx]) {
/* Visible */
- if(!!wb.Workbook.Sheets[idx].Hidden) o.push(writextag("Visible", (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden"), {}));
+ if(wb.Workbook.Sheets[idx].Hidden) o.push(writextag("Visible", (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden"), {}));
else {
/* Selected */
for(var i = 0; i < idx; ++i) if(wb.Workbook.Sheets[i] && !wb.Workbook.Sheets[i].Hidden) break;
diff --git a/bits/76_xls.js b/bits/76_xls.js
index 44a0446b39856877af0a317e82f7aeb4b8a6f0d9..8ca3a90964f344f068d4de9968a3614ba3781d04 100644
--- a/bits/76_xls.js
+++ b/bits/76_xls.js
@@ -56,7 +56,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) {
if(p.t === 'z') return;
if(!p.XF) return;
try {
- var fmtid = p.XF.ifmt||0;
+ var fmtid = p.z || p.XF.ifmt || 0;
if(opts.cellNF) p.z = SSF._table[fmtid];
} catch(e) { if(opts.WTF) throw e; }
if(!opts || opts.cellText !== false) try {
@@ -179,6 +179,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
var last_Rn = '';
var file_depth = 0; /* TODO: make a real stack */
var BIFF2Fmt = 0;
+ var BIFF2FmtTable = [];
var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */
var last_lbl;
@@ -309,7 +310,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
out = options.dense ? [] : {};
} break;
case 'BOF': {
- if(opts.biff !== 8){}
+ if(opts.biff !== 8){/* empty */}
else if(RecordType === 0x0009) opts.biff = 2;
else if(RecordType === 0x0209) opts.biff = 3;
else if(RecordType === 0x0409) opts.biff = 4;
@@ -342,17 +343,20 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c;
- temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:'n'};
+ temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'};
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
} break;
case 'BoolErr': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t};
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
} break;
case 'RK': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'};
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
} break;
@@ -360,6 +364,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
for(var j = val.c; j <= val.C; ++j) {
var ixfe = val.rkrec[j-val.c][0];
temp_val= {ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'};
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:j, r:val.r}, temp_val, options);
}
@@ -377,6 +382,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
else temp_val.F = ((options.dense ? (out[_fr]||[])[_fc]: out[_fe]) || {}).F;
} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
}
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell(val.cell, temp_val, options);
last_formula = val;
@@ -389,6 +395,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
if(options.cellFormula) {
temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
}
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell(last_formula.cell, temp_val, options);
last_formula = null;
@@ -419,11 +426,13 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'LabelSst':
temp_val=make_cell(sst[val.isst].t, val.ixfe, 's');
temp_val.XF = XFs[temp_val.ixfe];
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
break;
case 'Blank': if(options.sheetStubs) {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'};
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
} break;
@@ -431,6 +440,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
for(var _j = val.c; _j <= val.C; ++_j) {
var _ixfe = val.ixfe[_j-val.c];
temp_val= {ixfe:_ixfe, XF:XFs[_ixfe], t:'z'};
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:_j, r:val.r}, temp_val, options);
}
@@ -439,6 +449,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'Label': case 'BIFF2STR':
temp_val=make_cell(val.val, val.ixfe, 's');
temp_val.XF = XFs[temp_val.ixfe];
+ if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
break;
@@ -453,20 +464,23 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
SSF.load(val[1], val[0]);
} break;
case 'BIFF2FORMAT': {
- SSF.load(val, BIFF2Fmt++);
+ BIFF2FmtTable[BIFF2Fmt++] = val;
+ for(var b2idx = 0; b2idx < BIFF2Fmt + 163; ++b2idx) if(SSF._table[b2idx] == val) break;
+ if(b2idx >= 163) SSF.load(val, BIFF2Fmt + 163);
} break;
case 'MergeCells': mergecells = mergecells.concat(val); break;
case 'Obj': objects[val.cmo[0]] = opts.lastobj = val; break;
case 'TxO': opts.lastobj.TxO = val; break;
+ case 'ImData': opts.lastobj.ImData = val; break;
case 'HLink': {
for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR)
for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) {
cc = options.dense ? (out[rngR]||[])[rngC] : out[encode_cell({c:rngC,r:rngR})];
if(cc) cc.l = val[1];
- }
+ }
} break;
case 'HLinkTooltip': {
for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR)
@@ -611,24 +625,24 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
//console.log("Zoom Level:", val[0]/val[1],val);
} break;
case 'SheetExt': {
-
+ /* empty */
} break;
case 'SheetExtOptional': {
-
+ /* empty */
} break;
/* VBA */
case 'ObNoMacros': {
-
+ /* empty */
} break;
case 'ObProj': {
-
+ /* empty */
} break;
case 'CodeName': {
-
+ /* empty */
} break;
case 'GUIDTypeLib': {
-
+ /* empty */
} break;
case 'WOpt': break; // TODO: WTF?
@@ -657,7 +671,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
/* Explicitly Ignored */
case 'Excel9File': break;
case 'Units': break;
- case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': case 'BuiltInFnGroupCount':
+ case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': case 'BuiltInFnGroupCount': break;
/* View Stuff */
case 'Window1': case 'Window2': case 'HideObj': case 'GridSet': case 'Guts':
case 'UserBView': case 'UserSViewBegin': case 'UserSViewEnd':
@@ -724,13 +738,12 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
/* Drawing */
case 'ShapePropsStream': break;
case 'MsoDrawing': case 'MsoDrawingGroup': case 'MsoDrawingSelection': break;
- case 'ImData': break;
/* Pub Stuff */
- case 'WebPub': case 'AutoWebPub':
+ case 'WebPub': case 'AutoWebPub': break;
/* Print Stuff */
case 'HeaderFooter': case 'HFPicture': case 'PLV':
- case 'HorizontalPageBreaks': case 'VerticalPageBreaks':
+ case 'HorizontalPageBreaks': case 'VerticalPageBreaks': break;
/* Behavioral */
case 'Backup': case 'CompressPictures': case 'Compat12': break;
@@ -779,11 +792,11 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
function parse_props(cfb) {
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
var DSI = cfb.find('!DocumentSummaryInformation');
- if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {}
+ if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {/* empty */}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = cfb.find('!SummaryInformation');
- if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {}
+ if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {/* empty */}
}
function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ {
diff --git a/bits/77_parsetab.js b/bits/77_parsetab.js
index 05a188cc986e950b70a75b33aa37dbfcfbc26c30..f00a8003c6f27174ff8fc389e7202d888b316e1f 100644
--- a/bits/77_parsetab.js
+++ b/bits/77_parsetab.js
@@ -1192,9 +1192,10 @@ var XLSRecordEnum = {
/*::[*/0x0007/*::]*/: { n:"String", f:parse_BIFF2STRING },
/*::[*/0x0008/*::]*/: { n:"BIFF2ROW", f:parsenoop },
/*::[*/0x000b/*::]*/: { n:"Index", f:parse_Index },
+ /*::[*/0x0016/*::]*/: { n:"ExternCount", f:parsenoop },
/*::[*/0x001e/*::]*/: { n:"BIFF2FORMAT", f:parse_BIFF2Format },
/*::[*/0x001f/*::]*/: { n:"BIFF2FMTCNT", f:parsenoop }, /* 16-bit cnt of BIFF2FORMAT records */
- /*::[*/0x0016/*::]*/: { n:"ExternCount", f:parsenoop },
+ /*::[*/0x0020/*::]*/: { n:"BIFF2COLINFO", f:parsenoop },
/*::[*/0x0021/*::]*/: { n:"Array", f:parse_Array },
/*::[*/0x0025/*::]*/: { n:"DefaultRowHeight", f:parse_DefaultRowHeight },
/*::[*/0x0032/*::]*/: { n:"BIFF2FONTXTRA", f:parse_BIFF2FONTXTRA },
@@ -1202,7 +1203,7 @@ var XLSRecordEnum = {
/*::[*/0x0045/*::]*/: { n:"BIFF2FONTCLR", f:parsenoop },
/*::[*/0x0056/*::]*/: { n:"BIFF4FMTCNT", f:parsenoop }, /* 16-bit cnt, similar to BIFF2 */
/*::[*/0x007e/*::]*/: { n:"RK", f:parsenoop }, /* Not necessarily same as 0x027e */
- /*::[*/0x007f/*::]*/: { n:"ImData", f:parsenoop },
+ /*::[*/0x007f/*::]*/: { n:"ImData", f:parse_ImData },
/*::[*/0x0087/*::]*/: { n:"Addin", f:parsenoop },
/*::[*/0x0088/*::]*/: { n:"Edg", f:parsenoop },
/*::[*/0x0089/*::]*/: { n:"Pub", f:parsenoop },
diff --git a/bits/80_parseods.js b/bits/80_parseods.js
index 9b38b18a9042b7e887fce8308f6c43ef2683873e..0a949345c06a053ca06c331bd80fe3ea786db80b 100644
--- a/bits/80_parseods.js
+++ b/bits/80_parseods.js
@@ -312,7 +312,7 @@ var parse_content_xml = (function() {
try {
var AutoFilter = ods_to_csf_range_3D(parsexmltag(Rn[0])['target-range-address']);
Sheets[AutoFilter[0]]['!autofilter'] = { ref: AutoFilter[1] };
- } catch(e) { }
+ } catch(e) {/* empty */}
break;
case 's': break; //
@@ -362,7 +362,8 @@ var parse_content_xml = (function() {
case 'sheet-name': // 7.3.9
break;
- case 'event-listener': // TODO
+ case 'event-listener':
+ break;
/* TODO: FODS Properties */
case 'initial-creator':
case 'creation-date':
diff --git a/bits/86_writezip.js b/bits/86_writezip.js
index 4ee65472cfa649defd4e9c8ca3cb2404ddcde9eb..88c29495f3ed63fbe0ce5d30cb7b7d4656debd1c 100644
--- a/bits/86_writezip.js
+++ b/bits/86_writezip.js
@@ -9,6 +9,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
make_ssf(SSF); SSF.load_table(wb.SSF);
// $FlowIgnore
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
+ opts.ssf = wb.SSF;
}
opts.rels = {}; opts.wbrels = {};
opts.Strings = /*::((*/[]/*:: :any):SST)*/; opts.Strings.Count = 0; opts.Strings.Unique = 0;
@@ -37,7 +38,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
/*::if(!wb.Props) throw "unreachable"; */
f = "docProps/app.xml";
- if(wb.Props && wb.Props.SheetNames){}
+ if(wb.Props && wb.Props.SheetNames){/* empty */}
else if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;
// $FlowIgnore
else wb.Props.SheetNames = wb.SheetNames.map(function(x,i) { return [(wb.Workbook.Sheets[i]||{}).Hidden != 2, x];}).filter(function(x) { return x[0]; }).map(function(x) { return x[1]; });
@@ -126,5 +127,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
zip.file("[Content_Types].xml", write_ct(ct, opts));
zip.file('_rels/.rels', write_rels(opts.rels));
zip.file('xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
+
+ delete opts.revssf; delete opts.ssf;
return zip;
}
diff --git a/demos/browserify/browserify.html b/demos/browserify/browserify.html
index 2c72df89ab2c465ef7c9e7ce5c1b4856ac1f0ad7..d391aa2c748f76b2ad79a9c35c85bba2a6d40899 100644
--- a/demos/browserify/browserify.html
+++ b/demos/browserify/browserify.html
@@ -141,7 +141,7 @@ function get_radio_value( radioName ) {
function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
- var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
+ var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
if(roa.length > 0){
result[sheetName] = roa;
}
diff --git a/demos/requirejs/requirejs.js b/demos/requirejs/requirejs.js
index 0b303016b16701266644cfa9e126ae050e1e13b4..32918e1728102232c8a09becdcc10841843dee6c 100644
--- a/demos/requirejs/requirejs.js
+++ b/demos/requirejs/requirejs.js
@@ -41,7 +41,7 @@ function get_radio_value( radioName ) {
function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
- var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
+ var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
if(roa.length > 0){
result[sheetName] = roa;
}
diff --git a/demos/webpack/webpack.html b/demos/webpack/webpack.html
index cd5674dfa0154c61c370d444209078494183882d..870bbd88856300b5e7e4e1164dd54d2348436f2b 100644
--- a/demos/webpack/webpack.html
+++ b/demos/webpack/webpack.html
@@ -141,7 +141,7 @@ function get_radio_value( radioName ) {
function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
- var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
+ var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
if(roa.length > 0){
result[sheetName] = roa;
}
diff --git a/dist/xlsx.core.min.js b/dist/xlsx.core.min.js
index 03474bc07724aee623181e52d716d69494647996..6b60680caac93452ec5cdbdc868d0d18782aeb48 100644
Binary files a/dist/xlsx.core.min.js and b/dist/xlsx.core.min.js differ
diff --git a/dist/xlsx.core.min.map b/dist/xlsx.core.min.map
index 9991fa199cbb8e41835e0a5caacac531260fde3c..f4dfa95ac951082a14b6818b8e4c3d833a2530da 100644
Binary files a/dist/xlsx.core.min.map and b/dist/xlsx.core.min.map differ
diff --git a/dist/xlsx.full.min.js b/dist/xlsx.full.min.js
index 7685b9c6baf1d8a786c29c655a1e8b37e8d10d7e..aaccec35684de0486635faac930fba8b7c8a1a6a 100644
Binary files a/dist/xlsx.full.min.js and b/dist/xlsx.full.min.js differ
diff --git a/dist/xlsx.full.min.map b/dist/xlsx.full.min.map
index 9717011e1bbe6958a2c3b0f91ee7567d36bc47be..a1837f2e07b2a9e1076a4fe84af15760ea387012 100644
Binary files a/dist/xlsx.full.min.map and b/dist/xlsx.full.min.map differ
diff --git a/dist/xlsx.js b/dist/xlsx.js
index f3ab374b0805965eab18b17567b0f79606b5e70e..6a78a5836ba2404c3ba54de1e0f850c223419808 100644
Binary files a/dist/xlsx.js and b/dist/xlsx.js differ
diff --git a/dist/xlsx.min.js b/dist/xlsx.min.js
index 2eefee175cb0cc82d65f315abc9f29444b4bef0c..7f8861cb9009d31a1bd42d8b227602b4c15f3af9 100644
Binary files a/dist/xlsx.min.js and b/dist/xlsx.min.js differ
diff --git a/dist/xlsx.min.map b/dist/xlsx.min.map
index b2f0a3903b3006a12e6f81c01d03b7d8b77dd531..0a61ff981ac0438f230650ec34494dd41b0e06fc 100644
Binary files a/dist/xlsx.min.map and b/dist/xlsx.min.map differ
diff --git a/docbits/00_intro.md b/docbits/00_intro.md
index 9910fef115cb989aec8d5a0757f004c9277b9299..5126dde2844b1863fb06b498840a09f99320919e 100644
--- a/docbits/00_intro.md
+++ b/docbits/00_intro.md
@@ -6,7 +6,8 @@ Emphasis on parsing and writing robustness, cross-format feature compatibility
with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.
This is the community version. We also offer a pro version with performance
-enhancements and additional features by request.
+enhancements, additional features by request, and dedicated support.
+
[**Pro Version**](http://sheetjs.com/pro)
@@ -18,14 +19,30 @@ enhancements and additional features by request.
[**Source Code**](http://git.io/xlsx)
-[**File format support for known spreadsheet data formats:**](#file-formats)
+[**Issues and Bug Reports**](https://github.com/sheetjs/js-xlsx/issues)
-![circo graph of format support](formats.png)
+[**Other General Support Issues**](https://discourse.sheetjs.com)
+
+[**File format support for known spreadsheet data formats:**](#file-formats)
- Graph Legend
+ Graph of supported formats (click to show)
+
+![circo graph of format support](formats.png)
![graph legend](legend.png)
+[**Browser Test**](http://oss.sheetjs.com/js-xlsx/tests/)
+
+[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
+
+[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
+[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
+[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
+[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
+[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
+[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
+[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
+
diff --git a/docbits/10_install.md b/docbits/10_install.md
index edce5d8bd7ba58bfc0b9090e89c31857a3d31bb6..ace8f8ea264feeb87dc1cf52b802bb64a1118d2e 100644
--- a/docbits/10_install.md
+++ b/docbits/10_install.md
@@ -1,15 +1,15 @@
## Installation
-With [npm](https://www.npmjs.org/package/xlsx):
+In the browser, just add a script tag:
-```bash
-$ npm install xlsx
+```html
+
```
-In the browser:
+With [npm](https://www.npmjs.org/package/xlsx):
-```html
-
+```bash
+$ npm install xlsx
```
With [bower](http://bower.io/search/?q=js-xlsx):
diff --git a/docbits/15_phil.md b/docbits/15_phil.md
new file mode 100644
index 0000000000000000000000000000000000000000..9d4c8a7c0000f93841528e928312ecf797ad1d6e
--- /dev/null
+++ b/docbits/15_phil.md
@@ -0,0 +1,35 @@
+## Philosophy
+
+
+ Philosophy (click to show)
+
+Prior to SheetJS, APIs for processing spreadsheet files were format-specific.
+Third-party libraries either supported one format, or they involved a separate
+set of classes for each supported file type. Even though XLSB was introduced in
+Excel 2007, nothing outside of SheetJS or Excel supported the format.
+
+To promote a format-agnostic view, js-xlsx starts from a pure-JS representation
+that we call the ["Common Spreadsheet Format"](#common-spreadsheet-format).
+Emphasizing a uniform object representation enables radical features like format
+conversion (e.g. reading an XLSX template and saving as XLS) and circumvents the
+"class trap". By abstracting the complexities of the various formats, tools
+need not worry about the specific file type!
+
+A simple object representation combined with careful coding practices enables
+use cases in older browsers and in alternative environments like ExtendScript
+and Web Workers. It is always tempting to use the latest and greatest features,
+but they tend to require the latest versions of browsers, limiting usability.
+
+Utility functions capture common use cases like generating JS objects or HTML.
+Most simple operations should only require a few lines of code. More complex
+operations generally should be straightforward to implement.
+
+Excel pushes the XLSX format as default starting in Excel 2007. However, there
+are other formats with more appealing properties. For example, the XLSB format
+is spiritually similar to XLSX but files often tend up taking less than half the
+space and open much faster! Even though an XLSX writer is available, other
+format writers are available so users can take advantage of the unique
+characteristics of each format.
+
+
+
diff --git a/docbits/40_interface.md b/docbits/40_interface.md
index dc0c803087c14bd31bac81d17b649349d7a77285..e50d697cd7418fee97898ea51abaa095a0dc6a02 100644
--- a/docbits/40_interface.md
+++ b/docbits/40_interface.md
@@ -38,7 +38,6 @@ Utilities are available in the `XLSX.utils` object:
**Exporting:**
- `sheet_to_json` converts a worksheet object to an array of JSON objects.
- `sheet_to_row_object_array` is an alias that will be removed in the future.
- `sheet_to_csv` generates delimiter-separated-values output.
- `sheet_to_formulae` generates a list of the formulae (with value fallbacks).
diff --git a/docbits/63_numfmt.md b/docbits/63_numfmt.md
index d78b6f1d7f6a0d5a44eb1025771fcf9fa41ca057..4edc1579be610d9795533db9a0ca8ad601184452 100644
--- a/docbits/63_numfmt.md
+++ b/docbits/63_numfmt.md
@@ -15,17 +15,14 @@ at index 164. The following example creates a custom format from scratch:
```js
var tbl = {};
-XLSX.SSF.init_table(tbl); // <-- load builtin formats
-tbl[164] = "\"T\"\ #0.00";
var wb = {
- SSF: tbl,
SheetNames: ["Sheet1"],
Sheets: {
Sheet1: {
"!ref":"A1:C1",
- A1: { t:"n", v:10000 }, // <-- General format
- B1: { t:"n", v:10000, z: tbl[4] }, // <-- Builtin format
- C1: { t:"n", v:10000, z: tbl[164] } // <-- Custom format
+ 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
}
}
}
diff --git a/docbits/82_util.md b/docbits/82_util.md
index 83cd95f9478e9d4b7aba97562cf560832a22c976..aad8d8397c2d9feab0ed557616dd47384faf7dc2 100644
--- a/docbits/82_util.md
+++ b/docbits/82_util.md
@@ -135,8 +135,8 @@ the output will be encoded in codepage `1200` and the BOM will be prepended.
### JSON
-`XLSX.utils.sheet_to_json` and the alias `XLSX.utils.sheet_to_row_object_array`
-generate different types of JS objects. The function takes an options argument:
+`XLSX.utils.sheet_to_json` generates different types of JS objects. The function
+takes an options argument:
| Option Name | Default | Description |
| :---------- | :------: | :-------------------------------------------------- |
diff --git a/docbits/90_test.md b/docbits/90_test.md
index 490f784e58a65b217c91ce2c66a768cf3c0b0288..0e5cbff0969486af5688e7b685442d6ca9abe13d 100644
--- a/docbits/90_test.md
+++ b/docbits/90_test.md
@@ -61,6 +61,9 @@ $ open -a Chromium.app http://localhost:8000/stress.html
### Tested Environments
+
+ (click to show)
+
- NodeJS 0.8, 0.9, 0.10, 0.11, 0.12, 4.x, 5.x, 6.x, 7.x
- IE 6/7/8/9/10/11 (IE6-9 browsers require shims for interacting with client)
- Chrome 24+
@@ -74,6 +77,8 @@ Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:
- for XLS\* modules
- for XLS\* modules using Sauce Labs
+
+
### Test Files
Test files are housed in [another repo](https://github.com/SheetJS/test_files).
diff --git a/docbits/99_badges.md b/docbits/99_badges.md
deleted file mode 100644
index f8d2fb188f4cb640dc5ca4a92ee076bb478764b8..0000000000000000000000000000000000000000
--- a/docbits/99_badges.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## Badges
-
-[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
-
-[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
-
-[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
-
-[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
-
-[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
-
-[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
-
-[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
-
-[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/index.html b/index.html
index 97730c2327e5d624b7444999fc89c46d51dc83ad..659e319517edc003dca2a1040b784a34b70b973a 100644
--- a/index.html
+++ b/index.html
@@ -54,6 +54,9 @@ Use readAsBinaryString: (when available)