| 
									
										
										
										
											2017-05-17 04:23:36 +00:00
										 |  |  | /* note: browser DOM element cannot see mso- style attrs, must parse */ | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | var HTML_ = (function() { | 
					
						
							|  |  |  | 	function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ { | 
					
						
							|  |  |  | 		var opts = _opts || {}; | 
					
						
							|  |  |  | 		if(DENSE != null && opts.dense == null) opts.dense = DENSE; | 
					
						
							|  |  |  | 		var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/); | 
					
						
							| 
									
										
										
										
											2017-08-05 06:32:57 +00:00
										 |  |  | 		var mtch/*:any*/ = str.match(/<table/i); | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 		if(!mtch) throw new Error("Invalid HTML: could not find <table>"); | 
					
						
							| 
									
										
										
										
											2017-08-05 06:32:57 +00:00
										 |  |  | 		var mtch2/*:any*/ = str.match(/<\/table/i); | 
					
						
							|  |  |  | 		var i/*:number*/ = mtch.index, j/*:number*/ = mtch2 && mtch2.index || str.length; | 
					
						
							| 
									
										
										
										
											2017-08-10 23:46:34 +00:00
										 |  |  | 		var rows = split_regex(str.slice(i, j), /(:?<tr[^>]*>)/i, "<tr>"); | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 		var R = -1, C = 0, RS = 0, CS = 0; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 		var range/*:Range*/ = {s:{r:10000000, c:10000000},e:{r:0,c:0}}; | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | 		var merges/*:Array<Range>*/ = []; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 		for(i = 0; i < rows.length; ++i) { | 
					
						
							|  |  |  | 			var row = rows[i].trim(); | 
					
						
							| 
									
										
										
										
											2018-01-11 08:01:25 +00:00
										 |  |  | 			var hd = row.slice(0,3).toLowerCase(); | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 			if(hd == "<tr") { ++R; C = 0; continue; } | 
					
						
							|  |  |  | 			if(hd != "<td") continue; | 
					
						
							|  |  |  | 			var cells = row.split(/<\/td>/i); | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 			for(j = 0; j < cells.length; ++j) { | 
					
						
							|  |  |  | 				var cell = cells[j].trim(); | 
					
						
							| 
									
										
										
										
											2018-01-11 08:01:25 +00:00
										 |  |  | 				if(cell.slice(0,3).toLowerCase() != "<td") continue; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 				var m = cell, cc = 0; | 
					
						
							|  |  |  | 				/* TODO: parse styles etc */ | 
					
						
							|  |  |  | 				while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1); | 
					
						
							|  |  |  | 				var tag = parsexmltag(cell.slice(0, cell.indexOf(">"))); | 
					
						
							|  |  |  | 				CS = tag.colspan ? +tag.colspan : 1; | 
					
						
							|  |  |  | 				if((RS = +tag.rowspan)>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}}); | 
					
						
							| 
									
										
										
										
											2017-12-12 06:21:28 +00:00
										 |  |  | 				var _t/*:string*/ = tag.t || ""; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 				/* TODO: generate stub cells */ | 
					
						
							|  |  |  | 				if(!m.length) { C += CS; continue; } | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 				m = htmldecode(unescapexml(m)); | 
					
						
							| 
									
										
										
										
											2017-12-12 06:21:28 +00:00
										 |  |  | 				if(range.s.r > R) range.s.r = R; if(range.e.r < R) range.e.r = R; | 
					
						
							|  |  |  | 				if(range.s.c > C) range.s.c = C; if(range.e.c < C) range.e.c = C; | 
					
						
							|  |  |  | 				if(!m.length) continue; | 
					
						
							|  |  |  | 				var o/*:Cell*/ = {t:'s', v:m}; | 
					
						
							|  |  |  | 				if(opts.raw || !m.trim().length || _t == 's'){} | 
					
						
							|  |  |  | 				else if(m === 'TRUE') o = {t:'b', v:true}; | 
					
						
							|  |  |  | 				else if(m === 'FALSE') o = {t:'b', v:false}; | 
					
						
							|  |  |  | 				else if(!isNaN(fuzzynum(m))) o = {t:'n', v:fuzzynum(m)}; | 
					
						
							|  |  |  | 				else if(!isNaN(fuzzydate(m).getDate())) { | 
					
						
							|  |  |  | 					o = ({t:'d', v:parseDate(m)}/*:any*/); | 
					
						
							|  |  |  | 					if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/); | 
					
						
							|  |  |  | 					o.z = opts.dateNF || SSF._table[14]; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-12-12 06:21:28 +00:00
										 |  |  | 				if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; } | 
					
						
							|  |  |  | 				else ws[encode_cell({r:R, c:C})] = o; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 				C += CS; | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-09 05:24:32 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 		ws['!ref'] = encode_range(range); | 
					
						
							|  |  |  | 		return ws; | 
					
						
							| 
									
										
										
										
											2017-03-09 05:24:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 	function html_to_book(str/*:string*/, opts)/*:Workbook*/ { | 
					
						
							|  |  |  | 		return sheet_to_workbook(html_to_sheet(str, opts), opts); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-05-16 17:45:35 +00:00
										 |  |  | 	function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HTMLOpts*/)/*:string*/ { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 		var M/*:Array<Range>*/ = (ws['!merges'] ||[]); | 
					
						
							|  |  |  | 		var oo/*:Array<string>*/ = []; | 
					
						
							| 
									
										
										
										
											2017-11-15 18:14:02 +00:00
										 |  |  | 		var nullcell = "<td>" + (o.editable ? '<span contenteditable="true"></span>' : "" ) + "</td>"; | 
					
						
							| 
									
										
										
										
											2017-04-16 07:31:21 +00:00
										 |  |  | 		for(var C = r.s.c; C <= r.e.c; ++C) { | 
					
						
							|  |  |  | 			var RS = 0, CS = 0; | 
					
						
							|  |  |  | 			for(var j = 0; j < M.length; ++j) { | 
					
						
							|  |  |  | 				if(M[j].s.r > R || M[j].s.c > C) continue; | 
					
						
							|  |  |  | 				if(M[j].e.r < R || M[j].e.c < C) continue; | 
					
						
							|  |  |  | 				if(M[j].s.r < R || M[j].s.c < C) { RS = -1; break; } | 
					
						
							|  |  |  | 				RS = M[j].e.r - M[j].s.r + 1; CS = M[j].e.c - M[j].s.c + 1; break; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-04-16 07:31:21 +00:00
										 |  |  | 			if(RS < 0) continue; | 
					
						
							|  |  |  | 			var coord = encode_cell({r:R,c:C}); | 
					
						
							|  |  |  | 			var cell = o.dense ? (ws[R]||[])[C] : ws[coord]; | 
					
						
							| 
									
										
										
										
											2017-05-16 17:45:35 +00:00
										 |  |  | 			if(!cell || cell.v == null) { oo.push(nullcell); continue; } | 
					
						
							| 
									
										
										
										
											2017-04-16 07:31:21 +00:00
										 |  |  | 			/* TODO: html entities */ | 
					
						
							|  |  |  | 			var w = cell.h || escapexml(cell.w || (format_cell(cell), cell.w) || ""); | 
					
						
							|  |  |  | 			var sp = {}; | 
					
						
							|  |  |  | 			if(RS > 1) sp.rowspan = RS; | 
					
						
							|  |  |  | 			if(CS > 1) sp.colspan = CS; | 
					
						
							| 
									
										
										
										
											2017-12-12 06:21:28 +00:00
										 |  |  | 			sp.t = cell.t; | 
					
						
							| 
									
										
										
										
											2017-11-20 01:51:14 +00:00
										 |  |  | 			if(o.editable) w = '<span contenteditable="true">' + w + '</span>'; | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 			sp.id = "sjs-" + coord; | 
					
						
							| 
									
										
										
										
											2017-04-16 07:31:21 +00:00
										 |  |  | 			oo.push(writextag('td', w, sp)); | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 		var preamble = "<tr>"; | 
					
						
							|  |  |  | 		return preamble + oo.join("") + "</tr>"; | 
					
						
							| 
									
										
										
										
											2017-04-16 07:31:21 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-02-03 20:46:32 +00:00
										 |  |  | 	function make_html_preamble(ws/*:Worksheet*/, R/*:Range*/, o/*:Sheet2HTMLOpts*/)/*:string*/ { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 		var out/*:Array<string>*/ = []; | 
					
						
							| 
									
										
										
										
											2018-02-03 20:46:32 +00:00
										 |  |  | 		return out.join("") + '<table' + (o && o.id ? ' id="' + o.id + '"' : "") + '>'; | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	var _BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>'; | 
					
						
							|  |  |  | 	var _END = '</body></html>'; | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | 	function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*//*, wb:?Workbook*/)/*:string*/ { | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 		var o = opts || {}; | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 		var header = o.header != null ? o.header : _BEGIN; | 
					
						
							|  |  |  | 		var footer = o.footer != null ? o.footer : _END; | 
					
						
							|  |  |  | 		var out/*:Array<string>*/ = [header]; | 
					
						
							| 
									
										
										
										
											2017-04-16 07:31:21 +00:00
										 |  |  | 		var r = decode_range(ws['!ref']); | 
					
						
							|  |  |  | 		o.dense = Array.isArray(ws); | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 		out.push(make_html_preamble(ws, r, o)); | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 		out.push("</table>" + footer); | 
					
						
							|  |  |  | 		return out.join(""); | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return { | 
					
						
							|  |  |  | 		to_workbook: html_to_book, | 
					
						
							|  |  |  | 		to_sheet: html_to_sheet, | 
					
						
							| 
									
										
										
										
											2017-04-16 07:31:21 +00:00
										 |  |  | 		_row: make_html_row, | 
					
						
							| 
									
										
										
										
											2017-05-16 17:45:35 +00:00
										 |  |  | 		BEGIN: _BEGIN, | 
					
						
							|  |  |  | 		END: _END, | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 		_preamble: make_html_preamble, | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 		from_sheet: sheet_to_html | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | })(); | 
					
						
							| 
									
										
										
										
											2017-03-29 19:14:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ { | 
					
						
							|  |  |  | 	var opts = _opts || {}; | 
					
						
							|  |  |  | 	if(DENSE != null) opts.dense = DENSE; | 
					
						
							|  |  |  | 	var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/); | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var rows/*:HTMLCollection<HTMLTableRowElement>*/ = table.getElementsByTagName('tr'); | 
					
						
							|  |  |  | 	var range/*:Range*/ = {s:{r:0,c:0},e:{r:rows.length - 1,c:0}}; | 
					
						
							|  |  |  | 	var merges/*:Array<Range>*/ = [], midx = 0; | 
					
						
							| 
									
										
										
										
											2017-03-29 19:14:15 +00:00
										 |  |  | 	var R = 0, _C = 0, C = 0, RS = 0, CS = 0; | 
					
						
							|  |  |  | 	for(; R < rows.length; ++R) { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 		var row/*:HTMLTableRowElement*/ = rows[R]; | 
					
						
							|  |  |  | 		var elts/*:HTMLCollection<HTMLTableCellElement>*/ = (row.children/*:any*/); | 
					
						
							| 
									
										
										
										
											2017-03-29 19:14:15 +00:00
										 |  |  | 		for(_C = C = 0; _C < elts.length; ++_C) { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 			var elt/*:HTMLTableCellElement*/ = elts[_C], v = htmldecode(elts[_C].innerHTML); | 
					
						
							| 
									
										
										
										
											2017-03-29 19:14:15 +00:00
										 |  |  | 			for(midx = 0; midx < merges.length; ++midx) { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 				var m/*:Range*/ = merges[midx]; | 
					
						
							| 
									
										
										
										
											2017-03-29 19:14:15 +00:00
										 |  |  | 				if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; } | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			/* TODO: figure out how to extract nonstandard mso- style */ | 
					
						
							|  |  |  | 			CS = +elt.getAttribute("colspan") || 1; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 			if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}}); | 
					
						
							| 
									
										
										
										
											2017-05-17 04:23:36 +00:00
										 |  |  | 			var o/*:Cell*/ = {t:'s', v:v}; | 
					
						
							| 
									
										
										
										
											2017-12-12 06:21:28 +00:00
										 |  |  | 			var _t/*:string*/ = elt.getAttribute("t") || ""; | 
					
						
							| 
									
										
										
										
											2017-08-18 18:10:18 +00:00
										 |  |  | 			if(v != null) { | 
					
						
							| 
									
										
										
										
											2017-12-12 06:21:28 +00:00
										 |  |  | 				if(v.length == 0) o.t = _t || 'z'; | 
					
						
							|  |  |  | 				else if(opts.raw || v.trim().length == 0 || _t == "s"){} | 
					
						
							| 
									
										
										
										
											2017-08-18 18:10:18 +00:00
										 |  |  | 				else if(v === 'TRUE') o = {t:'b', v:true}; | 
					
						
							|  |  |  | 				else if(v === 'FALSE') o = {t:'b', v:false}; | 
					
						
							| 
									
										
										
										
											2017-08-09 22:38:23 +00:00
										 |  |  | 				else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)}; | 
					
						
							| 
									
										
										
										
											2017-05-17 04:23:36 +00:00
										 |  |  | 				else if(!isNaN(fuzzydate(v).getDate())) { | 
					
						
							|  |  |  | 					o = ({t:'d', v:parseDate(v)}/*:any*/); | 
					
						
							|  |  |  | 					if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/); | 
					
						
							|  |  |  | 					o.z = opts.dateNF || SSF._table[14]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 			if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; } | 
					
						
							|  |  |  | 			else ws[encode_cell({c:C, r:R})] = o; | 
					
						
							| 
									
										
										
										
											2017-04-04 16:09:41 +00:00
										 |  |  | 			if(range.e.c < C) range.e.c = C; | 
					
						
							| 
									
										
										
										
											2017-03-29 19:14:15 +00:00
										 |  |  | 			C += CS; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ws['!merges'] = merges; | 
					
						
							| 
									
										
										
										
											2017-04-01 07:32:12 +00:00
										 |  |  | 	ws['!ref'] = encode_range(range); | 
					
						
							| 
									
										
										
										
											2017-03-29 19:14:15 +00:00
										 |  |  | 	return ws; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function table_to_book(table/*:HTMLElement*/, opts/*:?any*/)/*:Workbook*/ { | 
					
						
							|  |  |  | 	return sheet_to_workbook(parse_dom_table(table, opts), opts); | 
					
						
							|  |  |  | } |