forked from sheetjs/sheetjs
		
	version bump 0.16.3
- updated SSF to 0.11.2 - XLS write support for `bookSST`
This commit is contained in:
		
							parent
							
								
									5b1440a186
								
							
						
					
					
						commit
						768e1bdcf8
					
				| @ -47,7 +47,7 @@ before_install: | ||||
|   - "npm install -g npm@4.3.0" | ||||
|   - "npm install -g mocha@2.x voc" | ||||
|   - "npm install blanket" | ||||
|   - "npm install xlsjs" | ||||
|   - "npm install word" | ||||
|   - "npm install coveralls mocha-lcov-reporter" | ||||
| # note: jsdom 11.x expects node >= 6 but is missing engines.node | ||||
|   - "npm install jsdom@11.x" | ||||
|  | ||||
							
								
								
									
										22
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										22
									
								
								README.md
									
									
									
									
									
								
							| @ -1713,7 +1713,7 @@ The exported `read` and `readFile` functions accept an options argument: | ||||
|   for files employing other encryption methods. | ||||
| - WTF is mainly for development.  By default, the parser will suppress read | ||||
|   errors on single worksheets, allowing you to read from the worksheets that do | ||||
|   parse properly. Setting `WTF:1` forces those errors to be thrown. | ||||
|   parse properly. Setting `WTF:true` forces those errors to be thrown. | ||||
| 
 | ||||
| ### Input Type | ||||
| 
 | ||||
| @ -2140,18 +2140,20 @@ For the example sheet: | ||||
| As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also | ||||
| produces CSV output.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name  |  Default | Description                                         | | ||||
| | :----------- | :------: | :-------------------------------------------------- | | ||||
| |`FS`          |  `","`   | "Field Separator"  delimiter between fields         | | ||||
| |`RS`          |  `"\n"`  | "Record Separator" delimiter between rows           | | ||||
| |`dateNF`      |  FMT 14  | Use specified date format in string output          | | ||||
| |`strip`       |  false   | Remove trailing field separators in each record **  | | ||||
| |`blankrows`   |  true    | Include blank lines in the CSV output               | | ||||
| |`skipHidden`  |  false   | Skips hidden rows/columns in the CSV output         | | ||||
| |`forceQuotes` |  false   | Force quotes around fields                          | | ||||
| | Option Name  |  Default | Description                                        | | ||||
| | :----------- | :------: | :------------------------------------------------- | | ||||
| |`FS`          |  `","`   | "Field Separator"  delimiter between fields        | | ||||
| |`RS`          |  `"\n"`  | "Record Separator" delimiter between rows          | | ||||
| |`dateNF`      |  FMT 14  | Use specified date format in string output         | | ||||
| |`strip`       |  false   | Remove trailing field separators in each record ** | | ||||
| |`blankrows`   |  true    | Include blank lines in the CSV output              | | ||||
| |`skipHidden`  |  false   | Skips hidden rows/columns in the CSV output        | | ||||
| |`forceQuotes` |  false   | Force quotes around fields                         | | ||||
| 
 | ||||
| - `strip` will remove trailing commas from each line under default `FS/RS` | ||||
| - `blankrows` must be set to `false` to skip blank lines. | ||||
| - Fields containing the record or field separator will automatically be wrapped | ||||
|   in double quotes; `forceQuotes` forces all cells to be wrapped in quotes. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| XLSX.version = '0.16.2'; | ||||
| XLSX.version = '0.16.3'; | ||||
|  | ||||
							
								
								
									
										193
									
								
								bits/10_ssf.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										193
									
								
								bits/10_ssf.js
									
									
									
									
									
								
							| @ -2,7 +2,7 @@ | ||||
| /*jshint -W041 */ | ||||
| var SSF/*:SSFModule*/ = ({}/*:any*/); | ||||
| var make_ssf = function make_ssf(SSF/*:SSFModule*/){ | ||||
| SSF.version = '0.10.3'; | ||||
| SSF.version = '0.11.2'; | ||||
| function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -69,11 +69,65 @@ function init_table(t/*:any*/) { | ||||
| 	t[48]= '##0.0E+0'; | ||||
| 	t[49]= '@'; | ||||
| 	t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "'; | ||||
| 	t[65535]= 'General'; | ||||
| } | ||||
| 
 | ||||
| var table_fmt = {}; | ||||
| init_table(table_fmt); | ||||
| /* Defaults determined by systematically testing in Excel 2019 */ | ||||
| 
 | ||||
| /* These formats appear to default to other formats in the table */ | ||||
| var default_map/*:Array<number>*/ = []; | ||||
| var defi = 0; | ||||
| 
 | ||||
| //  5 -> 37 ...  8 -> 40
 | ||||
| for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi; | ||||
| 
 | ||||
| // 23 ->  0 ... 26 ->  0
 | ||||
| for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0; | ||||
| 
 | ||||
| // 27 -> 14 ... 31 -> 14
 | ||||
| for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14; | ||||
| // 50 -> 14 ... 58 -> 14
 | ||||
| for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14; | ||||
| 
 | ||||
| // 59 ->  1 ... 62 ->  4
 | ||||
| for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58; | ||||
| // 67 ->  9 ... 68 -> 10
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58; | ||||
| // 72 -> 14 ... 75 -> 17
 | ||||
| for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58; | ||||
| 
 | ||||
| // 69 -> 12 ... 71 -> 14
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57; | ||||
| 
 | ||||
| // 76 -> 20 ... 78 -> 22
 | ||||
| for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56; | ||||
| 
 | ||||
| // 79 -> 45 ... 81 -> 47
 | ||||
| for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34; | ||||
| 
 | ||||
| // 82 ->  0 ... 65536 -> 0 (omitted)
 | ||||
| 
 | ||||
| /* These formats technically refer to Accounting formats with no equivalent */ | ||||
| var default_str/*:Array<string>*/ = []; | ||||
| 
 | ||||
| //  5 -- Currency,   0 decimal, black negative
 | ||||
| default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
| //  6 -- Currency,   0 decimal, red   negative
 | ||||
| default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)'; | ||||
| //  7 -- Currency,   2 decimal, black negative
 | ||||
| default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
| //  8 -- Currency,   2 decimal, red   negative
 | ||||
| default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'; | ||||
| 
 | ||||
| // 41 -- Accounting, 0 decimal, No Symbol
 | ||||
| default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'; | ||||
| // 42 -- Accounting, 0 decimal, $  Symbol
 | ||||
| default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'; | ||||
| // 43 -- Accounting, 2 decimal, No Symbol
 | ||||
| default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'; | ||||
| // 44 -- Accounting, 2 decimal, $  Symbol
 | ||||
