lint and type fixes

- removed CFB test (fixes #654 h/t @wolfgang42)
- book_append_sheet optional name (fixes #652 h/t @jomel)
- strict mode compliance (h/t @simon-p-r @loongdefect @appersonj)
- flow fixes (h/t @jameskraus for help with Date#getYear)
- fixed minifier to generate ExtendScript-compatible code
This commit is contained in:
SheetJS 2017-05-13 14:21:22 -04:00
parent c3c0bc5266
commit 99b513875b
43 changed files with 620 additions and 381 deletions

@ -5,6 +5,10 @@ but not limited to API changes and file location changes. Minor behavioral
changes may not be included if they are not expected to break existing code.
## 0.10.2 (2017-05-??)
* CSV generates numeric dates by default (aligning with XLSX cellDates behavior)
## 0.9.10 (2017-04-08)
* `--perf` renamed to `--read-only`

@ -1,8 +1,8 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
/*jshint -W041 */
/*jshint funcscope:true, eqnull:true */
/*jshint funcscope:true, eqnull:true, loopfunc:true */
/*exported XLSX */
/*global exports, module, require:false, process:false, Buffer:false */
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){

@ -2,7 +2,7 @@ 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');
if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js');
}
function reset_cp() { set_cp(1200); }
var set_cp = function(cp) { current_codepage = cp; };

@ -113,8 +113,7 @@ if(has_buf) {
if(ww !== 0) { out[k++] = ww&255; out[k++] = ww>>>8; ww = 0; }
out[k++] = w%256; out[k++] = w>>>8;
}
out.length = k;
return out.toString('ucs2');
return out.slice(0,k).toString('ucs2');
};
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;

@ -1,5 +1,5 @@
/* XLS ranges enforced */
function shift_cell_xls(cell, tgt/*:any*/, opts/*:?any*/) {
function shift_cell_xls(cell/*:CellAddress*/, tgt/*:any*/, opts/*:?any*/)/*:CellAddress*/ {
var out = dup(cell);
if(tgt.s) {
if(out.cRel) out.c += tgt.s.c;
@ -22,7 +22,7 @@ function shift_range_xls(cell, range, opts) {
return out;
}
function encode_cell_xls(c)/*:string*/ {
function encode_cell_xls(c/*:CellAddress*/)/*:string*/ {
var s = encode_cell(c);
if(c.cRel === 0) s = fix_col(s);
if(c.rRel === 0) s = fix_row(s);

@ -274,7 +274,7 @@ function parse_Window1(blob, length) {
/* 2.4.122 TODO */
function parse_Font(blob, length, opts) {
var o = {
var o/*:any*/ = {
dyHeight: blob.read_shift(2),
fl: blob.read_shift(2)
};

@ -193,7 +193,7 @@ function dbf_to_workbook(buf, opts)/*:Workbook*/ {
var SYLK = (function() {
/* TODO: find an actual specification */
function sylk_to_aoa(d/*:RawData*/, opts)/*:AOA*/ {
function sylk_to_aoa(d/*:RawData*/, opts)/*:[AOA, Worksheet]*/ {
switch(opts.type) {
case 'base64': return sylk_to_aoa_str(Base64.decode(d), opts);
case 'binary': return sylk_to_aoa_str(d, opts);
@ -202,7 +202,7 @@ var SYLK = (function() {
}
throw new Error("Unrecognized type " + opts.type);
}
function sylk_to_aoa_str(str/*:string*/, opts)/*:AOA*/ {
function sylk_to_aoa_str(str/*:string*/, opts)/*:[AOA, Worksheet]*/ {
var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr = [];
var formats = [];
var next_cell_format = null;
@ -242,7 +242,7 @@ var SYLK = (function() {
next_cell_format = null;
break;
case 'E':
formula = rc_to_a1(record[rj].substr(1), {r:R,c:C});
var formula = rc_to_a1(record[rj].substr(1), {r:R,c:C});
arr[R][C] = [arr[R][C], formula];
break;
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
@ -287,13 +287,12 @@ var SYLK = (function() {
}
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
if(colinfo.length > 0) sht['!cols'] = colinfo;
arr[arr.length] = sht;
return arr;
return [arr, sht];
}
function sylk_to_sheet(str/*:string*/, opts)/*:Worksheet*/ {
var aoa = sylk_to_aoa(str, opts);
var ws = aoa.pop();
var aoasht = sylk_to_aoa(str, opts);
var aoa = aoasht[0], ws = aoasht[1];
var o = aoa_to_sheet(aoa, opts);
keys(ws).forEach(function(k) { o[k] = ws[k]; });
return o;
@ -418,7 +417,7 @@ var DIF = (function() {
o.push(v + "," + n);
o.push('"' + s.replace(/"/g,'""') + '"');
};
var push_value = function po(o/*:Array<string>*/, type/*:number*/, v/*:number*/, s/*:string*/) {
var push_value = function po(o/*:Array<string>*/, type/*:number*/, v/*:any*/, s/*:string*/) {
o.push(type + "," + v);
o.push(type == 1 ? '"' + s.replace(/"/g,'""') + '"' : s);
};
@ -528,8 +527,12 @@ var PRN = (function() {
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; }
else if(!isNaN(fuzzydate(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); }
else {
else if(!isNaN(fuzzydate(s).getDate())) {
cell.z = o.dateNF || SSF._table[14];
if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s); }
else { cell.t = 'n'; cell.v = datenum(parseDate(s)); }
cell.w = SSF.format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
} else {
cell.t = 's';
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
cell.v = s;

@ -6,10 +6,12 @@ function _JS2ANSI(str/*:string*/)/*:Array<number>*/ {
}
/* [MS-OFFCRYPTO] 2.1.4 Version */
function parse_CRYPTOVersion(blob, length/*:number*/) {
var o = {};
function parse_CRYPTOVersion(blob, length/*:?number*/) {
var o/*:any*/ = {};
o.Major = blob.read_shift(2);
o.Minor = blob.read_shift(2);
/*:: if(length == null) return o; */
if(length >= 4) blob.l += length - 4;
return o;
}

@ -100,11 +100,11 @@ var XLSBFillPTNames = [
"gray125",
"gray0625"
];
var rev_XLSBFillPTNames = evert(XLSBFillPTNames);
var rev_XLSBFillPTNames/*:EvertNumType*/ = (evert(XLSBFillPTNames)/*:any*/);
/* 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];
var fls/*:number*/ = rev_XLSBFillPTNames[fill.patternType];
if(fls == null) fls = 0x28;
o.write_shift(4, fls);
var j = 0;
@ -256,16 +256,18 @@ function parse_sty_bin(data, themes, opts) {
return styles;
}
function write_FMTS_bin(ba, NF) {
function write_FMTS_bin(ba, NF/*:?SSFTable*/) {
if(!NF) return;
var cnt = 0;
[[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) {
/*:: if(!NF) return; */
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) {
/*:: if(!NF) return; */
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");

@ -693,7 +693,7 @@ var PtgBinOp = {
function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts) {
//console.log(formula);
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
var stack/*:Array<string>*/ = [], e1, e2, type, c, ixti=0, nameidx=0, r, sname="";
var stack/*:Array<string>*/ = [], e1, e2, type, c/*:CellAddress*/, ixti=0, nameidx=0, r, sname="";
if(!formula[0] || !formula[0][0]) return "";
var last_sp = -1, sp = "";
//console.log("--",cell,formula[0])
@ -764,15 +764,15 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
case 'PtgRef': /* 2.5.198.84 */
type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts);
type = f[1][0]; c = shift_cell_xls((f[1][1]/*:any*/), _range, opts);
stack.push(encode_cell_xls(c));
break;
case 'PtgRefN': /* 2.5.198.88 */
type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1];
type = f[1][0]; c = cell ? shift_cell_xls((f[1][1]/*:any*/), cell, opts) : (f[1][1]/*:any*/);
stack.push(encode_cell_xls(c));
break;
case 'PtgRef3d': /* 2.5.198.85 */
type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls(f[1][2], _range, opts);
type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls((f[1][2]/*:any*/), _range, opts);
sname = supbooks.SheetNames[ixti];
var w = sname; /* IE9 fails on defined names */
stack.push(sname + "!" + encode_cell_xls(c));
@ -823,7 +823,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
case 'PtgName': /* 2.5.97.60 TODO: revisions */
/* f[1] = type, 0, nameindex */
nameidx = f[1][2];
nameidx = (f[1][2]/*:any*/);
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx);
if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name];
@ -832,7 +832,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
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;
var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = (f[1][2]/*:any*/); var externbook;
/* TODO: Properly handle missing values */
//console.log(bookidx, supbooks);
if(opts.biff <= 5) {

@ -25,7 +25,7 @@ function col_obj_w(C/*:number*/, col) {
return p;
}
function default_margins(margins, mode) {
function default_margins(margins/*:Margins*/, mode/*:?string*/) {
if(!margins) return;
var defs = [0.7, 0.7, 0.75, 0.75, 0.3, 0.3];
if(mode == 'xlml') defs = [1, 1, 1, 1, 0.5, 0.5];
@ -60,7 +60,7 @@ function get_cell_style(styles, cell, opts) {
return len;
}
function safe_format(p, fmtid, fillid, opts, themes, styles) {
function safe_format(p, fmtid/*:number*/, fillid, opts, themes, styles) {
if(p.t === 'z') return;
if(p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v);
try {

@ -19,7 +19,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksh
var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/);
var data1 = "", data2 = "";
var mtch=data.match(sheetdataregex);
var mtch/*:?any*/ =data.match(sheetdataregex);
if(mtch) {
data1 = data.substr(0, mtch.index);
data2 = data.substr(mtch.index + mtch[0].length);
@ -490,7 +490,6 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
if(ws['!drawing'].length > 0) {
rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW);
ws['!drawing'].rid = rId;
o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId});
}
else delete ws['!drawing'];

@ -377,6 +377,7 @@ function write_BrtSheetProtection(sp, o) {
["pivotTables", true], // fPivotTables
["selectUnlockedCells", false] // fSelUnlockedCells
].forEach(function(n) {
/*:: if(o == null) throw "unreachable"; */
if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0);
else o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1);
});
@ -389,13 +390,13 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
var opts = _opts || {};
if(!rels) rels = {'!id':{}};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var s = opts.dense ? [] : {};
var s/*:Worksheet*/ = (opts.dense ? [] : {});
var ref;
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
var pass = false, end = false;
var row, p, cf, R, C, addr, sstr, rr, cell;
var row, p, cf, R, C, addr, sstr, rr, cell/*:Cell*/;
var mergecells = [];
opts.biff = 12;
opts['!row'] = 0;
@ -511,7 +512,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
case 0x01AA: /* 'BrtArrFmla' */
if(!opts.cellFormula) break;
array_formulae.push(val);
cell = (opts.dense ? s[R][C] : s[encode_col(C) + rr]);
cell = ((opts.dense ? s[R][C] : s[encode_col(C) + rr])/*:any*/);
cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts);
cell.F = encode_range(val[0]);
break;

@ -100,7 +100,7 @@ function parse_wb_defaults(wb) {
}
var badchars = "][*?\/\\".split("");
function check_ws_name(n/*:string*/, safe/*:boolean*/)/*:boolean*/ {
function check_ws_name(n/*:string*/, safe/*:?boolean*/)/*:boolean*/ {
if(n.length > 31) { if(safe) return false; throw new Error("Sheet names cannot exceed 31 chars"); }
var _good = true;
badchars.forEach(function(c) {

@ -7,7 +7,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
var dname = {}, dnstart = 0;
/*(data.match(tagregex)||[]).forEach */
data.replace(tagregex, function xml_wb(x, idx) {
var y = parsexmltag(x);
var y/*:any*/ = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<?xml': break;
@ -190,7 +190,7 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
if(write_names) {
o[o.length] = "<definedNames>";
if(wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function(n) {
var d = {name:n.Name};
var d/*:any*/ = {name:n.Name};
if(n.Comment) d.comment = n.Comment;
if(n.Sheet != null) d.localSheetId = ""+n.Sheet;
if(!n.Ref) return;

@ -69,7 +69,7 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
opts.biff = 12;
var Names = [];
var supbooks = [];
var supbooks = ([]/*:any*/);
supbooks.SheetNames = [];
recordhopper(data, function hopper_wb(val, R_n, RT) {

@ -177,7 +177,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
var Rn;
var state = [], tmp;
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var sheets = {}, sheetnames = [], cursheet = (opts.dense ? [] : {}), sheetname = "";
var sheets = {}, sheetnames = [], cursheet/*:Worksheet*/ = (opts.dense ? [] : {}), sheetname = "";
var table = {}, cell = ({}/*:any*/), row = {};
var dtag = xlml_parsexmltag('<Data ss:Type="String">'), didx = 0;
var c = 0, r = 0;
@ -190,7 +190,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
var cstys = [], csty, seencol = false;
var arrayf = [];
var rowinfo = [], rowobj = {};
var Workbook = { Sheets:[] }, wsprops = {};
var Workbook/*:WBWBProps*/ = { Sheets:[] }, wsprops = {};
xlmlregex.lastIndex = 0;
str = str.replace(/<!--([^\u2603]*?)-->/mg,"");
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
@ -324,12 +324,12 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
case 'NamedRange':
if(!Workbook.Names) Workbook.Names = [];
var _NamedRange = parsexmltag(Rn[0]);
var _DefinedName = {
var _DefinedName/*:DefinedName*/ = ({
Name: _NamedRange.Name,
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1))
};
}/*:any*/);
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
Workbook.Names.push(_DefinedName);
/*:: if(Workbook.Names) */Workbook.Names.push(_DefinedName);
break;
case 'NamedCell': break;
@ -1019,7 +1019,7 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
process_col(n);
var w = !!n.width;
var p = col_obj_w(i, n);
var k = {"ss:Index":i+1};
var k/*:any*/ = {"ss:Index":i+1};
if(w) k['ss:Width'] = width2px(p.width);
if(n.hidden) k['ss:Hidden']="1";
o.push(writextag("Column",null,k));

@ -55,8 +55,9 @@ function slurp(R, blob, length/*:number*/, opts) {
function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) {
if(p.t === 'z') return;
if(!p.XF) return;
var fmtid = 0;
try {
var fmtid = p.z || p.XF.ifmt || 0;
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 {
@ -75,7 +76,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) {
} catch(e) { if(opts.WTF) throw e; }
}
function make_cell(val, ixfe, t)/*:any*/ {
function make_cell(val, ixfe, t)/*:Cell*/ {
return ({v:val, ixfe:ixfe, t:t}/*:any*/);
}
@ -84,7 +85,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
var wb = ({opts:{}}/*:any*/);
var Sheets = {};
if(DENSE != null && options.dense == null) options.dense = DENSE;
var out = (options.dense ? [] : {});
var out/*:Worksheet*/ = ((options.dense ? [] : {})/*:any*/);
var Directory = {};
var found_sheet = false;
var range/*:Range*/ = ({}/*:any*/);
@ -95,12 +96,12 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
var lastcell, last_cell = "", cc, cmnt, rng, rngC, rngR;
var shared_formulae = {};
var array_formulae = []; /* TODO: something more clever */
var temp_val;
var temp_val/*:Cell*/;
var country;
var cell_valid = true;
var XFs = []; /* XF records */
var palette = [];
var Workbook = { Sheets:[] }, wsprops = {};
var Workbook/*:WBWBProps*/ = ({ Sheets:[] }/*:any*/), wsprops = {};
var get_rgb = function getrgb(icv) {
if(icv < 8) return XLSIcv[icv];
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
@ -179,9 +180,9 @@ 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 BIFF2FmtTable/*:Array<string>*/ = [];
var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */
var last_lbl;
var last_lbl/*:?DefinedName*/;
/* explicit override for some broken writers */
opts.codepage = 1200;
@ -263,10 +264,10 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
break;
case 'Index': break; // TODO
case 'Lbl':
last_lbl = {
last_lbl = ({
Name: val.Name,
Ref: stringify_formula(val.rgce,range,null,supbooks,opts)
};
}/*:DefinedName*/);
if(val.itab > 0) last_lbl.Sheet = val.itab - 1;
supbooks.names.push(last_lbl);
if(!supbooks[0]) supbooks[0] = [];
@ -281,7 +282,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'NameCmt':
/* TODO: search for correct name */
if(opts.biff < 8) break;
last_lbl.Comment = val[1];
if(last_lbl != null) last_lbl.Comment = val[1];
break;
case 'Protect': out["!protect"] = val; break; /* for sheet or book */
@ -307,7 +308,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
Workbook.Sheets.push(wsprops);
}
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
out = options.dense ? [] : {};
out = ((options.dense ? [] : {})/*:any*/);
} break;
case 'BOF': {
if(opts.biff !== 8){/* empty */}
@ -320,7 +321,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
else if(val.BIFFVer === 0x0007) opts.biff = 2;
if(file_depth++) break;
cell_valid = true;
out = (options.dense ? [] : {});
out = ((options.dense ? [] : {})/*:any*/);
if(opts.biff < 5) {
if(cur_sheet === "") cur_sheet = "Sheet1";
@ -343,19 +344,19 @@ 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'}/*:any*/);
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};
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/);
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'};
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/);
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);
@ -363,7 +364,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'MulRk': {
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'};
temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/);
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);
@ -371,7 +372,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
} break;
case 'Formula': {
if(val.val == 'String') { last_formula = val; break; }
temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt}/*:any*/);
temp_val = make_cell(val.val, val.cell.ixfe, val.tt);
temp_val.XF = XFs[temp_val.ixfe];
if(options.cellFormula) {
var _f = val.formula;
@ -390,7 +391,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'String': {
if(last_formula) { /* technically always true */
last_formula.val = val;
temp_val = ({v:val, ixfe:last_formula.cell.ixfe, t:'s'}/*:any*/);
temp_val = make_cell(val, last_formula.cell.ixfe, 's');
temp_val.XF = XFs[temp_val.ixfe];
if(options.cellFormula) {
temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
@ -431,7 +432,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
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'};
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/);
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);
@ -439,7 +440,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'MulBlank': if(options.sheetStubs) {
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'};
temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/);
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);
@ -530,12 +531,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'TopMargin':
case 'BottomMargin':
if(!out['!margins']) default_margins(out['!margins'] = {});
switch(Rn) {
case 'LeftMargin': out['!margins'].left = val; break;
case 'RightMargin': out['!margins'].right = val; break;
case 'TopMargin': out['!margins'].top = val; break;
case 'BottomMargin': out['!margins'].bottom = val; break;
}
out['!margins'][Rn.slice(0,-6).toLowerCase()] = val;
break;
case 'Setup': // TODO

@ -75,12 +75,13 @@ var HTML_ = (function() {
}
return "<tr>" + oo.join("") + "</tr>";
}
function sheet_to_html(ws/*:Worksheet*/, opts)/*:string*/ {
var o/*:Array<string>*/ = [];
function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ {
var o = opts || {};
var out/*:Array<string>*/ = [];
var r = decode_range(ws['!ref']);
o.dense = Array.isArray(ws);
for(var R = r.s.r; R <= r.e.r; ++R) o.push(make_html_row(ws, r, R, o));
return "<html><body><table>" + o.join("") + "</table></body></html>";
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
return "<html><body><table>" + out.join("") + "</table></body></html>";
}
return {

@ -1,4 +1,4 @@
function get_sheet_type(n) {
function get_sheet_type(n/*:string*/)/*:string*/ {
if(RELS.WS.indexOf(n) > -1) return "sheet";
if(RELS.CS && n == RELS.CS) return "chart";
if(RELS.DS && n == RELS.DS) return "dialog";
@ -181,8 +181,7 @@ function parse_xlsxcfb(cfb, opts/*:?ParseOpts*/)/*:Workbook*/ {
data = cfb.find(f);
if(!data) throw new Error("ECMA-376 Encrypted file missing " + f);
var dsm = parse_DataSpaceMap(data.content);
if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 ||
dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage")
if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage")
throw new Error("ECMA-376 Encrypted file bad " + f);
f = 'StrongEncryptionDataSpace';

@ -190,7 +190,7 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
return ws;
}
var utils = {
var utils/*:any*/ = {
encode_col: encode_col,
encode_row: encode_row,
encode_cell: encode_cell,

@ -1,8 +1,8 @@
(function(utils) {
utils.consts = utils.consts || {};
function add_consts(R) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); }
function add_consts(R/*Array<any>*/) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); }
function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); }
function get_default(x/*:any*/, y/*:any*/, z/*:any*/)/*:any*/ { return x[y] != null ? x[y] : (x[y] = z); }
/* get cell, creating a stub if necessary */
function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ {
@ -11,7 +11,7 @@ function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ {
/* cell address object */
if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R));
/* R and C are 0-based indices */
return ws_get_cell_stub(ws, encode_cell({r:R,c:C}));
return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0}));
}
/* find sheet index for given name / validate index */
@ -33,7 +33,8 @@ utils.book_new = function()/*:Workbook*/ {
/* add a worksheet to the end of a given workbook */
utils.book_append_sheet = function(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/) {
if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf("Sheet" + i) == -1) break;
if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break;
if(!name) throw new Error("Too many worksheets");
check_ws_name(name);
if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!");
@ -47,12 +48,14 @@ utils.book_set_sheet_visibility = function(wb/*:Workbook*/, sh/*:number|string*/
get_default(wb.Workbook,"Sheets",[]);
var idx = wb_sheet_idx(wb, sh);
// $FlowIgnore
get_default(wb.Workbook.Sheets,idx, {});
switch(vis) {
case 0: case 1: case 2: break;
default: throw new Error("Bad sheet visibility setting " + vis);
}
// $FlowIgnore
wb.Workbook.Sheets[idx].Hidden = vis;
};
add_consts([
@ -72,7 +75,7 @@ utils.cell_set_hyperlink = function(cell/*:Cell*/, target/*:string*/, tooltip/*:
if(!target) {
delete cell.l;
} else {
cell.l = { Target: target };
cell.l = ({ Target: target }/*:Hyperlink*/);
if(tooltip) cell.l.Tooltip = tooltip;
}
return cell;

@ -10,7 +10,7 @@ if(has_buf && typeof require != 'undefined') (function() {
var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0);
var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0);
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
var row/*:?string*/ = "", cols = [];
o.dense = Array.isArray(sheet);
for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
var R = r.s.r;
@ -18,11 +18,12 @@ if(has_buf && typeof require != 'undefined') (function() {
if(R > r.e.r) return stream.push(null);
while(R <= r.e.r) {
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
if(row == null) { ++R; continue; }
if(o.strip) row = row.replace(endregex,"");
stream.push(row + RS);
++R;
break;
if(row != null) {
if(o.strip) row = row.replace(endregex,"");
stream.push(row + RS);
break;
}
}
};
return stream;
@ -31,10 +32,10 @@ if(has_buf && typeof require != 'undefined') (function() {
var HTML_BEGIN = "<html><body><table>";
var HTML_END = "</table></body></html>";
var write_html_stream = function(sheet/*:Worksheet*/, opts) {
var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
var stream = Readable();
var o/*:Array<string>*/ = [];
var o = opts == null ? {} : opts;
var r = decode_range(sheet['!ref']), cell/*:Cell*/;
o.dense = Array.isArray(sheet);
stream.push(HTML_BEGIN);

@ -1,3 +1,5 @@
jszip.js
shim.js
xlsx.flow.js
xlsx.core.min.js
xlsx.full.min.js

@ -7,8 +7,7 @@ all: deps $(TARGETS)
.PHONY: deps
deps:
cp ../../shim.js .
cp ../../jszip.js .
cp ../../xlsx.flow.js .
cp ../../dist/xlsx.core.min.js .
%.base:
echo "#target $*" > $@

@ -2,6 +2,10 @@
The main file is `test.jsx`. Target-specific files prepend target directives.
Copy the `test.jsx` file as well as the `shim.js`, `jszip.js` and `xlsx.flow.js`
files to wherever you want the scripts to reside. The demo shows opening a file
and converting to an array of arrays.
Copy the `test.jsx` file as well as the `shim.js` and `xlsx.core.min.js` files
to wherever you want the scripts to reside. The demo shows opening a file and
converting to an array of arrays.
NOTE: [We forked the minifier](https://www.npmjs.com/package/@sheetjs/uglify-js)
and included a bugfix for ExtendScript's misparsing of switch statements.

@ -1,2 +1,2 @@
#target aftereffects
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);

@ -1,2 +1,2 @@
#target estoolkit
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);

@ -1,2 +1,2 @@
#target illustrator
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);

@ -1,2 +1,2 @@
#target indesign
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);

@ -1,2 +1,2 @@
#target photoshop
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);

@ -1 +1 @@
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);
var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data);

@ -10,7 +10,7 @@ type ColInfo = {
/* column width is specified in one of the following ways: */
wpx?:number; // width in screen pixels
width:number; // width in Excel's "Max Digit Width", width*256 is integral
width?:number; // width in Excel's "Max Digit Width", width*256 is integral
wch?:number; // width in characters
/* other fields for preserving features from files */
@ -49,7 +49,7 @@ objects which have the following properties:
```typescript
type RowInfo = {
/* visibility */
hidden:?boolean; // if true, the row is hidden
hidden?:boolean; // if true, the row is hidden
/* row height is specified in one of the following ways: */
hpx?:number; // height in screen pixels

@ -19,16 +19,13 @@ type Workbook = {
Workbook?: WBWBProps;
SSF?: {[n:number]:string};
SSF?: SSFTable;
cfb?: any;
};
type WorkbookProps = {
SheetNames?: Array<string>;
}
type WBWBProps = {
Sheets: Array<WBWSProp>;
Names?: Array<any>;
};
type WBWSProp = {
@ -52,6 +49,7 @@ type Worksheet = any;
type Sheet2CSVOpts = any;
type Sheet2JSONOpts = any;
type Sheet2HTMLOpts = any;
type ParseOpts = any;
@ -77,22 +75,44 @@ type SST = {
type Comment = any;
type RowInfo = {
hidden:?boolean; // if true, the row is hidden
hidden?:boolean; // if true, the row is hidden
hpx?:number; // height in screen pixels
hpt?:number; // height in points
};
type ColInfo = {
hidden:?boolean; // if true, the column is hidden
hidden?:boolean; // if true, the column is hidden
wpx?:number; // width in screen pixels
width:number; // width in Excel's "Max Digit Width", width*256 is integral
width?:number; // width in Excel's "Max Digit Width", width*256 is integral
wch?:number; // width in characters
MDW?:number; // Excel's "Max Digit Width" unit, always integral
};
interface Margins {
left?:number;
right?:number;
top?:number;
bottom?:number;
header?:number;
footer?:number;
};
interface DefinedName {
Name:string;
Ref:string;
Sheet?:number;
Comment?:string;
};
interface Hyperlink {
Target:string;
Tooltip?:string;
};
type SSFTable = any;
type AOA = Array<Array<any> >;
*/

@ -11,4 +11,81 @@ declare module 'crypto' { declare var exports:any; };
declare module 'fs' { declare var exports:any; };
type ZIP = any;
// ----------------------------------------------------------------------------
// Note: The following override is needed because Flow is missing Date#getYear
// ----------------------------------------------------------------------------
type Date$LocaleOptions = {
localeMatcher?: string,
timeZone?: string,
hour12?: boolean,
formatMatcher?: string,
weekday?: string,
era?: string,
year?: string,
month?: string,
day?: string,
hour?: string,
minute?: string,
second?: string,
timeZoneName?: string,
};
declare class Date {
constructor(): void;
constructor(timestamp: number): void;
constructor(dateString: string): void;
constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
getDate(): number;
getDay(): number;
getYear(): number;
getFullYear(): number;
getHours(): number;
getMilliseconds(): number;
getMinutes(): number;
getMonth(): number;
getSeconds(): number;
getTime(): number;
getTimezoneOffset(): number;
getUTCDate(): number;
getUTCDay(): number;
getUTCFullYear(): number;
getUTCHours(): number;
getUTCMilliseconds(): number;
getUTCMinutes(): number;
getUTCMonth(): number;
getUTCSeconds(): number;
setDate(date: number): number;
setFullYear(year: number, month?: number, date?: number): number;
setHours(hours: number, min?: number, sec?: number, ms?: number): number;
setMilliseconds(ms: number): number;
setMinutes(min: number, sec?: number, ms?: number): number;
setMonth(month: number, date?: number): number;
setSeconds(sec: number, ms?: number): number;
setTime(time: number): number;
setUTCDate(date: number): number;
setUTCFullYear(year: number, month?: number, date?: number): number;
setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number;
setUTCMilliseconds(ms: number): number;
setUTCMinutes(min: number, sec?: number, ms?: number): number;
setUTCMonth(month: number, date?: number): number;
setUTCSeconds(sec: number, ms?: number): number;
toDateString(): string;
toISOString(): string;
toJSON(key?: any): string;
toLocaleDateString(locales?: string, options?: Date$LocaleOptions): string;
toLocaleString(locales?: string, options?: Date$LocaleOptions): string;
toLocaleTimeString(locales?: string, options?: Date$LocaleOptions): string;
toTimeString(): string;
toUTCString(): string;
valueOf(): number;
static ():string;
static now(): number;
static parse(s: string): number;
static UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;
// multiple indexers not yet supported
[key: $SymbolToPrimitive]: (hint: 'string' | 'default' | 'number') => string | number;
}
*/

@ -6,33 +6,41 @@ AutoFilter .xls .xlsb .xlsx .xml
# note: XLML only supports sheets, ods does not support dialog
BlankSheetTypes .xls .xlsb .xlsm
NumberFormatCondition .xls .xlsb .xlsm .xml
RkNumber .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
#RkNumber .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
RkNumber .xls .xlsb .xlsx .xls.xml
#calendar_stress_test .xls .xlsb .xlsx .xml