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");
|
2019-11-15 01:46:49 +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.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 ? */
|
2019-11-01 03:09:14 +00:00
|
|
|
case '<fileSharing':
|
|
|
|
break;
|
|
|
|
case '<fileSharing/>': break;
|
2014-01-28 16:38:02 +00:00
|
|
|
|
|
|
|
/* 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]) {
|
2018-01-23 09:07:51 +00:00
|
|
|
case "bool": wb.WBProps[w[0]] = parsexmlbool(y[w[0]]); break;
|
2017-06-01 21:22:11 +00:00
|
|
|
case "int": wb.WBProps[w[0]] = parseInt(y[w[0]], 10); break;
|
|
|
|
default: wb.WBProps[w[0]] = y[w[0]];
|
|
|
|
}
|
|
|
|
});
|
2020-07-27 12:46:17 +00:00
|
|
|
if(y.codeName) wb.WBProps.CodeName = utf8read(y.codeName);
|
2017-06-01 21:22:11 +00:00
|
|
|
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 ? */
|
2019-11-01 03:09:14 +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 + */
|
2018-04-27 20:11:18 +00:00
|
|
|
case '<workbookView': 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 = {};
|
2018-08-22 04:47:23 +00:00
|
|
|
dname.Name = utf8read(y.name);
|
2017-03-19 17:26:13 +00:00
|
|
|
if(y.comment) dname.Comment = y.comment;
|
2017-04-11 22:15:36 +00:00
|
|
|
if(y.localSheetId) dname.Sheet = +y.localSheetId;
|
2019-04-01 14:25:15 +00:00
|
|
|
if(parsexmlbool(y.hidden||"0")) dname.Hidden = true;
|
2017-03-19 17:26:13 +00:00
|
|
|
dnstart = idx + x.length;
|
|
|
|
} break;
|
|
|
|
case '</definedName>': {
|
2018-08-22 04:47:23 +00:00
|
|
|
dname.Ref = unescapexml(utf8read(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;
|
2019-11-01 03:09:14 +00:00
|
|
|
/* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
|
2014-01-28 16:38:02 +00:00
|
|
|
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;
|
2019-11-01 03:09:14 +00:00
|
|
|
/* 18.2.22 smartTagType CT_SmartTagType ? */
|
2014-01-28 16:38:02 +00:00
|
|
|
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;
|
2019-11-01 03:09:14 +00:00
|
|
|
/* 18.2.7 ext CT_Extension + */
|
2014-01-28 16:38:02 +00:00
|
|
|
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;
|
2017-10-02 08:15:36 +00:00
|
|
|
case '<AlternateContent':
|
|
|
|
case '<AlternateContent>': pass=true; break;
|
2014-06-05 07:06:20 +00:00
|
|
|
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
|
|
|
|
});
|
|
|
|
|
2018-01-23 09:07:51 +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-11-20 01:51:14 +00:00
|
|
|
var workbookPr/*:any*/ = ({codeName:"ThisWorkbook"}/*:any*/);
|
2017-06-03 07:19:09 +00:00
|
|
|
if(wb.Workbook && wb.Workbook.WBProps) {
|
|
|
|
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*/);
|
|
|
|
});
|
2017-11-20 01:51:14 +00:00
|
|
|
/*:: if(!wb.Workbook || !wb.Workbook.WBProps) throw "unreachable"; */
|
|
|
|
if(wb.Workbook.WBProps.CodeName) { workbookPr.codeName = wb.Workbook.WBProps.CodeName; delete workbookPr.CodeName; }
|
2017-06-03 07:19:09 +00:00
|
|
|
}
|
|
|
|
o[o.length] = (writextag('workbookPr', null, workbookPr));
|
2017-04-10 05:10:54 +00:00
|
|
|
|
|
|
|
/* workbookProtection */
|
2019-04-01 14:25:15 +00:00
|
|
|
|
|
|
|
var sheets = wb.Workbook && wb.Workbook.Sheets || [];
|
|
|
|
var i = 0;
|
|
|
|
|
2017-04-10 05:10:54 +00:00
|
|
|
/* bookViews */
|
|
|
|
|
2014-06-29 18:29:45 +00:00
|
|
|
o[o.length] = "<sheets>";
|
2019-04-01 14:25:15 +00:00
|
|
|
for(i = 0; i != wb.SheetNames.length; ++i) {
|
2018-01-11 08:01:25 +00:00
|
|
|
var sht = ({name:escapexml(wb.SheetNames[i].slice(0,31))}/*:any*/);
|
2017-03-31 18:46:42 +00:00
|
|
|
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;
|
2019-04-01 14:25:15 +00:00
|
|
|
if(n.Hidden) d.hidden = "1";
|
2017-04-11 22:15:36 +00:00
|
|
|
if(!n.Ref) return;
|
2020-03-15 07:42:05 +00:00
|
|
|
o[o.length] = writextag('definedName', escapexml(n.Ref), d);
|
2017-04-11 22:15:36 +00:00
|
|
|
});
|
|
|
|
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
|
|
|
}
|