| default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'; | ||||
| function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ { | ||||
| 	var sgn = x < 0 ? -1 : 1; | ||||
| 	var B = x * sgn; | ||||
| @ -134,37 +188,64 @@ function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ { | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* The longest 32-bit integer text is "-4294967296", exactly 11 chars */ | ||||
| function general_fmt_int(v/*:number*/)/*:string*/ { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 
 | ||||
| /* ECMA-376 18.8.30 numFmt*/ | ||||
| /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */ | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| function gfn2(v) { | ||||
| 	var w = (v<0?12:11); | ||||
| 	var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 	o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 	return v.toExponential(5); | ||||
| } | ||||
| function gfn3(v) { | ||||
| 	var o = v.toFixed(11).replace(gnr1,".$1"); | ||||
| 	if(o.length > (v<0?12:11)) o = v.toPrecision(6); | ||||
| 	return o; | ||||
| } | ||||
| function gfn4(o) { | ||||
| 	for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v/*:number*/)/*:string*/ { | ||||
| 	var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 	if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 	else if(Math.abs(V) <= 9) o = gfn2(v); | ||||
| 	else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 	else o = gfn3(v); | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| 	var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/; | ||||
| 	function strip_decimal(o/*:string*/)/*:string*/ { | ||||
| 		return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* General Exponential always shows 2 digits exp and trims the mantissa */ | ||||
| 	var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/; | ||||
| 	var exp_with_single_digit = /(E[+-])(\d)$/; | ||||
| 	function normalize_exp(o/*:string*/)/*:string*/ { | ||||
| 		if(o.indexOf("E") == -1) return o; | ||||
| 		return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= -9 and <= 9 */ | ||||
| 	function small_exp(v/*:number*/)/*:string*/ { | ||||
| 		var w = (v<0?12:11); | ||||
| 		var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 		o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 		return v.toExponential(5); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= 11 or <= -10 likely exponential */ | ||||
| 	function large_exp(v/*:number*/)/*:string*/ { | ||||
| 		var o = strip_decimal(v.toFixed(11)); | ||||
| 		return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o; | ||||
| 	} | ||||
| 
 | ||||
| 	function general_fmt_num_base(v/*:number*/)/*:string*/ { | ||||
| 		var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 
 | ||||
| 		if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 		else if(Math.abs(V) <= 9) o = small_exp(v); | ||||
| 		else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 		else o = large_exp(v); | ||||
| 
 | ||||
| 		return strip_decimal(normalize_exp(o.toUpperCase())); | ||||
| 	} | ||||
| 
 | ||||
| 	return general_fmt_num_base; | ||||
| })(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| 
 | ||||
| /* | ||||
| 	"General" rules: | ||||
| 	- text is passed through ("@") | ||||
| 	- booleans are rendered as TRUE/FALSE | ||||
| 	- "up to 11 characters" displayed for numbers | ||||
| 	- Default date format (code 14) used for Dates | ||||
| 
 | ||||
| 	TODO: technically the display depends on the width of the cell | ||||
| */ | ||||
| function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| @ -178,7 +259,14 @@ function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri(/*::date, o*/) { return 0; } | ||||
| function fix_hijri(date/*:Date*/, o/*:[number, number, number]*/) { | ||||
|   /* TODO: properly adjust y/m/d and  */ | ||||
|   o[0] -= 581; | ||||
|   var dow = date.getDay(); | ||||
|   if(date < 60) dow = (dow + 6) % 7; | ||||
|   return dow; | ||||
| } | ||||
| //var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
 | ||||
| /*jshint -W086 */ | ||||
| function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:string*/ { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -239,9 +327,10 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str | ||||
| 			default: throw 'bad abstime format: ' + fmt; | ||||
| 		} outl = fmt.length === 3 ? 1 : 2; break; | ||||
| 		case 101: /* 'e' era */ | ||||
| 			out = y; outl = 1; | ||||
| 			out = y; outl = 1; break; | ||||
| 	} | ||||
| 	if(outl > 0) return pad0(out, outl); else return ""; | ||||
| 	var outstr = outl > 0 ? pad0(out, outl) : ""; | ||||
| 	return outstr; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s/*:string*/)/*:string*/ { | ||||
| @ -312,10 +401,9 @@ function hashq(str/*:string*/)/*:string*/ { | ||||
| } | ||||
| function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function dec(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return Math.round((val-Math.floor(val))*Math.pow(10,d)); | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
| 	return Math.round(_frac * dd); | ||||
| } | ||||
| function carry(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| @ -323,7 +411,10 @@ function carry(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| function flr(val/*:number*/)/*:string*/ { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } | ||||
| function flr(val/*:number*/)/*:string*/ { | ||||
| 	if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); | ||||
| 	return ""+Math.floor(val); | ||||
| } | ||||
| function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/ { | ||||
| 	if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { | ||||
| 		var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); | ||||
| @ -546,7 +637,7 @@ function split_fmt(fmt/*:string*/)/*:Array<string>*/ { | ||||
| 	return out; | ||||
| } | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/; | ||||
| function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| @ -562,9 +653,10 @@ function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| 			case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': | ||||
| 				/* falls through */ | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true; | ||||
| 				++i; break; | ||||
| 			case '[': | ||||
| 				o = c; | ||||
| @ -621,11 +713,12 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else { q.t = "t"; ++i; } | ||||
| 				if(dt==null && q.t === 'T') return ""; | ||||
| 				out[out.length] = q; lst = c; break; | ||||
| @ -650,7 +743,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -661,12 +754,14 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i); | ||||
| 				out[out.length] = {t:'D', v:o}; break; | ||||
| 			case ' ': out[out.length] = {t:c, v:c}; ++i; break; | ||||
| 			case "$": out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			case '$': out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			default: | ||||
| 				if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); | ||||
| 				out[out.length] = {t:'t', v:c}; ++i; break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Scan for date/time parts */ | ||||
| 	var bt = 0, ss0 = 0, ssm; | ||||
| 	for(i=out.length-1, lst='t'; i >= 0; --i) { | ||||
| 		switch(out[i].t) { | ||||
| @ -685,6 +780,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; | ||||
| 		} | ||||
| 	} | ||||
| 	/* time rounding depends on presence of minute / second / usec fields */ | ||||
| 	switch(bt) { | ||||
| 		case 0: break; | ||||
| 		case 1: | ||||
| @ -699,6 +795,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			if(dt.S >=  60) { dt.S = 0; ++dt.M; } | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* replace fields */ | ||||
| 	var nstr = "", jj; | ||||
| 	for(i=0; i < out.length; ++i) { | ||||
| @ -709,7 +806,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				/*::if(!dt) throw "unreachable"; */ | ||||
| 				out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				out[i].t = 't'; break; | ||||
| 			case 'n': case '(': case '?': | ||||
| 			case 'n': case '?': | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| @ -729,7 +826,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 	if(nstr.length > 0) { | ||||
| 		if(nstr.charCodeAt(0) == 40) /* '(' */ { | ||||
| 			myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); | ||||
| 			ostr = write_num('(', nstr, myv); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| 		} else { | ||||
| 			myv = (v<0 && flen > 1 ? -v : v); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| @ -744,7 +841,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 		var lasti=out.length; | ||||
| 		if(decpt === out.length && ostr.indexOf("E") === -1) { | ||||
| 			for(i=out.length-1; i>= 0;--i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } | ||||
| 				else if(jj < 0) out[i].v = ""; | ||||
| 				else { out[i].v = ostr.substr(0, jj+1); jj = -1; } | ||||
| @ -756,7 +853,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 		else if(decpt !== out.length && ostr.indexOf("E") === -1) { | ||||
| 			jj = ostr.indexOf(".")-1; | ||||
| 			for(i=decpt; i>= 0; --i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; | ||||
| 				vv = out[i].v.substr(j+1); | ||||
| 				for(; j>=0; --j) { | ||||
| @ -781,7 +878,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) { | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) { | ||||
| 		myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); | ||||
| 		out[i].v = write_num(out[i].t, out[i].v, myv); | ||||
| 		out[i].t = 't'; | ||||
| @ -838,6 +935,8 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) { | ||||
| 		case "number": | ||||
| 			if(fmt == 14 && o.dateNF) sfmt = o.dateNF; | ||||
| 			else sfmt = (o.table != null ? (o.table/*:any*/) : table_fmt)[fmt]; | ||||
| 			if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]]; | ||||
| 			if(sfmt == null) sfmt = default_str[fmt] || "General"; | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
|  | ||||
| @ -446,6 +446,21 @@ function parse_XLUnicodeRichExtendedString(blob) { | ||||
| 	current_codepage = cp; | ||||
| 	return z; | ||||
| } | ||||
| function write_XLUnicodeRichExtendedString(xlstr/*:: :XLString, opts*/) { | ||||
| 	var str = (xlstr.t||""), nfmts = 1; | ||||
| 
 | ||||
| 	var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0)); | ||||
| 	hdr.write_shift(2, str.length); | ||||
| 	hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01); | ||||
| 	if(nfmts > 1) hdr.write_shift(2, nfmts); | ||||
| 
 | ||||
| 	var otext = new_buf(2 * str.length); | ||||
| 	otext.write_shift(2 * str.length, str, 'utf16le'); | ||||
| 
 | ||||
| 	var out = [hdr, otext]; | ||||
| 
 | ||||
| 	return bconcat(out); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.296 XLUnicodeStringNoCch */ | ||||
| function parse_XLUnicodeStringNoCch(blob, cch, opts) { | ||||
|  | ||||
| @ -266,6 +266,16 @@ function parse_SST(blob, length)/*:SST*/ { | ||||
| 	strs.Count = cnt; strs.Unique = ucnt; | ||||
| 	return strs; | ||||
| } | ||||
| function write_SST(sst, opts) { | ||||
| 	var header = new_buf(8); | ||||
| 	header.write_shift(4, sst.Count); | ||||
| 	header.write_shift(4, sst.Unique); | ||||
| 	var strs = []; | ||||
| 	for(var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts); | ||||
| 	var o = bconcat([header].concat(strs)); | ||||
| 	/*::(*/o/*:: :any)*/.parts = [header.length].concat(strs.map(function(str) { return str.length; })); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.107 */ | ||||
| function parse_ExtSST(blob, length) { | ||||
| @ -403,6 +413,12 @@ function parse_LabelSst(blob) { | ||||
| 	cell.isst = blob.read_shift(4); | ||||
| 	return cell; | ||||
| } | ||||
| function write_LabelSst(R/*:number*/, C/*:number*/, v/*:number*/, os/*:number*/ /*::, opts*/) { | ||||
| 	var o = new_buf(10); | ||||
| 	write_XLSCell(R, C, os, o); | ||||
| 	o.write_shift(4, v); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.148 */ | ||||
| function parse_Label(blob, length, opts) { | ||||
|  | ||||
| @ -8,28 +8,28 @@ function write_biff_rec(ba/*:BufArray*/, type/*:number|string*/, payload, length | ||||
| 	if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload); | ||||
| } | ||||
| 
 | ||||
| //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;
 | ||||
| //	}
 | ||||
| //}
 | ||||
| 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; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) { | ||||
| 	if(!out) out = new_buf(7); | ||||
| @ -182,7 +182,10 @@ function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n | ||||
| 			break; | ||||
| 		/* TODO: codepage, sst */ | ||||
| 		case 's': case 'str': | ||||
| 			write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts)); | ||||
| 			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)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			write_biff_rec(ba, "Blank", write_XLSCell(R, C, os)); | ||||
| @ -311,7 +314,10 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) { | ||||
| 	/* METADATA [MTRSettings] [ForceFullCalculation] */ | ||||
| 	if(b8) write_biff_rec(C, "Country", write_Country()); | ||||
| 	/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */ | ||||
| 
 | ||||
| 	/* BIFF8: [SST *Continue] ExtSST */ | ||||
| 	if(b8 && opts.Strings) write_biff_continue(C, "SST", write_SST(opts.Strings, opts)); | ||||
| 
 | ||||
| 	/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */ | ||||
| 	write_biff_rec(C, "EOF"); | ||||
| 	var c = C.end(); | ||||
|  | ||||
| @ -135,4 +135,4 @@ deployments that use script tags to include the library. | ||||
| 
 | ||||
| ## Additional Notes | ||||
| 
 | ||||
| Some additional notes can be found in [NOTES.md](NOTES.md). | ||||
| Some additional notes can be found in [`NOTES.md`](NOTES.md). | ||||
|  | ||||
							
								
								
									
										1
									
								
								dist/jszip.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								dist/jszip.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -17,6 +17,7 @@ Note: since JSZip 3 removed critical functionality, this version assigns to the | ||||
| 	else if("function"==typeof define&&define.amd&&"undefined"==typeof DO_NOT_EXPORT_JSZIP){JSZipSync=e();define([],e);} | ||||
| 	else{ | ||||
| 		var f; | ||||
| 		"undefined"!=typeof globalThis?f=globalThis: | ||||
| 		"undefined"!=typeof window?f=window: | ||||
| 		"undefined"!=typeof global?f=global: | ||||
| 		"undefined"!=typeof $ && $.global?f=$.global: | ||||
|  | ||||
							
								
								
									
										32
									
								
								dist/xlsx.core.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										32
									
								
								dist/xlsx.core.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										299
									
								
								dist/xlsx.extendscript.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										299
									
								
								dist/xlsx.extendscript.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -174,6 +174,7 @@ Note: since JSZip 3 removed critical functionality, this version assigns to the | ||||
| 	else if("function"==typeof define&&define.amd&&"undefined"==typeof DO_NOT_EXPORT_JSZIP){JSZipSync=e();define([],e);} | ||||
| 	else{ | ||||
| 		var f; | ||||
| 		"undefined"!=typeof globalThis?f=globalThis: | ||||
| 		"undefined"!=typeof window?f=window: | ||||
| 		"undefined"!=typeof global?f=global: | ||||
| 		"undefined"!=typeof $ && $.global?f=$.global: | ||||
| @ -9160,7 +9161,7 @@ module.exports = ZStream; | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.16.2'; | ||||
| XLSX.version = '0.16.3'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| @ -9348,7 +9349,7 @@ var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g; | ||||
| /*jshint -W041 */ | ||||
| var SSF = ({}); | ||||
| var make_ssf = function make_ssf(SSF){ | ||||
| SSF.version = '0.10.3'; | ||||
| SSF.version = '0.11.2'; | ||||
| function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -9412,11 +9413,65 @@ function init_table(t) { | ||||
| 	t[48]= '##0.0E+0'; | ||||
| 	t[49]= '@'; | ||||
| 	t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "'; | ||||
| 	t[65535]= 'General'; | ||||
| } | ||||
| 
 | ||||
| var table_fmt = {}; | ||||
| init_table(table_fmt); | ||||
| /* Defaults determined by systematically testing in Excel 2019 */ | ||||
| 
 | ||||
| /* These formats appear to default to other formats in the table */ | ||||
| var default_map = []; | ||||
| var defi = 0; | ||||
| 
 | ||||
| //  5 -> 37 ...  8 -> 40
 | ||||
| for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi; | ||||
| 
 | ||||
| // 23 ->  0 ... 26 ->  0
 | ||||
| for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0; | ||||
| 
 | ||||
| // 27 -> 14 ... 31 -> 14
 | ||||
| for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14; | ||||
| // 50 -> 14 ... 58 -> 14
 | ||||
| for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14; | ||||
| 
 | ||||
| // 59 ->  1 ... 62 ->  4
 | ||||
| for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58; | ||||
| // 67 ->  9 ... 68 -> 10
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58; | ||||
| // 72 -> 14 ... 75 -> 17
 | ||||
| for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58; | ||||
| 
 | ||||
| // 69 -> 12 ... 71 -> 14
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57; | ||||
| 
 | ||||
| // 76 -> 20 ... 78 -> 22
 | ||||
| for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56; | ||||
| 
 | ||||
| // 79 -> 45 ... 81 -> 47
 | ||||
| for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34; | ||||
| 
 | ||||
| // 82 ->  0 ... 65536 -> 0 (omitted)
 | ||||
| 
 | ||||
| /* These formats technically refer to Accounting formats with no equivalent */ | ||||
| var default_str = []; | ||||
| 
 | ||||
| //  5 -- Currency,   0 decimal, black negative
 | ||||
| default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
| //  6 -- Currency,   0 decimal, red   negative
 | ||||
| default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)'; | ||||
| //  7 -- Currency,   2 decimal, black negative
 | ||||
| default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
| //  8 -- Currency,   2 decimal, red   negative
 | ||||
| default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'; | ||||
| 
 | ||||
| // 41 -- Accounting, 0 decimal, No Symbol
 | ||||
| default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'; | ||||
| // 42 -- Accounting, 0 decimal, $  Symbol
 | ||||
| default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'; | ||||
| // 43 -- Accounting, 2 decimal, No Symbol
 | ||||
| default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'; | ||||
| // 44 -- Accounting, 2 decimal, $  Symbol
 | ||||
| default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'; | ||||
| function frac(x, D, mixed) { | ||||
| 	var sgn = x < 0 ? -1 : 1; | ||||
| 	var B = x * sgn; | ||||
| @ -9477,37 +9532,64 @@ function datenum_local(v, date1904) { | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* The longest 32-bit integer text is "-4294967296", exactly 11 chars */ | ||||
| function general_fmt_int(v) { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 
 | ||||
| /* ECMA-376 18.8.30 numFmt*/ | ||||
| /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */ | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| function gfn2(v) { | ||||
| 	var w = (v<0?12:11); | ||||
| 	var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 	o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 	return v.toExponential(5); | ||||
| } | ||||
| function gfn3(v) { | ||||
| 	var o = v.toFixed(11).replace(gnr1,".$1"); | ||||
| 	if(o.length > (v<0?12:11)) o = v.toPrecision(6); | ||||
| 	return o; | ||||
| } | ||||
| function gfn4(o) { | ||||
| 	for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v) { | ||||
| 	var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 	if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 	else if(Math.abs(V) <= 9) o = gfn2(v); | ||||
| 	else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 	else o = gfn3(v); | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| 	var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/; | ||||
| 	function strip_decimal(o) { | ||||
| 		return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* General Exponential always shows 2 digits exp and trims the mantissa */ | ||||
| 	var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/; | ||||
| 	var exp_with_single_digit = /(E[+-])(\d)$/; | ||||
| 	function normalize_exp(o) { | ||||
| 		if(o.indexOf("E") == -1) return o; | ||||
| 		return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= -9 and <= 9 */ | ||||
| 	function small_exp(v) { | ||||
| 		var w = (v<0?12:11); | ||||
| 		var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 		o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 		return v.toExponential(5); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= 11 or <= -10 likely exponential */ | ||||
| 	function large_exp(v) { | ||||
| 		var o = strip_decimal(v.toFixed(11)); | ||||
| 		return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o; | ||||
| 	} | ||||
| 
 | ||||
| 	function general_fmt_num_base(v) { | ||||
| 		var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 
 | ||||
| 		if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 		else if(Math.abs(V) <= 9) o = small_exp(v); | ||||
| 		else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 		else o = large_exp(v); | ||||
| 
 | ||||
| 		return strip_decimal(normalize_exp(o.toUpperCase())); | ||||
| 	} | ||||
| 
 | ||||
| 	return general_fmt_num_base; | ||||
| })(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| 
 | ||||
| /* | ||||
| 	"General" rules: | ||||
| 	- text is passed through ("@") | ||||
| 	- booleans are rendered as TRUE/FALSE | ||||
| 	- "up to 11 characters" displayed for numbers | ||||
| 	- Default date format (code 14) used for Dates | ||||
| 
 | ||||
| 	TODO: technically the display depends on the width of the cell | ||||
| */ | ||||
| function general_fmt(v, opts) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| @ -9521,7 +9603,14 @@ function general_fmt(v, opts) { | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri() { return 0; } | ||||
| function fix_hijri(date, o) { | ||||
|   /* TODO: properly adjust y/m/d and  */ | ||||
|   o[0] -= 581; | ||||
|   var dow = date.getDay(); | ||||
|   if(date < 60) dow = (dow + 6) % 7; | ||||
|   return dow; | ||||
| } | ||||
| //var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
 | ||||
| /*jshint -W086 */ | ||||
| function write_date(type, fmt, val, ss0) { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -9581,9 +9670,10 @@ if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 			default: throw 'bad abstime format: ' + fmt; | ||||
| 		} outl = fmt.length === 3 ? 1 : 2; break; | ||||
| 		case 101: /* 'e' era */ | ||||
| 			out = y; outl = 1; | ||||
| 			out = y; outl = 1; break; | ||||
| 	} | ||||
| 	if(outl > 0) return pad0(out, outl); else return ""; | ||||
| 	var outstr = outl > 0 ? pad0(out, outl) : ""; | ||||
| 	return outstr; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s) { | ||||
| @ -9654,10 +9744,9 @@ function hashq(str) { | ||||
| } | ||||
| function rnd(val, d) { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function dec(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return Math.round((val-Math.floor(val))*Math.pow(10,d)); | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
| 	return Math.round(_frac * dd); | ||||
| } | ||||
| function carry(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| @ -9665,7 +9754,10 @@ function carry(val, d) { | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| function flr(val) { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } | ||||
| function flr(val) { | ||||
| 	if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); | ||||
| 	return ""+Math.floor(val); | ||||
| } | ||||
| function write_num_flt(type, fmt, val) { | ||||
| 	if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { | ||||
| 		var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); | ||||
| @ -9886,7 +9978,7 @@ function split_fmt(fmt) { | ||||
| 	return out; | ||||
| } | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/; | ||||
| function fmt_is_date(fmt) { | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| @ -9902,9 +9994,10 @@ function fmt_is_date(fmt) { | ||||
| 			case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': | ||||
| 				/* falls through */ | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true; | ||||
| 				++i; break; | ||||
| 			case '[': | ||||
| 				o = c; | ||||
| @ -9961,11 +10054,12 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else { q.t = "t"; ++i; } | ||||
| 				if(dt==null && q.t === 'T') return ""; | ||||
| 				out[out.length] = q; lst = c; break; | ||||
| @ -9990,7 +10084,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -10001,12 +10095,14 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i); | ||||
| 				out[out.length] = {t:'D', v:o}; break; | ||||
| 			case ' ': out[out.length] = {t:c, v:c}; ++i; break; | ||||
| 			case "$": out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			case '$': out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			default: | ||||
| 				if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); | ||||
| 				out[out.length] = {t:'t', v:c}; ++i; break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Scan for date/time parts */ | ||||
| 	var bt = 0, ss0 = 0, ssm; | ||||
| 	for(i=out.length-1, lst='t'; i >= 0; --i) { | ||||
| 		switch(out[i].t) { | ||||
| @ -10025,6 +10121,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; | ||||
| 		} | ||||
| 	} | ||||
| 	/* time rounding depends on presence of minute / second / usec fields */ | ||||
| 	switch(bt) { | ||||
| 		case 0: break; | ||||
| 		case 1: | ||||
| @ -10037,6 +10134,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			if(dt.S >=  60) { dt.S = 0; ++dt.M; } | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* replace fields */ | ||||
| 	var nstr = "", jj; | ||||
| 	for(i=0; i < out.length; ++i) { | ||||
| @ -10046,7 +10144,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z': | ||||
| out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				out[i].t = 't'; break; | ||||
| 			case 'n': case '(': case '?': | ||||
| 			case 'n': case '?': | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| @ -10066,7 +10164,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 	if(nstr.length > 0) { | ||||
| 		if(nstr.charCodeAt(0) == 40) /* '(' */ { | ||||
| 			myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); | ||||
| 			ostr = write_num('(', nstr, myv); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| 		} else { | ||||
| 			myv = (v<0 && flen > 1 ? -v : v); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| @ -10081,7 +10179,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		var lasti=out.length; | ||||
| 		if(decpt === out.length && ostr.indexOf("E") === -1) { | ||||
| 			for(i=out.length-1; i>= 0;--i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } | ||||
| 				else if(jj < 0) out[i].v = ""; | ||||
| 				else { out[i].v = ostr.substr(0, jj+1); jj = -1; } | ||||
| @ -10093,7 +10191,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		else if(decpt !== out.length && ostr.indexOf("E") === -1) { | ||||
| 			jj = ostr.indexOf(".")-1; | ||||
| 			for(i=decpt; i>= 0; --i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; | ||||
| 				vv = out[i].v.substr(j+1); | ||||
| 				for(; j>=0; --j) { | ||||
| @ -10118,7 +10216,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) { | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) { | ||||
| 		myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); | ||||
| 		out[i].v = write_num(out[i].t, out[i].v, myv); | ||||
| 		out[i].t = 't'; | ||||
| @ -10175,6 +10273,8 @@ function format(fmt,v,o) { | ||||
| 		case "number": | ||||
| 			if(fmt == 14 && o.dateNF) sfmt = o.dateNF; | ||||
| 			else sfmt = (o.table != null ? (o.table) : table_fmt)[fmt]; | ||||
| 			if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]]; | ||||
| 			if(sfmt == null) sfmt = default_str[fmt] || "General"; | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| @ -12737,7 +12837,7 @@ function encode_cell(cell) { | ||||
| 	for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s; | ||||
| 	return s + (cell.r + 1); | ||||
| } | ||||
| function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } | ||||
| function decode_range(range) { var x =range.split(":"); return {s:decode_cell(x[0]),e:decode_cell(x[x.length-1])}; } | ||||
| function encode_range(cs,ce) { | ||||
| 	if(typeof ce === 'undefined' || typeof ce === 'number') { | ||||
| return encode_range(cs.s, cs.e); | ||||
| @ -14697,6 +14797,21 @@ function parse_XLUnicodeRichExtendedString(blob) { | ||||
| 	current_codepage = cp; | ||||
| 	return z; | ||||
| } | ||||
| function write_XLUnicodeRichExtendedString(xlstr) { | ||||
| 	var str = (xlstr.t||""), nfmts = 1; | ||||
| 
 | ||||
| 	var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0)); | ||||
| 	hdr.write_shift(2, str.length); | ||||
| 	hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01); | ||||
| 	if(nfmts > 1) hdr.write_shift(2, nfmts); | ||||
| 
 | ||||
| 	var otext = new_buf(2 * str.length); | ||||
| 	otext.write_shift(2 * str.length, str, 'utf16le'); | ||||
| 
 | ||||
| 	var out = [hdr, otext]; | ||||
| 
 | ||||
| 	return bconcat(out); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.296 XLUnicodeStringNoCch */ | ||||
| function parse_XLUnicodeStringNoCch(blob, cch, opts) { | ||||
| @ -15122,6 +15237,16 @@ function parse_SST(blob, length) { | ||||
| 	strs.Count = cnt; strs.Unique = ucnt; | ||||
| 	return strs; | ||||
| } | ||||
| function write_SST(sst, opts) { | ||||
| 	var header = new_buf(8); | ||||
| 	header.write_shift(4, sst.Count); | ||||
| 	header.write_shift(4, sst.Unique); | ||||
| 	var strs = []; | ||||
| 	for(var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts); | ||||
| 	var o = bconcat([header].concat(strs)); | ||||
| o.parts = [header.length].concat(strs.map(function(str) { return str.length; })); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.107 */ | ||||
| function parse_ExtSST(blob, length) { | ||||
| @ -15259,6 +15384,12 @@ function parse_LabelSst(blob) { | ||||
| 	cell.isst = blob.read_shift(4); | ||||
| 	return cell; | ||||
| } | ||||
| function write_LabelSst(R, C, v, os ) { | ||||
| 	var o = new_buf(10); | ||||
| 	write_XLSCell(R, C, os, o); | ||||
| 	o.write_shift(4, v); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.148 */ | ||||
| function parse_Label(blob, length, opts) { | ||||
| @ -15973,6 +16104,7 @@ var dbf_reverse_map = evert({ | ||||
| 0xCA:  1254,           0xCB:  1253, | ||||
| 0x00: 20127 | ||||
| }); | ||||
| var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5]; | ||||
| /* TODO: find an actual specification */ | ||||
| function dbf_to_aoa(buf, opts) { | ||||
| 	var out = []; | ||||
| @ -16225,6 +16357,7 @@ function sheet_to_dbf(ws, opts) { | ||||
| 	return ba.end(); | ||||
| } | ||||
| 	return { | ||||
| 		versions: DBF_SUPPORTED_VERSIONS, | ||||
| 		to_workbook: dbf_to_workbook, | ||||
| 		to_sheet: dbf_to_sheet, | ||||
| 		from_sheet: sheet_to_dbf | ||||
| @ -16730,7 +16863,17 @@ var PRN = (function() { | ||||
| 		var ws = o.dense ? ([]) : ({}); | ||||
| 		var range = ({s: {c:0, r:0}, e: {c:0, r:0}}); | ||||
| 
 | ||||
| 		if(str.slice(0,4) == "sep=" && str.charCodeAt(5) == 10) { sep = str.charAt(4); str = str.slice(6); } | ||||
| 		if(str.slice(0,4) == "sep=") { | ||||
| 			// If the line ends in \r\n
 | ||||
| 			if(str.charCodeAt(5) == 13 && str.charCodeAt(6) == 10 ) { | ||||
| 				sep = str.charAt(4); str = str.slice(7); | ||||
| 			} | ||||
| 			// If line ends in \r OR \n
 | ||||
| 			else if(str.charCodeAt(5) == 13 || str.charCodeAt(5) == 10 ) { | ||||
| 				//
 | ||||
| 				sep = str.charAt(4); str = str.slice(6); | ||||
| 			} | ||||
| 		} | ||||
| 		else sep = guess_sep(str.slice(0,1024)); | ||||
| 		var R = 0, C = 0, v = 0; | ||||
| 		var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0; | ||||
| @ -28075,28 +28218,28 @@ function write_biff_rec(ba, type, payload, length) { | ||||
| 	if(len > 0 && is_buf(payload)) ba.push(payload); | ||||
| } | ||||
| 
 | ||||
| //function write_biff_continue(ba, type, payload, length) {
 | ||||
| //	var len = length || (payload||[]).length || 0;
 | ||||
| //	if(len <= 8224) return write_biff_rec(ba, type, payload, len);
 | ||||
| //	var t = +type || +XLSRE[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;
 | ||||
| //	}
 | ||||
| //}
 | ||||
| function write_biff_continue(ba, type, payload, length) { | ||||
| 	var len = length || (payload||[]).length || 0; | ||||
| 	if(len <= 8224) return write_biff_rec(ba, type, payload, len); | ||||
| 	var t = +type || +XLSRE[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; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function write_BIFF2Cell(out, r, c) { | ||||
| 	if(!out) out = new_buf(7); | ||||
| @ -28248,7 +28391,10 @@ function write_ws_biff8_cell(ba, cell, R, C, opts) { | ||||
| 			break; | ||||
| 		/* TODO: codepage, sst */ | ||||
| 		case 's': case 'str': | ||||
| 			write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts)); | ||||
| 			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)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			write_biff_rec(ba, "Blank", write_XLSCell(R, C, os)); | ||||
| @ -28377,7 +28523,10 @@ function write_biff8_global(wb, bufs, opts) { | ||||
| 	/* METADATA [MTRSettings] [ForceFullCalculation] */ | ||||
| 	if(b8) write_biff_rec(C, "Country", write_Country()); | ||||
| 	/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */ | ||||
| 
 | ||||
| 	/* BIFF8: [SST *Continue] ExtSST */ | ||||
| 	if(b8 && opts.Strings) write_biff_continue(C, "SST", write_SST(opts.Strings, opts)); | ||||
| 
 | ||||
| 	/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */ | ||||
| 	write_biff_rec(C, "EOF"); | ||||
| 	var c = C.end(); | ||||
| @ -29972,7 +30121,7 @@ function readSync(data, opts) { | ||||
| 		case 0x7B: if(n[1] === 0x5C && n[2] === 0x72 && n[3] === 0x74) return RTF.to_workbook(d, o); break; | ||||
| 		case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o); | ||||
| 	} | ||||
| 	if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o); | ||||
| 	if(DBF.versions.indexOf(n[0]) > -1 && n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o); | ||||
| 	return read_prn(data, d, o, str); | ||||
| } | ||||
| 
 | ||||
| @ -30226,7 +30375,7 @@ function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) { | ||||
| 		else if(val.v != null) { | ||||
| 			isempty = false; | ||||
| 			txt = ''+format_cell(val, null, o); | ||||
| 			for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			if(txt == "ID") txt = '"ID"'; | ||||
| 		} else if(val.f != null && !val.F) { | ||||
| 			isempty = false; | ||||
|  | ||||
							
								
								
									
										34
									
								
								dist/xlsx.full.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										34
									
								
								dist/xlsx.full.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										298
									
								
								dist/xlsx.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										298
									
								
								dist/xlsx.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -4,7 +4,7 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.16.2'; | ||||
| XLSX.version = '0.16.3'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| @ -192,7 +192,7 @@ var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g; | ||||
| /*jshint -W041 */ | ||||
| var SSF = ({}); | ||||
| var make_ssf = function make_ssf(SSF){ | ||||
| SSF.version = '0.10.3'; | ||||
| SSF.version = '0.11.2'; | ||||
| function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -256,11 +256,65 @@ function init_table(t) { | ||||
| 	t[48]= '##0.0E+0'; | ||||
| 	t[49]= '@'; | ||||
| 	t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "'; | ||||
| 	t[65535]= 'General'; | ||||
| } | ||||
| 
 | ||||
| var table_fmt = {}; | ||||
| init_table(table_fmt); | ||||
| /* Defaults determined by systematically testing in Excel 2019 */ | ||||
| 
 | ||||
| /* These formats appear to default to other formats in the table */ | ||||
| var default_map = []; | ||||
| var defi = 0; | ||||
| 
 | ||||
| //  5 -> 37 ...  8 -> 40
 | ||||
| for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi; | ||||
| 
 | ||||
| // 23 ->  0 ... 26 ->  0
 | ||||
| for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0; | ||||
| 
 | ||||
| // 27 -> 14 ... 31 -> 14
 | ||||
| for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14; | ||||
| // 50 -> 14 ... 58 -> 14
 | ||||
| for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14; | ||||
| 
 | ||||
| // 59 ->  1 ... 62 ->  4
 | ||||
| for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58; | ||||
| // 67 ->  9 ... 68 -> 10
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58; | ||||
| // 72 -> 14 ... 75 -> 17
 | ||||
| for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58; | ||||
| 
 | ||||
| // 69 -> 12 ... 71 -> 14
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57; | ||||
| 
 | ||||
| // 76 -> 20 ... 78 -> 22
 | ||||
| for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56; | ||||
| 
 | ||||
| // 79 -> 45 ... 81 -> 47
 | ||||
| for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34; | ||||
| 
 | ||||
| // 82 ->  0 ... 65536 -> 0 (omitted)
 | ||||
| 
 | ||||
| /* These formats technically refer to Accounting formats with no equivalent */ | ||||
| var default_str = []; | ||||
| 
 | ||||
| //  5 -- Currency,   0 decimal, black negative
 | ||||
| default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
| //  6 -- Currency,   0 decimal, red   negative
 | ||||
| default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)'; | ||||
| //  7 -- Currency,   2 decimal, black negative
 | ||||
| default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
| //  8 -- Currency,   2 decimal, red   negative
 | ||||
| default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'; | ||||
| 
 | ||||
| // 41 -- Accounting, 0 decimal, No Symbol
 | ||||
| default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'; | ||||
| // 42 -- Accounting, 0 decimal, $  Symbol
 | ||||
| default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'; | ||||
| // 43 -- Accounting, 2 decimal, No Symbol
 | ||||
| default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'; | ||||
| // 44 -- Accounting, 2 decimal, $  Symbol
 | ||||
| default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'; | ||||
| function frac(x, D, mixed) { | ||||
| 	var sgn = x < 0 ? -1 : 1; | ||||
| 	var B = x * sgn; | ||||
| @ -321,37 +375,64 @@ function datenum_local(v, date1904) { | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* The longest 32-bit integer text is "-4294967296", exactly 11 chars */ | ||||
| function general_fmt_int(v) { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 
 | ||||
| /* ECMA-376 18.8.30 numFmt*/ | ||||
| /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */ | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| function gfn2(v) { | ||||
| 	var w = (v<0?12:11); | ||||
| 	var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 	o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 	return v.toExponential(5); | ||||
| } | ||||
| function gfn3(v) { | ||||
| 	var o = v.toFixed(11).replace(gnr1,".$1"); | ||||
| 	if(o.length > (v<0?12:11)) o = v.toPrecision(6); | ||||
| 	return o; | ||||
| } | ||||
| function gfn4(o) { | ||||
| 	for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v) { | ||||
| 	var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 	if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 	else if(Math.abs(V) <= 9) o = gfn2(v); | ||||
| 	else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 	else o = gfn3(v); | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| 	var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/; | ||||
| 	function strip_decimal(o) { | ||||
| 		return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* General Exponential always shows 2 digits exp and trims the mantissa */ | ||||
| 	var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/; | ||||
| 	var exp_with_single_digit = /(E[+-])(\d)$/; | ||||
| 	function normalize_exp(o) { | ||||
| 		if(o.indexOf("E") == -1) return o; | ||||
| 		return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= -9 and <= 9 */ | ||||
| 	function small_exp(v) { | ||||
| 		var w = (v<0?12:11); | ||||
| 		var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 		o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 		return v.toExponential(5); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= 11 or <= -10 likely exponential */ | ||||
| 	function large_exp(v) { | ||||
| 		var o = strip_decimal(v.toFixed(11)); | ||||
| 		return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o; | ||||
| 	} | ||||
| 
 | ||||
| 	function general_fmt_num_base(v) { | ||||
| 		var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 
 | ||||
| 		if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 		else if(Math.abs(V) <= 9) o = small_exp(v); | ||||
| 		else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 		else o = large_exp(v); | ||||
| 
 | ||||
| 		return strip_decimal(normalize_exp(o.toUpperCase())); | ||||
| 	} | ||||
| 
 | ||||
| 	return general_fmt_num_base; | ||||
| })(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| 
 | ||||
| /* | ||||
| 	"General" rules: | ||||
| 	- text is passed through ("@") | ||||
| 	- booleans are rendered as TRUE/FALSE | ||||
| 	- "up to 11 characters" displayed for numbers | ||||
| 	- Default date format (code 14) used for Dates | ||||
| 
 | ||||
| 	TODO: technically the display depends on the width of the cell | ||||
| */ | ||||
| function general_fmt(v, opts) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| @ -365,7 +446,14 @@ function general_fmt(v, opts) { | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri() { return 0; } | ||||
| function fix_hijri(date, o) { | ||||
|   /* TODO: properly adjust y/m/d and  */ | ||||
|   o[0] -= 581; | ||||
|   var dow = date.getDay(); | ||||
|   if(date < 60) dow = (dow + 6) % 7; | ||||
|   return dow; | ||||
| } | ||||
| //var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
 | ||||
| /*jshint -W086 */ | ||||
| function write_date(type, fmt, val, ss0) { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -425,9 +513,10 @@ if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 			default: throw 'bad abstime format: ' + fmt; | ||||
| 		} outl = fmt.length === 3 ? 1 : 2; break; | ||||
| 		case 101: /* 'e' era */ | ||||
| 			out = y; outl = 1; | ||||
| 			out = y; outl = 1; break; | ||||
| 	} | ||||
| 	if(outl > 0) return pad0(out, outl); else return ""; | ||||
| 	var outstr = outl > 0 ? pad0(out, outl) : ""; | ||||
| 	return outstr; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s) { | ||||
| @ -498,10 +587,9 @@ function hashq(str) { | ||||
| } | ||||
| function rnd(val, d) { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function dec(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return Math.round((val-Math.floor(val))*Math.pow(10,d)); | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
| 	return Math.round(_frac * dd); | ||||
| } | ||||
| function carry(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| @ -509,7 +597,10 @@ function carry(val, d) { | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| function flr(val) { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } | ||||
| function flr(val) { | ||||
| 	if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); | ||||
| 	return ""+Math.floor(val); | ||||
| } | ||||
| function write_num_flt(type, fmt, val) { | ||||
| 	if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { | ||||
| 		var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); | ||||
| @ -730,7 +821,7 @@ function split_fmt(fmt) { | ||||
| 	return out; | ||||
| } | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/; | ||||
| function fmt_is_date(fmt) { | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| @ -746,9 +837,10 @@ function fmt_is_date(fmt) { | ||||
| 			case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': | ||||
| 				/* falls through */ | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true; | ||||
| 				++i; break; | ||||
| 			case '[': | ||||
| 				o = c; | ||||
| @ -805,11 +897,12 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else { q.t = "t"; ++i; } | ||||
| 				if(dt==null && q.t === 'T') return ""; | ||||
| 				out[out.length] = q; lst = c; break; | ||||
| @ -834,7 +927,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -845,12 +938,14 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i); | ||||
| 				out[out.length] = {t:'D', v:o}; break; | ||||
| 			case ' ': out[out.length] = {t:c, v:c}; ++i; break; | ||||
| 			case "$": out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			case '$': out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			default: | ||||
| 				if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); | ||||
| 				out[out.length] = {t:'t', v:c}; ++i; break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Scan for date/time parts */ | ||||
| 	var bt = 0, ss0 = 0, ssm; | ||||
| 	for(i=out.length-1, lst='t'; i >= 0; --i) { | ||||
| 		switch(out[i].t) { | ||||
| @ -869,6 +964,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; | ||||
| 		} | ||||
| 	} | ||||
| 	/* time rounding depends on presence of minute / second / usec fields */ | ||||
| 	switch(bt) { | ||||
| 		case 0: break; | ||||
| 		case 1: | ||||
| @ -881,6 +977,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			if(dt.S >=  60) { dt.S = 0; ++dt.M; } | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* replace fields */ | ||||
| 	var nstr = "", jj; | ||||
| 	for(i=0; i < out.length; ++i) { | ||||
| @ -890,7 +987,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z': | ||||
| out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				out[i].t = 't'; break; | ||||
| 			case 'n': case '(': case '?': | ||||
| 			case 'n': case '?': | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| @ -910,7 +1007,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 	if(nstr.length > 0) { | ||||
| 		if(nstr.charCodeAt(0) == 40) /* '(' */ { | ||||
| 			myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); | ||||
| 			ostr = write_num('(', nstr, myv); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| 		} else { | ||||
| 			myv = (v<0 && flen > 1 ? -v : v); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| @ -925,7 +1022,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		var lasti=out.length; | ||||
| 		if(decpt === out.length && ostr.indexOf("E") === -1) { | ||||
| 			for(i=out.length-1; i>= 0;--i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } | ||||
| 				else if(jj < 0) out[i].v = ""; | ||||
| 				else { out[i].v = ostr.substr(0, jj+1); jj = -1; } | ||||
| @ -937,7 +1034,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		else if(decpt !== out.length && ostr.indexOf("E") === -1) { | ||||
| 			jj = ostr.indexOf(".")-1; | ||||
| 			for(i=decpt; i>= 0; --i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; | ||||
| 				vv = out[i].v.substr(j+1); | ||||
| 				for(; j>=0; --j) { | ||||
| @ -962,7 +1059,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) { | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) { | ||||
| 		myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); | ||||
| 		out[i].v = write_num(out[i].t, out[i].v, myv); | ||||
| 		out[i].t = 't'; | ||||
| @ -1019,6 +1116,8 @@ function format(fmt,v,o) { | ||||
| 		case "number": | ||||
| 			if(fmt == 14 && o.dateNF) sfmt = o.dateNF; | ||||
| 			else sfmt = (o.table != null ? (o.table) : table_fmt)[fmt]; | ||||
| 			if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]]; | ||||
| 			if(sfmt == null) sfmt = default_str[fmt] || "General"; | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| @ -3581,7 +3680,7 @@ function encode_cell(cell) { | ||||
| 	for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s; | ||||
| 	return s + (cell.r + 1); | ||||
| } | ||||
| function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } | ||||
| function decode_range(range) { var x =range.split(":"); return {s:decode_cell(x[0]),e:decode_cell(x[x.length-1])}; } | ||||
| function encode_range(cs,ce) { | ||||
| 	if(typeof ce === 'undefined' || typeof ce === 'number') { | ||||
| return encode_range(cs.s, cs.e); | ||||
| @ -5541,6 +5640,21 @@ function parse_XLUnicodeRichExtendedString(blob) { | ||||
| 	current_codepage = cp; | ||||
| 	return z; | ||||
| } | ||||
| function write_XLUnicodeRichExtendedString(xlstr) { | ||||
| 	var str = (xlstr.t||""), nfmts = 1; | ||||
| 
 | ||||
| 	var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0)); | ||||
| 	hdr.write_shift(2, str.length); | ||||
| 	hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01); | ||||
| 	if(nfmts > 1) hdr.write_shift(2, nfmts); | ||||
| 
 | ||||
| 	var otext = new_buf(2 * str.length); | ||||
| 	otext.write_shift(2 * str.length, str, 'utf16le'); | ||||
| 
 | ||||
| 	var out = [hdr, otext]; | ||||
| 
 | ||||
| 	return bconcat(out); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.296 XLUnicodeStringNoCch */ | ||||
| function parse_XLUnicodeStringNoCch(blob, cch, opts) { | ||||
| @ -5966,6 +6080,16 @@ function parse_SST(blob, length) { | ||||
| 	strs.Count = cnt; strs.Unique = ucnt; | ||||
| 	return strs; | ||||
| } | ||||
| function write_SST(sst, opts) { | ||||
| 	var header = new_buf(8); | ||||
| 	header.write_shift(4, sst.Count); | ||||
| 	header.write_shift(4, sst.Unique); | ||||
| 	var strs = []; | ||||
| 	for(var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts); | ||||
| 	var o = bconcat([header].concat(strs)); | ||||
| o.parts = [header.length].concat(strs.map(function(str) { return str.length; })); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.107 */ | ||||
| function parse_ExtSST(blob, length) { | ||||
| @ -6103,6 +6227,12 @@ function parse_LabelSst(blob) { | ||||
| 	cell.isst = blob.read_shift(4); | ||||
| 	return cell; | ||||
| } | ||||
| function write_LabelSst(R, C, v, os ) { | ||||
| 	var o = new_buf(10); | ||||
| 	write_XLSCell(R, C, os, o); | ||||
| 	o.write_shift(4, v); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.148 */ | ||||
| function parse_Label(blob, length, opts) { | ||||
| @ -6817,6 +6947,7 @@ var dbf_reverse_map = evert({ | ||||
| 0xCA:  1254,           0xCB:  1253, | ||||
| 0x00: 20127 | ||||
| }); | ||||
| var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5]; | ||||
| /* TODO: find an actual specification */ | ||||
| function dbf_to_aoa(buf, opts) { | ||||
| 	var out = []; | ||||
| @ -7069,6 +7200,7 @@ function sheet_to_dbf(ws, opts) { | ||||
| 	return ba.end(); | ||||
| } | ||||
| 	return { | ||||
| 		versions: DBF_SUPPORTED_VERSIONS, | ||||
| 		to_workbook: dbf_to_workbook, | ||||
| 		to_sheet: dbf_to_sheet, | ||||
| 		from_sheet: sheet_to_dbf | ||||
| @ -7574,7 +7706,17 @@ var PRN = (function() { | ||||
| 		var ws = o.dense ? ([]) : ({}); | ||||
| 		var range = ({s: {c:0, r:0}, e: {c:0, r:0}}); | ||||
| 
 | ||||
| 		if(str.slice(0,4) == "sep=" && str.charCodeAt(5) == 10) { sep = str.charAt(4); str = str.slice(6); } | ||||
| 		if(str.slice(0,4) == "sep=") { | ||||
| 			// If the line ends in \r\n
 | ||||
| 			if(str.charCodeAt(5) == 13 && str.charCodeAt(6) == 10 ) { | ||||
| 				sep = str.charAt(4); str = str.slice(7); | ||||
| 			} | ||||
| 			// If line ends in \r OR \n
 | ||||
| 			else if(str.charCodeAt(5) == 13 || str.charCodeAt(5) == 10 ) { | ||||
| 				//
 | ||||
| 				sep = str.charAt(4); str = str.slice(6); | ||||
| 			} | ||||
| 		} | ||||
| 		else sep = guess_sep(str.slice(0,1024)); | ||||
| 		var R = 0, C = 0, v = 0; | ||||
| 		var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0; | ||||
| @ -18919,28 +19061,28 @@ function write_biff_rec(ba, type, payload, length) { | ||||
| 	if(len > 0 && is_buf(payload)) ba.push(payload); | ||||
| } | ||||
| 
 | ||||
| //function write_biff_continue(ba, type, payload, length) {
 | ||||
| //	var len = length || (payload||[]).length || 0;
 | ||||
| //	if(len <= 8224) return write_biff_rec(ba, type, payload, len);
 | ||||
| //	var t = +type || +XLSRE[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;
 | ||||
| //	}
 | ||||
| //}
 | ||||
| function write_biff_continue(ba, type, payload, length) { | ||||
| 	var len = length || (payload||[]).length || 0; | ||||
| 	if(len <= 8224) return write_biff_rec(ba, type, payload, len); | ||||
| 	var t = +type || +XLSRE[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; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function write_BIFF2Cell(out, r, c) { | ||||
| 	if(!out) out = new_buf(7); | ||||
| @ -19092,7 +19234,10 @@ function write_ws_biff8_cell(ba, cell, R, C, opts) { | ||||
| 			break; | ||||
| 		/* TODO: codepage, sst */ | ||||
| 		case 's': case 'str': | ||||
| 			write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts)); | ||||
| 			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)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			write_biff_rec(ba, "Blank", write_XLSCell(R, C, os)); | ||||
| @ -19221,7 +19366,10 @@ function write_biff8_global(wb, bufs, opts) { | ||||
| 	/* METADATA [MTRSettings] [ForceFullCalculation] */ | ||||
| 	if(b8) write_biff_rec(C, "Country", write_Country()); | ||||
| 	/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */ | ||||
| 
 | ||||
| 	/* BIFF8: [SST *Continue] ExtSST */ | ||||
| 	if(b8 && opts.Strings) write_biff_continue(C, "SST", write_SST(opts.Strings, opts)); | ||||
| 
 | ||||
| 	/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */ | ||||
| 	write_biff_rec(C, "EOF"); | ||||
| 	var c = C.end(); | ||||
| @ -20816,7 +20964,7 @@ function readSync(data, opts) { | ||||
| 		case 0x7B: if(n[1] === 0x5C && n[2] === 0x72 && n[3] === 0x74) return RTF.to_workbook(d, o); break; | ||||
| 		case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o); | ||||
| 	} | ||||
| 	if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o); | ||||
| 	if(DBF.versions.indexOf(n[0]) > -1 && n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o); | ||||
| 	return read_prn(data, d, o, str); | ||||
| } | ||||
| 
 | ||||
| @ -21070,7 +21218,7 @@ function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) { | ||||
| 		else if(val.v != null) { | ||||
| 			isempty = false; | ||||
| 			txt = ''+format_cell(val, null, o); | ||||
| 			for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			if(txt == "ID") txt = '"ID"'; | ||||
| 		} else if(val.f != null && !val.F) { | ||||
| 			isempty = false; | ||||
|  | ||||
							
								
								
									
										27
									
								
								dist/xlsx.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										27
									
								
								dist/xlsx.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										13
									
								
								dist/xlsx.mini.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										13
									
								
								dist/xlsx.mini.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.mini.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.mini.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -266,17 +266,20 @@ For the example sheet: | ||||
| As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also | ||||
| produces CSV output.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`FS`         |  `","`   | "Field Separator"  delimiter between fields         | | ||||
| |`RS`         |  `"\n"`  | "Record Separator" delimiter between rows           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`strip`      |  false   | Remove trailing field separators in each record **  | | ||||
| |`blankrows`  |  true    | Include blank lines in the CSV output               | | ||||
| |`skipHidden` |  false   | Skips hidden rows/columns in the CSV output         | | ||||
| | Option Name  |  Default | Description                                        | | ||||
| | :----------- | :------: | :------------------------------------------------- | | ||||
| |`FS`          |  `","`   | "Field Separator"  delimiter between fields        | | ||||
| |`RS`          |  `"\n"`  | "Record Separator" delimiter between rows          | | ||||
| |`dateNF`      |  FMT 14  | Use specified date format in string output         | | ||||
| |`strip`       |  false   | Remove trailing field separators in each record ** | | ||||
| |`blankrows`   |  true    | Include blank lines in the CSV output              | | ||||
| |`skipHidden`  |  false   | Skips hidden rows/columns in the CSV output        | | ||||
| |`forceQuotes` |  false   | Force quotes around fields                         | | ||||
| 
 | ||||
| - `strip` will remove trailing commas from each line under default `FS/RS` | ||||
| - `blankrows` must be set to `false` to skip blank lines. | ||||
| - Fields containing the record or field separator will automatically be wrapped | ||||
|   in double quotes; `forceQuotes` forces all cells to be wrapped in quotes. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
|  | ||||
| @ -1569,7 +1569,7 @@ The exported `read` and `readFile` functions accept an options argument: | ||||
|   for files employing other encryption methods. | ||||
| - WTF is mainly for development.  By default, the parser will suppress read | ||||
|   errors on single worksheets, allowing you to read from the worksheets that do | ||||
|   parse properly. Setting `WTF:1` forces those errors to be thrown. | ||||
|   parse properly. Setting `WTF:true` forces those errors to be thrown. | ||||
| 
 | ||||
| ### Input Type | ||||
| 
 | ||||
| @ -1972,17 +1972,20 @@ For the example sheet: | ||||
| As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also | ||||
| produces CSV output.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`FS`         |  `","`   | "Field Separator"  delimiter between fields         | | ||||
| |`RS`         |  `"\n"`  | "Record Separator" delimiter between rows           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`strip`      |  false   | Remove trailing field separators in each record **  | | ||||
| |`blankrows`  |  true    | Include blank lines in the CSV output               | | ||||
| |`skipHidden` |  false   | Skips hidden rows/columns in the CSV output         | | ||||
| | Option Name  |  Default | Description                                        | | ||||
| | :----------- | :------: | :------------------------------------------------- | | ||||
| |`FS`          |  `","`   | "Field Separator"  delimiter between fields        | | ||||
| |`RS`          |  `"\n"`  | "Record Separator" delimiter between rows          | | ||||
| |`dateNF`      |  FMT 14  | Use specified date format in string output         | | ||||
| |`strip`       |  false   | Remove trailing field separators in each record ** | | ||||
| |`blankrows`   |  true    | Include blank lines in the CSV output              | | ||||
| |`skipHidden`  |  false   | Skips hidden rows/columns in the CSV output        | | ||||
| |`forceQuotes` |  false   | Force quotes around fields                         | | ||||
| 
 | ||||
| - `strip` will remove trailing commas from each line under default `FS/RS` | ||||
| - `blankrows` must be set to `false` to skip blank lines. | ||||
| - Fields containing the record or field separator will automatically be wrapped | ||||
|   in double quotes; `forceQuotes` forces all cells to be wrapped in quotes. | ||||
| 
 | ||||
| 
 | ||||
| For the example sheet: | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "xlsx", | ||||
| 	"version": "0.16.2", | ||||
| 	"version": "0.16.3", | ||||
| 	"author": "sheetjs", | ||||
| 	"description": "SheetJS Spreadsheet data parser and writer", | ||||
| 	"keywords": [ | ||||
| @ -38,7 +38,8 @@ | ||||
| 		"commander": "~2.17.1", | ||||
| 		"crc-32": "~1.2.0", | ||||
| 		"exit-on-epipe": "~1.0.1", | ||||
| 		"ssf": "~0.10.3", | ||||
| 		"ssf": "~0.11.2", | ||||
| 		"word": "~0.3.0", | ||||
| 		"wmf": "~1.0.1" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| Subproject commit f1780af21ee98d62278283b4a455a2a4a21b2889 | ||||
| Subproject commit d73d7305f2fb85ef0c88b2a43ea7c496659d0dfa | ||||
							
								
								
									
										2
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -262,7 +262,7 @@ export interface WorkBook { | ||||
| 
 | ||||
| export interface SheetProps { | ||||
|     /** Name of Sheet */ | ||||
|     name: string; | ||||
|     name?: string; | ||||
| 
 | ||||
|     /** Sheet Visibility (0=Visible 1=Hidden 2=VeryHidden) */ | ||||
|     Hidden?: 0 | 1 | 2; | ||||
|  | ||||
							
								
								
									
										280
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										280
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.16.2'; | ||||
| XLSX.version = '0.16.3'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*:: declare var cptable:any; */ | ||||
| /*global cptable:true, window */ | ||||
| @ -213,7 +213,7 @@ type WriteObjStrFactory = {from_sheet(ws:Worksheet, o:any, wb:?Workbook):string} | ||||
| /*jshint -W041 */ | ||||
| var SSF/*:SSFModule*/ = ({}/*:any*/); | ||||
| var make_ssf = function make_ssf(SSF/*:SSFModule*/){ | ||||
| SSF.version = '0.10.3'; | ||||
| SSF.version = '0.11.2'; | ||||
| function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -280,11 +280,65 @@ function init_table(t/*:any*/) { | ||||
| 	t[48]= '##0.0E+0'; | ||||
| 	t[49]= '@'; | ||||
| 	t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "'; | ||||
| 	t[65535]= 'General'; | ||||
| } | ||||
| 
 | ||||
| var table_fmt = {}; | ||||
| init_table(table_fmt); | ||||
| /* Defaults determined by systematically testing in Excel 2019 */ | ||||
| 
 | ||||
| /* These formats appear to default to other formats in the table */ | ||||
| var default_map/*:Array<number>*/ = []; | ||||
| var defi = 0; | ||||
| 
 | ||||
| //  5 -> 37 ...  8 -> 40
 | ||||
| for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi; | ||||
| 
 | ||||
| // 23 ->  0 ... 26 ->  0
 | ||||
| for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0; | ||||
| 
 | ||||
| // 27 -> 14 ... 31 -> 14
 | ||||
| for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14; | ||||
| // 50 -> 14 ... 58 -> 14
 | ||||
| for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14; | ||||
| 
 | ||||
| // 59 ->  1 ... 62 ->  4
 | ||||
| for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58; | ||||
| // 67 ->  9 ... 68 -> 10
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58; | ||||
| // 72 -> 14 ... 75 -> 17
 | ||||
| for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58; | ||||
| 
 | ||||
| // 69 -> 12 ... 71 -> 14
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57; | ||||
| 
 | ||||
| // 76 -> 20 ... 78 -> 22
 | ||||
| for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56; | ||||
| 
 | ||||
| // 79 -> 45 ... 81 -> 47
 | ||||
| for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34; | ||||
| 
 | ||||
| // 82 ->  0 ... 65536 -> 0 (omitted)
 | ||||
| 
 | ||||
| /* These formats technically refer to Accounting formats with no equivalent */ | ||||
| var default_str/*:Array<string>*/ = []; | ||||
| 
 | ||||
| //  5 -- Currency,   0 decimal, black negative
 | ||||
| default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
| //  6 -- Currency,   0 decimal, red   negative
 | ||||
| default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)'; | ||||
| //  7 -- Currency,   2 decimal, black negative
 | ||||
| default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
| //  8 -- Currency,   2 decimal, red   negative
 | ||||
| default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'; | ||||
| 
 | ||||
| // 41 -- Accounting, 0 decimal, No Symbol
 | ||||
| default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'; | ||||
| // 42 -- Accounting, 0 decimal, $  Symbol
 | ||||
| default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'; | ||||
| // 43 -- Accounting, 2 decimal, No Symbol
 | ||||
| default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'; | ||||
| // 44 -- Accounting, 2 decimal, $  Symbol
 | ||||
| default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'; | ||||
| function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ { | ||||
| 	var sgn = x < 0 ? -1 : 1; | ||||
| 	var B = x * sgn; | ||||
| @ -345,37 +399,64 @@ function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ { | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* The longest 32-bit integer text is "-4294967296", exactly 11 chars */ | ||||
| function general_fmt_int(v/*:number*/)/*:string*/ { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 
 | ||||
| /* ECMA-376 18.8.30 numFmt*/ | ||||
| /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */ | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| function gfn2(v) { | ||||
| 	var w = (v<0?12:11); | ||||
| 	var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 	o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 	return v.toExponential(5); | ||||
| } | ||||
| function gfn3(v) { | ||||
| 	var o = v.toFixed(11).replace(gnr1,".$1"); | ||||
| 	if(o.length > (v<0?12:11)) o = v.toPrecision(6); | ||||
| 	return o; | ||||
| } | ||||
| function gfn4(o) { | ||||
| 	for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v/*:number*/)/*:string*/ { | ||||
| 	var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 	if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 	else if(Math.abs(V) <= 9) o = gfn2(v); | ||||
| 	else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 	else o = gfn3(v); | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| 	var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/; | ||||
| 	function strip_decimal(o/*:string*/)/*:string*/ { | ||||
| 		return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* General Exponential always shows 2 digits exp and trims the mantissa */ | ||||
| 	var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/; | ||||
| 	var exp_with_single_digit = /(E[+-])(\d)$/; | ||||
| 	function normalize_exp(o/*:string*/)/*:string*/ { | ||||
| 		if(o.indexOf("E") == -1) return o; | ||||
| 		return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= -9 and <= 9 */ | ||||
| 	function small_exp(v/*:number*/)/*:string*/ { | ||||
| 		var w = (v<0?12:11); | ||||
| 		var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 		o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 		return v.toExponential(5); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= 11 or <= -10 likely exponential */ | ||||
| 	function large_exp(v/*:number*/)/*:string*/ { | ||||
| 		var o = strip_decimal(v.toFixed(11)); | ||||
| 		return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o; | ||||
| 	} | ||||
| 
 | ||||
| 	function general_fmt_num_base(v/*:number*/)/*:string*/ { | ||||
| 		var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 
 | ||||
| 		if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 		else if(Math.abs(V) <= 9) o = small_exp(v); | ||||
| 		else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 		else o = large_exp(v); | ||||
| 
 | ||||
| 		return strip_decimal(normalize_exp(o.toUpperCase())); | ||||
| 	} | ||||
| 
 | ||||
| 	return general_fmt_num_base; | ||||
| })(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| 
 | ||||
| /* | ||||
| 	"General" rules: | ||||
| 	- text is passed through ("@") | ||||
| 	- booleans are rendered as TRUE/FALSE | ||||
| 	- "up to 11 characters" displayed for numbers | ||||
| 	- Default date format (code 14) used for Dates | ||||
| 
 | ||||
| 	TODO: technically the display depends on the width of the cell | ||||
| */ | ||||
| function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| @ -389,7 +470,14 @@ function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri(/*::date, o*/) { return 0; } | ||||
| function fix_hijri(date/*:Date*/, o/*:[number, number, number]*/) { | ||||
|   /* TODO: properly adjust y/m/d and  */ | ||||
|   o[0] -= 581; | ||||
|   var dow = date.getDay(); | ||||
|   if(date < 60) dow = (dow + 6) % 7; | ||||
|   return dow; | ||||
| } | ||||
| //var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
 | ||||
| /*jshint -W086 */ | ||||
| function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:string*/ { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -450,9 +538,10 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str | ||||
| 			default: throw 'bad abstime format: ' + fmt; | ||||
| 		} outl = fmt.length === 3 ? 1 : 2; break; | ||||
| 		case 101: /* 'e' era */ | ||||
| 			out = y; outl = 1; | ||||
| 			out = y; outl = 1; break; | ||||
| 	} | ||||
| 	if(outl > 0) return pad0(out, outl); else return ""; | ||||
| 	var outstr = outl > 0 ? pad0(out, outl) : ""; | ||||
| 	return outstr; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s/*:string*/)/*:string*/ { | ||||
| @ -523,10 +612,9 @@ function hashq(str/*:string*/)/*:string*/ { | ||||
| } | ||||
| function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function dec(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return Math.round((val-Math.floor(val))*Math.pow(10,d)); | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
| 	return Math.round(_frac * dd); | ||||
| } | ||||
| function carry(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| @ -534,7 +622,10 @@ function carry(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| function flr(val/*:number*/)/*:string*/ { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } | ||||
| function flr(val/*:number*/)/*:string*/ { | ||||
| 	if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); | ||||
| 	return ""+Math.floor(val); | ||||
| } | ||||
| function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/ { | ||||
| 	if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { | ||||
| 		var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); | ||||
| @ -757,7 +848,7 @@ function split_fmt(fmt/*:string*/)/*:Array<string>*/ { | ||||
| 	return out; | ||||
| } | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/; | ||||
| function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| @ -773,9 +864,10 @@ function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| 			case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': | ||||
| 				/* falls through */ | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true; | ||||
| 				++i; break; | ||||
| 			case '[': | ||||
| 				o = c; | ||||
| @ -832,11 +924,12 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else { q.t = "t"; ++i; } | ||||
| 				if(dt==null && q.t === 'T') return ""; | ||||
| 				out[out.length] = q; lst = c; break; | ||||
| @ -861,7 +954,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -872,12 +965,14 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i); | ||||
| 				out[out.length] = {t:'D', v:o}; break; | ||||
| 			case ' ': out[out.length] = {t:c, v:c}; ++i; break; | ||||
| 			case "$": out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			case '$': out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			default: | ||||
| 				if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); | ||||
| 				out[out.length] = {t:'t', v:c}; ++i; break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Scan for date/time parts */ | ||||
| 	var bt = 0, ss0 = 0, ssm; | ||||
| 	for(i=out.length-1, lst='t'; i >= 0; --i) { | ||||
| 		switch(out[i].t) { | ||||
| @ -896,6 +991,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; | ||||
| 		} | ||||
| 	} | ||||
| 	/* time rounding depends on presence of minute / second / usec fields */ | ||||
| 	switch(bt) { | ||||
| 		case 0: break; | ||||
| 		case 1: | ||||
| @ -910,6 +1006,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			if(dt.S >=  60) { dt.S = 0; ++dt.M; } | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* replace fields */ | ||||
| 	var nstr = "", jj; | ||||
| 	for(i=0; i < out.length; ++i) { | ||||
| @ -920,7 +1017,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				/*::if(!dt) throw "unreachable"; */ | ||||
| 				out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				out[i].t = 't'; break; | ||||
| 			case 'n': case '(': case '?': | ||||
| 			case 'n': case '?': | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| @ -940,7 +1037,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 	if(nstr.length > 0) { | ||||
| 		if(nstr.charCodeAt(0) == 40) /* '(' */ { | ||||
| 			myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); | ||||
| 			ostr = write_num('(', nstr, myv); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| 		} else { | ||||
| 			myv = (v<0 && flen > 1 ? -v : v); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| @ -955,7 +1052,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 		var lasti=out.length; | ||||
| 		if(decpt === out.length && ostr.indexOf("E") === -1) { | ||||
| 			for(i=out.length-1; i>= 0;--i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } | ||||
| 				else if(jj < 0) out[i].v = ""; | ||||
| 				else { out[i].v = ostr.substr(0, jj+1); jj = -1; } | ||||
| @ -967,7 +1064,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 		else if(decpt !== out.length && ostr.indexOf("E") === -1) { | ||||
| 			jj = ostr.indexOf(".")-1; | ||||
| 			for(i=decpt; i>= 0; --i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; | ||||
| 				vv = out[i].v.substr(j+1); | ||||
| 				for(; j>=0; --j) { | ||||
| @ -992,7 +1089,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) { | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) { | ||||
| 		myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); | ||||
| 		out[i].v = write_num(out[i].t, out[i].v, myv); | ||||
| 		out[i].t = 't'; | ||||
| @ -1049,6 +1146,8 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) { | ||||
| 		case "number": | ||||
| 			if(fmt == 14 && o.dateNF) sfmt = o.dateNF; | ||||
| 			else sfmt = (o.table != null ? (o.table/*:any*/) : table_fmt)[fmt]; | ||||
| 			if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]]; | ||||
| 			if(sfmt == null) sfmt = default_str[fmt] || "General"; | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| @ -3669,7 +3768,7 @@ function encode_cell(cell/*:CellAddress*/)/*:string*/ { | ||||
| 	for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s; | ||||
| 	return s + (cell.r + 1); | ||||
| } | ||||
| function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } | ||||
| function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":"); return {s:decode_cell(x[0]),e:decode_cell(x[x.length-1])}; } | ||||
| /*# if only one arg, it is assumed to be a Range.  If 2 args, both are cell addresses */ | ||||
| function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ { | ||||
| 	if(typeof ce === 'undefined' || typeof ce === 'number') { | ||||
| @ -5638,6 +5737,21 @@ function parse_XLUnicodeRichExtendedString(blob) { | ||||
| 	current_codepage = cp; | ||||
| 	return z; | ||||
| } | ||||
| function write_XLUnicodeRichExtendedString(xlstr/*:: :XLString, opts*/) { | ||||
| 	var str = (xlstr.t||""), nfmts = 1; | ||||
| 
 | ||||
| 	var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0)); | ||||
| 	hdr.write_shift(2, str.length); | ||||
| 	hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01); | ||||
| 	if(nfmts > 1) hdr.write_shift(2, nfmts); | ||||
| 
 | ||||
| 	var otext = new_buf(2 * str.length); | ||||
| 	otext.write_shift(2 * str.length, str, 'utf16le'); | ||||
| 
 | ||||
| 	var out = [hdr, otext]; | ||||
| 
 | ||||
| 	return bconcat(out); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.296 XLUnicodeStringNoCch */ | ||||
| function parse_XLUnicodeStringNoCch(blob, cch, opts) { | ||||
| @ -6063,6 +6177,16 @@ function parse_SST(blob, length)/*:SST*/ { | ||||
| 	strs.Count = cnt; strs.Unique = ucnt; | ||||
| 	return strs; | ||||
| } | ||||
| function write_SST(sst, opts) { | ||||
| 	var header = new_buf(8); | ||||
| 	header.write_shift(4, sst.Count); | ||||
| 	header.write_shift(4, sst.Unique); | ||||
| 	var strs = []; | ||||
| 	for(var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts); | ||||
| 	var o = bconcat([header].concat(strs)); | ||||
| 	/*::(*/o/*:: :any)*/.parts = [header.length].concat(strs.map(function(str) { return str.length; })); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.107 */ | ||||
| function parse_ExtSST(blob, length) { | ||||
| @ -6200,6 +6324,12 @@ function parse_LabelSst(blob) { | ||||
| 	cell.isst = blob.read_shift(4); | ||||
| 	return cell; | ||||
| } | ||||
| function write_LabelSst(R/*:number*/, C/*:number*/, v/*:number*/, os/*:number*/ /*::, opts*/) { | ||||
| 	var o = new_buf(10); | ||||
| 	write_XLSCell(R, C, os, o); | ||||
| 	o.write_shift(4, v); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.148 */ | ||||
| function parse_Label(blob, length, opts) { | ||||
| @ -19048,28 +19178,28 @@ function write_biff_rec(ba/*:BufArray*/, type/*:number|string*/, payload, length | ||||
| 	if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload); | ||||
| } | ||||
| 
 | ||||
| //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;
 | ||||
| //	}
 | ||||
| //}
 | ||||
| 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; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) { | ||||
| 	if(!out) out = new_buf(7); | ||||
| @ -19222,7 +19352,10 @@ function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n | ||||
| 			break; | ||||
| 		/* TODO: codepage, sst */ | ||||
| 		case 's': case 'str': | ||||
| 			write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts)); | ||||
| 			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)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			write_biff_rec(ba, "Blank", write_XLSCell(R, C, os)); | ||||
| @ -19351,7 +19484,10 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) { | ||||
| 	/* METADATA [MTRSettings] [ForceFullCalculation] */ | ||||
| 	if(b8) write_biff_rec(C, "Country", write_Country()); | ||||
| 	/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */ | ||||
| 
 | ||||
| 	/* BIFF8: [SST *Continue] ExtSST */ | ||||
| 	if(b8 && opts.Strings) write_biff_continue(C, "SST", write_SST(opts.Strings, opts)); | ||||
| 
 | ||||
| 	/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */ | ||||
| 	write_biff_rec(C, "EOF"); | ||||
| 	var c = C.end(); | ||||
|  | ||||
							
								
								
									
										280
									
								
								xlsx.js
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										280
									
								
								xlsx.js
									
									
									
										generated
									
									
									
								
							| @ -4,7 +4,7 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.16.2'; | ||||
| XLSX.version = '0.16.3'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| @ -192,7 +192,7 @@ var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g; | ||||
| /*jshint -W041 */ | ||||
| var SSF = ({}); | ||||
| var make_ssf = function make_ssf(SSF){ | ||||
| SSF.version = '0.10.3'; | ||||
| SSF.version = '0.11.2'; | ||||
| function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -256,11 +256,65 @@ function init_table(t) { | ||||
| 	t[48]= '##0.0E+0'; | ||||
| 	t[49]= '@'; | ||||
| 	t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "'; | ||||
| 	t[65535]= 'General'; | ||||
| } | ||||
| 
 | ||||
| var table_fmt = {}; | ||||
| init_table(table_fmt); | ||||
| /* Defaults determined by systematically testing in Excel 2019 */ | ||||
| 
 | ||||
| /* These formats appear to default to other formats in the table */ | ||||
| var default_map = []; | ||||
| var defi = 0; | ||||
| 
 | ||||
| //  5 -> 37 ...  8 -> 40
 | ||||
| for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi; | ||||
| 
 | ||||
| // 23 ->  0 ... 26 ->  0
 | ||||
| for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0; | ||||
| 
 | ||||
| // 27 -> 14 ... 31 -> 14
 | ||||
| for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14; | ||||
| // 50 -> 14 ... 58 -> 14
 | ||||
| for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14; | ||||
| 
 | ||||
| // 59 ->  1 ... 62 ->  4
 | ||||
| for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58; | ||||
| // 67 ->  9 ... 68 -> 10
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58; | ||||
| // 72 -> 14 ... 75 -> 17
 | ||||
| for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58; | ||||
| 
 | ||||
| // 69 -> 12 ... 71 -> 14
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57; | ||||
| 
 | ||||
| // 76 -> 20 ... 78 -> 22
 | ||||
| for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56; | ||||
| 
 | ||||
| // 79 -> 45 ... 81 -> 47
 | ||||
| for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34; | ||||
| 
 | ||||
| // 82 ->  0 ... 65536 -> 0 (omitted)
 | ||||
| 
 | ||||
| /* These formats technically refer to Accounting formats with no equivalent */ | ||||
| var default_str = []; | ||||
| 
 | ||||
| //  5 -- Currency,   0 decimal, black negative
 | ||||
| default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
| //  6 -- Currency,   0 decimal, red   negative
 | ||||
| default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)'; | ||||
| //  7 -- Currency,   2 decimal, black negative
 | ||||
| default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
| //  8 -- Currency,   2 decimal, red   negative
 | ||||
| default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'; | ||||
| 
 | ||||
| // 41 -- Accounting, 0 decimal, No Symbol
 | ||||
| default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'; | ||||
| // 42 -- Accounting, 0 decimal, $  Symbol
 | ||||
| default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'; | ||||
| // 43 -- Accounting, 2 decimal, No Symbol
 | ||||
| default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'; | ||||
| // 44 -- Accounting, 2 decimal, $  Symbol
 | ||||
| default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'; | ||||
| function frac(x, D, mixed) { | ||||
| 	var sgn = x < 0 ? -1 : 1; | ||||
| 	var B = x * sgn; | ||||
| @ -321,37 +375,64 @@ function datenum_local(v, date1904) { | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* The longest 32-bit integer text is "-4294967296", exactly 11 chars */ | ||||
| function general_fmt_int(v) { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 
 | ||||
| /* ECMA-376 18.8.30 numFmt*/ | ||||
| /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */ | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| function gfn2(v) { | ||||
| 	var w = (v<0?12:11); | ||||
| 	var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 	o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 	return v.toExponential(5); | ||||
| } | ||||
| function gfn3(v) { | ||||
| 	var o = v.toFixed(11).replace(gnr1,".$1"); | ||||
| 	if(o.length > (v<0?12:11)) o = v.toPrecision(6); | ||||
| 	return o; | ||||
| } | ||||
| function gfn4(o) { | ||||
| 	for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v) { | ||||
| 	var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 	if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 	else if(Math.abs(V) <= 9) o = gfn2(v); | ||||
| 	else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 	else o = gfn3(v); | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| 	var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/; | ||||
| 	function strip_decimal(o) { | ||||
| 		return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* General Exponential always shows 2 digits exp and trims the mantissa */ | ||||
| 	var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/; | ||||
| 	var exp_with_single_digit = /(E[+-])(\d)$/; | ||||
| 	function normalize_exp(o) { | ||||
| 		if(o.indexOf("E") == -1) return o; | ||||
| 		return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= -9 and <= 9 */ | ||||
| 	function small_exp(v) { | ||||
| 		var w = (v<0?12:11); | ||||
| 		var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 		o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 		return v.toExponential(5); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= 11 or <= -10 likely exponential */ | ||||
| 	function large_exp(v) { | ||||
| 		var o = strip_decimal(v.toFixed(11)); | ||||
| 		return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o; | ||||
| 	} | ||||
| 
 | ||||
| 	function general_fmt_num_base(v) { | ||||
| 		var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 
 | ||||
| 		if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 		else if(Math.abs(V) <= 9) o = small_exp(v); | ||||
| 		else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 		else o = large_exp(v); | ||||
| 
 | ||||
| 		return strip_decimal(normalize_exp(o.toUpperCase())); | ||||
| 	} | ||||
| 
 | ||||
| 	return general_fmt_num_base; | ||||
| })(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| 
 | ||||
| /* | ||||
| 	"General" rules: | ||||
| 	- text is passed through ("@") | ||||
| 	- booleans are rendered as TRUE/FALSE | ||||
| 	- "up to 11 characters" displayed for numbers | ||||
| 	- Default date format (code 14) used for Dates | ||||
| 
 | ||||
| 	TODO: technically the display depends on the width of the cell | ||||
| */ | ||||
| function general_fmt(v, opts) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| @ -365,7 +446,14 @@ function general_fmt(v, opts) { | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri() { return 0; } | ||||
| function fix_hijri(date, o) { | ||||
|   /* TODO: properly adjust y/m/d and  */ | ||||
|   o[0] -= 581; | ||||
|   var dow = date.getDay(); | ||||
|   if(date < 60) dow = (dow + 6) % 7; | ||||
|   return dow; | ||||
| } | ||||
| //var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
 | ||||
| /*jshint -W086 */ | ||||
| function write_date(type, fmt, val, ss0) { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -425,9 +513,10 @@ if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 			default: throw 'bad abstime format: ' + fmt; | ||||
| 		} outl = fmt.length === 3 ? 1 : 2; break; | ||||
| 		case 101: /* 'e' era */ | ||||
| 			out = y; outl = 1; | ||||
| 			out = y; outl = 1; break; | ||||
| 	} | ||||
| 	if(outl > 0) return pad0(out, outl); else return ""; | ||||
| 	var outstr = outl > 0 ? pad0(out, outl) : ""; | ||||
| 	return outstr; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s) { | ||||
| @ -498,10 +587,9 @@ function hashq(str) { | ||||
| } | ||||
| function rnd(val, d) { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function dec(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return Math.round((val-Math.floor(val))*Math.pow(10,d)); | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
| 	return Math.round(_frac * dd); | ||||
| } | ||||
| function carry(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| @ -509,7 +597,10 @@ function carry(val, d) { | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| function flr(val) { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } | ||||
| function flr(val) { | ||||
| 	if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); | ||||
| 	return ""+Math.floor(val); | ||||
| } | ||||
| function write_num_flt(type, fmt, val) { | ||||
| 	if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { | ||||
| 		var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); | ||||
| @ -730,7 +821,7 @@ function split_fmt(fmt) { | ||||
| 	return out; | ||||
| } | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/; | ||||
| function fmt_is_date(fmt) { | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| @ -746,9 +837,10 @@ function fmt_is_date(fmt) { | ||||
| 			case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': | ||||
| 				/* falls through */ | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true; | ||||
| 				++i; break; | ||||
| 			case '[': | ||||
| 				o = c; | ||||
| @ -805,11 +897,12 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else { q.t = "t"; ++i; } | ||||
| 				if(dt==null && q.t === 'T') return ""; | ||||
| 				out[out.length] = q; lst = c; break; | ||||
| @ -834,7 +927,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -845,12 +938,14 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i); | ||||
| 				out[out.length] = {t:'D', v:o}; break; | ||||
| 			case ' ': out[out.length] = {t:c, v:c}; ++i; break; | ||||
| 			case "$": out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			case '$': out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			default: | ||||
| 				if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); | ||||
| 				out[out.length] = {t:'t', v:c}; ++i; break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Scan for date/time parts */ | ||||
| 	var bt = 0, ss0 = 0, ssm; | ||||
| 	for(i=out.length-1, lst='t'; i >= 0; --i) { | ||||
| 		switch(out[i].t) { | ||||
| @ -869,6 +964,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; | ||||
| 		} | ||||
| 	} | ||||
| 	/* time rounding depends on presence of minute / second / usec fields */ | ||||
| 	switch(bt) { | ||||
| 		case 0: break; | ||||
| 		case 1: | ||||
| @ -881,6 +977,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			if(dt.S >=  60) { dt.S = 0; ++dt.M; } | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* replace fields */ | ||||
| 	var nstr = "", jj; | ||||
| 	for(i=0; i < out.length; ++i) { | ||||
| @ -890,7 +987,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z': | ||||
| out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				out[i].t = 't'; break; | ||||
| 			case 'n': case '(': case '?': | ||||
| 			case 'n': case '?': | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| @ -910,7 +1007,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 	if(nstr.length > 0) { | ||||
| 		if(nstr.charCodeAt(0) == 40) /* '(' */ { | ||||
| 			myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); | ||||
| 			ostr = write_num('(', nstr, myv); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| 		} else { | ||||
| 			myv = (v<0 && flen > 1 ? -v : v); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| @ -925,7 +1022,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		var lasti=out.length; | ||||
| 		if(decpt === out.length && ostr.indexOf("E") === -1) { | ||||
| 			for(i=out.length-1; i>= 0;--i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } | ||||
| 				else if(jj < 0) out[i].v = ""; | ||||
| 				else { out[i].v = ostr.substr(0, jj+1); jj = -1; } | ||||
| @ -937,7 +1034,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		else if(decpt !== out.length && ostr.indexOf("E") === -1) { | ||||
| 			jj = ostr.indexOf(".")-1; | ||||
| 			for(i=decpt; i>= 0; --i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; | ||||
| 				vv = out[i].v.substr(j+1); | ||||
| 				for(; j>=0; --j) { | ||||
| @ -962,7 +1059,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) { | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) { | ||||
| 		myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); | ||||
| 		out[i].v = write_num(out[i].t, out[i].v, myv); | ||||
| 		out[i].t = 't'; | ||||
| @ -1019,6 +1116,8 @@ function format(fmt,v,o) { | ||||
| 		case "number": | ||||
| 			if(fmt == 14 && o.dateNF) sfmt = o.dateNF; | ||||
| 			else sfmt = (o.table != null ? (o.table) : table_fmt)[fmt]; | ||||
| 			if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]]; | ||||
| 			if(sfmt == null) sfmt = default_str[fmt] || "General"; | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| @ -3581,7 +3680,7 @@ function encode_cell(cell) { | ||||
| 	for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s; | ||||
| 	return s + (cell.r + 1); | ||||
| } | ||||
| function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } | ||||
| function decode_range(range) { var x =range.split(":"); return {s:decode_cell(x[0]),e:decode_cell(x[x.length-1])}; } | ||||
| function encode_range(cs,ce) { | ||||
| 	if(typeof ce === 'undefined' || typeof ce === 'number') { | ||||
| return encode_range(cs.s, cs.e); | ||||
| @ -5541,6 +5640,21 @@ function parse_XLUnicodeRichExtendedString(blob) { | ||||
| 	current_codepage = cp; | ||||
| 	return z; | ||||
| } | ||||
| function write_XLUnicodeRichExtendedString(xlstr) { | ||||
| 	var str = (xlstr.t||""), nfmts = 1; | ||||
| 
 | ||||
| 	var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0)); | ||||
| 	hdr.write_shift(2, str.length); | ||||
| 	hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01); | ||||
| 	if(nfmts > 1) hdr.write_shift(2, nfmts); | ||||
| 
 | ||||
| 	var otext = new_buf(2 * str.length); | ||||
| 	otext.write_shift(2 * str.length, str, 'utf16le'); | ||||
| 
 | ||||
| 	var out = [hdr, otext]; | ||||
| 
 | ||||
| 	return bconcat(out); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.296 XLUnicodeStringNoCch */ | ||||
| function parse_XLUnicodeStringNoCch(blob, cch, opts) { | ||||
| @ -5966,6 +6080,16 @@ function parse_SST(blob, length) { | ||||
| 	strs.Count = cnt; strs.Unique = ucnt; | ||||
| 	return strs; | ||||
| } | ||||
| function write_SST(sst, opts) { | ||||
| 	var header = new_buf(8); | ||||
| 	header.write_shift(4, sst.Count); | ||||
| 	header.write_shift(4, sst.Unique); | ||||
| 	var strs = []; | ||||
| 	for(var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts); | ||||
| 	var o = bconcat([header].concat(strs)); | ||||
| o.parts = [header.length].concat(strs.map(function(str) { return str.length; })); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.107 */ | ||||
| function parse_ExtSST(blob, length) { | ||||
| @ -6103,6 +6227,12 @@ function parse_LabelSst(blob) { | ||||
| 	cell.isst = blob.read_shift(4); | ||||
| 	return cell; | ||||
| } | ||||
| function write_LabelSst(R, C, v, os ) { | ||||
| 	var o = new_buf(10); | ||||
| 	write_XLSCell(R, C, os, o); | ||||
| 	o.write_shift(4, v); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.148 */ | ||||
| function parse_Label(blob, length, opts) { | ||||
| @ -18931,28 +19061,28 @@ function write_biff_rec(ba, type, payload, length) { | ||||
| 	if(len > 0 && is_buf(payload)) ba.push(payload); | ||||
| } | ||||
| 
 | ||||
| //function write_biff_continue(ba, type, payload, length) {
 | ||||
| //	var len = length || (payload||[]).length || 0;
 | ||||
| //	if(len <= 8224) return write_biff_rec(ba, type, payload, len);
 | ||||
| //	var t = +type || +XLSRE[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;
 | ||||
| //	}
 | ||||
| //}
 | ||||
| function write_biff_continue(ba, type, payload, length) { | ||||
| 	var len = length || (payload||[]).length || 0; | ||||
| 	if(len <= 8224) return write_biff_rec(ba, type, payload, len); | ||||
| 	var t = +type || +XLSRE[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; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function write_BIFF2Cell(out, r, c) { | ||||
| 	if(!out) out = new_buf(7); | ||||
| @ -19104,7 +19234,10 @@ function write_ws_biff8_cell(ba, cell, R, C, opts) { | ||||
| 			break; | ||||
| 		/* TODO: codepage, sst */ | ||||
| 		case 's': case 'str': | ||||
| 			write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts)); | ||||
| 			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)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			write_biff_rec(ba, "Blank", write_XLSCell(R, C, os)); | ||||
| @ -19233,7 +19366,10 @@ function write_biff8_global(wb, bufs, opts) { | ||||
| 	/* METADATA [MTRSettings] [ForceFullCalculation] */ | ||||
| 	if(b8) write_biff_rec(C, "Country", write_Country()); | ||||
| 	/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */ | ||||
| 
 | ||||
| 	/* BIFF8: [SST *Continue] ExtSST */ | ||||
| 	if(b8 && opts.Strings) write_biff_continue(C, "SST", write_SST(opts.Strings, opts)); | ||||
| 
 | ||||
| 	/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */ | ||||
| 	write_biff_rec(C, "EOF"); | ||||
| 	var c = C.end(); | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.16.2'; | ||||
| XLSX.version = '0.16.3'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| 
 | ||||
| var VALID_ANSI = [ 874, 932, 936, 949, 950 ]; | ||||
| @ -191,7 +191,7 @@ type WriteObjStrFactory = {from_sheet(ws:Worksheet, o:any, wb:?Workbook):string} | ||||
| /*jshint -W041 */ | ||||
| var SSF/*:SSFModule*/ = ({}/*:any*/); | ||||
| var make_ssf = function make_ssf(SSF/*:SSFModule*/){ | ||||
| SSF.version = '0.10.3'; | ||||
| SSF.version = '0.11.2'; | ||||
| function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -258,11 +258,65 @@ function init_table(t/*:any*/) { | ||||
| 	t[48]= '##0.0E+0'; | ||||
| 	t[49]= '@'; | ||||
| 	t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "'; | ||||
| 	t[65535]= 'General'; | ||||
| } | ||||
| 
 | ||||
| var table_fmt = {}; | ||||
| init_table(table_fmt); | ||||
| /* Defaults determined by systematically testing in Excel 2019 */ | ||||
| 
 | ||||
| /* These formats appear to default to other formats in the table */ | ||||
| var default_map/*:Array<number>*/ = []; | ||||
| var defi = 0; | ||||
| 
 | ||||
| //  5 -> 37 ...  8 -> 40
 | ||||
| for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi; | ||||
| 
 | ||||
| // 23 ->  0 ... 26 ->  0
 | ||||
| for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0; | ||||
| 
 | ||||
| // 27 -> 14 ... 31 -> 14
 | ||||
| for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14; | ||||
| // 50 -> 14 ... 58 -> 14
 | ||||
| for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14; | ||||
| 
 | ||||
| // 59 ->  1 ... 62 ->  4
 | ||||
| for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58; | ||||
| // 67 ->  9 ... 68 -> 10
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58; | ||||
| // 72 -> 14 ... 75 -> 17
 | ||||
| for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58; | ||||
| 
 | ||||
| // 69 -> 12 ... 71 -> 14
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57; | ||||
| 
 | ||||
| // 76 -> 20 ... 78 -> 22
 | ||||
| for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56; | ||||
| 
 | ||||
| // 79 -> 45 ... 81 -> 47
 | ||||
| for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34; | ||||
| 
 | ||||
| // 82 ->  0 ... 65536 -> 0 (omitted)
 | ||||
| 
 | ||||
| /* These formats technically refer to Accounting formats with no equivalent */ | ||||
| var default_str/*:Array<string>*/ = []; | ||||
| 
 | ||||
| //  5 -- Currency,   0 decimal, black negative
 | ||||
| default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
| //  6 -- Currency,   0 decimal, red   negative
 | ||||
| default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)'; | ||||
| //  7 -- Currency,   2 decimal, black negative
 | ||||
| default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
| //  8 -- Currency,   2 decimal, red   negative
 | ||||
| default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'; | ||||
| 
 | ||||
| // 41 -- Accounting, 0 decimal, No Symbol
 | ||||
| default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'; | ||||
| // 42 -- Accounting, 0 decimal, $  Symbol
 | ||||
| default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'; | ||||
| // 43 -- Accounting, 2 decimal, No Symbol
 | ||||
| default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'; | ||||
| // 44 -- Accounting, 2 decimal, $  Symbol
 | ||||
| default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'; | ||||
| function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ { | ||||
| 	var sgn = x < 0 ? -1 : 1; | ||||
| 	var B = x * sgn; | ||||
| @ -323,37 +377,64 @@ function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ { | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* The longest 32-bit integer text is "-4294967296", exactly 11 chars */ | ||||
| function general_fmt_int(v/*:number*/)/*:string*/ { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 
 | ||||
| /* ECMA-376 18.8.30 numFmt*/ | ||||
| /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */ | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| function gfn2(v) { | ||||
| 	var w = (v<0?12:11); | ||||
| 	var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 	o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 	return v.toExponential(5); | ||||
| } | ||||
| function gfn3(v) { | ||||
| 	var o = v.toFixed(11).replace(gnr1,".$1"); | ||||
| 	if(o.length > (v<0?12:11)) o = v.toPrecision(6); | ||||
| 	return o; | ||||
| } | ||||
| function gfn4(o) { | ||||
| 	for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v/*:number*/)/*:string*/ { | ||||
| 	var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 	if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 	else if(Math.abs(V) <= 9) o = gfn2(v); | ||||
| 	else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 	else o = gfn3(v); | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| 	var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/; | ||||
| 	function strip_decimal(o/*:string*/)/*:string*/ { | ||||
| 		return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* General Exponential always shows 2 digits exp and trims the mantissa */ | ||||
| 	var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/; | ||||
| 	var exp_with_single_digit = /(E[+-])(\d)$/; | ||||
| 	function normalize_exp(o/*:string*/)/*:string*/ { | ||||
| 		if(o.indexOf("E") == -1) return o; | ||||
| 		return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= -9 and <= 9 */ | ||||
| 	function small_exp(v/*:number*/)/*:string*/ { | ||||
| 		var w = (v<0?12:11); | ||||
| 		var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 		o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 		return v.toExponential(5); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= 11 or <= -10 likely exponential */ | ||||
| 	function large_exp(v/*:number*/)/*:string*/ { | ||||
| 		var o = strip_decimal(v.toFixed(11)); | ||||
| 		return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o; | ||||
| 	} | ||||
| 
 | ||||
| 	function general_fmt_num_base(v/*:number*/)/*:string*/ { | ||||
| 		var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 
 | ||||
| 		if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 		else if(Math.abs(V) <= 9) o = small_exp(v); | ||||
| 		else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 		else o = large_exp(v); | ||||
| 
 | ||||
| 		return strip_decimal(normalize_exp(o.toUpperCase())); | ||||
| 	} | ||||
| 
 | ||||
| 	return general_fmt_num_base; | ||||
| })(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| 
 | ||||
| /* | ||||
| 	"General" rules: | ||||
| 	- text is passed through ("@") | ||||
| 	- booleans are rendered as TRUE/FALSE | ||||
| 	- "up to 11 characters" displayed for numbers | ||||
| 	- Default date format (code 14) used for Dates | ||||
| 
 | ||||
| 	TODO: technically the display depends on the width of the cell | ||||
| */ | ||||
| function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| @ -367,7 +448,14 @@ function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri(/*::date, o*/) { return 0; } | ||||
| function fix_hijri(date/*:Date*/, o/*:[number, number, number]*/) { | ||||
|   /* TODO: properly adjust y/m/d and  */ | ||||
|   o[0] -= 581; | ||||
|   var dow = date.getDay(); | ||||
|   if(date < 60) dow = (dow + 6) % 7; | ||||
|   return dow; | ||||
| } | ||||
| //var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
 | ||||
| /*jshint -W086 */ | ||||
| function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:string*/ { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -428,9 +516,10 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str | ||||
| 			default: throw 'bad abstime format: ' + fmt; | ||||
| 		} outl = fmt.length === 3 ? 1 : 2; break; | ||||
| 		case 101: /* 'e' era */ | ||||
| 			out = y; outl = 1; | ||||
| 			out = y; outl = 1; break; | ||||
| 	} | ||||
| 	if(outl > 0) return pad0(out, outl); else return ""; | ||||
| 	var outstr = outl > 0 ? pad0(out, outl) : ""; | ||||
| 	return outstr; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s/*:string*/)/*:string*/ { | ||||
| @ -501,10 +590,9 @@ function hashq(str/*:string*/)/*:string*/ { | ||||
| } | ||||
| function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function dec(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return Math.round((val-Math.floor(val))*Math.pow(10,d)); | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
| 	return Math.round(_frac * dd); | ||||
| } | ||||
| function carry(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| @ -512,7 +600,10 @@ function carry(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| function flr(val/*:number*/)/*:string*/ { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } | ||||
| function flr(val/*:number*/)/*:string*/ { | ||||
| 	if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); | ||||
| 	return ""+Math.floor(val); | ||||
| } | ||||
| function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/ { | ||||
| 	if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { | ||||
| 		var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); | ||||
| @ -735,7 +826,7 @@ function split_fmt(fmt/*:string*/)/*:Array<string>*/ { | ||||
| 	return out; | ||||
| } | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/; | ||||
| function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| @ -751,9 +842,10 @@ function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| 			case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': | ||||
| 				/* falls through */ | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true; | ||||
| 				++i; break; | ||||
| 			case '[': | ||||
| 				o = c; | ||||
| @ -810,11 +902,12 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else { q.t = "t"; ++i; } | ||||
| 				if(dt==null && q.t === 'T') return ""; | ||||
| 				out[out.length] = q; lst = c; break; | ||||
| @ -839,7 +932,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -850,12 +943,14 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i); | ||||
| 				out[out.length] = {t:'D', v:o}; break; | ||||
| 			case ' ': out[out.length] = {t:c, v:c}; ++i; break; | ||||
| 			case "$": out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			case '$': out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			default: | ||||
| 				if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); | ||||
| 				out[out.length] = {t:'t', v:c}; ++i; break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Scan for date/time parts */ | ||||
| 	var bt = 0, ss0 = 0, ssm; | ||||
| 	for(i=out.length-1, lst='t'; i >= 0; --i) { | ||||
| 		switch(out[i].t) { | ||||
| @ -874,6 +969,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; | ||||
| 		} | ||||
| 	} | ||||
| 	/* time rounding depends on presence of minute / second / usec fields */ | ||||
| 	switch(bt) { | ||||
| 		case 0: break; | ||||
| 		case 1: | ||||
| @ -888,6 +984,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			if(dt.S >=  60) { dt.S = 0; ++dt.M; } | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* replace fields */ | ||||
| 	var nstr = "", jj; | ||||
| 	for(i=0; i < out.length; ++i) { | ||||
| @ -898,7 +995,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				/*::if(!dt) throw "unreachable"; */ | ||||
| 				out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				out[i].t = 't'; break; | ||||
| 			case 'n': case '(': case '?': | ||||
| 			case 'n': case '?': | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| @ -918,7 +1015,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 	if(nstr.length > 0) { | ||||
| 		if(nstr.charCodeAt(0) == 40) /* '(' */ { | ||||
| 			myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); | ||||
| 			ostr = write_num('(', nstr, myv); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| 		} else { | ||||
| 			myv = (v<0 && flen > 1 ? -v : v); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| @ -933,7 +1030,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 		var lasti=out.length; | ||||
| 		if(decpt === out.length && ostr.indexOf("E") === -1) { | ||||
| 			for(i=out.length-1; i>= 0;--i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } | ||||
| 				else if(jj < 0) out[i].v = ""; | ||||
| 				else { out[i].v = ostr.substr(0, jj+1); jj = -1; } | ||||
| @ -945,7 +1042,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 		else if(decpt !== out.length && ostr.indexOf("E") === -1) { | ||||
| 			jj = ostr.indexOf(".")-1; | ||||
| 			for(i=decpt; i>= 0; --i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; | ||||
| 				vv = out[i].v.substr(j+1); | ||||
| 				for(; j>=0; --j) { | ||||
| @ -970,7 +1067,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) { | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) { | ||||
| 		myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); | ||||
| 		out[i].v = write_num(out[i].t, out[i].v, myv); | ||||
| 		out[i].t = 't'; | ||||
| @ -1027,6 +1124,8 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) { | ||||
| 		case "number": | ||||
| 			if(fmt == 14 && o.dateNF) sfmt = o.dateNF; | ||||
| 			else sfmt = (o.table != null ? (o.table/*:any*/) : table_fmt)[fmt]; | ||||
| 			if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]]; | ||||
| 			if(sfmt == null) sfmt = default_str[fmt] || "General"; | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| @ -3593,7 +3692,7 @@ function encode_cell(cell/*:CellAddress*/)/*:string*/ { | ||||
| 	for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s; | ||||
| 	return s + (cell.r + 1); | ||||
| } | ||||
| function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } | ||||
| function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":"); return {s:decode_cell(x[0]),e:decode_cell(x[x.length-1])}; } | ||||
| /*# if only one arg, it is assumed to be a Range.  If 2 args, both are cell addresses */ | ||||
| function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ { | ||||
| 	if(typeof ce === 'undefined' || typeof ce === 'number') { | ||||
| @ -4708,6 +4807,7 @@ var dbf_reverse_map = evert({ | ||||
| 	/*::[*/0xCA/*::]*/:  1254,           /*::[*/0xCB/*::]*/:  1253, | ||||
| 	/*::[*/0x00/*::]*/: 20127 | ||||
| }); | ||||
| var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5]; | ||||
| /* TODO: find an actual specification */ | ||||
| function dbf_to_aoa(buf, opts)/*:AOA*/ { | ||||
| 	var out/*:AOA*/ = []; | ||||
| @ -4961,6 +5061,7 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 	return ba.end(); | ||||
| } | ||||
| 	return { | ||||
| 		versions: DBF_SUPPORTED_VERSIONS, | ||||
| 		to_workbook: dbf_to_workbook, | ||||
| 		to_sheet: dbf_to_sheet, | ||||
| 		from_sheet: sheet_to_dbf | ||||
| @ -5466,7 +5567,17 @@ var PRN = (function() { | ||||
| 		var ws/*:Worksheet*/ = o.dense ? ([]/*:any*/) : ({}/*:any*/); | ||||
| 		var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:0}}/*:any*/); | ||||
| 
 | ||||
| 		if(str.slice(0,4) == "sep=" && str.charCodeAt(5) == 10) { sep = str.charAt(4); str = str.slice(6); } | ||||
| 		if(str.slice(0,4) == "sep=") { | ||||
| 			// If the line ends in \r\n
 | ||||
| 			if(str.charCodeAt(5) == 13 && str.charCodeAt(6) == 10 ) { | ||||
| 				sep = str.charAt(4); str = str.slice(7); | ||||
| 			} | ||||
| 			// If line ends in \r OR \n
 | ||||
| 			else if(str.charCodeAt(5) == 13 || str.charCodeAt(5) == 10 ) { | ||||
| 				//
 | ||||
| 				sep = str.charAt(4); str = str.slice(6); | ||||
| 			} | ||||
| 		} | ||||
| 		else sep = guess_sep(str.slice(0,1024)); | ||||
| 		var R = 0, C = 0, v = 0; | ||||
| 		var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0; | ||||
| @ -5518,6 +5629,7 @@ var PRN = (function() { | ||||
| 	} | ||||
| 
 | ||||
| 	function prn_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ { | ||||
| 		if(!(opts && opts.PRN)) return dsv_to_sheet_str(str, opts); | ||||
| 		if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts); | ||||
| 		if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts); | ||||
| 		return aoa_to_sheet(prn_to_aoa_str(str, opts), opts); | ||||
|  | ||||
							
								
								
									
										212
									
								
								xlsx.mini.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										212
									
								
								xlsx.mini.js
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.16.2'; | ||||
| XLSX.version = '0.16.3'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| 
 | ||||
| var VALID_ANSI = [ 874, 932, 936, 949, 950 ]; | ||||
| @ -171,7 +171,7 @@ var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g; | ||||
| /*jshint -W041 */ | ||||
| var SSF = ({}); | ||||
| var make_ssf = function make_ssf(SSF){ | ||||
| SSF.version = '0.10.3'; | ||||
| SSF.version = '0.11.2'; | ||||
| function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -235,11 +235,65 @@ function init_table(t) { | ||||
| 	t[48]= '##0.0E+0'; | ||||
| 	t[49]= '@'; | ||||
| 	t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "'; | ||||
| 	t[65535]= 'General'; | ||||
| } | ||||
| 
 | ||||
| var table_fmt = {}; | ||||
| init_table(table_fmt); | ||||
| /* Defaults determined by systematically testing in Excel 2019 */ | ||||
| 
 | ||||
| /* These formats appear to default to other formats in the table */ | ||||
| var default_map = []; | ||||
| var defi = 0; | ||||
| 
 | ||||
| //  5 -> 37 ...  8 -> 40
 | ||||
| for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi; | ||||
| 
 | ||||
| // 23 ->  0 ... 26 ->  0
 | ||||
| for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0; | ||||
| 
 | ||||
| // 27 -> 14 ... 31 -> 14
 | ||||
| for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14; | ||||
| // 50 -> 14 ... 58 -> 14
 | ||||
| for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14; | ||||
| 
 | ||||
| // 59 ->  1 ... 62 ->  4
 | ||||
| for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58; | ||||
| // 67 ->  9 ... 68 -> 10
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58; | ||||
| // 72 -> 14 ... 75 -> 17
 | ||||
| for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58; | ||||
| 
 | ||||
| // 69 -> 12 ... 71 -> 14
 | ||||
| for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57; | ||||
| 
 | ||||
| // 76 -> 20 ... 78 -> 22
 | ||||
| for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56; | ||||
| 
 | ||||
| // 79 -> 45 ... 81 -> 47
 | ||||
| for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34; | ||||
| 
 | ||||
| // 82 ->  0 ... 65536 -> 0 (omitted)
 | ||||
| 
 | ||||
| /* These formats technically refer to Accounting formats with no equivalent */ | ||||
| var default_str = []; | ||||
| 
 | ||||
| //  5 -- Currency,   0 decimal, black negative
 | ||||
| default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
| //  6 -- Currency,   0 decimal, red   negative
 | ||||
| default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)'; | ||||
| //  7 -- Currency,   2 decimal, black negative
 | ||||
| default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
| //  8 -- Currency,   2 decimal, red   negative
 | ||||
| default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'; | ||||
| 
 | ||||
| // 41 -- Accounting, 0 decimal, No Symbol
 | ||||
| default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'; | ||||
| // 42 -- Accounting, 0 decimal, $  Symbol
 | ||||
| default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'; | ||||
| // 43 -- Accounting, 2 decimal, No Symbol
 | ||||
| default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'; | ||||
| // 44 -- Accounting, 2 decimal, $  Symbol
 | ||||
| default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'; | ||||
| function frac(x, D, mixed) { | ||||
| 	var sgn = x < 0 ? -1 : 1; | ||||
| 	var B = x * sgn; | ||||
| @ -300,37 +354,64 @@ function datenum_local(v, date1904) { | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* The longest 32-bit integer text is "-4294967296", exactly 11 chars */ | ||||
| function general_fmt_int(v) { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 
 | ||||
| /* ECMA-376 18.8.30 numFmt*/ | ||||
| /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */ | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| function gfn2(v) { | ||||
| 	var w = (v<0?12:11); | ||||
| 	var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 	o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 	return v.toExponential(5); | ||||
| } | ||||
| function gfn3(v) { | ||||
| 	var o = v.toFixed(11).replace(gnr1,".$1"); | ||||
| 	if(o.length > (v<0?12:11)) o = v.toPrecision(6); | ||||
| 	return o; | ||||
| } | ||||
| function gfn4(o) { | ||||
| 	for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v) { | ||||
| 	var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 	if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 	else if(Math.abs(V) <= 9) o = gfn2(v); | ||||
| 	else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 	else o = gfn3(v); | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| 	var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/; | ||||
| 	function strip_decimal(o) { | ||||
| 		return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* General Exponential always shows 2 digits exp and trims the mantissa */ | ||||
| 	var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/; | ||||
| 	var exp_with_single_digit = /(E[+-])(\d)$/; | ||||
| 	function normalize_exp(o) { | ||||
| 		if(o.indexOf("E") == -1) return o; | ||||
| 		return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2"); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= -9 and <= 9 */ | ||||
| 	function small_exp(v) { | ||||
| 		var w = (v<0?12:11); | ||||
| 		var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o; | ||||
| 		o = v.toPrecision(10); if(o.length <= w) return o; | ||||
| 		return v.toExponential(5); | ||||
| 	} | ||||
| 
 | ||||
| 	/* exponent >= 11 or <= -10 likely exponential */ | ||||
| 	function large_exp(v) { | ||||
| 		var o = strip_decimal(v.toFixed(11)); | ||||
| 		return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o; | ||||
| 	} | ||||
| 
 | ||||
| 	function general_fmt_num_base(v) { | ||||
| 		var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; | ||||
| 
 | ||||
| 		if(V >= -4 && V <= -1) o = v.toPrecision(10+V); | ||||
| 		else if(Math.abs(V) <= 9) o = small_exp(v); | ||||
| 		else if(V === 10) o = v.toFixed(10).substr(0,12); | ||||
| 		else o = large_exp(v); | ||||
| 
 | ||||
| 		return strip_decimal(normalize_exp(o.toUpperCase())); | ||||
| 	} | ||||
| 
 | ||||
| 	return general_fmt_num_base; | ||||
| })(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| 
 | ||||
| /* | ||||
| 	"General" rules: | ||||
| 	- text is passed through ("@") | ||||
| 	- booleans are rendered as TRUE/FALSE | ||||
| 	- "up to 11 characters" displayed for numbers | ||||
| 	- Default date format (code 14) used for Dates | ||||
| 
 | ||||
| 	TODO: technically the display depends on the width of the cell | ||||
| */ | ||||
| function general_fmt(v, opts) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| @ -344,7 +425,14 @@ function general_fmt(v, opts) { | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri() { return 0; } | ||||
| function fix_hijri(date, o) { | ||||
|   /* TODO: properly adjust y/m/d and  */ | ||||
|   o[0] -= 581; | ||||
|   var dow = date.getDay(); | ||||
|   if(date < 60) dow = (dow + 6) % 7; | ||||
|   return dow; | ||||
| } | ||||
| //var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
 | ||||
| /*jshint -W086 */ | ||||
| function write_date(type, fmt, val, ss0) { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -404,9 +492,10 @@ if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 			default: throw 'bad abstime format: ' + fmt; | ||||
| 		} outl = fmt.length === 3 ? 1 : 2; break; | ||||
| 		case 101: /* 'e' era */ | ||||
| 			out = y; outl = 1; | ||||
| 			out = y; outl = 1; break; | ||||
| 	} | ||||
| 	if(outl > 0) return pad0(out, outl); else return ""; | ||||
| 	var outstr = outl > 0 ? pad0(out, outl) : ""; | ||||
| 	return outstr; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s) { | ||||
| @ -477,10 +566,9 @@ function hashq(str) { | ||||
| } | ||||
| function rnd(val, d) { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function dec(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return Math.round((val-Math.floor(val))*Math.pow(10,d)); | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
| 	return Math.round(_frac * dd); | ||||
| } | ||||
| function carry(val, d) { | ||||
| 	if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) { | ||||
| @ -488,7 +576,10 @@ function carry(val, d) { | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| function flr(val) { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } | ||||
| function flr(val) { | ||||
| 	if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); | ||||
| 	return ""+Math.floor(val); | ||||
| } | ||||
| function write_num_flt(type, fmt, val) { | ||||
| 	if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { | ||||
| 		var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); | ||||
| @ -709,7 +800,7 @@ function split_fmt(fmt) { | ||||
| 	return out; | ||||
| } | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/; | ||||
| function fmt_is_date(fmt) { | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| @ -725,9 +816,10 @@ function fmt_is_date(fmt) { | ||||
| 			case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': | ||||
| 				/* falls through */ | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true; | ||||
| 				if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true; | ||||
| 				++i; break; | ||||
| 			case '[': | ||||
| 				o = c; | ||||
| @ -784,11 +876,12 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 			case 'A': case 'a': case '上': | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; } | ||||
| 				else { q.t = "t"; ++i; } | ||||
| 				if(dt==null && q.t === 'T') return ""; | ||||
| 				out[out.length] = q; lst = c; break; | ||||
| @ -813,7 +906,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -824,12 +917,14 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i); | ||||
| 				out[out.length] = {t:'D', v:o}; break; | ||||
| 			case ' ': out[out.length] = {t:c, v:c}; ++i; break; | ||||
| 			case "$": out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			case '$': out[out.length] = {t:'t', v:'$'}; ++i; break; | ||||
| 			default: | ||||
| 				if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); | ||||
| 				out[out.length] = {t:'t', v:c}; ++i; break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Scan for date/time parts */ | ||||
| 	var bt = 0, ss0 = 0, ssm; | ||||
| 	for(i=out.length-1, lst='t'; i >= 0; --i) { | ||||
| 		switch(out[i].t) { | ||||
| @ -848,6 +943,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; | ||||
| 		} | ||||
| 	} | ||||
| 	/* time rounding depends on presence of minute / second / usec fields */ | ||||
| 	switch(bt) { | ||||
| 		case 0: break; | ||||
| 		case 1: | ||||
| @ -860,6 +956,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			if(dt.S >=  60) { dt.S = 0; ++dt.M; } | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* replace fields */ | ||||
| 	var nstr = "", jj; | ||||
| 	for(i=0; i < out.length; ++i) { | ||||
| @ -869,7 +966,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } | ||||
| 			case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z': | ||||
| out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				out[i].t = 't'; break; | ||||
| 			case 'n': case '(': case '?': | ||||
| 			case 'n': case '?': | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| @ -889,7 +986,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 	if(nstr.length > 0) { | ||||
| 		if(nstr.charCodeAt(0) == 40) /* '(' */ { | ||||
| 			myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); | ||||
| 			ostr = write_num('(', nstr, myv); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| 		} else { | ||||
| 			myv = (v<0 && flen > 1 ? -v : v); | ||||
| 			ostr = write_num('n', nstr, myv); | ||||
| @ -904,7 +1001,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		var lasti=out.length; | ||||
| 		if(decpt === out.length && ostr.indexOf("E") === -1) { | ||||
| 			for(i=out.length-1; i>= 0;--i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } | ||||
| 				else if(jj < 0) out[i].v = ""; | ||||
| 				else { out[i].v = ostr.substr(0, jj+1); jj = -1; } | ||||
| @ -916,7 +1013,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 		else if(decpt !== out.length && ostr.indexOf("E") === -1) { | ||||
| 			jj = ostr.indexOf(".")-1; | ||||
| 			for(i=decpt; i>= 0; --i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; | ||||
| 				if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; | ||||
| 				vv = out[i].v.substr(j+1); | ||||
| 				for(; j>=0; --j) { | ||||
| @ -941,7 +1038,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) { | ||||
| 	for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) { | ||||
| 		myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); | ||||
| 		out[i].v = write_num(out[i].t, out[i].v, myv); | ||||
| 		out[i].t = 't'; | ||||
| @ -998,6 +1095,8 @@ function format(fmt,v,o) { | ||||
| 		case "number": | ||||
| 			if(fmt == 14 && o.dateNF) sfmt = o.dateNF; | ||||
| 			else sfmt = (o.table != null ? (o.table) : table_fmt)[fmt]; | ||||
| 			if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]]; | ||||
| 			if(sfmt == null) sfmt = default_str[fmt] || "General"; | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| @ -3508,7 +3607,7 @@ function encode_cell(cell) { | ||||
| 	for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s; | ||||
| 	return s + (cell.r + 1); | ||||
| } | ||||
| function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } | ||||
| function decode_range(range) { var x =range.split(":"); return {s:decode_cell(x[0]),e:decode_cell(x[x.length-1])}; } | ||||
| function encode_range(cs,ce) { | ||||
| 	if(typeof ce === 'undefined' || typeof ce === 'number') { | ||||
| return encode_range(cs.s, cs.e); | ||||
| @ -4618,6 +4717,7 @@ var dbf_reverse_map = evert({ | ||||
| 0xCA:  1254,           0xCB:  1253, | ||||
| 0x00: 20127 | ||||
| }); | ||||
| var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5]; | ||||
| /* TODO: find an actual specification */ | ||||
| function dbf_to_aoa(buf, opts) { | ||||
| 	var out = []; | ||||
| @ -4870,6 +4970,7 @@ function sheet_to_dbf(ws, opts) { | ||||
| 	return ba.end(); | ||||
| } | ||||
| 	return { | ||||
| 		versions: DBF_SUPPORTED_VERSIONS, | ||||
| 		to_workbook: dbf_to_workbook, | ||||
| 		to_sheet: dbf_to_sheet, | ||||
| 		from_sheet: sheet_to_dbf | ||||
| @ -5375,7 +5476,17 @@ var PRN = (function() { | ||||
| 		var ws = o.dense ? ([]) : ({}); | ||||
| 		var range = ({s: {c:0, r:0}, e: {c:0, r:0}}); | ||||
| 
 | ||||
| 		if(str.slice(0,4) == "sep=" && str.charCodeAt(5) == 10) { sep = str.charAt(4); str = str.slice(6); } | ||||
| 		if(str.slice(0,4) == "sep=") { | ||||
| 			// If the line ends in \r\n
 | ||||
| 			if(str.charCodeAt(5) == 13 && str.charCodeAt(6) == 10 ) { | ||||
| 				sep = str.charAt(4); str = str.slice(7); | ||||
| 			} | ||||
| 			// If line ends in \r OR \n
 | ||||
| 			else if(str.charCodeAt(5) == 13 || str.charCodeAt(5) == 10 ) { | ||||
| 				//
 | ||||
| 				sep = str.charAt(4); str = str.slice(6); | ||||
| 			} | ||||
| 		} | ||||
| 		else sep = guess_sep(str.slice(0,1024)); | ||||
| 		var R = 0, C = 0, v = 0; | ||||
| 		var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0; | ||||
| @ -5427,6 +5538,7 @@ var PRN = (function() { | ||||
| 	} | ||||
| 
 | ||||
| 	function prn_to_sheet_str(str, opts) { | ||||
| 		if(!(opts && opts.PRN)) return dsv_to_sheet_str(str, opts); | ||||
| 		if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts); | ||||
| 		if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts); | ||||
| 		return aoa_to_sheet(prn_to_aoa_str(str, opts), opts); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user