| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | function write_biff_rec(ba/*:BufArray*/, type/*:number|string*/, payload, length/*:?number*/)/*:void*/ { | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 	var t/*:number*/ = +type || +XLSRE[/*::String(*/type/*::)*/]; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	if(isNaN(t)) return; | 
					
						
							|  |  |  | 	var len = length || (payload||[]).length || 0; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var o = ba.next(4); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	o.write_shift(2, t); | 
					
						
							|  |  |  | 	o.write_shift(2, len); | 
					
						
							|  |  |  | 	if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-29 08:07:23 +00:00
										 |  |  | function write_biff_continue(ba/*:BufArray*/, type/*:number|string*/, payload, length/*:?number*/)/*:void*/ { | 
					
						
							|  |  |  | 	var len = length || (payload||[]).length || 0; | 
					
						
							|  |  |  | 	if(len <= 8224) return write_biff_rec(ba, type, payload, len); | 
					
						
							|  |  |  | 	var t/*:number*/ = +type || +XLSRE[/*::String(*/type/*::)*/]; | 
					
						
							|  |  |  | 	if(isNaN(t)) return; | 
					
						
							|  |  |  | 	var parts = payload.parts || [], sidx = 0; | 
					
						
							|  |  |  | 	var i = 0, w = 0; | 
					
						
							|  |  |  | 	while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; } | 
					
						
							|  |  |  | 	var o = ba.next(4); | 
					
						
							|  |  |  | 	o.write_shift(2, t); | 
					
						
							|  |  |  | 	o.write_shift(2, w); | 
					
						
							|  |  |  | 	ba.push(payload.slice(i, i + w)); | 
					
						
							|  |  |  | 	i += w; | 
					
						
							|  |  |  | 	while(i < len) { | 
					
						
							|  |  |  | 		o = ba.next(4); | 
					
						
							|  |  |  | 		o.write_shift(2, 0x3c); // TODO: figure out correct continue type
 | 
					
						
							|  |  |  | 		w = 0; | 
					
						
							|  |  |  | 		while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; } | 
					
						
							|  |  |  | 		o.write_shift(2, w); | 
					
						
							|  |  |  | 		ba.push(payload.slice(i, i+w)); i+= w; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-15 07:42:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) { | 
					
						
							|  |  |  | 	if(!out) out = new_buf(7); | 
					
						
							|  |  |  | 	out.write_shift(2, r); | 
					
						
							|  |  |  | 	out.write_shift(2, c); | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	out.write_shift(2, 0); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	out.write_shift(1, 0); | 
					
						
							|  |  |  | 	return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-27 20:07:51 +00:00
										 |  |  | function write_BIFF2BERR(r/*:number*/, c/*:number*/, val, t/*:?string*/) { | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	var out = new_buf(9); | 
					
						
							|  |  |  | 	write_BIFF2Cell(out, r, c); | 
					
						
							|  |  |  | 	if(t == 'e') { out.write_shift(1, val); out.write_shift(1, 1); } | 
					
						
							|  |  |  | 	else { out.write_shift(1, val?1:0); out.write_shift(1, 0); } | 
					
						
							|  |  |  | 	return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* TODO: codepage, large strings */ | 
					
						
							| 
									
										
										
										
											2017-07-27 20:07:51 +00:00
										 |  |  | function write_BIFF2LABEL(r/*:number*/, c/*:number*/, val) { | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	var out = new_buf(8 + 2*val.length); | 
					
						
							|  |  |  | 	write_BIFF2Cell(out, r, c); | 
					
						
							|  |  |  | 	out.write_shift(1, val.length); | 
					
						
							|  |  |  | 	out.write_shift(val.length, val, 'sbcs'); | 
					
						
							|  |  |  | 	return out.l < out.length ? out.slice(0, out.l) : out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*//*::, opts*/) { | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 	if(cell.v != null) switch(cell.t) { | 
					
						
							| 
									
										
										
										
											2017-04-02 06:47:25 +00:00
										 |  |  | 		case 'd': case 'n': | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 			var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v; | 
					
						
							| 
									
										
										
										
											2017-04-02 06:47:25 +00:00
										 |  |  | 			if((v == (v|0)) && (v >= 0) && (v < 65536)) | 
					
						
							|  |  |  | 				write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, v)); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 				write_biff_rec(ba, 0x0003, write_BIFF2NUM(R,C, v)); | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		case 'b': case 'e': write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t)); return; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 		/* TODO: codepage, sst */ | 
					
						
							|  |  |  | 		case 's': case 'str': | 
					
						
							|  |  |  | 			write_biff_rec(ba, 0x0004, write_BIFF2LABEL(R, C, cell.v)); | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 	write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C)); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Workbook*/) { | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 	var dense = Array.isArray(ws); | 
					
						
							| 
									
										
										
										
											2017-07-27 20:07:51 +00:00
										 |  |  | 	var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = []; | 
					
						
							| 
									
										
										
										
											2018-04-27 20:11:18 +00:00
										 |  |  | 	if(range.e.c > 0xFF || range.e.r > 0x3FFF) { | 
					
						
							|  |  |  | 		if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384"); | 
					
						
							|  |  |  | 		range.e.c = Math.min(range.e.c, 0xFF); | 
					
						
							|  |  |  | 		range.e.r = Math.min(range.e.c, 0x3FFF); | 
					
						
							|  |  |  | 		ref = encode_range(range); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	for(var R = range.s.r; R <= range.e.r; ++R) { | 
					
						
							|  |  |  | 		rr = encode_row(R); | 
					
						
							|  |  |  | 		for(var C = range.s.c; C <= range.e.c; ++C) { | 
					
						
							|  |  |  | 			if(R === range.s.r) cols[C] = encode_col(C); | 
					
						
							|  |  |  | 			ref = cols[C] + rr; | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 			var cell = dense ? (ws[R]||[])[C] : ws[ref]; | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 			if(!cell) continue; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 			/* write cell */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 			write_ws_biff2_cell(ba, cell, R, C, opts); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Based on test files */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) { | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 	var o = opts || {}; | 
					
						
							| 
									
										
										
										
											2017-04-09 04:03:19 +00:00
										 |  |  | 	if(DENSE != null && o.dense == null) o.dense = DENSE; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	var ba = buf_array(); | 
					
						
							|  |  |  | 	var idx = 0; | 
					
						
							|  |  |  | 	for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i; | 
					
						
							|  |  |  | 	if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(ba, 0x0009, write_BOF(wb, 0x10, o)); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	/* ... */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_ws_biff2(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	/* ... */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(ba, 0x000A); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	return ba.end(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | function write_FONTS_biff8(ba, data, opts) { | 
					
						
							|  |  |  | 	write_biff_rec(ba, "Font", write_Font({ | 
					
						
							|  |  |  | 		sz:12, | 
					
						
							|  |  |  | 		color: {theme:1}, | 
					
						
							|  |  |  | 		name: "Arial", | 
					
						
							|  |  |  | 		family: 2, | 
					
						
							|  |  |  | 		scheme: "minor" | 
					
						
							|  |  |  | 	}, opts)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function write_FMTS_biff8(ba, NF/*:?SSFTable*/, opts) { | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 	if(!NF) return; | 
					
						
							|  |  |  | 	[[5,8],[23,26],[41,44],[/*63*/50,/*66],[164,*/392]].forEach(function(r) { | 
					
						
							|  |  |  | 		/*:: if(!NF) return; */ | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 		for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_biff_rec(ba, "Format", write_Format(i, NF[i], opts)); | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 	}); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | function write_FEAT(ba, ws) { | 
					
						
							|  |  |  | 	/* [MS-XLS] 2.4.112 */ | 
					
						
							|  |  |  | 	var o = new_buf(19); | 
					
						
							|  |  |  | 	o.write_shift(4, 0x867); o.write_shift(4, 0); o.write_shift(4, 0); | 
					
						
							|  |  |  | 	o.write_shift(2, 3); o.write_shift(1, 1); o.write_shift(4, 0); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "FeatHdr", o); | 
					
						
							|  |  |  | 	/* [MS-XLS] 2.4.111 */ | 
					
						
							|  |  |  | 	o = new_buf(39); | 
					
						
							|  |  |  | 	o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0); | 
					
						
							|  |  |  | 	o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0); | 
					
						
							|  |  |  | 	o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0); | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | 	write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o); | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	o.write_shift(4, 4); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "Feat", o); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function write_CELLXFS_biff8(ba, opts) { | 
					
						
							|  |  |  | 	for(var i = 0; i < 16; ++i) write_biff_rec(ba, "XF", write_XF({numFmtId:0, style:true}, 0, opts)); | 
					
						
							|  |  |  | 	opts.cellXfs.forEach(function(c) { | 
					
						
							|  |  |  | 		write_biff_rec(ba, "XF", write_XF(c, 0, opts)); | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 	}); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 01:18:40 +00:00
										 |  |  | function write_ws_biff8_hlinks(ba/*:BufArray*/, ws) { | 
					
						
							|  |  |  | 	for(var R=0; R<ws['!links'].length; ++R) { | 
					
						
							|  |  |  | 		var HL = ws['!links'][R]; | 
					
						
							|  |  |  | 		write_biff_rec(ba, "HLink", write_HLink(HL)); | 
					
						
							|  |  |  | 		if(HL[1].Tooltip) write_biff_rec(ba, "HLinkTooltip", write_HLinkTooltip(HL)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	delete ws['!links']; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) { | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	var os = 16 + get_cell_style(opts.cellXfs, cell, opts); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	if(cell.v == null && !cell.bf) { | 
					
						
							|  |  |  | 		write_biff_rec(ba, "Blank", write_XLSCell(R, C, os)); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(cell.bf) write_biff_rec(ba, "Formula", write_Formula(cell, R, C, opts, os)); | 
					
						
							|  |  |  | 	else switch(cell.t) { | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 		case 'd': case 'n': | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 			var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 			/* TODO: emit RK as appropriate */ | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 			write_biff_rec(ba, "Number", write_Number(R, C, v, os, opts)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case 'b': case 'e': | 
					
						
							|  |  |  | 			write_biff_rec(ba, 0x0205, write_BoolErr(R, C, cell.v, os, opts, cell.t)); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 		/* TODO: codepage, sst */ | 
					
						
							|  |  |  | 		case 's': case 'str': | 
					
						
							| 
									
										
										
										
											2020-06-29 08:07:23 +00:00
										 |  |  | 			if(opts.bookSST) { | 
					
						
							|  |  |  | 				var isst = get_sst_id(opts.Strings, cell.v, opts.revStrings); | 
					
						
							|  |  |  | 				write_biff_rec(ba, "LabelSst", write_LabelSst(R, C, isst, os, opts)); | 
					
						
							|  |  |  | 			} else write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			write_biff_rec(ba, "Blank", write_XLSCell(R, C, os)); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* [MS-XLS] 2.1.7.20.5 */ | 
					
						
							|  |  |  | function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) { | 
					
						
							|  |  |  | 	var ba = buf_array(); | 
					
						
							|  |  |  | 	var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/); | 
					
						
							|  |  |  | 	var _sheet/*:WBWSProp*/ = ((_WB.Sheets||[])[idx]||{}/*:any*/); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	var dense = Array.isArray(ws); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:11:18 +00:00
										 |  |  | 	var b8 = opts.biff == 8; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	var ref/*:string*/, rr = "", cols/*:Array<string>*/ = []; | 
					
						
							|  |  |  | 	var range = safe_decode_range(ws['!ref'] || "A1"); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:11:18 +00:00
										 |  |  | 	var MAX_ROWS = b8 ? 65536 : 16384; | 
					
						
							|  |  |  | 	if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) { | 
					
						
							|  |  |  | 		if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384"); | 
					
						
							|  |  |  | 		range.e.c = Math.min(range.e.c, 0xFF); | 
					
						
							|  |  |  | 		range.e.r = Math.min(range.e.c, MAX_ROWS-1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* [Uncalced] Index */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(ba, "CalcMode", writeuint16(1)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "CalcCount", writeuint16(100)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "CalcRefMode", writebool(true)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "CalcIter", writebool(false)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "CalcDelta", write_Xnum(0.001)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "CalcSaveRecalc", writebool(true)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "PrintRowCol", writebool(false)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "PrintGrid", writebool(false)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "GridSet", writeuint16(1)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "Guts", write_Guts([0,0])); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* DefaultRowHeight WsBool [Sync] [LPr] [HorizontalPageBreaks] [VerticalPageBreaks] */ | 
					
						
							|  |  |  | 	/* Header (string) */ | 
					
						
							|  |  |  | 	/* Footer (string) */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(ba, "HCenter", writebool(false)); | 
					
						
							|  |  |  | 	write_biff_rec(ba, "VCenter", writebool(false)); | 
					
						
							|  |  |  | 	/* ... */ | 
					
						
							| 
									
										
										
										
											2018-08-30 01:14:04 +00:00
										 |  |  | 	write_biff_rec(ba, 0x200, write_Dimensions(range, opts)); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	/* ... */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 01:18:40 +00:00
										 |  |  | 	if(b8) ws['!links'] = []; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	for(var R = range.s.r; R <= range.e.r; ++R) { | 
					
						
							|  |  |  | 		rr = encode_row(R); | 
					
						
							|  |  |  | 		for(var C = range.s.c; C <= range.e.c; ++C) { | 
					
						
							|  |  |  | 			if(R === range.s.r) cols[C] = encode_col(C); | 
					
						
							|  |  |  | 			ref = cols[C] + rr; | 
					
						
							|  |  |  | 			var cell = dense ? (ws[R]||[])[C] : ws[ref]; | 
					
						
							|  |  |  | 			if(!cell) continue; | 
					
						
							|  |  |  | 			/* write cell */ | 
					
						
							|  |  |  | 			write_ws_biff8_cell(ba, cell, R, C, opts); | 
					
						
							| 
									
										
										
										
											2017-12-15 01:18:40 +00:00
										 |  |  | 			if(b8 && cell.l) ws['!links'].push([ref, cell.l]); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-20 01:51:14 +00:00
										 |  |  | 	var cname/*:string*/ = _sheet.CodeName || _sheet.name || s; | 
					
						
							| 
									
										
										
										
											2017-12-15 01:18:40 +00:00
										 |  |  | 	/* ... */ | 
					
						
							| 
									
										
										
										
											2020-10-06 20:25:37 +00:00
										 |  |  | 	if(b8) write_biff_rec(ba, "Window2", write_Window2((_WB.Views||[])[0])); | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	/* ... */ | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	if(b8 && (ws['!merges']||[]).length) write_biff_rec(ba, "MergeCells", write_MergeCells(ws['!merges'])); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */ | 
					
						
							| 
									
										
										
										
											2017-12-15 01:18:40 +00:00
										 |  |  | 	if(b8) write_ws_biff8_hlinks(ba, ws); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* [DVAL] */ | 
					
						
							| 
									
										
										
										
											2017-10-27 16:25:54 +00:00
										 |  |  | 	write_biff_rec(ba, "CodeName", write_XLUnicodeString(cname, opts)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* *WebPub *CellWatch [SheetExt] */ | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	if(b8) write_FEAT(ba, ws); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* *FEAT11 *RECORD12 */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(ba, "EOF"); | 
					
						
							|  |  |  | 	return ba.end(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* [MS-XLS] 2.1.7.20.3 */ | 
					
						
							|  |  |  | function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) { | 
					
						
							|  |  |  | 	var A = buf_array(); | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/); | 
					
						
							|  |  |  | 	var _sheets/*:Array<WBWSProp>*/ = (_WB.Sheets||[]); | 
					
						
							|  |  |  | 	var _wb/*:WBProps*/ = /*::((*/_WB.WBProps||{/*::CodeName:"ThisWorkbook"*/}/*:: ):any)*/; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	var b8 = opts.biff == 8, b5 = opts.biff == 5; | 
					
						
							|  |  |  | 	write_biff_rec(A, 0x0809, write_BOF(wb, 0x05, opts)); | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	if(opts.bookType == "xla") write_biff_rec(A, "Addin"); | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	write_biff_rec(A, "InterfaceHdr", b8 ? writeuint16(0x04b0) : null); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(A, "Mms", writezeroes(2)); | 
					
						
							|  |  |  | 	if(b5) write_biff_rec(A, "ToolbarHdr"); | 
					
						
							|  |  |  | 	if(b5) write_biff_rec(A, "ToolbarEnd"); | 
					
						
							|  |  |  | 	write_biff_rec(A, "InterfaceEnd"); | 
					
						
							|  |  |  | 	write_biff_rec(A, "WriteAccess", write_WriteAccess("SheetJS", opts)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* [FileSharing] */ | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	write_biff_rec(A, "CodePage", writeuint16(b8 ? 0x04b0 : 0x04E4)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* *2047 Lel */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	if(b8) write_biff_rec(A, "DSF", writeuint16(0)); | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	if(b8) write_biff_rec(A, "Excel9File"); | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	write_biff_rec(A, "RRTabId", write_RRTabId(wb.SheetNames.length)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	if(b8 && wb.vbaraw) write_biff_rec(A, "ObProj"); | 
					
						
							|  |  |  | 	/* [ObNoMacros] */ | 
					
						
							| 
									
										
										
										
											2017-10-27 16:25:54 +00:00
										 |  |  | 	if(b8 && wb.vbaraw) { | 
					
						
							| 
									
										
										
										
											2017-11-20 01:51:14 +00:00
										 |  |  | 		var cname/*:string*/ = _wb.CodeName || "ThisWorkbook"; | 
					
						
							| 
									
										
										
										
											2017-10-27 16:25:54 +00:00
										 |  |  | 		write_biff_rec(A, "CodeName", write_XLUnicodeString(cname, opts)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	write_biff_rec(A, "BuiltInFnGroupCount", writeuint16(0x11)); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* *FnGroupName *FnGrp12 */ | 
					
						
							|  |  |  | 	/* *Lbl */ | 
					
						
							|  |  |  | 	/* [OleObjectSize] */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(A, "WinProtect", writebool(false)); | 
					
						
							|  |  |  | 	write_biff_rec(A, "Protect", writebool(false)); | 
					
						
							|  |  |  | 	write_biff_rec(A, "Password", writeuint16(0)); | 
					
						
							|  |  |  | 	if(b8) write_biff_rec(A, "Prot4Rev", writebool(false)); | 
					
						
							|  |  |  | 	if(b8) write_biff_rec(A, "Prot4RevPass", writeuint16(0)); | 
					
						
							|  |  |  | 	write_biff_rec(A, "Window1", write_Window1(opts)); | 
					
						
							|  |  |  | 	write_biff_rec(A, "Backup", writebool(false)); | 
					
						
							|  |  |  | 	write_biff_rec(A, "HideObj", writeuint16(0)); | 
					
						
							|  |  |  | 	write_biff_rec(A, "Date1904", writebool(safe1904(wb)=="true")); | 
					
						
							|  |  |  | 	write_biff_rec(A, "CalcPrecision", writebool(true)); | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	if(b8) write_biff_rec(A, "RefreshAll", writebool(false)); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(A, "BookBool", writeuint16(0)); | 
					
						
							|  |  |  | 	/* ... */ | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	write_FONTS_biff8(A, wb, opts); | 
					
						
							|  |  |  | 	write_FMTS_biff8(A, wb.SSF, opts); | 
					
						
							|  |  |  | 	write_CELLXFS_biff8(A, opts); | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 	/* ... */ | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	if(b8) write_biff_rec(A, "UsesELFs", writebool(false)); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	var a = A.end(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var C = buf_array(); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* METADATA [MTRSettings] [ForceFullCalculation] */ | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	if(b8) write_biff_rec(C, "Country", write_Country()); | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */ | 
					
						
							| 
									
										
										
										
											2020-06-29 08:07:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	/* BIFF8: [SST *Continue] ExtSST */ | 
					
						
							| 
									
										
										
										
											2020-06-29 08:07:23 +00:00
										 |  |  | 	if(b8 && opts.Strings) write_biff_continue(C, "SST", write_SST(opts.Strings, opts)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	write_biff_rec(C, "EOF"); | 
					
						
							|  |  |  | 	var c = C.end(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var B = buf_array(); | 
					
						
							|  |  |  | 	var blen = 0, j = 0; | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 	for(j = 0; j < wb.SheetNames.length; ++j) blen += (b8 ? 12 : 11) + (b8 ? 2 : 1) * wb.SheetNames[j].length; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	var start = a.length + blen + c.length; | 
					
						
							|  |  |  | 	for(j = 0; j < wb.SheetNames.length; ++j) { | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 		var _sheet/*:WBWSProp*/ = _sheets[j] || ({}/*:any*/); | 
					
						
							|  |  |  | 		write_biff_rec(B, "BoundSheet8", write_BoundSheet8({pos:start, hs:_sheet.Hidden||0, dt:0, name:wb.SheetNames[j]}, opts)); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 		start += bufs[j].length; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* 1*BoundSheet8 */ | 
					
						
							|  |  |  | 	var b = B.end(); | 
					
						
							|  |  |  | 	if(blen != b.length) throw new Error("BS8 " + blen + " != " + b.length); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var out = []; | 
					
						
							|  |  |  | 	if(a.length) out.push(a); | 
					
						
							|  |  |  | 	if(b.length) out.push(b); | 
					
						
							|  |  |  | 	if(c.length) out.push(c); | 
					
						
							|  |  |  | 	return __toBuffer([out]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* [MS-XLS] 2.1.7.20 Workbook Stream */ | 
					
						
							|  |  |  | function write_biff8_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) { | 
					
						
							|  |  |  | 	var o = opts || {}; | 
					
						
							|  |  |  | 	var bufs = []; | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(wb && !wb.SSF) { | 
					
						
							|  |  |  | 		wb.SSF = SSF.get_table(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(wb && wb.SSF) { | 
					
						
							|  |  |  | 		make_ssf(SSF); SSF.load_table(wb.SSF); | 
					
						
							|  |  |  | 		// $FlowIgnore
 | 
					
						
							|  |  |  | 		o.revssf = evert_num(wb.SSF); o.revssf[wb.SSF[65535]] = 0; | 
					
						
							|  |  |  | 		o.ssf = wb.SSF; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 	o.Strings = /*::((*/[]/*:: :any):SST)*/; o.Strings.Count = 0; o.Strings.Unique = 0; | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	fix_write_opts(o); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	o.cellXfs = []; | 
					
						
							| 
									
										
										
										
											2018-02-08 18:21:39 +00:00
										 |  |  | 	get_cell_style(o.cellXfs, {}, {revssf:{"General":0}}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	if(!wb.Props) wb.Props = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	for(var i = 0; i < wb.SheetNames.length; ++i) bufs[bufs.length] = write_ws_biff8(i, o, wb); | 
					
						
							|  |  |  | 	bufs.unshift(write_biff8_global(wb, bufs, o)); | 
					
						
							|  |  |  | 	return __toBuffer([bufs]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) { | 
					
						
							|  |  |  | 	var o = opts || {}; | 
					
						
							|  |  |  | 	switch(o.biff || 2) { | 
					
						
							|  |  |  | 		case 8: case 5: return write_biff8_buf(wb, opts); | 
					
						
							|  |  |  | 		case 4: case 3: case 2: return write_biff2_buf(wb, opts); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	throw new Error("invalid type " + o.bookType + " for BIFF"); | 
					
						
							|  |  |  | } |