From 8938336e1c001593e949612b8d95dcb2556e1e2c Mon Sep 17 00:00:00 2001 From: Alex Litskevich <alitskevich@gmail.com> Date: Sun, 19 Mar 2017 20:26:13 +0300 Subject: [PATCH] XLSX Defined Names closes #162 h/t @alitskevich --- bits/72_wbxml.js | 20 +++++++++++++++++--- xlsx.flow.js | 20 +++++++++++++++++--- xlsx.js | 20 +++++++++++++++++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/bits/72_wbxml.js b/bits/72_wbxml.js index 9048628..2c1e134 100644 --- a/bits/72_wbxml.js +++ b/bits/72_wbxml.js @@ -2,9 +2,11 @@ var wbnsregex = /<\w+:workbook/; function parse_wb_xml(data, opts)/*:WorkbookFile*/ { if(!data) throw new Error("Could not find file"); - var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" }; + var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, Names:{'!names':[]}, xmlns: "" }; var pass = false, xmlns = "xmlns"; - (data.match(tagregex)||[]).forEach(function xml_wb(x) { + var dname = {}, dnstart = 0; + /*(data.match(tagregex)||[]).forEach */ + data.replace(tagregex, function xml_wb(x, idx) { var y = parsexmltag(x); switch(strip_ns(y[0])) { case '<?xml': break; @@ -59,7 +61,18 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ { case '<definedNames>': case '<definedNames': pass=true; break; case '</definedNames>': pass=false; break; /* 18.2.5 definedName CT_DefinedName + */ - case '<definedName': case '<definedName/>': case '</definedName>': break; + case '<definedName': { + dname = {}; + dname.Name = y.name; + if(y.comment) dname.Comment = y.comment; + dnstart = idx + x.length; + } break; + case '</definedName>': { + dname.Ref = data.slice(dnstart, idx); + wb.Names[dname.Name] = dname; + wb.Names['!names'].push(dname.Name); + } break; + case '<definedName/>': break; /* 18.2.2 calcPr CT_CalcPr ? */ case '<calcPr': delete y[0]; wb.CalcPr = y; break; @@ -111,6 +124,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ { default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in workbook'); } + return x; }); if(XMLNS.main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns); diff --git a/xlsx.flow.js b/xlsx.flow.js index ff917de..1a05868 100644 --- a/xlsx.flow.js +++ b/xlsx.flow.js @@ -9513,9 +9513,11 @@ function check_wb(wb) { var wbnsregex = /<\w+:workbook/; function parse_wb_xml(data, opts)/*:WorkbookFile*/ { if(!data) throw new Error("Could not find file"); - var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" }; + var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, Names:{'!names':[]}, xmlns: "" }; var pass = false, xmlns = "xmlns"; - (data.match(tagregex)||[]).forEach(function xml_wb(x) { + var dname = {}, dnstart = 0; + /*(data.match(tagregex)||[]).forEach */ + data.replace(tagregex, function xml_wb(x, idx) { var y = parsexmltag(x); switch(strip_ns(y[0])) { case '<?xml': break; @@ -9570,7 +9572,18 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ { case '<definedNames>': case '<definedNames': pass=true; break; case '</definedNames>': pass=false; break; /* 18.2.5 definedName CT_DefinedName + */ - case '<definedName': case '<definedName/>': case '</definedName>': break; + case '<definedName': { + dname = {}; + dname.Name = y.name; + if(y.comment) dname.Comment = y.comment; + dnstart = idx + x.length; + } break; + case '</definedName>': { + dname.Ref = data.slice(dnstart, idx); + wb.Names[dname.Name] = dname; + wb.Names['!names'].push(dname.Name); + } break; + case '<definedName/>': break; /* 18.2.2 calcPr CT_CalcPr ? */ case '<calcPr': delete y[0]; wb.CalcPr = y; break; @@ -9622,6 +9635,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ { default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in workbook'); } + return x; }); if(XMLNS.main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns); diff --git a/xlsx.js b/xlsx.js index ea29657..7c0ac53 100644 --- a/xlsx.js +++ b/xlsx.js @@ -9460,9 +9460,11 @@ function check_wb(wb) { var wbnsregex = /<\w+:workbook/; function parse_wb_xml(data, opts) { if(!data) throw new Error("Could not find file"); - var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" }; + var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, Names:{'!names':[]}, xmlns: "" }; var pass = false, xmlns = "xmlns"; - (data.match(tagregex)||[]).forEach(function xml_wb(x) { + var dname = {}, dnstart = 0; + /*(data.match(tagregex)||[]).forEach */ + data.replace(tagregex, function xml_wb(x, idx) { var y = parsexmltag(x); switch(strip_ns(y[0])) { case '<?xml': break; @@ -9517,7 +9519,18 @@ function parse_wb_xml(data, opts) { case '<definedNames>': case '<definedNames': pass=true; break; case '</definedNames>': pass=false; break; /* 18.2.5 definedName CT_DefinedName + */ - case '<definedName': case '<definedName/>': case '</definedName>': break; + case '<definedName': { + dname = {}; + dname.Name = y.name; + if(y.comment) dname.Comment = y.comment; + dnstart = idx + x.length; + } break; + case '</definedName>': { + dname.Ref = data.slice(dnstart, idx); + wb.Names[dname.Name] = dname; + wb.Names['!names'].push(dname.Name); + } break; + case '<definedName/>': break; /* 18.2.2 calcPr CT_CalcPr ? */ case '<calcPr': delete y[0]; wb.CalcPr = y; break; @@ -9569,6 +9582,7 @@ function parse_wb_xml(data, opts) { default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in workbook'); } + return x; }); if(XMLNS.main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns);