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

View File

@ -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`

View File

@ -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){

View File

@ -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; };

View File

@ -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;

View File

@ -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);

View File

@ -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)
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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");

View File

@ -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) {

View File

@ -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 {

View File

@ -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'];

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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));

View File

@ -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

View File

@ -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 {

View File

@ -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';

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

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

View File

@ -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 $*" > $@

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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> >;
*/

View File

@ -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;
}
*/

View File

@ -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
cell_style_simple .xls .xlsb .xlsx .xml
# no-csv (newline character \r vs \n)
comments_stress_test .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
#comments_stress_test .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
comments_stress_test .xls .xlsb .xlsx .xls.xml
# yes-csv
custom_properties .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
#custom_properties .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
custom_properties .xls .xlsb .xlsx .xls.xml
defined_names_simple .xls .xlsb .xlsx .xml
# no-csv (randbetween) note: ODS does not support many XLSX functions
formula_stress_test .xls .xlsb .xlsx .xlsb.xml
formula_stress_test .xls .xlsb .xlsx .xls.xml
# yes-csv
formulae_test_simple .xls .xlsb .xlsx .xml
hyperlink_stress_test_2011 .xls .xlsb .xlsx .xml
#large_strings .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
merge_cells .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
#merge_cells .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
merge_cells .xls .xlsb .xlsx .xls.xml
# no-formula (filename-references in XLSX encoding as [0])
named_ranges_2011 .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
#named_ranges_2011 .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
named_ranges_2011 .xls .xlsb .xlsx .xls.xml
# yes-formula
# no-csv (macro serialization in xml)
number_format .xls .xlsb .xlsm .xls.xml .xlsb.xml .xlsm.xml
#number_format .xls .xlsb .xlsm .xls.xml .xlsb.xml .xlsm.xml
number_format .xls .xlsb .xlsm .xls.xml
# yes-csv
number_format_entities .xls .xlsb .xlsx .xml
pivot_table_named_range .xls .xlsb .xlsx .xml
pivot_table_test .xls .xlsb .xlsm
rich_text_stress .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
#rich_text_stress .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
rich_text_stress .xls .xlsb .xlsx .xls.xml
smart_tags_2007 .xls .xlsb .xlsx .xml
sushi .xls .xlsb .xlsx .xml
text_and_numbers .xls .xlsb .xlsx .xml
#time_stress_test_1 .xls .xlsb .xlsx .xml
xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
#xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml

View File

@ -27,7 +27,7 @@
"devDependencies": {
"mocha":"",
"xlsjs":"",
"uglify-js":""
"@sheetjs/uglify-js":""
},
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-xlsx.git" },
"scripts": {

152
test.js
View File

@ -144,7 +144,7 @@ function parsetest(x, wb, full, ext) {
if(fs.existsSync(sname)) it('should have the right sheet names', function() {
var file = fs.readFileSync(sname, 'utf-8').replace(/\r/g,"");
var names = wb.SheetNames.map(fixsheetname).join("\n") + "\n";
if(file.length) assert.equal(names, file);
if(file.length && !x.match(/artifacts/)) assert.equal(names, file);
});
});
describe(x + ext + ' should generate CSV', function() {
@ -642,6 +642,23 @@ describe('output formats', function() {
});
});
function eqarr(a,b) {
assert.equal(a.length, b.length);
a.forEach(function(x, i) { assert.equal(x, b[i]); });
}
describe('API', function() {
it('book_append_sheet', function() {
var wb = X.utils.book_new();
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]), "A");
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]), "B");
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
eqarr(wb.SheetNames, ["A","Sheet1","Sheet2","B","Sheet3"]);
});
});
function coreprop(wb) {
assert.equal(wb.Props.Title, 'Example with properties');
assert.equal(wb.Props.Subject, 'Test it before you code it');
@ -1634,53 +1651,90 @@ describe('json output', function() {
});
describe('csv', function() {
var data, ws;
var bef = (function() {
data = [
[1,2,3,null],
[true, false, null, "sheetjs"],
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
[null, null, null],
["baz", undefined, "qux"]
];
ws = X.utils.aoa_to_sheet(data);
describe('input', function(){
var b = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
it('should generate date numbers by default', function() {
var opts = {type:"binary"};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
assert.equal(cell.t, 'n');
assert(typeof cell.v == "number");
});
it('should generate dates when requested', function() {
var opts = {type:"binary", cellDates:true};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
assert.equal(cell.t, 'd');
assert(cell.v instanceof Date || typeof cell.v == "string");
});
it('should use US date code 14 by default', function() {
var opts = {type:"binary"};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
opts.cellDates = true;
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
});
it('should honor dateNF override', function() {
var opts = {type:"binary", dateNF:"YYYY-MM-DD"};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2014-02-19');
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '14-02-19');
});
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
it('should generate csv', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws));
});
it('should handle FS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws));
});
it('should handle RS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws));
});
it('should handle dateNF', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n";
var _ws = X.utils.aoa_to_sheet(data, {cellDates:true});
delete get_cell(_ws,"C3").w;
delete get_cell(_ws,"C3").z;
assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"}));
});
it('should handle strip', function() {
var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true}));
});
it('should handle blankrows', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false}));
});
it('should handle various line endings', function() {
var data = ["1,a", "2,b", "3,c"];
[ "\r", "\n", "\r\n" ].forEach(function(RS) {
var wb = X.read(data.join(RS), {type:'binary'});
assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1);
assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c");
assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3");
describe('output', function(){
var data, ws;
var bef = (function() {
data = [
[1,2,3,null],
[true, false, null, "sheetjs"],
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
[null, null, null],
["baz", undefined, "qux"]
];
ws = X.utils.aoa_to_sheet(data);
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
it('should generate csv', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws));
});
it('should handle FS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws));
});
it('should handle RS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws));
});
it('should handle dateNF', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n";
var _ws = X.utils.aoa_to_sheet(data, {cellDates:true});
delete get_cell(_ws,"C3").w;
delete get_cell(_ws,"C3").z;
assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"}));
});
it('should handle strip', function() {
var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true}));
});
it('should handle blankrows', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false}));
});
it('should handle various line endings', function() {
var data = ["1,a", "2,b", "3,c"];
[ "\r", "\n", "\r\n" ].forEach(function(RS) {
var wb = X.read(data.join(RS), {type:'binary'});
assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1);
assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c");
assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3");
});
});
});
});
@ -1778,10 +1832,6 @@ describe('corner cases', function() {
}
});
});
it('CFB', function() {
var cfb = X.CFB.read(paths.swcxls, {type:"file"});
var xls = X.parse_xlscfb(cfb);
});
it('codepage', function() {
X.readFile(dir + "biff5/number_format_greek.xls");
});

View File

@ -1371,4 +1371,27 @@ xlsx-stream-d-date-cell.xlsx.xml
2013/apachepoi_54016.xls.xlsb
2013/apachepoi_ReadOnlyRecommended.xls.xlsb
2013/apachepoi_testArraysAndTables.xls.xlsb
artifacts/quattro/write_.csv
artifacts/quattro/write_.dif
artifacts/quattro/write_.slk
artifacts/quattro/write_57.xls
artifacts/quattro/write_6.wb2
artifacts/quattro/write_6b.wb2
artifacts/quattro/write_8.wb3
artifacts/quattro/write_9.qpw
artifacts/quattro/write_97.xls
artifacts/quattro/write_L1.wks
artifacts/quattro/write_L2.wk1
artifacts/quattro/write_L3.wk3
artifacts/quattro/write_L45.wk4
artifacts/quattro/write_L9.123
artifacts/quattro/write_L97.123
artifacts/quattro/write_Led.wke
artifacts/quattro/write_qpdos.wq1
artifacts/quattro/write_qpw.wb1
artifacts/wps/write.dbf
artifacts/wps/write.dif
artifacts/wps/write.et
# artifacts/wps/write.xls ## bad sheet name
artifacts/wps/write.xlsx
artifacts/wps/write.xml

View File

@ -1636,53 +1636,90 @@ describe('json output', function() {
});
describe('csv', function() {
var data, ws;
var bef = (function() {
data = [
[1,2,3,null],
[true, false, null, "sheetjs"],
["foo", "bar", parseDate("2014-02-19T14:30:00.000Z"), "0.3"],
[null, null, null],
["baz", undefined, "qux"]
];
ws = X.utils.aoa_to_sheet(data);
describe('input', function(){
var b = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
it('should generate date numbers by default', function() {
var opts = {type:"binary"};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
assert.equal(cell.t, 'n');
assert(typeof cell.v == "number");
});
it('should generate dates when requested', function() {
var opts = {type:"binary", cellDates:true};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
assert.equal(cell.t, 'd');
assert(cell.v instanceof Date || typeof cell.v == "string");
});
it('should use US date code 14 by default', function() {
var opts = {type:"binary"};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
opts.cellDates = true;
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2/19/14');
});
it('should honor dateNF override', function() {
var opts = {type:"binary", dateNF:"YYYY-MM-DD"};
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '2014-02-19');
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
assert.equal(cell.w, '14-02-19');
});
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
it('should generate csv', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws));
});
it('should handle FS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws));
});
it('should handle RS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws));
});
it('should handle dateNF', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n";
var _ws = X.utils.aoa_to_sheet(data, {cellDates:true});
delete get_cell(_ws,"C3").w;
delete get_cell(_ws,"C3").z;
assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"}));
});
it('should handle strip', function() {
var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true}));
});
it('should handle blankrows', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false}));
});
it('should handle various line endings', function() {
var data = ["1,a", "2,b", "3,c"];
[ "\r", "\n", "\r\n" ].forEach(function(RS) {
var wb = X.read(data.join(RS), {type:'binary'});
assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1);
assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c");
assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3");
describe('output', function(){
var data, ws;
var bef = (function() {
data = [
[1,2,3,null],
[true, false, null, "sheetjs"],
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
[null, null, null],
["baz", undefined, "qux"]
];
ws = X.utils.aoa_to_sheet(data);
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
it('should generate csv', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws));
});
it('should handle FS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws));
});
it('should handle RS', function() {
assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws));
assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws));
});
it('should handle dateNF', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n";
var _ws = X.utils.aoa_to_sheet(data, {cellDates:true});
delete get_cell(_ws,"C3").w;
delete get_cell(_ws,"C3").z;
assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"}));
});
it('should handle strip', function() {
var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true}));
});
it('should handle blankrows', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n";
assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false}));
});
it('should handle various line endings', function() {
var data = ["1,a", "2,b", "3,c"];
[ "\r", "\n", "\r\n" ].forEach(function(RS) {
var wb = X.read(data.join(RS), {type:'binary'});
assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1);
assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c");
assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3");
});
});
});
});
@ -1815,14 +1852,15 @@ describe('encryption', function() {
});
});
describe.skip('multiformat tests', function() {
describe('multiformat tests', function() {
var mfopts = opts;
var mft = fs.readFileSync('multiformat.lst','utf-8').split("\n");
var csv = true, formulae = false;
mft.forEach(function(x) {
if(x[0]!="#") describe('MFT ' + x, function() {
if(x.charAt(0)!="#") describe('MFT ' + x, function() {
var fil = {}, f = [], r = x.split(/\s+/);
if(r.length < 3) return;
if(!fs.existsSync(dir + r[0] + r[1])) return;
it('should parse all', function() {
for(var j = 1; j != r.length; ++j) f[j-1] = X.read(fs.readFileSync(dir + r[0] + r[j]), mfopts);
});

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
/* 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){
XLSX.version = '0.10.1';
@ -11,7 +11,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; };
@ -1713,8 +1713,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;
@ -2075,7 +2074,7 @@ function write_record(ba/*:BufArray*/, type/*:string*/, payload, length/*:?numbe
if(/*:: length != null &&*/length > 0 && is_buf(payload)) ba.push(payload);
}
/* 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;
@ -2098,7 +2097,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);
@ -4294,7 +4293,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)
};
@ -5330,7 +5329,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);
@ -5339,7 +5338,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;
@ -5379,7 +5378,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);
@ -5424,13 +5423,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;
@ -5555,7 +5553,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);
};
@ -5665,8 +5663,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;
@ -6365,10 +6367,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;
}
@ -7253,11 +7257,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;
@ -7409,16 +7413,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");
@ -8956,7 +8962,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])
@ -9027,15 +9033,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));
@ -9086,7 +9092,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];
@ -9095,7 +9101,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) {
@ -10562,7 +10568,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];
@ -10597,7 +10603,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 {
@ -10654,7 +10660,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);
@ -11125,7 +11131,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'];
@ -11526,6 +11531,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);
});
@ -11538,13 +11544,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;
@ -11660,7 +11666,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;
@ -12200,7 +12206,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) {
@ -12230,7 +12236,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;
@ -12413,7 +12419,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;
@ -12507,7 +12513,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) {
@ -12944,7 +12950,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;
@ -12957,7 +12963,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]) {
@ -13091,12 +13097,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;
@ -13786,7 +13792,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));
@ -13901,8 +13907,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 {
@ -13921,7 +13928,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*/);
}
@ -13930,7 +13937,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*/);
@ -13941,12 +13948,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];
@ -14025,9 +14032,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;
@ -14109,10 +14116,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] = [];
@ -14127,7 +14134,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 */
@ -14153,7 +14160,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 */}
@ -14166,7 +14173,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";
@ -14189,19 +14196,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);
@ -14209,7 +14216,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);
@ -14217,7 +14224,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;
@ -14236,7 +14243,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);
@ -14277,7 +14284,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);
@ -14285,7 +14292,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);
@ -14376,12 +14383,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
@ -16121,12 +16123,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 {
@ -16882,7 +16885,7 @@ var fix_write_opts = fix_opts_func([
['WTF', false] /* WTF mode (throws errors) */
]);
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";
@ -17065,8 +17068,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';
@ -17600,7 +17602,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,
@ -17627,9 +17629,9 @@ var utils = {
(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*/ {
@ -17638,7 +17640,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 */
@ -17660,7 +17662,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!");
@ -17674,12 +17677,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([
@ -17699,7 +17704,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;
@ -17740,7 +17745,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;
@ -17748,11 +17753,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;
@ -17761,10 +17767,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);

132
xlsx.js
View File

@ -1,16 +1,16 @@
/* 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){
XLSX.version = '0.10.1';
var current_codepage = 1200;
/*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; };
@ -1662,8 +1662,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;
@ -5318,7 +5317,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);
@ -5363,13 +5362,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, opts) {
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;
@ -5604,8 +5602,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;
@ -6308,6 +6310,7 @@ function parse_CRYPTOVersion(blob, length) {
var o = {};
o.Major = blob.read_shift(2);
o.Minor = blob.read_shift(2);
if(length >= 4) blob.l += length - 4;
return o;
}
@ -7192,7 +7195,7 @@ var XLSBFillPTNames = [
"gray125",
"gray0625"
];
var rev_XLSBFillPTNames = evert(XLSBFillPTNames);
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);
@ -7352,13 +7355,13 @@ 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;
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]));
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");
}
@ -8965,15 +8968,15 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
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]), _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]), cell, opts) : (f[1][1]);
stack.push(encode_cell_xls(c));
break;
case 'PtgRef3d': /* 2.5.198.85 */
type = f[1][0]; ixti = f[1][1]; c = shift_cell_xls(f[1][2], _range, opts);
type = f[1][0]; ixti = 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));
@ -9024,7 +9027,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
case 'PtgName': /* 2.5.97.60 TODO: revisions */
/* f[1] = type, 0, nameindex */
nameidx = f[1][2];
nameidx = (f[1][2]);
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx);
if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name];
@ -9033,7 +9036,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
case 'PtgNameX': /* 2.5.97.61 TODO: revisions */
/* f[1] = type, ixti, nameindex */
var bookidx = (f[1][1]); nameidx = f[1][2]; var externbook;
var bookidx = (f[1][1]); nameidx = (f[1][2]); var externbook;
/* TODO: Properly handle missing values */
//console.log(bookidx, supbooks);
if(opts.biff <= 5) {
@ -10592,7 +10595,7 @@ function parse_ws_xml(data, opts, rels, wb, themes, styles) {
var refguess = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} });
var data1 = "", data2 = "";
var mtch=data.match(sheetdataregex);
var mtch =data.match(sheetdataregex);
if(mtch) {
data1 = data.substr(0, mtch.index);
data2 = data.substr(mtch.index + mtch[0].length);
@ -11063,7 +11066,6 @@ function write_ws_xml(idx, opts, wb, rels) {
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'];
@ -11464,7 +11466,7 @@ function write_BrtSheetProtection(sp, o) {
["pivotTables", true], // fPivotTables
["selectUnlockedCells", false] // fSelUnlockedCells
].forEach(function(n) {
if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0);
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);
});
return o;
@ -11476,7 +11478,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) {
var opts = _opts || {};
if(!rels) rels = {'!id':{}};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var s = opts.dense ? [] : {};
var s = (opts.dense ? [] : {});
var ref;
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
@ -11598,7 +11600,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) {
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]));
cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts);
cell.F = encode_range(val[0]);
break;
@ -12445,7 +12447,7 @@ function parse_wb_bin(data, opts) {
opts.biff = 12;
var Names = [];
var supbooks = [];
var supbooks = ([]);
supbooks.SheetNames = [];
recordhopper(data, function hopper_wb(val, R_n, RT) {
@ -13026,12 +13028,12 @@ for(var cma = c; cma <= cc; ++cma) {
case 'NamedRange':
if(!Workbook.Names) Workbook.Names = [];
var _NamedRange = parsexmltag(Rn[0]);
var _DefinedName = {
var _DefinedName = ({
Name: _NamedRange.Name,
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1))
};
});
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
Workbook.Names.push(_DefinedName);
Workbook.Names.push(_DefinedName);
break;
case 'NamedCell': break;
@ -13835,8 +13837,9 @@ function slurp(R, blob, length, opts) {
function safe_format_xf(p, opts, date1904) {
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 {
@ -13864,7 +13867,7 @@ function parse_workbook(blob, options) {
var wb = ({opts:{}});
var Sheets = {};
if(DENSE != null && options.dense == null) options.dense = DENSE;
var out = (options.dense ? [] : {});
var out = ((options.dense ? [] : {}));
var Directory = {};
var found_sheet = false;
var range = ({});
@ -13880,7 +13883,7 @@ function parse_workbook(blob, options) {
var cell_valid = true;
var XFs = []; /* XF records */
var palette = [];
var Workbook = { Sheets:[] }, wsprops = {};
var Workbook = ({ Sheets:[] }), wsprops = {};
var get_rgb = function getrgb(icv) {
if(icv < 8) return XLSIcv[icv];
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
@ -14043,10 +14046,10 @@ function parse_workbook(blob, options) {
break;
case 'Index': break; // TODO
case 'Lbl':
last_lbl = {
last_lbl = ({
Name: val.Name,
Ref: stringify_formula(val.rgce,range,null,supbooks,opts)
};
});
if(val.itab > 0) last_lbl.Sheet = val.itab - 1;
supbooks.names.push(last_lbl);
if(!supbooks[0]) supbooks[0] = [];
@ -14061,7 +14064,7 @@ function parse_workbook(blob, options) {
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 */
@ -14087,7 +14090,7 @@ function parse_workbook(blob, options) {
Workbook.Sheets.push(wsprops);
}
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
out = options.dense ? [] : {};
out = ((options.dense ? [] : {}));
} break;
case 'BOF': {
if(opts.biff !== 8){/* empty */}
@ -14100,7 +14103,7 @@ function parse_workbook(blob, options) {
else if(val.BIFFVer === 0x0007) opts.biff = 2;
if(file_depth++) break;
cell_valid = true;
out = (options.dense ? [] : {});
out = ((options.dense ? [] : {}));
if(opts.biff < 5) {
if(cur_sheet === "") cur_sheet = "Sheet1";
@ -14123,19 +14126,19 @@ function parse_workbook(blob, options) {
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};
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'};
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);
@ -14143,7 +14146,7 @@ function parse_workbook(blob, options) {
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'});
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);
@ -14151,7 +14154,7 @@ function parse_workbook(blob, options) {
} break;
case 'Formula': {
if(val.val == 'String') { last_formula = val; break; }
temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt});
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;
@ -14170,7 +14173,7 @@ function parse_workbook(blob, options) {
case 'String': {
if(last_formula) { /* technically always true */
last_formula.val = val;
temp_val = ({v:val, ixfe:last_formula.cell.ixfe, t:'s'});
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);
@ -14211,7 +14214,7 @@ function parse_workbook(blob, options) {
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'});
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);
@ -14219,7 +14222,7 @@ function parse_workbook(blob, options) {
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'});
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);
@ -14310,12 +14313,7 @@ function parse_workbook(blob, options) {
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
@ -16056,11 +16054,12 @@ var HTML_ = (function() {
return "<tr>" + oo.join("") + "</tr>";
}
function sheet_to_html(ws, opts) {
var o = [];
var o = opts || {};
var out = [];
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 {
@ -16998,8 +16997,7 @@ function parse_xlsxcfb(cfb, opts) {
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';
@ -17557,7 +17555,7 @@ var utils = {
(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); }
@ -17568,7 +17566,7 @@ function ws_get_cell_stub(ws, R, C) {
/* 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 */
@ -17590,7 +17588,8 @@ utils.book_new = function() {
/* add a worksheet to the end of a given workbook */
utils.book_append_sheet = function(wb, ws, name) {
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!");
@ -17604,12 +17603,14 @@ utils.book_set_sheet_visibility = function(wb, sh, vis) {
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([
@ -17629,7 +17630,7 @@ utils.cell_set_hyperlink = function(cell, target, tooltip) {
if(!target) {
delete cell.l;
} else {
cell.l = { Target: target };
cell.l = ({ Target: target });
if(tooltip) cell.l.Tooltip = tooltip;
}
return cell;
@ -17678,11 +17679,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;
@ -17694,7 +17696,7 @@ if(has_buf && typeof require != 'undefined') (function() {
var write_html_stream = function(sheet, opts) {
var stream = Readable();
var o = [];
var o = opts == null ? {} : opts;
var r = decode_range(sheet['!ref']), cell;
o.dense = Array.isArray(sheet);
stream.push(HTML_BEGIN);