diff --git a/xlsx.js b/xlsx.js index a9ffb58..48bdc05 100644 --- a/xlsx.js +++ b/xlsx.js @@ -102,13 +102,15 @@ function parseSheet(data) { //TODO: use a real xml parser if(!data.match(//)) data.match(/(.*)<\/sheetData>/)[1].split("").forEach(function(x) { if(x === "") return; var row = parsexmltag(x.match(/]*>/)[0]); //s.rows[row.r]=row.spans; - var cells = x.substr(x.indexOf('>')+1).split(""); + var cells = x.substr(x.indexOf('>')+1).split(/<\/c>|\/>/); cells.forEach(function(c) { if(c === "") return; - var cell = parsexmltag(c.match(/]*>/)[0]); delete cell[0]; + var cell = parsexmltag((c.match(/]*>/)||[c])[0]); delete cell[0]; var d = c.substr(c.indexOf('>')+1); var p = {}; q.forEach(function(f){var x=d.match(matchtag(f));if(x)p[f]=unescapexml(x[1]);}); - p.t = (cell.t ? cell.t : "n"); // default is "n" in schema + /* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */ + if(cell.t === undefined) { p.t = "str"; p.v = undefined; } + else p.t = (cell.t ? cell.t : "n"); // default is "n" in schema switch(p.t) { case 'n': p.v = parseFloat(p.v); break; case 's': p.v = strs[parseInt(p.v, 10)].t; break; @@ -125,14 +127,14 @@ function parseSheet(data) { //TODO: use a real xml parser } // matches ... extracts content -function matchtag(f,g) {return new RegExp('<' + f + '>(.*)',g||"");} +function matchtag(f,g) {return new RegExp('<' + f + '>([\\s\\S]*)',g||"");} function parseStrs(data) { var s = []; - var sst = data.match(new RegExp("]*)>(.*)<\/sst>")); + var sst = data.match(new RegExp("]*)>([\\s\\S]*)<\/sst>","m")); if(sst) { s = sst[2].replace(//g,"").split(/<\/si>/).map(function(x) { var z = {}; - var y=x.match(/<(.*)>(.*)<\/.*/); if(x) z[y[1]]=unescapexml(y[2]); return z;}); + var y=x.match(/<(.*)>([\s\S]*)<\/.*/); if(y) z[y[1]]=unescapexml(y[2]); return z;}); sst = parsexmltag(sst[1]); s.count = sst.count; s.uniqueCount = sst.uniqueCount; } @@ -147,7 +149,7 @@ function parseProps(data) { var xtra = ["HeadingPairs", "TitlesOfParts","dc:creator","cp:lastModifiedBy","dcterms:created", "dcterms:modified"]; strings.forEach(function(f){p[f] = (data.match(matchtag(f))||[])[1];}); - bools.forEach(function(f){p[f] = data.match(matchtag(f))[1] == "true";}); + bools.forEach(function(f){p[f] = (data.match(matchtag(f))||[])[1] == "true";}); xtra.forEach(function(f) { var cur = data.match(new RegExp("<" + f + "[^>]*>(.*)<\/" + f + ">")); if(cur && cur.length > 0) q[f] = cur[1]; @@ -215,6 +217,7 @@ function parseWB(data) { if(y.appName != "xl") throw "Unexpected workbook.appName: "+y.appName; delete y[0]; wb.AppVersion = y; break; case '': delete y[0]; wb.WBProps = y; break; case '': case '': break; // aggregate workbookView case '': case '': break; // aggregate sheet @@ -222,6 +225,7 @@ function parseWB(data) { case '': case '': case '': break; case '': break; case '': delete y[0]; wb.CalcPr = y; break; case '