| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | /* 18.2 Workbook */ | 
					
						
							| 
									
										
										
										
											2014-07-28 13:22:32 +00:00
										 |  |  | var wbnsregex = /<\w+:workbook/; | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | function parse_wb_xml(data, opts)/*:WorkbookFile*/ { | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	if(!data) throw new Error("Could not find file"); | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 	var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, Names:[], xmlns: "" }; | 
					
						
							| 
									
										
										
										
											2014-04-03 22:51:54 +00:00
										 |  |  | 	var pass = false, xmlns = "xmlns"; | 
					
						
							| 
									
										
										
										
											2017-03-19 17:26:13 +00:00
										 |  |  | 	var dname = {}, dnstart = 0; | 
					
						
							|  |  |  | 	/*(data.match(tagregex)||[]).forEach */ | 
					
						
							|  |  |  | 	data.replace(tagregex, function xml_wb(x, idx) { | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 		var y/*:any*/ = parsexmltag(x); | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 		switch(strip_ns(y[0])) { | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			case '<?xml': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.27 workbook CT_Workbook 1 */ | 
					
						
							| 
									
										
										
										
											2014-04-03 22:51:54 +00:00
										 |  |  | 			case '<workbook': | 
					
						
							| 
									
										
										
										
											2014-07-28 13:22:32 +00:00
										 |  |  | 				if(x.match(wbnsregex)) xmlns = "xmlns" + x.match(/<(\w+):/)[1]; | 
					
						
							| 
									
										
										
										
											2014-04-03 22:51:54 +00:00
										 |  |  | 				wb.xmlns = y[xmlns]; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			case '</workbook>': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.13 fileVersion CT_FileVersion ? */ | 
					
						
							|  |  |  | 			case '<fileVersion': delete y[0]; wb.AppVersion = y; break; | 
					
						
							| 
									
										
										
										
											2017-03-10 08:39:51 +00:00
										 |  |  | 			case '<fileVersion/>': case '</fileVersion>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.12 fileSharing CT_FileSharing ? */ | 
					
						
							|  |  |  | 			case '<fileSharing': case '<fileSharing/>': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.28 workbookPr CT_WorkbookPr ? */ | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | 			case '<workbookPr': | 
					
						
							|  |  |  | 			case '<workbookPr/>': | 
					
						
							|  |  |  | 				WBPropsDef.forEach(function(w) { | 
					
						
							|  |  |  | 					if(y[w[0]] == null) return; | 
					
						
							|  |  |  | 					switch(w[2]) { | 
					
						
							|  |  |  | 						case "bool": wb.WBProps[w[0]] = parsexmlbool(y[w[0]], w[0]); break; | 
					
						
							|  |  |  | 						case "int": wb.WBProps[w[0]] = parseInt(y[w[0]], 10); break; | 
					
						
							|  |  |  | 						default: wb.WBProps[w[0]] = y[w[0]]; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2017-03-10 08:39:51 +00:00
										 |  |  | 			case '</workbookPr>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.29 workbookProtection CT_WorkbookProtection ? */ | 
					
						
							| 
									
										
										
										
											2014-06-05 07:06:20 +00:00
										 |  |  | 			case '<workbookProtection': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			case '<workbookProtection/>': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.1  bookViews CT_BookViews ? */ | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 			case '<bookViews': case '<bookViews>': case '</bookViews>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			/* 18.2.30   workbookView CT_BookView + */ | 
					
						
							|  |  |  | 			case '<workbookView': delete y[0]; wb.WBView.push(y); break; | 
					
						
							| 
									
										
										
										
											2017-03-10 08:39:51 +00:00
										 |  |  | 			case '</workbookView>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.20 sheets CT_Sheets 1 */ | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 			case '<sheets': case '<sheets>': case '</sheets>': break; // aggregate sheet
 | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			/* 18.2.19   sheet CT_Sheet + */ | 
					
						
							| 
									
										
										
										
											2017-03-31 18:46:42 +00:00
										 |  |  | 			case '<sheet': | 
					
						
							|  |  |  | 				switch(y.state) { | 
					
						
							|  |  |  | 					case "hidden": y.Hidden = 1; break; | 
					
						
							|  |  |  | 					case "veryHidden": y.Hidden = 2; break; | 
					
						
							|  |  |  | 					default: y.Hidden = 0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				delete y.state; | 
					
						
							|  |  |  | 				y.name = unescapexml(utf8read(y.name)); | 
					
						
							|  |  |  | 				delete y[0]; wb.Sheets.push(y); break; | 
					
						
							| 
									
										
										
										
											2017-03-10 08:39:51 +00:00
										 |  |  | 			case '</sheet>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.15 functionGroups CT_FunctionGroups ? */ | 
					
						
							|  |  |  | 			case '<functionGroups': case '<functionGroups/>': break; | 
					
						
							|  |  |  | 			/* 18.2.14   functionGroup CT_FunctionGroup + */ | 
					
						
							|  |  |  | 			case '<functionGroup': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.9  externalReferences CT_ExternalReferences ? */ | 
					
						
							| 
									
										
										
										
											2014-06-05 07:06:20 +00:00
										 |  |  | 			case '<externalReferences': case '</externalReferences>': case '<externalReferences>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			/* 18.2.8    externalReference CT_ExternalReference + */ | 
					
						
							|  |  |  | 			case '<externalReference': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.6  definedNames CT_DefinedNames ? */ | 
					
						
							|  |  |  | 			case '<definedNames/>': break; | 
					
						
							| 
									
										
										
										
											2014-06-05 07:06:20 +00:00
										 |  |  | 			case '<definedNames>': case '<definedNames': pass=true; break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			case '</definedNames>': pass=false; break; | 
					
						
							|  |  |  | 			/* 18.2.5    definedName CT_DefinedName + */ | 
					
						
							| 
									
										
										
										
											2017-03-19 17:26:13 +00:00
										 |  |  | 			case '<definedName': { | 
					
						
							|  |  |  | 				dname = {}; | 
					
						
							|  |  |  | 				dname.Name = y.name; | 
					
						
							|  |  |  | 				if(y.comment) dname.Comment = y.comment; | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 				if(y.localSheetId) dname.Sheet = +y.localSheetId; | 
					
						
							| 
									
										
										
										
											2017-03-19 17:26:13 +00:00
										 |  |  | 				dnstart = idx + x.length; | 
					
						
							|  |  |  | 			}	break; | 
					
						
							|  |  |  | 			case '</definedName>': { | 
					
						
							|  |  |  | 				dname.Ref = data.slice(dnstart, idx); | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 				wb.Names.push(dname); | 
					
						
							| 
									
										
										
										
											2017-03-19 17:26:13 +00:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case '<definedName/>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.2  calcPr CT_CalcPr ? */ | 
					
						
							|  |  |  | 			case '<calcPr': delete y[0]; wb.CalcPr = y; break; | 
					
						
							|  |  |  | 			case '<calcPr/>': delete y[0]; wb.CalcPr = y; break; | 
					
						
							| 
									
										
										
										
											2017-03-10 08:39:51 +00:00
										 |  |  | 			case '</calcPr>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.16 oleSize CT_OleSize ? (ref required) */ | 
					
						
							|  |  |  | 			case '<oleSize': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.4  customWorkbookViews CT_CustomWorkbookViews ? */ | 
					
						
							|  |  |  | 			case '<customWorkbookViews>': case '</customWorkbookViews>': case '<customWorkbookViews': break; | 
					
						
							|  |  |  | 			/* 18.2.3    customWorkbookView CT_CustomWorkbookView + */ | 
					
						
							|  |  |  | 			case '<customWorkbookView': case '</customWorkbookView>': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.18 pivotCaches CT_PivotCaches ? */ | 
					
						
							|  |  |  | 			case '<pivotCaches>': case '</pivotCaches>': case '<pivotCaches': break; | 
					
						
							|  |  |  | 			/* 18.2.17 pivotCache CT_PivotCache ? */ | 
					
						
							|  |  |  | 			case '<pivotCache': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.21 smartTagPr CT_SmartTagPr ? */ | 
					
						
							|  |  |  | 			case '<smartTagPr': case '<smartTagPr/>': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.23 smartTagTypes CT_SmartTagTypes ? */ | 
					
						
							|  |  |  | 			case '<smartTagTypes': case '<smartTagTypes>': case '</smartTagTypes>': break; | 
					
						
							|  |  |  | 			/* 18.2.22   smartTagType CT_SmartTagType ? */ | 
					
						
							|  |  |  | 			case '<smartTagType': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.24 webPublishing CT_WebPublishing ? */ | 
					
						
							|  |  |  | 			case '<webPublishing': case '<webPublishing/>': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.11 fileRecoveryPr CT_FileRecoveryPr ? */ | 
					
						
							|  |  |  | 			case '<fileRecoveryPr': case '<fileRecoveryPr/>': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.26 webPublishObjects CT_WebPublishObjects ? */ | 
					
						
							|  |  |  | 			case '<webPublishObjects>': case '<webPublishObjects': case '</webPublishObjects>': break; | 
					
						
							|  |  |  | 			/* 18.2.25 webPublishObject CT_WebPublishObject ? */ | 
					
						
							|  |  |  | 			case '<webPublishObject': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* 18.2.10 extLst CT_ExtensionList ? */ | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 			case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 			/* 18.2.7    ext CT_Extension + */ | 
					
						
							|  |  |  | 			case '<ext': pass=true; break; //TODO: check with versions of excel
 | 
					
						
							|  |  |  | 			case '</ext>': pass=false; break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Others */ | 
					
						
							| 
									
										
										
										
											2014-06-05 07:06:20 +00:00
										 |  |  | 			case '<ArchID': break; | 
					
						
							|  |  |  | 			case '<AlternateContent': pass=true; break; | 
					
						
							|  |  |  | 			case '</AlternateContent>': pass=false; break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-10 22:18:18 +00:00
										 |  |  | 			/* TODO */ | 
					
						
							|  |  |  | 			case '<revisionPtr': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-10 08:39:51 +00:00
										 |  |  | 			default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in workbook'); | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-19 17:26:13 +00:00
										 |  |  | 		return x; | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2014-05-16 00:33:34 +00:00
										 |  |  | 	if(XMLNS.main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns); | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	parse_wb_defaults(wb); | 
					
						
							| 
									
										
										
										
											2014-01-28 16:38:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return wb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:33:34 +00:00
										 |  |  | var WB_XML_ROOT = writextag('workbook', null, { | 
					
						
							|  |  |  | 	'xmlns': XMLNS.main[0], | 
					
						
							|  |  |  | 	//'xmlns:mx': XMLNS.mx,
 | 
					
						
							|  |  |  | 	//'xmlns:s': XMLNS.main[0],
 | 
					
						
							|  |  |  | 	'xmlns:r': XMLNS.r | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ { | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	var o = [XML_HEADER]; | 
					
						
							|  |  |  | 	o[o.length] = WB_XML_ROOT; | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 	var write_names = (wb.Workbook && (wb.Workbook.Names||[]).length > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 	/* fileVersion */ | 
					
						
							|  |  |  | 	/* fileSharing */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-03 07:19:09 +00:00
										 |  |  | 	var workbookPr/*:WBProps*/ = ({codeName:"ThisWorkbook"}/*:any*/); | 
					
						
							|  |  |  | 	if(wb.Workbook && wb.Workbook.WBProps) { | 
					
						
							|  |  |  | 		if(wb.Workbook.WBProps.codeName) workbookPr.codeName = wb.Workbook.WBProps.codeName; | 
					
						
							|  |  |  | 		WBPropsDef.forEach(function(x) { | 
					
						
							|  |  |  | 			/*:: if(!wb.Workbook || !wb.Workbook.WBProps) throw "unreachable"; */ | 
					
						
							|  |  |  | 			if((wb.Workbook.WBProps[x[0]]/*:any*/) == null) return; | 
					
						
							|  |  |  | 			if((wb.Workbook.WBProps[x[0]]/*:any*/) == x[1]) return; | 
					
						
							|  |  |  | 			workbookPr[x[0]] = (wb.Workbook.WBProps[x[0]]/*:any*/); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	o[o.length] = (writextag('workbookPr', null, workbookPr)); | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* workbookProtection */ | 
					
						
							|  |  |  | 	/* bookViews */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	o[o.length] = "<sheets>"; | 
					
						
							| 
									
										
										
										
											2017-03-31 18:46:42 +00:00
										 |  |  | 	var sheets = wb.Workbook && wb.Workbook.Sheets || []; | 
					
						
							|  |  |  | 	for(var i = 0; i != wb.SheetNames.length; ++i) { | 
					
						
							|  |  |  | 		var sht = ({name:escapexml(wb.SheetNames[i].substr(0,31))}/*:any*/); | 
					
						
							|  |  |  | 		sht.sheetId = ""+(i+1); | 
					
						
							|  |  |  | 		sht["r:id"] = "rId"+(i+1); | 
					
						
							|  |  |  | 		if(sheets[i]) switch(sheets[i].Hidden) { | 
					
						
							|  |  |  | 			case 1: sht.state = "hidden"; break; | 
					
						
							|  |  |  | 			case 2: sht.state = "veryHidden"; break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		o[o.length] = (writextag('sheet',null,sht)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	o[o.length] = "</sheets>"; | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* functionGroups */ | 
					
						
							|  |  |  | 	/* externalReferences */ | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 	if(write_names) { | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 		o[o.length] = "<definedNames>"; | 
					
						
							| 
									
										
										
										
											2017-04-16 04:32:13 +00:00
										 |  |  | 		if(wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function(n) { | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 			var d/*:any*/ = {name:n.Name}; | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 			if(n.Comment) d.comment = n.Comment; | 
					
						
							|  |  |  | 			if(n.Sheet != null) d.localSheetId = ""+n.Sheet; | 
					
						
							|  |  |  | 			if(!n.Ref) return; | 
					
						
							|  |  |  | 			o[o.length] = writextag('definedName', String(n.Ref), d); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		o[o.length] = "</definedNames>"; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 	/* calcPr */ | 
					
						
							|  |  |  | 	/* oleSize */ | 
					
						
							|  |  |  | 	/* customWorkbookViews */ | 
					
						
							|  |  |  | 	/* pivotCaches */ | 
					
						
							|  |  |  | 	/* smartTagPr */ | 
					
						
							|  |  |  | 	/* smartTagTypes */ | 
					
						
							|  |  |  | 	/* webPublishing */ | 
					
						
							|  |  |  | 	/* fileRecoveryPr */ | 
					
						
							|  |  |  | 	/* webPublishObjects */ | 
					
						
							|  |  |  | 	/* extLst */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); } | 
					
						
							| 
									
										
										
										
											2014-05-16 00:33:34 +00:00
										 |  |  | 	return o.join(""); | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | } |