forked from sheetjs/sheetjs
		
	version bump 0.10.1: json_to_sheet, misc fmts
- SYLK auto fail into DSV on bad header (fixes #651 h/t @mmancosu) - CSV automatically wrap `ID` in quotes - json_to_sheet (see issue #610)
This commit is contained in:
		
							parent
							
								
									7b4bafba49
								
							
						
					
					
						commit
						c3c0bc5266
					
				
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
								
							| @ -98,6 +98,7 @@ enhancements, additional features by request, and dedicated support. | ||||
|   * [Output Type](#output-type) | ||||
| - [Utility Functions](#utility-functions) | ||||
|   * [Array of Arrays Input](#array-of-arrays-input) | ||||
|   * [Array of Objects Input](#array-of-objects-input) | ||||
|   * [HTML Table Input](#html-table-input) | ||||
|   * [Formulae Output](#formulae-output) | ||||
|   * [Delimiter-Separated Output](#delimiter-separated-output) | ||||
| @ -553,6 +554,7 @@ Utilities are available in the `XLSX.utils` object: | ||||
| **Importing:** | ||||
| 
 | ||||
| - `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. | ||||
| - `json_to_sheet` converts an array of JS objects to a worksheet. | ||||
| 
 | ||||
| **Exporting:** | ||||
| 
 | ||||
| @ -560,7 +562,7 @@ Utilities are available in the `XLSX.utils` object: | ||||
| - `sheet_to_csv` generates delimiter-separated-values output. | ||||
| - `sheet_to_formulae` generates a list of the formulae (with value fallbacks). | ||||
| 
 | ||||
| Exporters are described in the [Utility Functions](#utility-functions) section. | ||||
| These utilities are described in [Utility Functions](#utility-functions) below. | ||||
| 
 | ||||
| 
 | ||||
| **Cell and cell address manipulation:** | ||||
| @ -1394,6 +1396,25 @@ var ws = XLSX.utils.aoa_to_sheet([ | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### Array of Objects Input | ||||
| 
 | ||||
| `XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet | ||||
| with automatically-generated "headers" based on the keys of the objects. | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| The original sheet cannot be reproduced because JS object keys must be unique. | ||||
| After replacing the second `e` and `S` with `e_1` and `S_1`: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.json_to_sheet([ | ||||
| 	{S:1,h:2,e:3,e_1:4,t:5,J:6,S_1:7}, | ||||
| 	{S:2,h:3,e:4,e_1:5,t:6,J:7,S_1:8} | ||||
| ]); | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### HTML Table Input | ||||
| 
 | ||||
| `XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| XLSX.version = '0.10.0'; | ||||
| XLSX.version = '0.10.1'; | ||||
|  | ||||
| @ -599,3 +599,17 @@ var PRN = (function() { | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| /* Excel defaults to SYLK but warns if data is not valid */ | ||||
| function read_wb_ID(d, opts) { | ||||
| 	var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true; | ||||
| 	try { | ||||
| 		var out = SYLK.to_workbook(d, o); | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		return out; | ||||
| 	} catch(e) { | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		if(!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e; | ||||
| 		return PRN.to_workbook(d, opts); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -49,7 +49,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| 		case 0xD0: return read_cfb(CFB.read(d, o), o); | ||||
| 		case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o); | ||||
| 		case 0x3C: return parse_xlml(d, o); | ||||
| 		case 0x49: if(n[1] == 0x44) return SYLK.to_workbook(d, o); break; | ||||
| 		case 0x49: if(n[1] == 0x44) return read_wb_ID(d, o); break; | ||||
| 		case 0x54: if(n[1] == 0x41 && n[2] == 0x42 && n[3] == 0x4C) return DIF.to_workbook(d, o); break; | ||||
| 		case 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break; | ||||
| 		case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o); | ||||
|  | ||||
| @ -88,8 +88,8 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr | ||||
| 		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) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			if(txt == "ID") txt = '"ID"'; | ||||
| 		} else if(val.f != null && !val.F) { | ||||
| 			isempty = false; | ||||
| 			txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"'; | ||||
| @ -166,6 +166,30 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ { | ||||
| 	return cmds; | ||||
| } | ||||
| 
 | ||||
| function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ { | ||||
| 	var o = opts || {}; | ||||
| 	var ws = ({}/*:any*/); | ||||
| 	var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:js.length}}/*:any*/); | ||||
| 	var hdr = o.header || [], C = 0; | ||||
| 
 | ||||
| 	for(var R = 0; R != js.length; ++R) { | ||||
| 		Object.keys(js[R]).filter(function(x) { return js[R].hasOwnProperty(x); }).forEach(function(k) { | ||||
| 			if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k; | ||||
| 			var v = js[R][k]; | ||||
| 			var t = 'z'; | ||||
| 			if(typeof v == 'number') t = 'n'; | ||||
| 			else if(typeof v == 'boolean') t = 'b'; | ||||
| 			else if(typeof v == 'string') t = 's'; | ||||
| 			else if(v instanceof Date) t = 'd'; | ||||
| 			ws[encode_cell({c:C,r:R+1})] = {t:t, v:v}; | ||||
| 		}); | ||||
| 	} | ||||
| 	range.e.c = hdr.length - 1; | ||||
| 	for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]}; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| var utils = { | ||||
| 	encode_col: encode_col, | ||||
| 	encode_row: encode_row, | ||||
| @ -182,6 +206,7 @@ var utils = { | ||||
| 	make_json: sheet_to_json, | ||||
| 	make_formulae: sheet_to_formulae, | ||||
| 	aoa_to_sheet: aoa_to_sheet, | ||||
| 	json_to_sheet: json_to_sheet, | ||||
| 	table_to_sheet: parse_dom_table, | ||||
| 	table_to_book: table_to_book, | ||||
| 	sheet_to_csv: sheet_to_csv, | ||||
|  | ||||
| @ -92,11 +92,11 @@ utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:stri | ||||
| 		var cell = ws_get_cell_stub(ws, R, C); | ||||
| 		cell.t = 'n'; | ||||
| 		cell.F = rngstr; | ||||
| 		delete cell.v;  | ||||
| 		delete cell.v; | ||||
| 		if(R == rng.s.r && C == rng.s.c) cell.f = formula; | ||||
| 	} | ||||
| 	return ws; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| return utils; | ||||
| })(utils); | ||||
|  | ||||
							
								
								
									
										29
									
								
								dist/xlsx.core.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										29
									
								
								dist/xlsx.core.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										30
									
								
								dist/xlsx.full.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										30
									
								
								dist/xlsx.full.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										404
									
								
								dist/xlsx.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										404
									
								
								dist/xlsx.js
									
									
									
									
										vendored
									
									
								
							| @ -6,7 +6,7 @@ | ||||
| /*global exports, module, require:false, process:false, Buffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.10.0'; | ||||
| XLSX.version = '0.10.1'; | ||||
| var current_codepage = 1200; | ||||
| /*global cptable:true */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| @ -198,7 +198,7 @@ function frac(x, D, mixed) { | ||||
| 	var q = Math.floor(sgn * P/Q); | ||||
| 	return [q, sgn*P - q*Q, Q]; | ||||
| } | ||||
| function general_fmt_int(v, opts) { return ""+v; } | ||||
| function general_fmt_int(v) { return ""+v; } | ||||
| SSF._general_int = general_fmt_int; | ||||
| 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)$/; | ||||
| @ -218,11 +218,9 @@ function gfn4(o) { | ||||
| 	return o; | ||||
| } | ||||
| function gfn5(o) { | ||||
| 	//for(var i = 0; i != o.length; ++i) if(o.charCodeAt(i) === 46) return o.replace(gnr2,"").replace(gnr1,".$1");
 | ||||
| 	//return o;
 | ||||
| 	return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; | ||||
| } | ||||
| return function general_fmt_num(v, opts) { | ||||
| 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); | ||||
| @ -231,18 +229,18 @@ return function general_fmt_num(v, opts) { | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| function general_fmt(v, opts) { | ||||
| function general_fmt(v) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| 		case 'boolean': return v ? "TRUE" : "FALSE"; | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v, opts) : general_fmt_num(v, opts); | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v/*, opts*/) : general_fmt_num(v/*, opts*/); | ||||
| 		case 'undefined': return ""; | ||||
| 		case 'object': if(v == null) return ""; | ||||
| 	} | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri(date, o) { return 0; } | ||||
| function fix_hijri(/*date, o*/) { return 0; } | ||||
| function parse_date_code(v,opts,b2) { | ||||
| 	if(v > 2958465 || v < 0) return null; | ||||
| 	var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; | ||||
| @ -620,8 +618,7 @@ return "." + $1 + fill("0", r[1].length-$1.length); }); | ||||
| 		case "##,###": | ||||
| 		case "#,###": var x = commaify(""+aval); return x !== "0" ? sign + x : ""; | ||||
| 		default: | ||||
| 			if(fmt.slice(-3) == ".00") return write_num_int(type, fmt.slice(0,-3), val) + ".00"; | ||||
| 			if(fmt.slice(-2) == ".0") return write_num_int(type, fmt.slice(0,-2), val) + ".0"; | ||||
| 			if(fmt.match(/\.[0#?]*$/)) return write_num_int(type, fmt.slice(0,fmt.lastIndexOf(".")), val) + hashq(fmt.slice(fmt.lastIndexOf("."))); | ||||
| 	} | ||||
| 	throw new Error("unsupported format |" + fmt + "|"); | ||||
| } | ||||
| @ -630,8 +627,8 @@ return function write_num(type, fmt, val) { | ||||
| };})(); | ||||
| function split_fmt(fmt) { | ||||
| 	var out = []; | ||||
| 	var in_str = false, cc; | ||||
| 	for(var i = 0, j = 0; i < fmt.length; ++i) switch((cc=fmt.charCodeAt(i))) { | ||||
| 	var in_str = false/*, cc*/; | ||||
| 	for(var i = 0, j = 0; i < fmt.length; ++i) switch((/*cc=*/fmt.charCodeAt(i))) { | ||||
| 		case 34: /* '"' */ | ||||
| 			in_str = !in_str; break; | ||||
| 		case 95: case 42: case 92: /* '_' '*' '\\' */ | ||||
| @ -647,11 +644,11 @@ function split_fmt(fmt) { | ||||
| SSF._split = split_fmt; | ||||
| var abstime = /\[[HhMmSs]*\]/; | ||||
| function fmt_is_date(fmt) { | ||||
| 	var i = 0, cc = 0, c = "", o = ""; | ||||
| 	var i = 0, /*cc = 0,*/ c = "", o = ""; | ||||
| 	while(i < fmt.length) { | ||||
| 		switch((c = fmt.charAt(i))) { | ||||
| 			case 'G': if(isgeneral(fmt, i)) i+= 6; i++; break; | ||||
| 			case '"': for(;(cc=fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) ++i; ++i; break; | ||||
| 			case '"': for(;(/*cc=*/fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) ++i; ++i; break; | ||||
| 			case '\\': i+=2; break; | ||||
| 			case '_': i+=2; break; | ||||
| 			case '@': ++i; break; | ||||
| @ -673,13 +670,13 @@ function fmt_is_date(fmt) { | ||||
| 			case '.': | ||||
| 				/* falls through */ | ||||
| 			case '0': case '#': | ||||
| 				while(i < fmt.length && ("0#?.,E+-%".indexOf(c=fmt.charAt(++i)) > -1 || c=='\\' && fmt.charAt(i+1) == "-" && "0#".indexOf(fmt.charAt(i+2))>-1)){} | ||||
| 				while(i < fmt.length && ("0#?.,E+-%".indexOf(c=fmt.charAt(++i)) > -1 || (c=='\\' && fmt.charAt(i+1) == "-" && "0#".indexOf(fmt.charAt(i+2))>-1))){/* empty */} | ||||
| 				break; | ||||
| 			case '?': while(fmt.charAt(++i) === c){} break; | ||||
| 			case '?': while(fmt.charAt(++i) === c){/* empty */} break; | ||||
| 			case '*': ++i; if(fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i; break; | ||||
| 			case '(': case ')': ++i; break; | ||||
| 			case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': | ||||
| 				while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1){} break; | ||||
| 				while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1){/* empty */} break; | ||||
| 			case ' ': ++i; break; | ||||
| 			default: ++i; break; | ||||
| 		} | ||||
| @ -749,7 +746,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) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| @ -808,9 +805,9 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 				jj = i+1; | ||||
| 				while(out[jj] != null && ( | ||||
| 					(c=out[jj].t) === "?" || c === "D" || | ||||
| 					(c === " " || c === "t") && out[jj+1] != null && (out[jj+1].t === '?' || out[jj+1].t === "t" && out[jj+1].v === '/') || | ||||
| 					out[i].t === '(' && (c === ' ' || c === 'n' || c === ')') || | ||||
| 					c === 't' && (out[jj].v === '/' || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?') | ||||
| 					((c === " " || c === "t") && out[jj+1] != null && (out[jj+1].t === '?' || out[jj+1].t === "t" && out[jj+1].v === '/')) || | ||||
| 					(out[i].t === '(' && (c === ' ' || c === 'n' || c === ')')) || | ||||
| 					(c === 't' && (out[jj].v === '/' || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?')) | ||||
| 				)) { | ||||
| 					out[i].v += out[jj].v; | ||||
| 					out[jj] = {v:"", t:";"}; ++jj; | ||||
| @ -864,7 +861,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); | ||||
| 			if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v; | ||||
| 			jj = ostr.indexOf(".")+1; | ||||
| 			for(i=decpt; i<out.length; ++i) { | ||||
| 				if(out[i] == null || 'n?('.indexOf(out[i].t) === -1 && i !== decpt ) continue; | ||||
| 				if(out[i] == null || ('n?('.indexOf(out[i].t) === -1 && i !== decpt)) continue; | ||||
| 				j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")+1:0; | ||||
| 				vv = out[i].v.substr(0,j); | ||||
| 				for(; j<out[i].v.length; ++j) { | ||||
| @ -1463,6 +1460,19 @@ function dup(o) { | ||||
| } | ||||
| 
 | ||||
| function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| 
 | ||||
| /* TODO: stress test */ | ||||
| function fuzzydate(s) { | ||||
| 	var o = new Date(s), n = new Date(NaN); | ||||
| 	var y = o.getYear(), m = o.getMonth(), d = o.getDate(); | ||||
| 	if(isNaN(d)) return n; | ||||
| 	if(y < 0 || y > 8099) return n; | ||||
| 	if((m > 0 || d > 1) && y != 101) return o; | ||||
| 	if(s.toLowerCase().match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) return o; | ||||
| 	if(!s.match(/[a-zA-Z]/)) return o; | ||||
| 	return n; | ||||
| } | ||||
| 
 | ||||
| function getdatastr(data) { | ||||
| 	if(!data) return null; | ||||
| 	if(data.data) return debom(data.data); | ||||
| @ -2178,11 +2188,12 @@ function aoa_to_sheet(data, opts) { | ||||
| 		for(var C = 0; C != data[R].length; ++C) { | ||||
| 			if(typeof data[R][C] === 'undefined') continue; | ||||
| 			var cell = ({v: data[R][C] }); | ||||
| 			if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; } | ||||
| 			if(range.s.r > R) range.s.r = R; | ||||
| 			if(range.s.c > C) range.s.c = C; | ||||
| 			if(range.e.r < R) range.e.r = R; | ||||
| 			if(range.e.c < C) range.e.c = C; | ||||
| 			if(cell.v === null) { if(!o.cellStubs) continue; cell.t = 'z'; } | ||||
| 			if(cell.v === null) { if(cell.f) cell.t = 'n'; else if(!o.cellStubs) continue; else cell.t = 'z'; } | ||||
| 			else if(typeof cell.v === 'number') cell.t = 'n'; | ||||
| 			else if(typeof cell.v === 'boolean') cell.t = 'b'; | ||||
| 			else if(cell.v instanceof Date) { | ||||
| @ -3162,6 +3173,14 @@ function write_rdf(rdf, opts) { | ||||
| 	o.push('</rdf:RDF>'); | ||||
| 	return o.join(""); | ||||
| } | ||||
| /* TODO: pull properties */ | ||||
| var write_meta_ods = (function() { | ||||
| 	var payload = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xlink="http://www.w3.org/1999/xlink" office:version="1.2"><office:meta><meta:generator>Sheet' + 'JS ' + XLSX.version + '</meta:generator></office:meta></office:document-meta>'; | ||||
| 	return function wmo(wb, opts) { | ||||
| 		return payload; | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| /* ECMA-376 Part II 11.1 Core Properties Part */ | ||||
| /* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */ | ||||
| var CORE_PROPS = [ | ||||
| @ -5217,7 +5236,7 @@ function dbf_to_aoa(buf, opts) { | ||||
| 				case 'T': | ||||
| 					var day = dd.read_shift(4), ms = dd.read_shift(4); | ||||
| 					throw new Error(day + " | " + ms); | ||||
| 					//out[R][C] = new Date(); // FIXME!!!
 | ||||
| 					//out[R][C] = new Date(); // TODO
 | ||||
| 					//break;
 | ||||
| 				case 'Y': out[R][C] = dd.read(4,'i')/1e4; break; | ||||
| 				case '0': | ||||
| @ -5267,7 +5286,9 @@ var SYLK = (function() { | ||||
| 		var Mval = 0, j; | ||||
| 		for (; ri !== records.length; ++ri) { | ||||
| 			Mval = 0; | ||||
| 			var rstr=records[ri].trim(), record=rstr.split(";"), RT=record[0], val; | ||||
| 			var rstr=records[ri].trim(); | ||||
| 			var record=rstr.replace(/;;/g, "\u0001").split(";").map(function(x) { return x.replace(/\u0001/g, ";"); }); | ||||
| 			var RT=record[0], val; | ||||
| 			if(rstr.length > 0) switch(RT) { | ||||
| 			case 'ID': break; /* header */ | ||||
| 			case 'E': break; /* EOF */ | ||||
| @ -5297,17 +5318,19 @@ var SYLK = (function() { | ||||
| 					next_cell_format = null; | ||||
| 					break; | ||||
| 				case 'E': | ||||
| 					/* formula = record[rj].substr(1); */ | ||||
| 					break; /* TODO: formula */ | ||||
| 					formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); | ||||
| 					arr[R][C] = [arr[R][C], formula]; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} break; | ||||
| 			case 'F': | ||||
| 			var F_seen = 0; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| 				case 'X': C = parseInt(record[rj].substr(1))-1; break; | ||||
| 				case 'X': C = parseInt(record[rj].substr(1))-1; ++F_seen; break; | ||||
| 				case 'Y': | ||||
| 					R = parseInt(record[rj].substr(1))-1; C = 0; | ||||
| 					R = parseInt(record[rj].substr(1))-1; /*C = 0;*/ | ||||
| 					for(j = arr.length; j <= R; ++j) arr[j] = []; | ||||
| 					break; | ||||
| 					++F_seen; break; | ||||
| 				case 'M': Mval = parseInt(record[rj].substr(1)) / 20; break; | ||||
| 				case 'F': break; /* ??? */ | ||||
| 				case 'P': | ||||
| @ -5322,14 +5345,19 @@ var SYLK = (function() { | ||||
| 						Mval = parseInt(cw[2], 10); | ||||
| 						colinfo[j-1] = Mval == 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]); | ||||
| 					} break; | ||||
| 				case 'R': | ||||
| 				case 'C': /* default column format */ | ||||
| 					C = parseInt(record[rj].substr(1))-1; | ||||
| 					if(!colinfo[C]) colinfo[C] = {}; | ||||
| 					break; | ||||
| 				case 'R': /* row properties */ | ||||
| 					R = parseInt(record[rj].substr(1))-1; | ||||
| 					rowinfo[R] = {}; | ||||
| 					if(!rowinfo[R]) rowinfo[R] = {}; | ||||
| 					if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); } | ||||
| 					else if(Mval == 0) rowinfo[R].hidden = true; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} break; | ||||
| 			} | ||||
| 			if(F_seen < 2) next_cell_format = null; break; | ||||
| 			default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} | ||||
| 		} | ||||
| @ -5444,7 +5472,7 @@ var DIF = (function() { | ||||
| 					if(data === 'TRUE') arr[R][C] = true; | ||||
| 					else if(data === 'FALSE') arr[R][C] = false; | ||||
| 					else if(+value == +value) arr[R][C] = +value; | ||||
| 					else if(!isNaN(new Date(value).getDate())) arr[R][C] = parseDate(value); | ||||
| 					else if(!isNaN(fuzzydate(value).getDate())) arr[R][C] = parseDate(value); | ||||
| 					else arr[R][C] = value; | ||||
| 					++C; break; | ||||
| 				case 1: | ||||
| @ -5576,7 +5604,7 @@ var PRN = (function() { | ||||
| 			else if(s == "TRUE") { cell.t = 'b'; cell.v = true; } | ||||
| 			else if(s == "FALSE") { cell.t = 'b'; cell.v = false; } | ||||
| 			else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; } | ||||
| 			else if(!isNaN(new Date(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); } | ||||
| 			else if(!isNaN(fuzzydate(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); } | ||||
| 			else { | ||||
| 				cell.t = 's'; | ||||
| 				if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"'); | ||||
| @ -5607,13 +5635,16 @@ var PRN = (function() { | ||||
| 	} | ||||
| 
 | ||||
| 	function prn_to_sheet(d, opts) { | ||||
| 		var str = "", bytes = firstbyte(d, opts); | ||||
| 		switch(opts.type) { | ||||
| 			case 'base64': return prn_to_sheet_str(Base64.decode(d), opts); | ||||
| 			case 'binary': return prn_to_sheet_str(d, opts); | ||||
| 			case 'buffer': return prn_to_sheet_str(d.toString('binary'), opts); | ||||
| 			case 'array': return prn_to_sheet_str(cc2str(d), opts); | ||||
| 			case 'base64': str = Base64.decode(d); break; | ||||
| 			case 'binary': str = d; break; | ||||
| 			case 'buffer': str = d.toString('binary'); break; | ||||
| 			case 'array': str = cc2str(d); break; | ||||
| 			default: throw new Error("Unrecognized type " + opts.type); | ||||
| 		} | ||||
| 		throw new Error("Unrecognized type " + opts.type); | ||||
| 		if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str); | ||||
| 		return prn_to_sheet_str(str, opts); | ||||
| 	} | ||||
| 
 | ||||
| 	function prn_to_workbook(str, opts) { return sheet_to_workbook(prn_to_sheet(str, opts), opts); } | ||||
| @ -5644,6 +5675,20 @@ var PRN = (function() { | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| /* Excel defaults to SYLK but warns if data is not valid */ | ||||
| function read_wb_ID(d, opts) { | ||||
| 	var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true; | ||||
| 	try { | ||||
| 		var out = SYLK.to_workbook(d, o); | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		return out; | ||||
| 	} catch(e) { | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		if(!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e; | ||||
| 		return PRN.to_workbook(d, opts); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var WK_ = (function() { | ||||
| 	function lotushopper(data, cb, opts) { | ||||
| 		if(!data) return; | ||||
| @ -10726,8 +10771,8 @@ function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) { | ||||
| 			else { | ||||
| 				cell.t = 'n'; | ||||
| 				vv = ''+(cell.v = datenum(parseDate(cell.v))); | ||||
| 				if(typeof cell.z === 'undefined') cell.z = SSF._table[14]; | ||||
| 			} | ||||
| 			if(typeof cell.z === 'undefined') cell.z = SSF._table[14]; | ||||
| 			break; | ||||
| 		default: vv = cell.v; break; | ||||
| 	} | ||||
| @ -10840,8 +10885,10 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) { | ||||
| 			} | ||||
| 
 | ||||
| 			if(tag.t == null && p.v === undefined) { | ||||
| 				if(!opts.sheetStubs) continue; | ||||
| 				p.t = "z"; | ||||
| 				if(p.f || p.F) { | ||||
| 					p.v = 0; p.t = "n"; | ||||
| 				} else if(!opts.sheetStubs) continue; | ||||
| 				else p.t = "z"; | ||||
| 			} | ||||
| 			else p.t = tag.t || "n"; | ||||
| 			if(guess.s.c > idx) guess.s.c = idx; | ||||
| @ -12090,11 +12137,20 @@ function parse_wb_defaults(wb) { | ||||
| 	_ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904, 'date1904'); | ||||
| } | ||||
| 
 | ||||
| var badchars = "][*?\/\\".split(""); | ||||
| function check_ws_name(n, safe) { | ||||
| 	if(n.length > 31) { if(safe) return false; throw new Error("Sheet names cannot exceed 31 chars"); } | ||||
| 	var _good = true; | ||||
| 	badchars.forEach(function(c) { | ||||
| 		if(n.indexOf(c) == -1) return; | ||||
| 		if(!safe) throw new Error("Sheet name cannot contain : \\ / ? * [ ]"); | ||||
| 		_good = false; | ||||
| 	}); | ||||
| 	return _good; | ||||
| } | ||||
| function check_wb_names(N) { | ||||
| 	var badchars = "][*?\/\\".split(""); | ||||
| 	N.forEach(function(n,i) { | ||||
| 		badchars.forEach(function(c) { if(n.indexOf(c) > -1) throw new Error("Sheet name cannot contain : \\ / ? * [ ]"); }); | ||||
| 		if(n.length > 31) throw new Error("Sheet names cannot exceed 31 chars"); | ||||
| 		check_ws_name(n); | ||||
| 		for(var j = 0; j < i; ++j) if(n == N[j]) throw new Error("Duplicate Sheet Name: " + n); | ||||
| 	}); | ||||
| } | ||||
| @ -13943,7 +13999,7 @@ function parse_workbook(blob, options) { | ||||
| 					opts.enc = val; | ||||
| 					if(opts.WTF) console.error(val); | ||||
| 					if(!options.password) throw new Error("File is password-protected"); | ||||
| 					if(val.Type !== 0) throw new Error("Encryption scheme unsupported"); | ||||
| 					if(val.valid == null) throw new Error("Encryption scheme unsupported"); | ||||
| 					if(!val.valid) throw new Error("Password is incorrect"); | ||||
| 					break; | ||||
| 				case 'WriteAccess': opts.lastuser = val; break; | ||||
| @ -13960,7 +14016,7 @@ function parse_workbook(blob, options) { | ||||
| 				case 'Template': break; // TODO
 | ||||
| 				case 'RefreshAll': wb.opts.RefreshAll = val; break; | ||||
| 				case 'BookBool': break; // TODO
 | ||||
| 				case 'UsesELFs': /* if(val) console.error("Unsupported ELFs"); */ break; | ||||
| 				case 'UsesELFs': break; | ||||
| 				case 'MTRSettings': break; | ||||
| 				case 'CalcCount': wb.opts.CalcCount = val; break; | ||||
| 				case 'CalcDelta': wb.opts.CalcDelta = val; break; | ||||
| @ -16051,6 +16107,7 @@ function parse_dom_table(table, _opts) { | ||||
| function table_to_book(table, opts) { | ||||
| 	return sheet_to_workbook(parse_dom_table(table, opts), opts); | ||||
| } | ||||
| /* OpenDocument */ | ||||
| var parse_content_xml = (function() { | ||||
| 
 | ||||
| 	var parse_text_p = function(text, tag) { | ||||
| @ -16490,7 +16547,27 @@ var parse_content_xml = (function() { | ||||
| 		return out; | ||||
| 	}; | ||||
| })(); | ||||
| var write_content_xml = (function() { | ||||
| 
 | ||||
| function parse_ods(zip, opts) { | ||||
| 	opts = opts || ({}); | ||||
| 	var ods = !!safegetzipfile(zip, 'objectdata'); | ||||
| 	if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts); | ||||
| 	var content = getzipstr(zip, 'content.xml'); | ||||
| 	if(!content) throw new Error("Missing content.xml in " + (ods ? "ODS" : "UOF")+ " file"); | ||||
| 	return parse_content_xml(ods ? content : utf8read(content), opts); | ||||
| } | ||||
| function parse_fods(data, opts) { | ||||
| 	return parse_content_xml(data, opts); | ||||
| } | ||||
| 
 | ||||
| /* OpenDocument */ | ||||
| var write_styles_ods = (function() { | ||||
| 	var payload = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><office:document-styles xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" office:version="1.2"></office:document-styles>'; | ||||
| 	return function wso(wb, opts) { | ||||
| 		return payload; | ||||
| 	}; | ||||
| })(); | ||||
| var write_content_ods = (function() { | ||||
| 	var null_cell_xml = '          <table:table-cell />\n'; | ||||
| 	var covered_cell_xml = '          <table:covered-table-cell/>\n'; | ||||
| 	var write_ws = function(ws, wb, i, opts) { | ||||
| @ -16553,7 +16630,7 @@ var write_content_xml = (function() { | ||||
| 					//case 'e':
 | ||||
| 					default: o.push(null_cell_xml); continue; | ||||
| 				} | ||||
| 				o.push(writextag('table:table-cell', writextag('text:p', textp, {}), ct)); | ||||
| 				o.push('          ' + writextag('table:table-cell', writextag('text:p', textp, {}), ct) + '\n'); | ||||
| 			} | ||||
| 			o.push('        </table:table-row>\n'); | ||||
| 		} | ||||
| @ -16635,6 +16712,50 @@ var write_content_xml = (function() { | ||||
| 		return o.join(""); | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| function write_ods(wb, opts) { | ||||
| 	if(opts.bookType == "fods") return write_content_ods(wb, opts); | ||||
| 
 | ||||
| var zip = new jszip(); | ||||
| 	var f = ""; | ||||
| 
 | ||||
| 	var manifest = []; | ||||
| 	var rdf = []; | ||||
| 
 | ||||
| 	/* 3:3.3 and 2:2.2.4 */ | ||||
| 	f = "mimetype"; | ||||
| 	zip.file(f, "application/vnd.oasis.opendocument.spreadsheet"); | ||||
| 
 | ||||
| 	/* Part 1 Section 2.2 Documents */ | ||||
| 	f = "content.xml"; | ||||
| 	zip.file(f, write_content_ods(wb, opts)); | ||||
| 	manifest.push([f, "text/xml"]); | ||||
| 	rdf.push([f, "ContentFile"]); | ||||
| 
 | ||||
| 	/* TODO: these are hard-coded styles to satiate excel */ | ||||
| 	f = "styles.xml"; | ||||
| 	zip.file(f, write_styles_ods(wb, opts)); | ||||
| 	manifest.push([f, "text/xml"]); | ||||
| 	rdf.push([f, "StylesFile"]); | ||||
| 
 | ||||
| 	/* Part 3 Section 6 Metadata Manifest File */ | ||||
| 	f = "manifest.rdf"; | ||||
| 	zip.file(f, write_rdf(rdf, opts)); | ||||
| 	manifest.push([f, "application/rdf+xml"]); | ||||
| 
 | ||||
| 	/* TODO: this is hard-coded to satiate excel */ | ||||
| 	f = "meta.xml"; | ||||
| 	zip.file(f, write_meta_ods(wb, opts)); | ||||
| 	manifest.push([f, "text/xml"]); | ||||
| 	rdf.push([f, "MetadataFile"]); | ||||
| 
 | ||||
| 	/* Part 3 Section 4 Manifest File */ | ||||
| 	f = "META-INF/manifest.xml"; | ||||
| 	zip.file(f, write_manifest(manifest, opts)); | ||||
| 
 | ||||
| 	return zip; | ||||
| } | ||||
| 
 | ||||
| /* actual implementation elsewhere, wrappers are for read/write */ | ||||
| function write_obj_str(factory) { | ||||
| 	return function write_str(wb, o) { | ||||
| @ -16651,49 +16772,6 @@ var write_slk_str = write_obj_str(SYLK); | ||||
| var write_dif_str = write_obj_str(DIF); | ||||
| var write_prn_str = write_obj_str(PRN); | ||||
| var write_txt_str = write_obj_str({from_sheet:sheet_to_txt}); | ||||
| /* Part 3: Packages */ | ||||
| function parse_ods(zip, opts) { | ||||
| 	opts = opts || ({}); | ||||
| 	var ods = !!safegetzipfile(zip, 'objectdata'); | ||||
| 	if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts); | ||||
| 	var content = getzipstr(zip, 'content.xml'); | ||||
| 	if(!content) throw new Error("Missing content.xml in " + (ods ? "ODS" : "UOF")+ " file"); | ||||
| 	return parse_content_xml(ods ? content : utf8read(content), opts); | ||||
| } | ||||
| function parse_fods(data, opts) { | ||||
| 	return parse_content_xml(data, opts); | ||||
| } | ||||
| 
 | ||||
| function write_ods(wb, opts) { | ||||
| 	if(opts.bookType == "fods") return write_content_xml(wb, opts); | ||||
| 
 | ||||
| var zip = new jszip(); | ||||
| 	var f = ""; | ||||
| 
 | ||||
| 	var manifest = []; | ||||
| 	var rdf = []; | ||||
| 
 | ||||
| 	/* 3:3.3 and 2:2.2.4 */ | ||||
| 	f = "mimetype"; | ||||
| 	zip.file(f, "application/vnd.oasis.opendocument.spreadsheet"); | ||||
| 
 | ||||
| 	/* Part 1 Section 2.2 Documents */ | ||||
| 	f = "content.xml"; | ||||
| 	zip.file(f, write_content_xml(wb, opts)); | ||||
| 	manifest.push([f, "text/xml"]); | ||||
| 	rdf.push([f, "ContentFile"]); | ||||
| 
 | ||||
| 	/* Part 3 Section 6 Metadata Manifest File */ | ||||
| 	f = "manifest.rdf"; | ||||
| 	zip.file(f, write_rdf(rdf, opts)); | ||||
| 	manifest.push([f, "application/rdf+xml"]); | ||||
| 
 | ||||
| 	/* Part 3 Section 4 Manifest File */ | ||||
| 	f = "META-INF/manifest.xml"; | ||||
| 	zip.file(f, write_manifest(manifest, opts)); | ||||
| 
 | ||||
| 	return zip; | ||||
| } | ||||
| function fix_opts_func(defaults) { | ||||
| 	return function fix_opts(opts) { | ||||
| 		for(var i = 0; i != defaults.length; ++i) { | ||||
| @ -17126,10 +17204,10 @@ function readSync(data, opts) { | ||||
| 		case 0xD0: return read_cfb(CFB.read(d, o), o); | ||||
| 		case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o); | ||||
| 		case 0x3C: return parse_xlml(d, o); | ||||
| 		case 0x49: if(n[1] == 0x44) return SYLK.to_workbook(d, o); break; | ||||
| 		case 0x49: if(n[1] == 0x44) return read_wb_ID(d, o); break; | ||||
| 		case 0x54: if(n[1] == 0x41 && n[2] == 0x42 && n[3] == 0x4C) return DIF.to_workbook(d, o); break; | ||||
| 		case 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break; | ||||
| 		case 0xEF: return parse_xlml(d, o); | ||||
| 		case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o); | ||||
| 		case 0xFF: if(n[1] == 0xFE){ return read_utf16(d, o); } break; | ||||
| 		case 0x00: if(n[1] == 0x00 && n[2] >= 0x02 && n[3] == 0x00) return WK_.to_workbook(d, o); break; | ||||
| 		case 0x03: case 0x83: case 0x8B: return DBF.to_workbook(d, o); | ||||
| @ -17283,7 +17361,7 @@ function sheet_to_json(sheet, opts){ | ||||
| 	var outi = 0, counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	if(!sheet[R]) sheet[R] = []; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| 		val = dense ? sheet[R][C] : sheet[cols[C] + rr]; | ||||
| @ -17350,8 +17428,8 @@ 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) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			if(txt == "ID") txt = '"ID"'; | ||||
| 		} else if(val.f != null && !val.F) { | ||||
| 			isempty = false; | ||||
| 			txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"'; | ||||
| @ -17428,6 +17506,30 @@ function sheet_to_formulae(sheet) { | ||||
| 	return cmds; | ||||
| } | ||||
| 
 | ||||
| function json_to_sheet(js, opts) { | ||||
| 	var o = opts || {}; | ||||
| 	var ws = ({}); | ||||
| 	var range = ({s: {c:0, r:0}, e: {c:0, r:js.length}}); | ||||
| 	var hdr = o.header || [], C = 0; | ||||
| 
 | ||||
| 	for(var R = 0; R != js.length; ++R) { | ||||
| 		Object.keys(js[R]).filter(function(x) { return js[R].hasOwnProperty(x); }).forEach(function(k) { | ||||
| 			if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k; | ||||
| 			var v = js[R][k]; | ||||
| 			var t = 'z'; | ||||
| 			if(typeof v == 'number') t = 'n'; | ||||
| 			else if(typeof v == 'boolean') t = 'b'; | ||||
| 			else if(typeof v == 'string') t = 's'; | ||||
| 			else if(v instanceof Date) t = 'd'; | ||||
| 			ws[encode_cell({c:C,r:R+1})] = {t:t, v:v}; | ||||
| 		}); | ||||
| 	} | ||||
| 	range.e.c = hdr.length - 1; | ||||
| 	for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]}; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| var utils = { | ||||
| 	encode_col: encode_col, | ||||
| 	encode_row: encode_row, | ||||
| @ -17444,6 +17546,7 @@ var utils = { | ||||
| 	make_json: sheet_to_json, | ||||
| 	make_formulae: sheet_to_formulae, | ||||
| 	aoa_to_sheet: aoa_to_sheet, | ||||
| 	json_to_sheet: json_to_sheet, | ||||
| 	table_to_sheet: parse_dom_table, | ||||
| 	table_to_book: table_to_book, | ||||
| 	sheet_to_csv: sheet_to_csv, | ||||
| @ -17451,6 +17554,110 @@ var utils = { | ||||
| 	sheet_to_formulae: sheet_to_formulae, | ||||
| 	sheet_to_row_object_array: sheet_to_json | ||||
| }; | ||||
| 
 | ||||
| (function(utils) { | ||||
| utils.consts = utils.consts || {}; | ||||
| function add_consts(R) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } | ||||
| 
 | ||||
| function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); } | ||||
| 
 | ||||
| /* get cell, creating a stub if necessary */ | ||||
| function ws_get_cell_stub(ws, R, C) { | ||||
| 	/* A1 cell address */ | ||||
| 	if(typeof R == "string") return ws[R] || (ws[R] = {t:'z'}); | ||||
| 	/* cell address object */ | ||||
| 	if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R)); | ||||
| 	/* R and C are 0-based indices */ | ||||
| 	return ws_get_cell_stub(ws, encode_cell({r:R,c:C})); | ||||
| } | ||||
| 
 | ||||
| /* find sheet index for given name / validate index */ | ||||
| function wb_sheet_idx(wb, sh) { | ||||
| 	if(typeof sh == "number") { | ||||
| 		if(sh >= 0 && wb.SheetNames.length > sh) return sh; | ||||
| 		throw new Error("Cannot find sheet # " + sh); | ||||
| 	} else if(typeof sh == "string") { | ||||
| 		var idx = wb.SheetNames.indexOf(sh); | ||||
| 		if(idx > -1) return idx; | ||||
| 		throw new Error("Cannot find sheet name |" + sh + "|"); | ||||
| 	} else throw new Error("Cannot find sheet |" + sh + "|"); | ||||
| } | ||||
| 
 | ||||
| /* simple blank workbook object */ | ||||
| utils.book_new = function() { | ||||
| 	return { SheetNames: [], Sheets: {} }; | ||||
| }; | ||||
| 
 | ||||
| /* add a worksheet to the end of a given workbook */ | ||||
| utils.book_append_sheet = function(wb, ws, name) { | ||||
| 	if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf("Sheet" + i) == -1) break; | ||||
| 	check_ws_name(name); | ||||
| 	if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!"); | ||||
| 
 | ||||
| 	wb.SheetNames.push(name); | ||||
| 	wb.Sheets[name] = ws; | ||||
| }; | ||||
| 
 | ||||
| /* set sheet visibility (visible/hidden/very hidden) */ | ||||
| utils.book_set_sheet_visibility = function(wb, sh, vis) { | ||||
| 	get_default(wb,"Workbook",{}); | ||||
| 	get_default(wb.Workbook,"Sheets",[]); | ||||
| 
 | ||||
| 	var idx = wb_sheet_idx(wb, sh); | ||||
| 	get_default(wb.Workbook.Sheets,idx, {}); | ||||
| 
 | ||||
| 	switch(vis) { | ||||
| 		case 0: case 1: case 2: break; | ||||
| 		default: throw new Error("Bad sheet visibility setting " + vis); | ||||
| 	} | ||||
| 	wb.Workbook.Sheets[idx].Hidden = vis; | ||||
| }; | ||||
| add_consts([ | ||||
| 	["SHEET_VISIBLE", 0], | ||||
| 	["SHEET_HIDDEN", 1], | ||||
| 	["SHEET_VERY_HIDDEN", 2] | ||||
| ]); | ||||
| 
 | ||||
| /* set number format */ | ||||
| utils.cell_set_number_format = function(cell, fmt) { | ||||
| 	cell.z = fmt; | ||||
| 	return cell; | ||||
| }; | ||||
| 
 | ||||
| /* set cell hyperlink */ | ||||
| utils.cell_set_hyperlink = function(cell, target, tooltip) { | ||||
| 	if(!target) { | ||||
| 		delete cell.l; | ||||
| 	} else { | ||||
| 		cell.l = { Target: target }; | ||||
| 		if(tooltip) cell.l.Tooltip = tooltip; | ||||
| 	} | ||||
| 	return cell; | ||||
| }; | ||||
| 
 | ||||
| /* add to cell comments */ | ||||
| utils.cell_add_comment = function(cell, text, author) { | ||||
| 	if(!cell.c) cell.c = []; | ||||
| 	cell.c.push({t:text, a:author||"SheetJS"}); | ||||
| }; | ||||
| 
 | ||||
| /* set array formula and flush related cells */ | ||||
| utils.sheet_set_array_formula = function(ws, range, formula) { | ||||
| 	var rng = typeof range != "string" ? range : safe_decode_range(range); | ||||
| 	var rngstr = typeof range == "string" ? range : encode_range(range); | ||||
| 	for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) { | ||||
| 		var cell = ws_get_cell_stub(ws, R, C); | ||||
| 		cell.t = 'n'; | ||||
| 		cell.F = rngstr; | ||||
| 		delete cell.v; | ||||
| 		if(R == rng.s.r && C == rng.s.c) cell.f = formula; | ||||
| 	} | ||||
| 	return ws; | ||||
| }; | ||||
| 
 | ||||
| return utils; | ||||
| })(utils); | ||||
| 
 | ||||
| if(has_buf && typeof require != 'undefined') (function() { | ||||
| 	var Readable = require('stream').Readable; | ||||
| 
 | ||||
| @ -17513,6 +17720,7 @@ if(has_buf && typeof require != 'undefined') (function() { | ||||
| 		to_csv: write_csv_stream | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| XLSX.parse_xlscfb = parse_xlscfb; | ||||
| XLSX.parse_ods = parse_ods; | ||||
| XLSX.parse_fods = parse_fods; | ||||
|  | ||||
							
								
								
									
										28
									
								
								dist/xlsx.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										28
									
								
								dist/xlsx.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -34,6 +34,7 @@ Utilities are available in the `XLSX.utils` object: | ||||
| **Importing:** | ||||
| 
 | ||||
| - `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. | ||||
| - `json_to_sheet` converts an array of JS objects to a worksheet. | ||||
| 
 | ||||
| **Exporting:** | ||||
| 
 | ||||
| @ -41,7 +42,7 @@ Utilities are available in the `XLSX.utils` object: | ||||
| - `sheet_to_csv` generates delimiter-separated-values output. | ||||
| - `sheet_to_formulae` generates a list of the formulae (with value fallbacks). | ||||
| 
 | ||||
| Exporters are described in the [Utility Functions](#utility-functions) section. | ||||
| These utilities are described in [Utility Functions](#utility-functions) below. | ||||
| 
 | ||||
| 
 | ||||
| **Cell and cell address manipulation:** | ||||
|  | ||||
| @ -42,6 +42,25 @@ var ws = XLSX.utils.aoa_to_sheet([ | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### Array of Objects Input | ||||
| 
 | ||||
| `XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet | ||||
| with automatically-generated "headers" based on the keys of the objects. | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| The original sheet cannot be reproduced because JS object keys must be unique. | ||||
| After replacing the second `e` and `S` with `e_1` and `S_1`: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.json_to_sheet([ | ||||
| 	{S:1,h:2,e:3,e_1:4,t:5,J:6,S_1:7}, | ||||
| 	{S:2,h:3,e:4,e_1:5,t:6,J:7,S_1:8} | ||||
| ]); | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### HTML Table Input | ||||
| 
 | ||||
| `XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet | ||||
|  | ||||
| @ -46,6 +46,7 @@ | ||||
|   * [Output Type](README.md#output-type) | ||||
| - [Utility Functions](README.md#utility-functions) | ||||
|   * [Array of Arrays Input](README.md#array-of-arrays-input) | ||||
|   * [Array of Objects Input](README.md#array-of-objects-input) | ||||
|   * [HTML Table Input](README.md#html-table-input) | ||||
|   * [Formulae Output](README.md#formulae-output) | ||||
|   * [Delimiter-Separated Output](README.md#delimiter-separated-output) | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "xlsx", | ||||
| 	"version": "0.10.0", | ||||
| 	"version": "0.10.1", | ||||
| 	"author": "sheetjs", | ||||
| 	"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS (ODS/FODS/UOS) spreadsheet parser and writer", | ||||
| 	"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "office", "spreadsheet" ], | ||||
|  | ||||
							
								
								
									
										15
									
								
								test.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										15
									
								
								test.js
									
									
									
									
									
								
							| @ -1413,6 +1413,21 @@ describe('roundtrip features', function() { | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| 
 | ||||
| 	it('should preserve js objects', function() { | ||||
| 		var data = [ | ||||
| 			{a:1}, | ||||
| 			{b:2,c:3}, | ||||
| 			{b:"a",d:"b"}, | ||||
| 			{a:true, c:false}, | ||||
| 			{c:new Date("2017-02-19T14:30Z")} | ||||
| 		]; | ||||
| 		var wb = X.utils.json_to_sheet(data); | ||||
| 		var out = X.utils.sheet_to_json(wb, {raw:true}); | ||||
| 		data.forEach(function(row, i) { | ||||
| 			Object.keys(row).forEach(function(k) { assert.equal(row[k], out[i][k]); }); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| //function password_file(x){return x.match(/^password.*\.xls$/); }
 | ||||
|  | ||||
| @ -543,16 +543,19 @@ describe('input formats', function() { | ||||
| 		X.read(fs.readFileSync(paths.cstxlsb, 'binary'), {type: 'binary'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxls, 'binary'), {type: 'binary'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxml, 'binary'), {type: 'binary'}); | ||||
| 		X.read(fs.readFileSync(paths.cstods, 'binary'), {type: 'binary'}); | ||||
| 	}); | ||||
| 	it('should read base64 strings', function() { | ||||
| 		X.read(fs.readFileSync(paths.cstxls, 'base64'), {type: 'base64'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxml, 'base64'), {type: 'base64'}); | ||||
| 		X.read(fs.readFileSync(paths.cstods, 'base64'), {type: 'base64'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxlsx, 'base64'), {type: 'base64'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxlsb, 'base64'), {type: 'base64'}); | ||||
| 	}); | ||||
| 	(typeof UInt8Array !== 'undefined' ? it : it.skip)('should read arrays', function() { | ||||
| 		X.read(fs.readFileSync(paths.cstxls, 'buffer'), {type: 'array'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxml, 'buffer'), {type: 'array'}); | ||||
| 		X.read(fs.readFileSync(paths.cstods, 'buffer'), {type: 'array'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxlsx, 'buffer'), {type: 'array'}); | ||||
| 		X.read(fs.readFileSync(paths.cstxlsb, 'buffer'), {type: 'array'}); | ||||
| 	}); | ||||
| @ -566,12 +569,14 @@ describe('input formats', function() { | ||||
| 	it('should throw if format is unknown', function() { | ||||
| 		assert.throws(function() { X.read(fs.readFileSync(paths.cstxls), {type: 'dafuq'}); }); | ||||
| 		assert.throws(function() { X.read(fs.readFileSync(paths.cstxml), {type: 'dafuq'}); }); | ||||
| 		assert.throws(function() { X.read(fs.readFileSync(paths.cstods), {type: 'dafuq'}); }); | ||||
| 		assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsx), {type: 'dafuq'}); }); | ||||
| 		assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsb), {type: 'dafuq'}); }); | ||||
| 	}); | ||||
| 	it('should default to base64 type', function() { | ||||
| 		X.read(fs.readFileSync(paths.cstxls, 'base64')); | ||||
| 		X.read(fs.readFileSync(paths.cstxml, 'base64')); | ||||
| 		X.read(fs.readFileSync(paths.cstods, 'base64')); | ||||
| 		X.read(fs.readFileSync(paths.cstxlsx, 'base64')); | ||||
| 		X.read(fs.readFileSync(paths.cstxlsb, 'base64')); | ||||
| 	}); | ||||
| @ -816,8 +821,9 @@ describe('parse features', function() { | ||||
| 			var wb2 = X.read(fs.readFileSync(paths.cstxlsb), opts); | ||||
| 			var wb3 = X.read(fs.readFileSync(paths.cstxls), opts); | ||||
| 			var wb4 = X.read(fs.readFileSync(paths.cstxml), opts); | ||||
| 			var wb5 = X.read(fs.readFileSync(paths.cstods), opts); | ||||
| 			/* TODO */ | ||||
| 			[wb1, wb2 /*, wb3, wb4 */].forEach(function(wb) { | ||||
| 			[wb1, wb2 /*, wb3, wb4, wb5 */].forEach(function(wb) { | ||||
| 				assert.equal(wb.Sheets.Sheet7["!fullref"],"A1:N34"); | ||||
| 				assert.equal(wb.Sheets.Sheet7["!ref"],"A1"); | ||||
| 			}); | ||||
| @ -1401,10 +1407,29 @@ describe('roundtrip features', function() { | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| 
 | ||||
| 	it('should preserve js objects', function() { | ||||
| 		var data = [ | ||||
| 			{a:1}, | ||||
| 			{b:2,c:3}, | ||||
| 			{b:"a",d:"b"}, | ||||
| 			{a:true, c:false}, | ||||
| 			{c:new Date("2017-02-19T14:30Z")} | ||||
| 		]; | ||||
| 		var wb = X.utils.json_to_sheet(data); | ||||
| 		var out = X.utils.sheet_to_json(wb, {raw:true}); | ||||
| 		data.forEach(function(row, i) { | ||||
| 			Object.keys(row).forEach(function(k) { assert.equal(row[k], out[i][k]); }); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| function password_file(x){return x.match(/^password.*\.xls$/); } | ||||
| var password_files = fs.readdirSync('test_files').filter(password_file); | ||||
| //function password_file(x){return x.match(/^password.*\.xls$/); }
 | ||||
| //var password_files = fs.readdirSync('test_files').filter(password_file);
 | ||||
| var password_files = [ | ||||
| 	//"password_2002_40_972000.xls",
 | ||||
| 	"password_2002_40_xor.xls" | ||||
| ]; | ||||
| describe('invalid files', function() { | ||||
| 	describe('parse', function() { [ | ||||
| 			['password', 'apachepoi_password.xls'], | ||||
| @ -1768,10 +1793,20 @@ describe('encryption', function() { | ||||
| 	password_files.forEach(function(x) { | ||||
| 		describe(x, function() { | ||||
| 			it('should throw with no password', function() {assert.throws(function() { X.read(fs.readFileSync(dir + x), {type:"binary"}); }); }); | ||||
| 			it('should throw with wrong password', function() {assert.throws(function() { X.read(fs.readFileSync(dir + x), {type:"binary",password:'passwor',WTF:opts.WTF}); }); }); | ||||
| 			it('should throw with wrong password', function() { | ||||
| 				try { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:"binary",password:'passwor',WTF:opts.WTF}); | ||||
| 					throw new Error("incorrect password was accepted"); | ||||
| 				} catch(e) { | ||||
| 					if(e.message != "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			it('should recognize correct password', function() { | ||||
| 				try { X.read(fs.readFileSync(dir + x), {type:"binary",password:'password',WTF:opts.WTF}); } | ||||
| 				catch(e) { if(e.message == "Password is incorrect") throw e; } | ||||
| 				try { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:"binary",password:'password',WTF:opts.WTF}); | ||||
| 				} catch(e) { | ||||
| 					if(e.message == "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			it.skip('should decrypt file', function() { | ||||
| 				var wb = X.read(fs.readFileSync(dir + x), {type:"binary",password:'password',WTF:opts.WTF}); | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -70,3 +70,4 @@ | ||||
| ./test_files/2011/apachepoi_SimpleWithComments.xls.xml | ||||
| ./test_files/apachepoi_SimpleWithComments.xlsx | ||||
| ./test_files/2013/apachepoi_SimpleWithComments.xlsx.xlsb | ||||
| ./test_files/password_2002_40_xor.xls | ||||
|  | ||||
							
								
								
									
										51
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										51
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -6,7 +6,7 @@ | ||||
| /*global exports, module, require:false, process:false, Buffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.10.0'; | ||||
| XLSX.version = '0.10.1'; | ||||
| var current_codepage = 1200; | ||||
| /*:: declare var cptable:any; */ | ||||
| /*global cptable:true */ | ||||
| @ -5736,6 +5736,20 @@ var PRN = (function() { | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| /* Excel defaults to SYLK but warns if data is not valid */ | ||||
| function read_wb_ID(d, opts) { | ||||
| 	var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true; | ||||
| 	try { | ||||
| 		var out = SYLK.to_workbook(d, o); | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		return out; | ||||
| 	} catch(e) { | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		if(!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e; | ||||
| 		return PRN.to_workbook(d, opts); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var WK_ = (function() { | ||||
| 	function lotushopper(data, cb/*:RecordHopperCB*/, opts/*:any*/) { | ||||
| 		if(!data) return; | ||||
| @ -17260,7 +17274,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| 		case 0xD0: return read_cfb(CFB.read(d, o), o); | ||||
| 		case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o); | ||||
| 		case 0x3C: return parse_xlml(d, o); | ||||
| 		case 0x49: if(n[1] == 0x44) return SYLK.to_workbook(d, o); break; | ||||
| 		case 0x49: if(n[1] == 0x44) return read_wb_ID(d, o); break; | ||||
| 		case 0x54: if(n[1] == 0x41 && n[2] == 0x42 && n[3] == 0x4C) return DIF.to_workbook(d, o); break; | ||||
| 		case 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break; | ||||
| 		case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o); | ||||
| @ -17484,8 +17498,8 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr | ||||
| 		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) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			if(txt == "ID") txt = '"ID"'; | ||||
| 		} else if(val.f != null && !val.F) { | ||||
| 			isempty = false; | ||||
| 			txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"'; | ||||
| @ -17562,6 +17576,30 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ { | ||||
| 	return cmds; | ||||
| } | ||||
| 
 | ||||
| function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ { | ||||
| 	var o = opts || {}; | ||||
| 	var ws = ({}/*:any*/); | ||||
| 	var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:js.length}}/*:any*/); | ||||
| 	var hdr = o.header || [], C = 0; | ||||
| 
 | ||||
| 	for(var R = 0; R != js.length; ++R) { | ||||
| 		Object.keys(js[R]).filter(function(x) { return js[R].hasOwnProperty(x); }).forEach(function(k) { | ||||
| 			if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k; | ||||
| 			var v = js[R][k]; | ||||
| 			var t = 'z'; | ||||
| 			if(typeof v == 'number') t = 'n'; | ||||
| 			else if(typeof v == 'boolean') t = 'b'; | ||||
| 			else if(typeof v == 'string') t = 's'; | ||||
| 			else if(v instanceof Date) t = 'd'; | ||||
| 			ws[encode_cell({c:C,r:R+1})] = {t:t, v:v}; | ||||
| 		}); | ||||
| 	} | ||||
| 	range.e.c = hdr.length - 1; | ||||
| 	for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]}; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| var utils = { | ||||
| 	encode_col: encode_col, | ||||
| 	encode_row: encode_row, | ||||
| @ -17578,6 +17616,7 @@ var utils = { | ||||
| 	make_json: sheet_to_json, | ||||
| 	make_formulae: sheet_to_formulae, | ||||
| 	aoa_to_sheet: aoa_to_sheet, | ||||
| 	json_to_sheet: json_to_sheet, | ||||
| 	table_to_sheet: parse_dom_table, | ||||
| 	table_to_book: table_to_book, | ||||
| 	sheet_to_csv: sheet_to_csv, | ||||
| @ -17680,11 +17719,11 @@ utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:stri | ||||
| 		var cell = ws_get_cell_stub(ws, R, C); | ||||
| 		cell.t = 'n'; | ||||
| 		cell.F = rngstr; | ||||
| 		delete cell.v;  | ||||
| 		delete cell.v; | ||||
| 		if(R == rng.s.r && C == rng.s.c) cell.f = formula; | ||||
| 	} | ||||
| 	return ws; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| return utils; | ||||
| })(utils); | ||||
|  | ||||
							
								
								
									
										51
									
								
								xlsx.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										51
									
								
								xlsx.js
									
									
									
									
									
								
							| @ -6,7 +6,7 @@ | ||||
| /*global exports, module, require:false, process:false, Buffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.10.0'; | ||||
| XLSX.version = '0.10.1'; | ||||
| var current_codepage = 1200; | ||||
| /*global cptable:true */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| @ -5675,6 +5675,20 @@ var PRN = (function() { | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| /* Excel defaults to SYLK but warns if data is not valid */ | ||||
| function read_wb_ID(d, opts) { | ||||
| 	var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true; | ||||
| 	try { | ||||
| 		var out = SYLK.to_workbook(d, o); | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		return out; | ||||
| 	} catch(e) { | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		if(!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e; | ||||
| 		return PRN.to_workbook(d, opts); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var WK_ = (function() { | ||||
| 	function lotushopper(data, cb, opts) { | ||||
| 		if(!data) return; | ||||
| @ -17190,7 +17204,7 @@ function readSync(data, opts) { | ||||
| 		case 0xD0: return read_cfb(CFB.read(d, o), o); | ||||
| 		case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o); | ||||
| 		case 0x3C: return parse_xlml(d, o); | ||||
| 		case 0x49: if(n[1] == 0x44) return SYLK.to_workbook(d, o); break; | ||||
| 		case 0x49: if(n[1] == 0x44) return read_wb_ID(d, o); break; | ||||
| 		case 0x54: if(n[1] == 0x41 && n[2] == 0x42 && n[3] == 0x4C) return DIF.to_workbook(d, o); break; | ||||
| 		case 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break; | ||||
| 		case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o); | ||||
| @ -17414,8 +17428,8 @@ 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) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			if(txt == "ID") txt = '"ID"'; | ||||
| 		} else if(val.f != null && !val.F) { | ||||
| 			isempty = false; | ||||
| 			txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"'; | ||||
| @ -17492,6 +17506,30 @@ function sheet_to_formulae(sheet) { | ||||
| 	return cmds; | ||||
| } | ||||
| 
 | ||||
| function json_to_sheet(js, opts) { | ||||
| 	var o = opts || {}; | ||||
| 	var ws = ({}); | ||||
| 	var range = ({s: {c:0, r:0}, e: {c:0, r:js.length}}); | ||||
| 	var hdr = o.header || [], C = 0; | ||||
| 
 | ||||
| 	for(var R = 0; R != js.length; ++R) { | ||||
| 		Object.keys(js[R]).filter(function(x) { return js[R].hasOwnProperty(x); }).forEach(function(k) { | ||||
| 			if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k; | ||||
| 			var v = js[R][k]; | ||||
| 			var t = 'z'; | ||||
| 			if(typeof v == 'number') t = 'n'; | ||||
| 			else if(typeof v == 'boolean') t = 'b'; | ||||
| 			else if(typeof v == 'string') t = 's'; | ||||
| 			else if(v instanceof Date) t = 'd'; | ||||
| 			ws[encode_cell({c:C,r:R+1})] = {t:t, v:v}; | ||||
| 		}); | ||||
| 	} | ||||
| 	range.e.c = hdr.length - 1; | ||||
| 	for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]}; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| var utils = { | ||||
| 	encode_col: encode_col, | ||||
| 	encode_row: encode_row, | ||||
| @ -17508,6 +17546,7 @@ var utils = { | ||||
| 	make_json: sheet_to_json, | ||||
| 	make_formulae: sheet_to_formulae, | ||||
| 	aoa_to_sheet: aoa_to_sheet, | ||||
| 	json_to_sheet: json_to_sheet, | ||||
| 	table_to_sheet: parse_dom_table, | ||||
| 	table_to_book: table_to_book, | ||||
| 	sheet_to_csv: sheet_to_csv, | ||||
| @ -17610,11 +17649,11 @@ utils.sheet_set_array_formula = function(ws, range, formula) { | ||||
| 		var cell = ws_get_cell_stub(ws, R, C); | ||||
| 		cell.t = 'n'; | ||||
| 		cell.F = rngstr; | ||||
| 		delete cell.v;  | ||||
| 		delete cell.v; | ||||
| 		if(R == rng.s.r && C == rng.s.c) cell.f = formula; | ||||
| 	} | ||||
| 	return ws; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| return utils; | ||||
| })(utils); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user