forked from sheetjs/sheetjs
		
	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:
		
							parent
							
								
									c3c0bc5266
								
							
						
					
					
						commit
						99b513875b
					
				| @ -5,6 +5,10 @@ but not limited to API changes and file location changes.  Minor behavioral | ||||
| changes may not be included if they are not expected to break existing code. | ||||
| 
 | ||||
| 
 | ||||
| ## 0.10.2 (2017-05-??) | ||||
| 
 | ||||
| * CSV generates numeric dates by default (aligning with XLSX cellDates behavior) | ||||
| 
 | ||||
| ## 0.9.10 (2017-04-08) | ||||
| 
 | ||||
| * `--perf` renamed to `--read-only` | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| /* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /* vim: set ts=2: */ | ||||
| /*jshint -W041 */ | ||||
| /*jshint funcscope:true, eqnull:true */ | ||||
| /*jshint funcscope:true, eqnull:true, loopfunc:true */ | ||||
| /*exported XLSX */ | ||||
| /*global exports, module, require:false, process:false, Buffer:false */ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
|  | ||||
| @ -2,7 +2,7 @@ var current_codepage = 1200; | ||||
| /*:: declare var cptable:any; */ | ||||
| /*global cptable:true */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| 	if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js'); | ||||
| 	if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js'); | ||||
| } | ||||
| function reset_cp() { set_cp(1200); } | ||||
| var set_cp = function(cp) { current_codepage = cp; }; | ||||
|  | ||||
| @ -113,8 +113,7 @@ if(has_buf) { | ||||
| 			if(ww !== 0) { out[k++] = ww&255; out[k++] = ww>>>8; ww = 0; } | ||||
| 			out[k++] = w%256; out[k++] = w>>>8; | ||||
| 		} | ||||
| 		out.length = k; | ||||
| 		return out.toString('ucs2'); | ||||
| 		return out.slice(0,k).toString('ucs2'); | ||||
| 	}; | ||||
| 	var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; | ||||
| 	if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* XLS ranges enforced */ | ||||
| function shift_cell_xls(cell, tgt/*:any*/, opts/*:?any*/) { | ||||
| function shift_cell_xls(cell/*:CellAddress*/, tgt/*:any*/, opts/*:?any*/)/*:CellAddress*/ { | ||||
| 	var out = dup(cell); | ||||
| 	if(tgt.s) { | ||||
| 		if(out.cRel) out.c += tgt.s.c; | ||||
| @ -22,7 +22,7 @@ function shift_range_xls(cell, range, opts) { | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| function encode_cell_xls(c)/*:string*/ { | ||||
| function encode_cell_xls(c/*:CellAddress*/)/*:string*/ { | ||||
| 	var s = encode_cell(c); | ||||
| 	if(c.cRel === 0) s = fix_col(s); | ||||
| 	if(c.rRel === 0) s = fix_row(s); | ||||
|  | ||||
| @ -274,7 +274,7 @@ function parse_Window1(blob, length) { | ||||
| 
 | ||||
| /* 2.4.122 TODO */ | ||||
| function parse_Font(blob, length, opts) { | ||||
| 	var o = { | ||||
| 	var o/*:any*/ = { | ||||
| 		dyHeight: blob.read_shift(2), | ||||
| 		fl: blob.read_shift(2) | ||||
| 	}; | ||||
|  | ||||
| @ -193,7 +193,7 @@ function dbf_to_workbook(buf, opts)/*:Workbook*/ { | ||||
| 
 | ||||
| var SYLK = (function() { | ||||
| 	/* TODO: find an actual specification */ | ||||
| 	function sylk_to_aoa(d/*:RawData*/, opts)/*:AOA*/ { | ||||
| 	function sylk_to_aoa(d/*:RawData*/, opts)/*:[AOA, Worksheet]*/ { | ||||
| 		switch(opts.type) { | ||||
| 			case 'base64': return sylk_to_aoa_str(Base64.decode(d), opts); | ||||
| 			case 'binary': return sylk_to_aoa_str(d, opts); | ||||
| @ -202,7 +202,7 @@ var SYLK = (function() { | ||||
| 		} | ||||
| 		throw new Error("Unrecognized type " + opts.type); | ||||
| 	} | ||||
| 	function sylk_to_aoa_str(str/*:string*/, opts)/*:AOA*/ { | ||||
| 	function sylk_to_aoa_str(str/*:string*/, opts)/*:[AOA, Worksheet]*/ { | ||||
| 		var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr = []; | ||||
| 		var formats = []; | ||||
| 		var next_cell_format = null; | ||||
| @ -242,7 +242,7 @@ var SYLK = (function() { | ||||
| 					next_cell_format = null; | ||||
| 					break; | ||||
| 				case 'E': | ||||
| 					formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); | ||||
| 					var formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); | ||||
| 					arr[R][C] = [arr[R][C], formula]; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| @ -287,13 +287,12 @@ var SYLK = (function() { | ||||
| 		} | ||||
| 		if(rowinfo.length > 0) sht['!rows'] = rowinfo; | ||||
| 		if(colinfo.length > 0) sht['!cols'] = colinfo; | ||||
| 		arr[arr.length] = sht; | ||||
| 		return arr; | ||||
| 		return [arr, sht]; | ||||
| 	} | ||||
| 
 | ||||
| 	function sylk_to_sheet(str/*:string*/, opts)/*:Worksheet*/ { | ||||
| 		var aoa = sylk_to_aoa(str, opts); | ||||
| 		var ws = aoa.pop(); | ||||
| 		var aoasht = sylk_to_aoa(str, opts); | ||||
| 		var aoa = aoasht[0], ws = aoasht[1]; | ||||
| 		var o = aoa_to_sheet(aoa, opts); | ||||
| 		keys(ws).forEach(function(k) { o[k] = ws[k]; }); | ||||
| 		return o; | ||||
| @ -418,7 +417,7 @@ var DIF = (function() { | ||||
| 			o.push(v + "," + n); | ||||
| 			o.push('"' + s.replace(/"/g,'""') + '"'); | ||||
| 		}; | ||||
| 		var push_value = function po(o/*:Array<string>*/, type/*:number*/, v/*:number*/, s/*:string*/) { | ||||
| 		var push_value = function po(o/*:Array<string>*/, type/*:number*/, v/*:any*/, s/*:string*/) { | ||||
| 			o.push(type + "," + v); | ||||
| 			o.push(type == 1 ? '"' + s.replace(/"/g,'""') + '"' : s); | ||||
| 		}; | ||||
| @ -528,8 +527,12 @@ var PRN = (function() { | ||||
| 			else if(s == "TRUE") { cell.t = 'b'; cell.v = true; } | ||||
| 			else if(s == "FALSE") { cell.t = 'b'; cell.v = false; } | ||||
| 			else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; } | ||||
| 			else if(!isNaN(fuzzydate(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); } | ||||
| 			else { | ||||
| 			else if(!isNaN(fuzzydate(s).getDate())) { | ||||
| 				cell.z = o.dateNF || SSF._table[14]; | ||||
| 				if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s); } | ||||
| 				else { cell.t = 'n'; cell.v = datenum(parseDate(s)); } | ||||
| 				cell.w = SSF.format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v); | ||||
| 			} else { | ||||
| 				cell.t = 's'; | ||||
| 				if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"'); | ||||
| 				cell.v = s; | ||||
|  | ||||
| @ -6,10 +6,12 @@ function _JS2ANSI(str/*:string*/)/*:Array<number>*/ { | ||||
| } | ||||
| 
 | ||||
| /* [MS-OFFCRYPTO] 2.1.4 Version */ | ||||
| function parse_CRYPTOVersion(blob, length/*:number*/) { | ||||
| 	var o = {}; | ||||
| function parse_CRYPTOVersion(blob, length/*:?number*/) { | ||||
| 	var o/*:any*/ = {}; | ||||
| 	o.Major = blob.read_shift(2); | ||||
| 	o.Minor = blob.read_shift(2); | ||||
| 	/*:: if(length == null) return o; */ | ||||
| 	if(length >= 4) blob.l += length - 4; | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -100,11 +100,11 @@ var XLSBFillPTNames = [ | ||||
| 	"gray125", | ||||
| 	"gray0625" | ||||
| ]; | ||||
| var rev_XLSBFillPTNames = evert(XLSBFillPTNames); | ||||
| var rev_XLSBFillPTNames/*:EvertNumType*/ = (evert(XLSBFillPTNames)/*:any*/); | ||||
| /* TODO: gradient fill representation */ | ||||
| function write_BrtFill(fill, o) { | ||||
| 	if(!o) o = new_buf(4*3 + 8*7 + 16*1); | ||||
| 	var fls = rev_XLSBFillPTNames[fill.patternType]; | ||||
| 	var fls/*:number*/ = rev_XLSBFillPTNames[fill.patternType]; | ||||
| 	if(fls == null) fls = 0x28; | ||||
| 	o.write_shift(4, fls); | ||||
| 	var j = 0; | ||||
| @ -256,16 +256,18 @@ function parse_sty_bin(data, themes, opts) { | ||||
| 	return styles; | ||||
| } | ||||
| 
 | ||||
| function write_FMTS_bin(ba, NF) { | ||||
| function write_FMTS_bin(ba, NF/*:?SSFTable*/) { | ||||
| 	if(!NF) return; | ||||
| 	var cnt = 0; | ||||
| 	[[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { | ||||
| 		/*:: if(!NF) return; */ | ||||
| 		for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt; | ||||
| 	}); | ||||
| 
 | ||||
| 	if(cnt == 0) return; | ||||
| 	write_record(ba, "BrtBeginFmts", write_UInt32LE(cnt)); | ||||
| 	[[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { | ||||
| 		/*:: if(!NF) return; */ | ||||
| 		for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i])); | ||||
| 	}); | ||||
| 	write_record(ba, "BrtEndFmts"); | ||||
|  | ||||
| @ -693,7 +693,7 @@ var PtgBinOp = { | ||||
| function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts) { | ||||
| 	//console.log(formula);
 | ||||
| 	var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}}; | ||||
| 	var stack/*:Array<string>*/ = [], e1, e2, type, c, ixti=0, nameidx=0, r, sname=""; | ||||
| 	var stack/*:Array<string>*/ = [], e1, e2, type, c/*:CellAddress*/, ixti=0, nameidx=0, r, sname=""; | ||||
| 	if(!formula[0] || !formula[0][0]) return ""; | ||||
| 	var last_sp = -1, sp = ""; | ||||
| 	//console.log("--",cell,formula[0])
 | ||||
| @ -764,15 +764,15 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 
 | ||||
| 
 | ||||
| 			case 'PtgRef': /* 2.5.198.84 */ | ||||
| 				type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts); | ||||
| 				type = f[1][0]; c = shift_cell_xls((f[1][1]/*:any*/), _range, opts); | ||||
| 				stack.push(encode_cell_xls(c)); | ||||
| 				break; | ||||
| 			case 'PtgRefN': /* 2.5.198.88 */ | ||||
| 				type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1]; | ||||
| 				type = f[1][0]; c = cell ? shift_cell_xls((f[1][1]/*:any*/), cell, opts) : (f[1][1]/*:any*/); | ||||
| 				stack.push(encode_cell_xls(c)); | ||||
| 				break; | ||||
| 			case 'PtgRef3d': /* 2.5.198.85 */ | ||||
| 				type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls(f[1][2], _range, opts); | ||||
| 				type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls((f[1][2]/*:any*/), _range, opts); | ||||
| 				sname = supbooks.SheetNames[ixti]; | ||||
| 				var w = sname; /* IE9 fails on defined names */ | ||||
| 				stack.push(sname + "!" + encode_cell_xls(c)); | ||||
| @ -823,7 +823,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 
 | ||||
| 			case 'PtgName': /* 2.5.97.60 TODO: revisions */ | ||||
| 				/* f[1] = type, 0, nameindex */ | ||||
| 				nameidx = f[1][2]; | ||||
| 				nameidx = (f[1][2]/*:any*/); | ||||
| 				var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx]; | ||||
| 				var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx); | ||||
| 				if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name]; | ||||
| @ -832,7 +832,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 
 | ||||
| 			case 'PtgNameX': /* 2.5.97.61 TODO: revisions */ | ||||
| 				/* f[1] = type, ixti, nameindex */ | ||||
| 				var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = f[1][2]; var externbook; | ||||
| 				var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = (f[1][2]/*:any*/); var externbook; | ||||
| 				/* TODO: Properly handle missing values */ | ||||
| 				//console.log(bookidx, supbooks);
 | ||||
| 				if(opts.biff <= 5) { | ||||
|  | ||||
| @ -25,7 +25,7 @@ function col_obj_w(C/*:number*/, col) { | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| function default_margins(margins, mode) { | ||||
| function default_margins(margins/*:Margins*/, mode/*:?string*/) { | ||||
| 	if(!margins) return; | ||||
| 	var defs = [0.7, 0.7, 0.75, 0.75, 0.3, 0.3]; | ||||
| 	if(mode == 'xlml') defs = [1, 1, 1, 1, 0.5, 0.5]; | ||||
| @ -60,7 +60,7 @@ function get_cell_style(styles, cell, opts) { | ||||
| 	return len; | ||||
| } | ||||
| 
 | ||||
| function safe_format(p, fmtid, fillid, opts, themes, styles) { | ||||
| function safe_format(p, fmtid/*:number*/, fillid, opts, themes, styles) { | ||||
| 	if(p.t === 'z') return; | ||||
| 	if(p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v); | ||||
| 	try { | ||||
|  | ||||
| @ -19,7 +19,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksh | ||||
| 	var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/); | ||||
| 
 | ||||
| 	var data1 = "", data2 = ""; | ||||
| 	var mtch=data.match(sheetdataregex); | ||||
| 	var mtch/*:?any*/ =data.match(sheetdataregex); | ||||
| 	if(mtch) { | ||||
| 		data1 = data.substr(0, mtch.index); | ||||
| 		data2 = data.substr(mtch.index + mtch[0].length); | ||||
| @ -490,7 +490,6 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ { | ||||
| 
 | ||||
| 	if(ws['!drawing'].length > 0) { | ||||
| 		rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW); | ||||
| 		ws['!drawing'].rid = rId; | ||||
| 		o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId}); | ||||
| 	} | ||||
| 	else delete ws['!drawing']; | ||||
|  | ||||
| @ -377,6 +377,7 @@ function write_BrtSheetProtection(sp, o) { | ||||
| 		["pivotTables",          true], // fPivotTables
 | ||||
| 		["selectUnlockedCells", false]  // fSelUnlockedCells
 | ||||
| 	].forEach(function(n) { | ||||
| 		/*:: if(o == null) throw "unreachable"; */ | ||||
| 		if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0); | ||||
| 		else      o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1); | ||||
| 	}); | ||||
| @ -389,13 +390,13 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ { | ||||
| 	var opts = _opts || {}; | ||||
| 	if(!rels) rels = {'!id':{}}; | ||||
| 	if(DENSE != null && opts.dense == null) opts.dense = DENSE; | ||||
| 	var s = opts.dense ? [] : {}; | ||||
| 	var s/*:Worksheet*/ = (opts.dense ? [] : {}); | ||||
| 
 | ||||
| 	var ref; | ||||
| 	var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} }; | ||||
| 
 | ||||
| 	var pass = false, end = false; | ||||
| 	var row, p, cf, R, C, addr, sstr, rr, cell; | ||||
| 	var row, p, cf, R, C, addr, sstr, rr, cell/*:Cell*/; | ||||
| 	var mergecells = []; | ||||
| 	opts.biff = 12; | ||||
| 	opts['!row'] = 0; | ||||
| @ -511,7 +512,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ { | ||||
| 			case 0x01AA: /* 'BrtArrFmla' */ | ||||
| 				if(!opts.cellFormula) break; | ||||
| 				array_formulae.push(val); | ||||
| 				cell = (opts.dense ? s[R][C] : s[encode_col(C) + rr]); | ||||
| 				cell = ((opts.dense ? s[R][C] : s[encode_col(C) + rr])/*:any*/); | ||||
| 				cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts); | ||||
| 				cell.F = encode_range(val[0]); | ||||
| 				break; | ||||
|  | ||||
| @ -100,7 +100,7 @@ function parse_wb_defaults(wb) { | ||||
| } | ||||
| 
 | ||||
| var badchars = "][*?\/\\".split(""); | ||||
| function check_ws_name(n/*:string*/, safe/*:boolean*/)/*:boolean*/ { | ||||
| function check_ws_name(n/*:string*/, safe/*:?boolean*/)/*:boolean*/ { | ||||
| 	if(n.length > 31) { if(safe) return false; throw new Error("Sheet names cannot exceed 31 chars"); } | ||||
| 	var _good = true; | ||||
| 	badchars.forEach(function(c) { | ||||
|  | ||||
| @ -7,7 +7,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ { | ||||
| 	var dname = {}, dnstart = 0; | ||||
| 	/*(data.match(tagregex)||[]).forEach */ | ||||
| 	data.replace(tagregex, function xml_wb(x, idx) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		var y/*:any*/ = parsexmltag(x); | ||||
| 		switch(strip_ns(y[0])) { | ||||
| 			case '<?xml': break; | ||||
| 
 | ||||
| @ -190,7 +190,7 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ { | ||||
| 	if(write_names) { | ||||
| 		o[o.length] = "<definedNames>"; | ||||
| 		if(wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function(n) { | ||||
| 			var d = {name:n.Name}; | ||||
| 			var d/*:any*/ = {name:n.Name}; | ||||
| 			if(n.Comment) d.comment = n.Comment; | ||||
| 			if(n.Sheet != null) d.localSheetId = ""+n.Sheet; | ||||
| 			if(!n.Ref) return; | ||||
|  | ||||
| @ -69,7 +69,7 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ { | ||||
| 	opts.biff = 12; | ||||
| 
 | ||||
| 	var Names = []; | ||||
| 	var supbooks = []; | ||||
| 	var supbooks = ([]/*:any*/); | ||||
| 	supbooks.SheetNames = []; | ||||
| 
 | ||||
| 	recordhopper(data, function hopper_wb(val, R_n, RT) { | ||||
|  | ||||
| @ -177,7 +177,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { | ||||
| 	var Rn; | ||||
| 	var state = [], tmp; | ||||
| 	if(DENSE != null && opts.dense == null) opts.dense = DENSE; | ||||
| 	var sheets = {}, sheetnames = [], cursheet = (opts.dense ? [] : {}), sheetname = ""; | ||||
| 	var sheets = {}, sheetnames = [], cursheet/*:Worksheet*/ = (opts.dense ? [] : {}), sheetname = ""; | ||||
| 	var table = {}, cell = ({}/*:any*/), row = {}; | ||||
| 	var dtag = xlml_parsexmltag('<Data ss:Type="String">'), didx = 0; | ||||
| 	var c = 0, r = 0; | ||||
| @ -190,7 +190,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { | ||||
| 	var cstys = [], csty, seencol = false; | ||||
| 	var arrayf = []; | ||||
| 	var rowinfo = [], rowobj = {}; | ||||
| 	var Workbook = { Sheets:[] }, wsprops = {}; | ||||
| 	var Workbook/*:WBWBProps*/ = { Sheets:[] }, wsprops = {}; | ||||
| 	xlmlregex.lastIndex = 0; | ||||
| 	str = str.replace(/<!--([^\u2603]*?)-->/mg,""); | ||||
| 	while((Rn = xlmlregex.exec(str))) switch(Rn[3]) { | ||||
| @ -324,12 +324,12 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { | ||||
| 		case 'NamedRange': | ||||
| 			if(!Workbook.Names) Workbook.Names = []; | ||||
| 			var _NamedRange = parsexmltag(Rn[0]); | ||||
| 			var _DefinedName = { | ||||
| 			var _DefinedName/*:DefinedName*/ = ({ | ||||
| 				Name: _NamedRange.Name, | ||||
| 				Ref: rc_to_a1(_NamedRange.RefersTo.substr(1)) | ||||
| 			}; | ||||
| 			}/*:any*/); | ||||
| 			if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1; | ||||
| 			Workbook.Names.push(_DefinedName); | ||||
| 			/*:: if(Workbook.Names) */Workbook.Names.push(_DefinedName); | ||||
| 			break; | ||||
| 
 | ||||
| 		case 'NamedCell': break; | ||||
| @ -1019,7 +1019,7 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo | ||||
| 		process_col(n); | ||||
| 		var w = !!n.width; | ||||
| 		var p = col_obj_w(i, n); | ||||
| 		var k = {"ss:Index":i+1}; | ||||
| 		var k/*:any*/ = {"ss:Index":i+1}; | ||||
| 		if(w) k['ss:Width'] = width2px(p.width); | ||||
| 		if(n.hidden) k['ss:Hidden']="1"; | ||||
| 		o.push(writextag("Column",null,k)); | ||||
|  | ||||
| @ -55,8 +55,9 @@ function slurp(R, blob, length/*:number*/, opts) { | ||||
| function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) { | ||||
| 	if(p.t === 'z') return; | ||||
| 	if(!p.XF) return; | ||||
| 	var fmtid = 0; | ||||
| 	try { | ||||
| 		var fmtid = p.z || p.XF.ifmt || 0; | ||||
| 		fmtid = p.z || p.XF.ifmt || 0; | ||||
| 		if(opts.cellNF) p.z = SSF._table[fmtid]; | ||||
| 	} catch(e) { if(opts.WTF) throw e; } | ||||
| 	if(!opts || opts.cellText !== false) try { | ||||
| @ -75,7 +76,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) { | ||||
| 	} catch(e) { if(opts.WTF) throw e; } | ||||
| } | ||||
| 
 | ||||
| function make_cell(val, ixfe, t)/*:any*/ { | ||||
| function make_cell(val, ixfe, t)/*:Cell*/ { | ||||
| 	return ({v:val, ixfe:ixfe, t:t}/*:any*/); | ||||
| } | ||||
| 
 | ||||
| @ -84,7 +85,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 	var wb = ({opts:{}}/*:any*/); | ||||
| 	var Sheets = {}; | ||||
| 	if(DENSE != null && options.dense == null) options.dense = DENSE; | ||||
| 	var out = (options.dense ? [] : {}); | ||||
| 	var out/*:Worksheet*/ = ((options.dense ? [] : {})/*:any*/); | ||||
| 	var Directory = {}; | ||||
| 	var found_sheet = false; | ||||
| 	var range/*:Range*/ = ({}/*:any*/); | ||||
| @ -95,12 +96,12 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 	var lastcell, last_cell = "", cc, cmnt, rng, rngC, rngR; | ||||
| 	var shared_formulae = {}; | ||||
| 	var array_formulae = []; /* TODO: something more clever */ | ||||
| 	var temp_val; | ||||
| 	var temp_val/*:Cell*/; | ||||
| 	var country; | ||||
| 	var cell_valid = true; | ||||
| 	var XFs = []; /* XF records */ | ||||
| 	var palette = []; | ||||
| 	var Workbook = { Sheets:[] }, wsprops = {}; | ||||
| 	var Workbook/*:WBWBProps*/ = ({ Sheets:[] }/*:any*/), wsprops = {}; | ||||
| 	var get_rgb = function getrgb(icv) { | ||||
| 		if(icv < 8) return XLSIcv[icv]; | ||||
| 		if(icv < 64) return palette[icv-8] || XLSIcv[icv]; | ||||
| @ -179,9 +180,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 	var last_Rn = ''; | ||||
| 	var file_depth = 0; /* TODO: make a real stack */ | ||||
| 	var BIFF2Fmt = 0; | ||||
| 	var BIFF2FmtTable = []; | ||||
| 	var BIFF2FmtTable/*:Array<string>*/ = []; | ||||
| 	var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */ | ||||
| 	var last_lbl; | ||||
| 	var last_lbl/*:?DefinedName*/; | ||||
| 
 | ||||
| 	/* explicit override for some broken writers */ | ||||
| 	opts.codepage = 1200; | ||||
| @ -263,10 +264,10 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 					break; | ||||
| 				case 'Index': break; // TODO
 | ||||
| 				case 'Lbl': | ||||
| 					last_lbl = { | ||||
| 					last_lbl = ({ | ||||
| 						Name: val.Name, | ||||
| 						Ref: stringify_formula(val.rgce,range,null,supbooks,opts) | ||||
| 					}; | ||||
| 					}/*:DefinedName*/); | ||||
| 					if(val.itab > 0) last_lbl.Sheet = val.itab - 1; | ||||
| 					supbooks.names.push(last_lbl); | ||||
| 					if(!supbooks[0]) supbooks[0] = []; | ||||
| @ -281,7 +282,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 				case 'NameCmt': | ||||
| 					/* TODO: search for correct name */ | ||||
| 					if(opts.biff < 8) break; | ||||
| 					last_lbl.Comment = val[1]; | ||||
| 					if(last_lbl != null) last_lbl.Comment = val[1]; | ||||
| 					break; | ||||
| 
 | ||||
| 				case 'Protect': out["!protect"] = val; break; /* for sheet or book */ | ||||
| @ -307,7 +308,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 						Workbook.Sheets.push(wsprops); | ||||
| 					} | ||||
| 					if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out; | ||||
| 					out = options.dense ? [] : {}; | ||||
| 					out = ((options.dense ? [] : {})/*:any*/); | ||||
| 				} break; | ||||
| 				case 'BOF': { | ||||
| 					if(opts.biff !== 8){/* empty */} | ||||
| @ -320,7 +321,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 					else if(val.BIFFVer === 0x0007) opts.biff = 2; | ||||
| 					if(file_depth++) break; | ||||
| 					cell_valid = true; | ||||
| 					out = (options.dense ? [] : {}); | ||||
| 					out = ((options.dense ? [] : {})/*:any*/); | ||||
| 
 | ||||
| 					if(opts.biff < 5) { | ||||
| 						if(cur_sheet === "") cur_sheet = "Sheet1"; | ||||
| @ -343,19 +344,19 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 
 | ||||
| 				case 'Number': case 'BIFF2NUM': case 'BIFF2INT': { | ||||
| 					if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c; | ||||
| 					temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}; | ||||
| 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}/*:any*/); | ||||
| 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; | ||||
| 					safe_format_xf(temp_val, options, wb.opts.Date1904); | ||||
| 					addcell({c:val.c, r:val.r}, temp_val, options); | ||||
| 				} break; | ||||
| 				case 'BoolErr': { | ||||
| 					temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}; | ||||
| 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/); | ||||
| 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; | ||||
| 					safe_format_xf(temp_val, options, wb.opts.Date1904); | ||||
| 					addcell({c:val.c, r:val.r}, temp_val, options); | ||||
| 				} break; | ||||
| 				case 'RK': { | ||||
| 					temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}; | ||||
| 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/); | ||||
| 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; | ||||
| 					safe_format_xf(temp_val, options, wb.opts.Date1904); | ||||
| 					addcell({c:val.c, r:val.r}, temp_val, options); | ||||
| @ -363,7 +364,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 				case 'MulRk': { | ||||
| 					for(var j = val.c; j <= val.C; ++j) { | ||||
| 						var ixfe = val.rkrec[j-val.c][0]; | ||||
| 						temp_val= {ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}; | ||||
| 						temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/); | ||||
| 						if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; | ||||
| 						safe_format_xf(temp_val, options, wb.opts.Date1904); | ||||
| 						addcell({c:j, r:val.r}, temp_val, options); | ||||
| @ -371,7 +372,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 				} break; | ||||
| 				case 'Formula': { | ||||
| 					if(val.val == 'String') { last_formula = val; break; } | ||||
| 					temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt}/*:any*/); | ||||
| 					temp_val = make_cell(val.val, val.cell.ixfe, val.tt); | ||||
| 					temp_val.XF = XFs[temp_val.ixfe]; | ||||
| 					if(options.cellFormula) { | ||||
| 						var _f = val.formula; | ||||
| @ -390,7 +391,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 				case 'String': { | ||||
| 					if(last_formula) { /* technically always true */ | ||||
| 						last_formula.val = val; | ||||
| 						temp_val = ({v:val, ixfe:last_formula.cell.ixfe, t:'s'}/*:any*/); | ||||
| 						temp_val = make_cell(val, last_formula.cell.ixfe, 's'); | ||||
| 						temp_val.XF = XFs[temp_val.ixfe]; | ||||
| 						if(options.cellFormula) { | ||||
| 							temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts); | ||||
| @ -431,7 +432,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 					addcell({c:val.c, r:val.r}, temp_val, options); | ||||
| 					break; | ||||
| 				case 'Blank': if(options.sheetStubs) { | ||||
| 					temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}; | ||||
| 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/); | ||||
| 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; | ||||
| 					safe_format_xf(temp_val, options, wb.opts.Date1904); | ||||
| 					addcell({c:val.c, r:val.r}, temp_val, options); | ||||
| @ -439,7 +440,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 				case 'MulBlank': if(options.sheetStubs) { | ||||
| 					for(var _j = val.c; _j <= val.C; ++_j) { | ||||
| 						var _ixfe = val.ixfe[_j-val.c]; | ||||
| 						temp_val= {ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}; | ||||
| 						temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/); | ||||
| 						if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; | ||||
| 						safe_format_xf(temp_val, options, wb.opts.Date1904); | ||||
| 						addcell({c:_j, r:val.r}, temp_val, options); | ||||
| @ -530,12 +531,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 				case 'TopMargin': | ||||
| 				case 'BottomMargin': | ||||
| 					if(!out['!margins']) default_margins(out['!margins'] = {}); | ||||
| 					switch(Rn) { | ||||
| 						case 'LeftMargin': out['!margins'].left = val; break; | ||||
| 						case 'RightMargin': out['!margins'].right = val; break; | ||||
| 						case 'TopMargin': out['!margins'].top = val; break; | ||||
| 						case 'BottomMargin': out['!margins'].bottom = val; break; | ||||
| 					} | ||||
| 					out['!margins'][Rn.slice(0,-6).toLowerCase()] = val; | ||||
| 					break; | ||||
| 
 | ||||
| 				case 'Setup': // TODO
 | ||||
|  | ||||
| @ -75,12 +75,13 @@ var HTML_ = (function() { | ||||
| 		} | ||||
| 		return "<tr>" + oo.join("") + "</tr>"; | ||||
| 	} | ||||
| 	function sheet_to_html(ws/*:Worksheet*/, opts)/*:string*/ { | ||||
| 		var o/*:Array<string>*/ = []; | ||||
| 	function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ { | ||||
| 		var o = opts || {}; | ||||
| 		var out/*:Array<string>*/ = []; | ||||
| 		var r = decode_range(ws['!ref']); | ||||
| 		o.dense = Array.isArray(ws); | ||||
| 		for(var R = r.s.r; R <= r.e.r; ++R) o.push(make_html_row(ws, r, R, o)); | ||||
| 		return "<html><body><table>" + o.join("") + "</table></body></html>"; | ||||
| 		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); | ||||
| 		return "<html><body><table>" + out.join("") + "</table></body></html>"; | ||||
| 	} | ||||
| 
 | ||||
| 	return { | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| function get_sheet_type(n) { | ||||
| function get_sheet_type(n/*:string*/)/*:string*/ { | ||||
| 	if(RELS.WS.indexOf(n) > -1) return "sheet"; | ||||
| 	if(RELS.CS && n == RELS.CS) return "chart"; | ||||
| 	if(RELS.DS && n == RELS.DS) return "dialog"; | ||||
| @ -181,8 +181,7 @@ function parse_xlsxcfb(cfb, opts/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| 	data = cfb.find(f); | ||||
| 	if(!data) throw new Error("ECMA-376 Encrypted file missing " + f); | ||||
| 	var dsm = parse_DataSpaceMap(data.content); | ||||
| 	if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || | ||||
| 	   dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") | ||||
| 	if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") | ||||
| 		throw new Error("ECMA-376 Encrypted file bad " + f); | ||||
| 
 | ||||
| 	f = 'StrongEncryptionDataSpace'; | ||||
|  | ||||
| @ -190,7 +190,7 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ { | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| var utils = { | ||||
| var utils/*:any*/ = { | ||||
| 	encode_col: encode_col, | ||||
| 	encode_row: encode_row, | ||||
| 	encode_cell: encode_cell, | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| (function(utils) { | ||||
| utils.consts = utils.consts || {}; | ||||
| function add_consts(R) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } | ||||
| function add_consts(R/*Array<any>*/) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } | ||||
| 
 | ||||
| function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); } | ||||
| function get_default(x/*:any*/, y/*:any*/, z/*:any*/)/*:any*/ { return x[y] != null ? x[y] : (x[y] = z); } | ||||
| 
 | ||||
| /* get cell, creating a stub if necessary */ | ||||
| function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ { | ||||
| @ -11,7 +11,7 @@ function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ { | ||||
| 	/* cell address object */ | ||||
| 	if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R)); | ||||
| 	/* R and C are 0-based indices */ | ||||
| 	return ws_get_cell_stub(ws, encode_cell({r:R,c:C})); | ||||
| 	return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0})); | ||||
| } | ||||
| 
 | ||||
| /* find sheet index for given name / validate index */ | ||||
| @ -33,7 +33,8 @@ utils.book_new = function()/*:Workbook*/ { | ||||
| 
 | ||||
| /* add a worksheet to the end of a given workbook */ | ||||
| utils.book_append_sheet = function(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/) { | ||||
| 	if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf("Sheet" + i) == -1) break; | ||||
| 	if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break; | ||||
| 	if(!name) throw new Error("Too many worksheets"); | ||||
| 	check_ws_name(name); | ||||
| 	if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!"); | ||||
| 
 | ||||
| @ -47,12 +48,14 @@ utils.book_set_sheet_visibility = function(wb/*:Workbook*/, sh/*:number|string*/ | ||||
| 	get_default(wb.Workbook,"Sheets",[]); | ||||
| 
 | ||||
| 	var idx = wb_sheet_idx(wb, sh); | ||||
| 	// $FlowIgnore
 | ||||
| 	get_default(wb.Workbook.Sheets,idx, {}); | ||||
| 
 | ||||
| 	switch(vis) { | ||||
| 		case 0: case 1: case 2: break; | ||||
| 		default: throw new Error("Bad sheet visibility setting " + vis); | ||||
| 	} | ||||
| 	// $FlowIgnore
 | ||||
| 	wb.Workbook.Sheets[idx].Hidden = vis; | ||||
| }; | ||||
| add_consts([ | ||||
| @ -72,7 +75,7 @@ utils.cell_set_hyperlink = function(cell/*:Cell*/, target/*:string*/, tooltip/*: | ||||
| 	if(!target) { | ||||
| 		delete cell.l; | ||||
| 	} else { | ||||
| 		cell.l = { Target: target }; | ||||
| 		cell.l = ({ Target: target }/*:Hyperlink*/); | ||||
| 		if(tooltip) cell.l.Tooltip = tooltip; | ||||
| 	} | ||||
| 	return cell; | ||||
|  | ||||
| @ -10,7 +10,7 @@ if(has_buf && typeof require != 'undefined') (function() { | ||||
| 		var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0); | ||||
| 		var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0); | ||||
| 		var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$"); | ||||
| 		var row = "", cols = []; | ||||
| 		var row/*:?string*/ = "", cols = []; | ||||
| 		o.dense = Array.isArray(sheet); | ||||
| 		for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C); | ||||
| 		var R = r.s.r; | ||||
| @ -18,11 +18,12 @@ if(has_buf && typeof require != 'undefined') (function() { | ||||
| 			if(R > r.e.r) return stream.push(null); | ||||
| 			while(R <= r.e.r) { | ||||
| 				row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o); | ||||
| 				if(row == null) { ++R; continue; } | ||||
| 				if(o.strip) row = row.replace(endregex,""); | ||||
| 				stream.push(row + RS); | ||||
| 				++R; | ||||
| 				break; | ||||
| 				if(row != null) { | ||||
| 					if(o.strip) row = row.replace(endregex,""); | ||||
| 					stream.push(row + RS); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		}; | ||||
| 		return stream; | ||||
| @ -31,10 +32,10 @@ if(has_buf && typeof require != 'undefined') (function() { | ||||
| 	var HTML_BEGIN = "<html><body><table>"; | ||||
| 	var HTML_END = "</table></body></html>"; | ||||
| 
 | ||||
| 	var write_html_stream = function(sheet/*:Worksheet*/, opts) { | ||||
| 	var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) { | ||||
| 		var stream = Readable(); | ||||
| 
 | ||||
| 		var o/*:Array<string>*/ = []; | ||||
| 		var o = opts == null ? {} : opts; | ||||
| 		var r = decode_range(sheet['!ref']), cell/*:Cell*/; | ||||
| 		o.dense = Array.isArray(sheet); | ||||
| 		stream.push(HTML_BEGIN); | ||||
|  | ||||
							
								
								
									
										2
									
								
								demos/extendscript/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								demos/extendscript/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,5 @@ | ||||
| jszip.js | ||||
| shim.js | ||||
| xlsx.flow.js | ||||
| xlsx.core.min.js | ||||
| xlsx.full.min.js | ||||
|  | ||||
| @ -7,8 +7,7 @@ all: deps $(TARGETS) | ||||
| .PHONY: deps | ||||
| deps: | ||||
| 	cp ../../shim.js . | ||||
| 	cp ../../jszip.js . | ||||
| 	cp ../../xlsx.flow.js . | ||||
| 	cp ../../dist/xlsx.core.min.js . | ||||
| 
 | ||||
| %.base: | ||||
| 	echo "#target $*" > $@ | ||||
|  | ||||
| @ -2,6 +2,10 @@ | ||||
| 
 | ||||
| The main file is `test.jsx`.  Target-specific files prepend target directives. | ||||
| 
 | ||||
| Copy the `test.jsx` file as well as the `shim.js`, `jszip.js` and `xlsx.flow.js` | ||||
| files to wherever you want the scripts to reside.  The demo shows opening a file | ||||
| and converting to an array of arrays. | ||||
| Copy the `test.jsx` file as well as the `shim.js` and `xlsx.core.min.js` files | ||||
| to wherever you want the scripts to reside.  The demo shows opening a file and | ||||
| converting to an array of arrays. | ||||
| 
 | ||||
| NOTE: [We forked the minifier](https://www.npmjs.com/package/@sheetjs/uglify-js) | ||||
| and included a bugfix for ExtendScript's misparsing of switch statements. | ||||
| 
 | ||||
|  | ||||
| @ -1,2 +1,2 @@ | ||||
| #target aftereffects | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "jszip.js";
#include "xlsx.flow.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "xlsx.core.min.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
|  | ||||
| @ -1,2 +1,2 @@ | ||||
| #target estoolkit | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "jszip.js";
#include "xlsx.flow.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "xlsx.core.min.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
|  | ||||
| @ -1,2 +1,2 @@ | ||||
| #target illustrator | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "jszip.js";
#include "xlsx.flow.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "xlsx.core.min.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
|  | ||||
| @ -1,2 +1,2 @@ | ||||
| #target indesign | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "jszip.js";
#include "xlsx.flow.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "xlsx.core.min.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
|  | ||||
| @ -1,2 +1,2 @@ | ||||
| #target photoshop | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "jszip.js";
#include "xlsx.flow.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "xlsx.core.min.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "jszip.js";
#include "xlsx.flow.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
| var thisFile = new File($.fileName);  
var basePath = thisFile.path;  
#include "shim.js";
#include "xlsx.core.min.js";
var filename = "/sheetjs.xlsx";
var infile = File(basePath+filename);
infile.open("r");
infile.encoding = "binary";
var data = infile.read();
var workbook = XLSX.read(data, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var first_worksheet = workbook.Sheets[first_sheet_name];
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
alert(data); | ||||
|  | ||||
| @ -10,7 +10,7 @@ type ColInfo = { | ||||
| 
 | ||||
| 	/* column width is specified in one of the following ways: */ | ||||
| 	wpx?:number;     // width in screen pixels | ||||
| 	width:number;    // width in Excel's "Max Digit Width", width*256 is integral | ||||
| 	width?:number;    // width in Excel's "Max Digit Width", width*256 is integral | ||||
| 	wch?:number;     // width in characters | ||||
| 
 | ||||
| 	/* other fields for preserving features from files */ | ||||
| @ -49,7 +49,7 @@ objects which have the following properties: | ||||
| ```typescript | ||||
| type RowInfo = { | ||||
| 	/* visibility */ | ||||
| 	hidden:?boolean; // if true, the row is hidden | ||||
| 	hidden?:boolean; // if true, the row is hidden | ||||
| 
 | ||||
| 	/* row height is specified in one of the following ways: */ | ||||
| 	hpx?:number;     // height in screen pixels | ||||
|  | ||||
							
								
								
									
										36
									
								
								misc/flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										36
									
								
								misc/flow.js
									
									
									
									
									
								
							| @ -19,16 +19,13 @@ type Workbook = { | ||||
| 
 | ||||
| 	Workbook?: WBWBProps; | ||||
| 
 | ||||
| 	SSF?: {[n:number]:string}; | ||||
| 	SSF?: SSFTable; | ||||
| 	cfb?: any; | ||||
| }; | ||||
| 
 | ||||
| type WorkbookProps = { | ||||
| 	SheetNames?: Array<string>; | ||||
| } | ||||
| 
 | ||||
| type WBWBProps = { | ||||
| 	Sheets: Array<WBWSProp>; | ||||
| 	Names?: Array<any>; | ||||
| }; | ||||
| 
 | ||||
| type WBWSProp = { | ||||
| @ -52,6 +49,7 @@ type Worksheet = any; | ||||
| 
 | ||||
| type Sheet2CSVOpts = any; | ||||
| type Sheet2JSONOpts = any; | ||||
| type Sheet2HTMLOpts = any; | ||||
| 
 | ||||
| type ParseOpts = any; | ||||
| 
 | ||||
| @ -77,22 +75,44 @@ type SST = { | ||||
| type Comment = any; | ||||
| 
 | ||||
| type RowInfo = { | ||||
| 	hidden:?boolean; // if true, the row is hidden
 | ||||
| 	hidden?:boolean; // if true, the row is hidden
 | ||||
| 
 | ||||
| 	hpx?:number;     // height in screen pixels
 | ||||
| 	hpt?:number;     // height in points
 | ||||
| }; | ||||
| 
 | ||||
| type ColInfo = { | ||||
| 	hidden:?boolean; // if true, the column is hidden
 | ||||
| 	hidden?:boolean; // if true, the column is hidden
 | ||||
| 
 | ||||
| 	wpx?:number;     // width in screen pixels
 | ||||
| 	width:number;    // width in Excel's "Max Digit Width", width*256 is integral
 | ||||
| 	width?:number;    // width in Excel's "Max Digit Width", width*256 is integral
 | ||||
| 	wch?:number;     // width in characters
 | ||||
| 
 | ||||
| 	MDW?:number;     // Excel's "Max Digit Width" unit, always integral
 | ||||
| }; | ||||
| 
 | ||||
| interface Margins { | ||||
| 	left?:number; | ||||
| 	right?:number; | ||||
| 	top?:number; | ||||
| 	bottom?:number; | ||||
| 	header?:number; | ||||
| 	footer?:number; | ||||
| }; | ||||
| 
 | ||||
| interface DefinedName { | ||||
| 	Name:string; | ||||
| 	Ref:string; | ||||
| 	Sheet?:number; | ||||
| 	Comment?:string; | ||||
| }; | ||||
| 
 | ||||
| interface Hyperlink { | ||||
| 	Target:string; | ||||
| 	Tooltip?:string; | ||||
| }; | ||||
| 
 | ||||
| type SSFTable = any; | ||||
| 
 | ||||
| type AOA = Array<Array<any> >; | ||||
| */ | ||||
|  | ||||
| @ -11,4 +11,81 @@ declare module 'crypto' { declare var exports:any; }; | ||||
| declare module 'fs' { declare var exports:any; }; | ||||
| 
 | ||||
| type ZIP = any; | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
| // Note: The following override is needed because Flow is missing Date#getYear
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
| type Date$LocaleOptions = { | ||||
| 	localeMatcher?: string, | ||||
| 	timeZone?: string, | ||||
| 	hour12?: boolean, | ||||
| 	formatMatcher?: string, | ||||
| 	weekday?: string, | ||||
| 	era?: string, | ||||
| 	year?: string, | ||||
| 	month?: string, | ||||
| 	day?: string, | ||||
| 	hour?: string, | ||||
| 	minute?: string, | ||||
| 	second?: string, | ||||
| 	timeZoneName?: string, | ||||
| }; | ||||
| 
 | ||||
| declare class Date { | ||||
| 	constructor(): void; | ||||
| 	constructor(timestamp: number): void; | ||||
| 	constructor(dateString: string): void; | ||||
| 	constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void; | ||||
| 	getDate(): number; | ||||
| 	getDay(): number; | ||||
| 	getYear(): number; | ||||
| 	getFullYear(): number; | ||||
| 	getHours(): number; | ||||
| 	getMilliseconds(): number; | ||||
| 	getMinutes(): number; | ||||
| 	getMonth(): number; | ||||
| 	getSeconds(): number; | ||||
| 	getTime(): number; | ||||
| 	getTimezoneOffset(): number; | ||||
| 	getUTCDate(): number; | ||||
| 	getUTCDay(): number; | ||||
| 	getUTCFullYear(): number; | ||||
| 	getUTCHours(): number; | ||||
| 	getUTCMilliseconds(): number; | ||||
| 	getUTCMinutes(): number; | ||||
| 	getUTCMonth(): number; | ||||
| 	getUTCSeconds(): number; | ||||
| 	setDate(date: number): number; | ||||
| 	setFullYear(year: number, month?: number, date?: number): number; | ||||
| 	setHours(hours: number, min?: number, sec?: number, ms?: number): number; | ||||
| 	setMilliseconds(ms: number): number; | ||||
| 	setMinutes(min: number, sec?: number, ms?: number): number; | ||||
| 	setMonth(month: number, date?: number): number; | ||||
| 	setSeconds(sec: number, ms?: number): number; | ||||
| 	setTime(time: number): number; | ||||
| 	setUTCDate(date: number): number; | ||||
| 	setUTCFullYear(year: number, month?: number, date?: number): number; | ||||
| 	setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number; | ||||
| 	setUTCMilliseconds(ms: number): number; | ||||
| 	setUTCMinutes(min: number, sec?: number, ms?: number): number; | ||||
| 	setUTCMonth(month: number, date?: number): number; | ||||
| 	setUTCSeconds(sec: number, ms?: number): number; | ||||
| 	toDateString(): string; | ||||
| 	toISOString(): string; | ||||
| 	toJSON(key?: any): string; | ||||
| 	toLocaleDateString(locales?: string, options?: Date$LocaleOptions): string; | ||||
| 	toLocaleString(locales?: string, options?: Date$LocaleOptions): string; | ||||
| 	toLocaleTimeString(locales?: string, options?: Date$LocaleOptions): string; | ||||
| 	toTimeString(): string; | ||||
| 	toUTCString(): string; | ||||
| 	valueOf(): number; | ||||
| 	static ():string; | ||||
| 	static now(): number; | ||||
| 	static parse(s: string): number; | ||||
| 	static UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number; | ||||
| 	// multiple indexers not yet supported
 | ||||
| 	[key: $SymbolToPrimitive]: (hint: 'string' | 'default' | 'number') => string | number; | ||||
| } | ||||
| 
 | ||||
| */ | ||||
|  | ||||
| @ -6,33 +6,41 @@ AutoFilter              	.xls .xlsb .xlsx .xml | ||||
| # note: XLML only supports sheets, ods does not support dialog | ||||
| BlankSheetTypes         	.xls .xlsb .xlsm | ||||
| NumberFormatCondition   	.xls .xlsb .xlsm .xml | ||||
| RkNumber                	.xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml | ||||
| #RkNumber                	.xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml | ||||
| RkNumber                	.xls .xlsb .xlsx .xls.xml | ||||
| #calendar_stress_test    	.xls .xlsb .xlsx .xml | ||||
| 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 | ||||
|  | ||||
| @ -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
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										152
									
								
								test.js
									
									
									
									
									
								
							| @ -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"); | ||||
| 	}); | ||||
|  | ||||
							
								
								
									
										25
									
								
								tests.lst
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										25
									
								
								tests.lst
									
									
									
									
									
								
							| @ -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 | ||||
|  | ||||
							
								
								
									
										134
									
								
								tests/core.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										134
									
								
								tests/core.js
									
									
									
									
									
								
							| @ -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
											
										
									
								
							
							
								
								
									
										190
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										190
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -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
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										132
									
								
								xlsx.js
									
									
									
									
									
								
							| @ -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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user