fixed flow typecheck

- update FilterDatabase defined name when writing AutoFilter
- XLML stub cells have blank Data block
- HTML export honor `id` option
- expose `sheet_get_cell`
This commit is contained in:
SheetJS 2019-10-31 23:09:14 -04:00
parent b0d18ed6db
commit b7c0b0d914
64 changed files with 2581 additions and 1239 deletions

View File

@ -8,11 +8,14 @@
.*/misc/.*
.*/perf/.*
.*/_book/.*
.*/packages/.*
.*/demo/browser.js
.*/shim.js
.*/xlsx.js
.*/xlsx.mini.js
.*/xlsx.mini.flow.js
.*/xlsxworker.js
.*/jszip.js
.*/tests/.*

1
.github/FUNDING.yml vendored
View File

@ -1,2 +1,3 @@
github: SheetJSDev
custom: https://sheetjs.com
open_collective: s5s

View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (C) 2012-present SheetJS LLC
Copyright (C) 2012-present SheetJS LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -261,21 +261,21 @@ switch(true) {
break;
}
function dump_props(wb) {
function dump_props(wb/*:Workbook*/) {
var propaoa = [];
if(Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops));
else {
var Keys, pi;
var Keys/*:: :Array<string> = []*/, pi;
if(wb.Props) {
Keys = Object.keys(wb.Props);
for(pi = 0; pi < Keys.length; ++pi) {
if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[Keys[pi]]]);
if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]);
}
}
if(wb.Custprops) {
Keys = Object.keys(wb.Custprops);
for(pi = 0; pi < Keys.length; ++pi) {
if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[Keys[pi]]]);
if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]);
}
}
}

View File

@ -25,7 +25,6 @@ function new_unsafe_buf(len/*:number*/) {
}
var s2a = function s2a(s/*:string*/)/*:any*/ {
// $FlowIgnore
if(has_buf) return Buffer_from(s, "binary");
return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; });
};

View File

@ -64,17 +64,6 @@ function zip_add_file(zip, path, content) {
else zip.file(path, content);
}
function zip_read(d, o) {
var zip;
switch(o.type) {
case "base64": zip = new jszip(d, { base64:true }); break;
case "binary": case "array": zip = new jszip(d, { base64:false }); break;
case "buffer": zip = new jszip(d); break;
default: throw new Error("Unrecognized type " + o.type);
}
return zip;
}
var jszip;
/*:: declare var JSZipSync:any; */
/*global JSZipSync:true */
@ -86,10 +75,29 @@ if(typeof exports !== 'undefined') {
}
function zip_new() {
if(!jszip) return CFB.utils.cfb_new();
return new jszip();
}
function zip_read(d, o) {
var zip;
if(jszip) switch(o.type) {
case "base64": zip = new jszip(d, { base64:true }); break;
case "binary": case "array": zip = new jszip(d, { base64:false }); break;
case "buffer": zip = new jszip(d); break;
default: throw new Error("Unrecognized type " + o.type);
}
else switch(o.type) {
case "base64": zip = CFB.read(d, { type: "base64" }); break;
case "binary": zip = CFB.read(d, { type: "binary" }); break;
case "buffer": case "array": zip = CFB.read(d, { type: "buffer" }); break;
default: throw new Error("Unrecognized type " + o.type);
}
return zip;
}
function resolve_path(path/*:string*/, base/*:string*/)/*:string*/ {
if(path.charAt(0) == "/") return path.slice(1);
var result = base.split('/');
if(base.slice(-1) != "/") result.pop(); // folder path
var target = path.split('/');

View File

@ -1,6 +1,7 @@
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s?[\/\?]?>/g;
if(!(XML_HEADER.match(tagregex))) tagregex = /<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
@ -154,11 +155,9 @@ if(has_buf) {
};
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer_from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
// $FlowIgnore
utf8write = function(data) { return Buffer_from(data, 'utf8').toString("binary"); };
}

View File

@ -26,8 +26,8 @@ function encode_cell_xls(c/*:CellAddress*/, biff/*:number*/)/*:string*/ {
if(c.cRel && c.c < 0) { c = dup(c); c.c += (biff > 8) ? 0x4000 : 0x100; }
if(c.rRel && c.r < 0) { c = dup(c); c.r += (biff > 8) ? 0x100000 : ((biff > 5) ? 0x10000 : 0x4000); }
var s = encode_cell(c);
if(c.cRel === 0) s = fix_col(s);
if(c.rRel === 0) s = fix_row(s);
if(!c.cRel && c.cRel != null) s = fix_col(s);
if(!c.rRel && c.rRel != null) s = fix_row(s);
return s;
}

View File

@ -149,6 +149,7 @@ function write_RfX(r/*:Range*/, o) {
var parse_UncheckedRfX = parse_RfX;
var write_UncheckedRfX = write_RfX;
/* [MS-XLS] 2.5.342 ; [MS-XLSB] 2.5.171 */
/* TODO: error checking, NaN and Infinity values are not valid Xnum */
function parse_Xnum(data/*::, length*/) { return data.read_shift(8, 'f'); }
@ -204,10 +205,10 @@ function parse_BrtColor(data/*::, length*/) {
function write_BrtColor(color, o) {
if(!o) o = new_buf(8);
if(!color||color.auto) { o.write_shift(4, 0); o.write_shift(4, 0); return o; }
if(color.index) {
if(color.index != null) {
o.write_shift(1, 0x02);
o.write_shift(1, color.index);
} else if(color.theme) {
} else if(color.theme != null) {
o.write_shift(1, 0x06);
o.write_shift(1, color.theme);
} else {
@ -218,12 +219,13 @@ function write_BrtColor(color, o) {
if(nTS > 0) nTS *= 32767;
else if(nTS < 0) nTS *= 32768;
o.write_shift(2, nTS);
if(!color.rgb) {
if(!color.rgb || color.theme != null) {
o.write_shift(2, 0);
o.write_shift(1, 0);
o.write_shift(1, 0);
} else {
var rgb = (color.rgb || 'FFFFFF');
if(typeof rgb == 'number') rgb = ("000000" + rgb.toString(16)).slice(-6);
o.write_shift(1, parseInt(rgb.slice(0,2),16));
o.write_shift(1, parseInt(rgb.slice(2,4),16));
o.write_shift(1, parseInt(rgb.slice(4,6),16));
@ -237,9 +239,9 @@ function parse_FontFlags(data/*::, length, opts*/) {
var d = data.read_shift(1);
data.l++;
var out = {
/* fBold: d & 0x01 */
fBold: d & 0x01,
fItalic: d & 0x02,
/* fUnderline: d & 0x04 */
fUnderline: d & 0x04,
fStrikeout: d & 0x08,
fOutline: d & 0x10,
fShadow: d & 0x20,

View File

@ -185,11 +185,11 @@ var XLSFillPattern = [
'gray0625'
];
function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
function rgbify(arr/*:Array<number>*/)/*:Array<[number, number, number]>*/ { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
/* [MS-XLS] 2.5.161 */
/* [MS-XLSB] 2.5.75 Icv */
var XLSIcv = rgbify([
var _XLSIcv = rgbify([
/* Color Constants */
0x000000,
0xFFFFFF,
@ -281,4 +281,4 @@ var XLSIcv = rgbify([
0x000000, /* 0x50 icvInfoBk ?? */
0x000000 /* 0x51 icvInfoText ?? */
]);
var XLSIcv = dup(_XLSIcv);

View File

@ -26,12 +26,18 @@ var ct2type/*{[string]:string}*/ = ({
"application/vnd.ms-excel.pivotTable": "TODO",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO",
/* Chart Objects */
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
/* Chart Colors */
"application/vnd.ms-office.chartcolorstyle+xml": "TODO",
/* Chart Style */
"application/vnd.ms-office.chartstyle+xml": "TODO",
/* Chart Advanced */
"application/vnd.ms-office.chartex+xml": "TODO",
/* Calculation Chain */
"application/vnd.ms-excel.calcChain": "calcchains",
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
@ -122,7 +128,6 @@ var ct2type/*{[string]:string}*/ = ({
/* Drawing */
"application/vnd.openxmlformats-officedocument.drawing+xml": "drawings",
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO",
@ -231,6 +236,7 @@ var CTYPE_DEFAULTS = [
['xml', 'application/xml'],
['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'],
['vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'],
['data', 'application/vnd.openxmlformats-officedocument.model+data'],
/* from test files */
['bmp', 'image/bmp'],
['png', 'image/png'],
@ -250,6 +256,8 @@ function write_ct(ct, opts)/*:string*/ {
o[o.length] = (XML_HEADER);
o[o.length] = (CTYPE_XML_ROOT);
o = o.concat(CTYPE_DEFAULTS);
/* only write first instance */
var f1 = function(w) {
if(ct[w] && ct[w].length > 0) {
v = ct[w][0];
@ -259,6 +267,8 @@ function write_ct(ct, opts)/*:string*/ {
}));
}
};
/* book type-specific */
var f2 = function(w) {
(ct[w]||[]).forEach(function(v) {
o[o.length] = (writextag('Override', null, {
@ -267,6 +277,8 @@ function write_ct(ct, opts)/*:string*/ {
}));
});
};
/* standard type */
var f3 = function(t) {
(ct[t]||[]).forEach(function(v) {
o[o.length] = (writextag('Override', null, {
@ -275,6 +287,7 @@ function write_ct(ct, opts)/*:string*/ {
}));
});
};
f1('workbooks');
f2('sheets');
f2('charts');

View File

@ -4,6 +4,9 @@ var RELS = ({
SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
HLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
VML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
XPATH: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath",
XMISS: "http://schemas.microsoft.com/office/2006/relationships/xlExternalLinkPath/xlPathMissing",
XLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
VBA: "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
}/*:any*/);
@ -52,14 +55,16 @@ function write_rels(rels)/*:string*/ {
return o.join("");
}
function add_rels(rels, rId, f, type, relobj)/*:number*/ {
var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
if(!relobj) relobj = {};
if(!rels['!id']) rels['!id'] = {};
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
relobj.Id = 'rId' + rId;
relobj.Type = type;
relobj.Target = f;
if(relobj.Type == RELS.HLINK) relobj.TargetMode = "External";
if(targetmode) relobj.TargetMode = targetmode;
else if(RELS_EXTERN.indexOf(relobj.Type) > -1) relobj.TargetMode = "External";
if(rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId);
rels['!id'][relobj.Id] = relobj;
rels[('/' + relobj.Target).replace("//","/")] = relobj;

View File

@ -44,12 +44,14 @@ function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) {
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Hojas de cálculo":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "Rangos con nombre":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":

View File

@ -943,7 +943,9 @@ function parse_ColInfo(blob, length, opts) {
var ixfe = blob.read_shift(w);
var flags = blob.read_shift(2);
if(w == 2) blob.l += 2;
return {s:colFirst, e:colLast, w:coldx, ixfe:ixfe, flags:flags};
var o = ({s:colFirst, e:colLast, w:coldx, ixfe:ixfe, flags:flags}/*:any*/);
if(opts.biff >= 5 || !opts.biff) o.level = (flags >> 8) & 0x7;
return o;
}
/* [MS-XLS] 2.4.257 */

View File

@ -259,7 +259,7 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
h.write_shift(2, 296 + 32 * hcnt);
h.write_shift(2, rlen);
for(i=0; i < 4; ++i) h.write_shift(4, 0);
h.write_shift(4, 0x00000000 | ((+dbf_reverse_map[current_ansi] || 0x03)<<8));
h.write_shift(4, 0x00000000 | ((+dbf_reverse_map[/*::String(*/current_ansi/*::)*/] || 0x03)<<8));
for(i = 0, j = 0; i < headers.length; ++i) {
if(headers[i] == null) continue;
@ -316,7 +316,7 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
var SYLK = (function() {
/* TODO: stress test sequences */
var sylk_escapes = {
var sylk_escapes = ({
AA:'À', BA:'Á', CA:'Â', DA:195, HA:'Ä', JA:197,
AE:'È', BE:'É', CE:'Ê', HE:'Ë',
AI:'Ì', BI:'Í', CI:'Î', HI:'Ï',
@ -329,11 +329,13 @@ var SYLK = (function() {
Au:'ù', Bu:'ú', Cu:'û', Hu:'ü',
KC:'Ç', Kc:'ç', q:'æ', z:'œ', a:'Æ', j:'Œ',
DN:209, Dn:241, Hy:255,
S:169, c:170, R:174, 0:176, 1:177, 2:178, 3:179, B:180, 5:181,
6:182, 7:183, Q:185, k:186, b:208, i:216, l:222, s:240, y:248,
S:169, c:170, R:174, B:180,
/*::[*/0/*::]*/:176, /*::[*/1/*::]*/:177, /*::[*/2/*::]*/:178,
/*::[*/3/*::]*/:179, /*::[*/5/*::]*/:181, /*::[*/6/*::]*/:182,
/*::[*/7/*::]*/:183, Q:185, k:186, b:208, i:216, l:222, s:240, y:248,
"!":161, '"':162, "#":163, "(":164, "%":165, "'":167, "H ":168,
"+":171, ";":187, "<":188, "=":189, ">":190, "?":191, "{":223
};
}/*:any*/);
var sylk_char_regex = new RegExp("\u001BN(" + keys(sylk_escapes).join("|").replace(/\|\|\|/, "|\\||").replace(/([?()+])/g,"\\$1") + "|\\|)", "gm");
var sylk_char_fn = function(_, $1){ var o = sylk_escapes[$1]; return typeof o == "number" ? _getansi(o) : o; };
var decode_sylk_char = function($$, $1, $2) { var newcc = (($1.charCodeAt(0) - 0x20)<<4) | ($2.charCodeAt(0) - 0x30); return newcc == 59 ? $$ : _getansi(newcc); };

View File

@ -3,7 +3,7 @@ function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<borders': case '<borders>': case '</borders>': break;
@ -11,8 +11,8 @@ function parse_borders(t, styles, themes, opts) {
/* 18.8.4 border CT_Border */
case '<border': case '<border>': case '<border/>':
border = {};
if (y.diagonalUp) { border.diagonalUp = y.diagonalUp; }
if (y.diagonalDown) { border.diagonalDown = y.diagonalDown; }
if(y.diagonalUp) border.diagonalUp = parsexmlbool(y.diagonalUp);
if(y.diagonalDown) border.diagonalDown = parsexmlbool(y.diagonalDown);
styles.Borders.push(border);
break;
case '</border>': break;
@ -58,7 +58,8 @@ function parse_borders(t, styles, themes, opts) {
case '</end>': break;
/* 18.8.? color CT_Color */
case '<color': case '<color>': break;
case '<color': case '<color>':
break;
case '<color/>': case '</color>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
@ -77,7 +78,7 @@ function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fills': case '<fills>': case '</fills>': break;
@ -115,7 +116,7 @@ function parse_fills(t, styles, themes, opts) {
if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.fgColor.rgb = y.rgb.slice(-6);
if(y.rgb != null) fill.fgColor.rgb = y.rgb.slice(-6);
break;
case '<fgColor/>': case '</fgColor>': break;
@ -143,7 +144,7 @@ function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fonts': case '<fonts>': case '</fonts>': break;
@ -243,6 +244,10 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
@ -300,7 +305,7 @@ function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(strip_ns(y[0])) {
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
@ -326,13 +331,19 @@ function parse_cellXfs(t, styles, opts) {
if(y.horizontal) alignment.horizontal = y.horizontal;
if(y.textRotation != null) alignment.textRotation = y.textRotation;
if(y.indent) alignment.indent = y.indent;
if(y.wrapText) alignment.wrapText = y.wrapText;
if(y.wrapText) alignment.wrapText = parsexmlbool(y.wrapText);
xf.alignment = alignment;
break;
case '</alignment>': break;
/* 18.8.33 protection CT_CellProtection */
case '<protection': case '</protection>': case '<protection/>': break;
case '<protection':
break;
case '</protection>': case '<protection/>': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -348,7 +359,9 @@ function parse_cellXfs(t, styles, opts) {
function write_cellXfs(cellXfs)/*:string*/ {
var o/*:Array<string>*/ = [];
o[o.length] = (writextag('cellXfs',null));
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
cellXfs.forEach(function(c) {
o[o.length] = (writextag('xf', null, c));
});
o[o.length] = ("</cellXfs>");
if(o.length === 2) return "";
o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");

View File

@ -151,7 +151,8 @@ function write_BrtXF(data, ixfeP, o) {
o.write_shift(2, 0); /* ixBorder */
o.write_shift(1, 0); /* trot */
o.write_shift(1, 0); /* indent */
o.write_shift(1, 0); /* flags */
var flow = 0;
o.write_shift(1, flow); /* flags */
o.write_shift(1, 0); /* flags */
o.write_shift(1, 0); /* xfGrbitAtr */
o.write_shift(1, 0);
@ -222,8 +223,10 @@ function parse_sty_bin(data, themes, opts) {
}
break;
case 0x0401: /* 'BrtKnownFonts' */ break;
case 0x002D: /* 'BrtFill' */ break;
case 0x002E: /* 'BrtBorder' */ break;
case 0x002D: /* 'BrtFill' */
break;
case 0x002E: /* 'BrtBorder' */
break;
case 0x002F: /* 'BrtXF' */
if(state[state.length - 1] == "BrtBeginCellXFs") {
styles.CellXf.push(val);
@ -248,14 +251,14 @@ function parse_sty_bin(data, themes, opts) {
case 0x0024: /* 'BrtFRTEnd' */
pass = false; break;
case 0x0025: /* 'BrtACBegin' */
state.push(R_n); break;
state.push(R_n); pass = true; break;
case 0x0026: /* 'BrtACEnd' */
state.pop(); break;
state.pop(); pass = false; break;
default:
if((R_n||"").indexOf("Begin") > 0) state.push(R_n);
else if((R_n||"").indexOf("End") > 0) state.pop();
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
else if(!pass || (opts.WTF && state[state.length-1] != "BrtACBegin")) throw new Error("Unexpected record " + RT + " " + R_n);
}
});
return styles;
@ -319,10 +322,10 @@ function write_CELLSTYLEXFS_bin(ba/*::, data*/) {
var cnt = 1;
write_record(ba, "BrtBeginCellStyleXFs", write_UInt32LE(cnt));
write_record(ba, "BrtXF", write_BrtXF({
numFmtId:0,
fontId:0,
fillId:0,
borderId:0
numFmtId: 0,
fontId: 0,
fillId: 0,
borderId: 0
}, 0xFFFF));
/* 1*65430(BrtXF *FRT) */
write_record(ba, "BrtEndCellStyleXFs");

View File

@ -103,6 +103,7 @@ function parse_theme_xml(data/*:string*/, opts) {
function write_theme(Themes, opts)/*:string*/ {
if(opts && opts.themeXLSX) return opts.themeXLSX;
if(Themes && typeof Themes.raw == "string") return Themes.raw;
var o = [XML_HEADER];
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
o[o.length] = '<a:themeElements>';

View File

@ -1,11 +1,11 @@
/* 18.14 Supplementary Workbook Data */
function parse_xlink_xml(/*::data, name:string, _opts*/) {
function parse_xlink_xml(/*::data, rel, name:string, _opts*/) {
//var opts = _opts || {};
//if(opts.WTF) throw "XLSX External Link";
}
/* [MS-XLSB] 2.1.7.25 External Link */
function parse_xlink_bin(data, name/*:string*/, _opts) {
function parse_xlink_bin(data, rel, name/*:string*/, _opts) {
if(!data) return data;
var opts = _opts || {};

View File

@ -1,6 +1,8 @@
/* 20.5 DrawingML - SpreadsheetML Drawing */
RELS.IMG = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
RELS.DRAW = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
/* 20.5 DrawingML - SpreadsheetML Drawing */
/* 20.5.2.35 wsDr CT_Drawing */
function parse_drawing(data, rels/*:any*/) {
if(!data) return "??";
/*

View File

@ -1,24 +1,6 @@
RELS.CMNT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
for(var i = 0; i != dirComments.length; ++i) {
var canonicalpath=dirComments[i];
var comments=parse_cmnt(getzipdata(zip, canonicalpath.replace(/^\//,''), true), canonicalpath, opts);
if(!comments || !comments.length) continue;
// find the sheets targeted by these comments
var sheetNames = keys(sheets);
for(var j = 0; j != sheetNames.length; ++j) {
var sheetName = sheetNames[j];
var rels = sheetRels[sheetName];
if(rels) {
var rel = rels[canonicalpath];
if(rel) insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
}
}
}
}
function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*/) {
function sheet_insert_comments(sheet, comments/*:Array<RawComment>*/) {
var dense = Array.isArray(sheet);
var cell/*:Cell*/;
comments.forEach(function(comment) {
@ -28,7 +10,7 @@ function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*
cell = sheet[r.r][r.c];
} else cell = sheet[comment.ref];
if (!cell) {
cell = {};
cell = ({t:"z"}/*:any*/);
if(dense) sheet[r.r][r.c] = cell;
else sheet[comment.ref] = cell;
var range = safe_decode_range(sheet["!ref"]||"BDWGO1000001:A1");

View File

@ -39,8 +39,8 @@ function parse_comments_bin(data, opts)/*:Array<RawComment>*/ {
c.t = val.t; c.h = val.h; c.r = val.r; break;
case 0x027C: /* 'BrtEndComment' */
c.author = authors[c.iauthor];
delete c.iauthor;
if(opts.sheetRows && opts.sheetRows <= c.rfx.r) break;
delete (c/*:any*/).iauthor;
if(opts.sheetRows && c.rfx && opts.sheetRows <= c.rfx.r) break;
if(!c.t) c.t = "";
delete c.rfx; out.push(c); break;

View File

@ -1,13 +1,20 @@
/* TODO: it will be useful to parse the function str */
var rc_to_a1 = (function(){
var rcregex = /(^|[^A-Za-z])R(\[?)(-?\d+|)\]?C(\[?)(-?\d+|)\]?/g;
var rcregex = /(^|[^A-Za-z_])R(\[?-?\d+\]|[1-9]\d*|)C(\[?-?\d+\]|[1-9]\d*|)(?![A-Za-z0-9_])/g;
var rcbase/*:Cell*/ = ({r:0,c:0}/*:any*/);
function rcfunc($$,$1,$2,$3,$4,$5) {
var R = $3.length>0?parseInt($3,10)|0:0, C = $5.length>0?parseInt($5,10)|0:0;
if(C<0 && $4.length === 0) C=0;
function rcfunc($$,$1,$2,$3) {
var cRel = false, rRel = false;
if($4.length > 0 || $5.length == 0) cRel = true; if(cRel) C += rcbase.c; else --C;
if($2.length > 0 || $3.length == 0) rRel = true; if(rRel) R += rcbase.r; else --R;
if($2.length == 0) rRel = true;
else if($2.charAt(0) == "[") { rRel = true; $2 = $2.slice(1, -1); }
if($3.length == 0) cRel = true;
else if($3.charAt(0) == "[") { cRel = true; $3 = $3.slice(1, -1); }
var R = $2.length>0?parseInt($2,10)|0:0, C = $3.length>0?parseInt($3,10)|0:0;
if(cRel) C += rcbase.c; else --C;
if(rRel) R += rcbase.r; else --R;
return $1 + (cRel ? "" : "$") + encode_col(C) + (rRel ? "" : "$") + encode_row(R);
}
return function rc_to_a1(fstr/*:string*/, base/*:Cell*/)/*:string*/ {

View File

@ -51,6 +51,19 @@ function parse_FormulaValue(blob/*::, length*/) {
}
return [];
}
function write_FormulaValue(value) {
if(value == null) {
// Blank String Value
var o = new_buf(8);
o.write_shift(1, 0x03);
o.write_shift(1, 0);
o.write_shift(2, 0);
o.write_shift(2, 0);
o.write_shift(2, 0xFFFF);
return o;
} else if(typeof value == "number") return write_Xnum(value);
return write_Xnum(0);
}
/* [MS-XLS] 2.4.127 TODO */
function parse_Formula(blob, length, opts) {
@ -68,6 +81,27 @@ function parse_Formula(blob, length, opts) {
var cbf = parse_XLSCellParsedFormula(blob, end - blob.l, opts);
return {cell:cell, val:val[0], formula:cbf, shared: (flags >> 3) & 1, tt:val[1]};
}
function write_Formula(cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, os/*:number*/) {
// Cell
var o1 = write_XLSCell(R, C, os);
// FormulaValue
var o2 = write_FormulaValue(cell.v);
// flags + cache
var o3 = new_buf(6);
var flags = 0x01 | 0x20;
o3.write_shift(2, flags);
o3.write_shift(4, 0);
// CellParsedFormula
var bf = new_buf(cell.bf.length);
for(var i = 0; i < cell.bf.length; ++i) bf[i] = cell.bf[i];
var out = bconcat([o1, o2, o3, bf]);
return out;
}
/* XLSB Parsed Formula records have the same shape */
function parse_XLSBParsedFormula(data, length, opts) {
@ -82,6 +116,10 @@ function parse_XLSBParsedFormula(data, length, opts) {
var parse_XLSBArrayParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.4 CellParsedFormula */
var parse_XLSBCellParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.8 DVParsedFormula */
//var parse_XLSBDVParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.9 FRTParsedFormula */
//var parse_XLSBFRTParsedFormula = parse_XLSBParsedFormula2;
/* [MS-XLSB] 2.5.97.12 NameParsedFormula */
var parse_XLSBNameParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.98 SharedParsedFormula */

View File

@ -11,9 +11,11 @@ var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g
var marginregex= /<(?:\w:)?pageMargins[^>]*\/>/g;
var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;
/* 18.3 Worksheets */
function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
if(!data) return data;
if(!rels) rels = {'!id':{}};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
/* 18.3.1.99 worksheet CT_Worksheet */
@ -32,7 +34,6 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
/* 18.3.1.35 dimension CT_SheetDimension */
// $FlowIgnore
var ridx = (data1.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
if(ridx > 0) {
var ref = data1.slice(ridx,ridx+50).match(dimregex);
@ -105,18 +106,18 @@ function parse_ws_xml_sheetpr(sheetPr/*:string*/, s, wb/*:WBWBProps*/, idx/*:num
}
/* 18.3.1.85 sheetProtection CT_SheetProtection */
var sheetprot_deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
var sheetprot_deftrue = [
"formatColumns", "formatRows", "formatCells",
"insertColumns", "insertRows", "insertHyperlinks",
"deleteColumns", "deleteRows",
"sort", "autoFilter", "pivotTables"
];
function write_ws_xml_protection(sp)/*:string*/ {
// algorithmName, hashValue, saltValue, spinCountpassword
var o = ({sheet:1}/*:any*/);
var deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
var deftrue = [
"formatColumns", "formatRows", "formatCells",
"insertColumns", "insertRows", "insertHyperlinks",
"deleteColumns", "deleteRows",
"sort", "autoFilter", "pivotTables"
];
deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
sheetprot_deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
sheetprot_deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
/* TODO: algorithm */
if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
return writextag('sheetProtection', null, o);
@ -176,7 +177,6 @@ function parse_ws_xml_cols(columns, cols) {
while(colm <= colM) columns[colm++] = dup(coll);
}
}
function write_ws_xml_cols(ws, cols)/*:string*/ {
var o = ["<cols>"], col;
for(var i = 0; i != cols.length; ++i) {
@ -193,7 +193,7 @@ function parse_ws_xml_autofilter(data/*:string*/) {
}
function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
var ref = typeof data.ref == "string" ? data.ref : encode_range(data.ref);
if(!wb.Workbook) wb.Workbook = {};
if(!wb.Workbook) wb.Workbook = ({Sheets:[]}/*:any*/);
if(!wb.Workbook.Names) wb.Workbook.Names = [];
var names/*: Array<any> */ = wb.Workbook.Names;
var range = decode_range(ref);
@ -210,21 +210,21 @@ function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
/* 18.3.1.88 sheetViews CT_SheetViews */
/* 18.3.1.87 sheetView CT_SheetView */
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/>/;
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/;
function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
(data.match(sviewregex)||[]).forEach(function(r/*:string*/) {
if(!wb.Views) wb.Views = [{}];
(data.match(sviewregex)||[]).forEach(function(r/*:string*/, i/*:number*/) {
var tag = parsexmltag(r);
if(parsexmlbool(tag.rightToLeft)) {
if(!wb.Views) wb.Views = [{}];
if(!wb.Views[0]) wb.Views[0] = {};
wb.Views[0].RTL = true;
}
// $FlowIgnore
if(!wb.Views[i]) wb.Views[i] = {};
// $FlowIgnore
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
});
}
function write_ws_xml_sheetviews(ws, opts, idx, wb)/*:string*/ {
var sview = {workbookViewId:"0"};
var sview = ({workbookViewId:"0"}/*:any*/);
// $FlowIgnore
if( (((wb||{}).Workbook||{}).Views||[])[0] ) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
if((((wb||{}).Workbook||{}).Views||[])[0]) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
return writextag("sheetViews", writextag("sheetView", null, sview), {});
}
@ -232,12 +232,12 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string
if(cell.v === undefined && cell.f === undefined || cell.t === 'z') return "";
var vv = "";
var oldt = cell.t, oldv = cell.v;
switch(cell.t) {
if(cell.t !== "z") switch(cell.t) {
case 'b': vv = cell.v ? "1" : "0"; break;
case 'n': vv = ''+cell.v; break;
case 'e': vv = BErr[cell.v]; break;
case 'd':
if(opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
if(opts && opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
else {
cell = dup(cell);
cell.t = 'n';
@ -312,6 +312,8 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
/* 18.3.1.4 c CT_Cell */
cells = x.slice(ri).split(cellregex);
for(var rslice = 0; rslice != cells.length; ++rslice) if(cells[rslice].trim().charAt(0) != "<") break;
cells = cells.slice(rslice);
for(ri = 0; ri != cells.length; ++ri) {
x = cells[ri].trim();
if(x.length === 0) continue;
@ -393,7 +395,10 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
case 'inlineStr':
cref = d.match(isregex);
p.t = 's';
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
if(cref != null && (sstr = parse_si(cref[1]))) {
p.v = sstr.t;
if(opts.cellHTML) p.h = sstr.h;
} else p.v = "";
break;
case 'b': p.v = parsexmlbool(p.v); break;
case 'd':
@ -407,6 +412,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
}
/* formatting */
fmtid = fillid = 0;
cf = null;
if(do_format && tag.s !== undefined) {
cf = styles.CellXf[tag.s];
if(cf != null) {
@ -541,9 +547,9 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
/* dataValidations */
var relc = -1, rel, rId = -1;
if(ws['!links'].length > 0) {
if(/*::(*/ws['!links']/*::||[])*/.length > 0) {
o[o.length] = "<hyperlinks>";
ws['!links'].forEach(function(l) {
/*::(*/ws['!links']/*::||[])*/.forEach(function(l) {
if(!l[1].Target) return;
rel = ({"ref":l[0]}/*:any*/);
if(l[1].Target.charAt(0) != "#") {
@ -562,7 +568,6 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
if (ws['!margins'] != null) o[o.length] = write_ws_xml_margins(ws['!margins']);
/* pageSetup */
//var hfidx = o.length;
o[o.length] = "";
/* rowBreaks */
@ -574,7 +579,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
/* smartTags */
if(ws['!drawing'].length > 0) {
if(/*::(*/ws['!drawing']/*::||[])*/.length > 0) {
rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW);
o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId});
}

View File

@ -315,8 +315,8 @@ function write_BrtColInfo(C/*:number*/, col, o) {
var flags = 0;
if(col.hidden) flags |= 0x01;
if(typeof p.width == 'number') flags |= 0x02;
o.write_shift(1, flags); // bit flag
o.write_shift(1, 0); // bit flag
if(col.level) flags |= (col.level << 8);
o.write_shift(2, flags); // bit flag
return o;
}
@ -408,6 +408,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
var ref;
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
var state/*:Array<string>*/ = [];
var pass = false, end = false;
var row, p, cf, R, C, addr, sstr, rr, cell/*:Cell*/;
var merges/*:Array<Range>*/ = [];
@ -418,7 +419,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
var arrayf/*:Array<[Range, string]>*/ = [];
var sharedf = {};
var supbooks = opts.supbooks || wb.supbooks || ([[]]/*:any*/);
var supbooks = opts.supbooks || /*::(*/wb/*:: :any)*/.supbooks || ([[]]/*:any*/);
supbooks.sharedf = sharedf;
supbooks.arrayf = arrayf;
supbooks.SheetNames = wb.SheetNames || wb.Sheets.map(function(x) { return x.name; });
@ -543,7 +544,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
case 0x003C: /* 'BrtColInfo' */
if(!opts.cellStyles) break;
while(val.e >= val.s) {
colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01) };
colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01), level: val.level };
if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
process_col(colinfo[val.e+1]);
}
@ -570,6 +571,13 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
case 0x01E5: /* 'BrtWsFmtInfo' */
break;
case 0x0040: /* 'BrtDVal' */
case 0x041D: /* 'BrtDVal14' */
break;
case 0x0097: /* 'BrtPane' */
break;
case 0x00AF: /* 'BrtAFilterDateGroupItem' */
case 0x0284: /* 'BrtActiveX' */
case 0x0271: /* 'BrtBigName' */
@ -590,8 +598,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
case 0x00AE: /* 'BrtCustomFilter' */
case 0x049C: /* 'BrtCustomFilter14' */
case 0x01F3: /* 'BrtDRef' */
case 0x0040: /* 'BrtDVal' */
case 0x041D: /* 'BrtDVal14' */
case 0x0226: /* 'BrtDrawing' */
case 0x00AB: /* 'BrtDynamicFilter' */
case 0x00A7: /* 'BrtFilter' */
@ -603,7 +609,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
case 0x0295: /* 'BrtListPart' */
case 0x027F: /* 'BrtOleObject' */
case 0x01DE: /* 'BrtPageSetup' */
case 0x0097: /* 'BrtPane' */
case 0x0219: /* 'BrtPhoneticInfo' */
case 0x01DD: /* 'BrtPrintOptions' */
case 0x0218: /* 'BrtRangeProtection' */
@ -629,8 +634,10 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
pass = true; break;
case 0x0024: /* 'BrtFRTEnd' */
pass = false; break;
case 0x0025: /* 'BrtACBegin' */ break;
case 0x0026: /* 'BrtACEnd' */ break;
case 0x0025: /* 'BrtACBegin' */
state.push(R_n); pass = true; break;
case 0x0026: /* 'BrtACEnd' */
state.pop(); pass = false; break;
default:
if((R_n||"").indexOf("Begin") > 0){/* empty */}
@ -663,7 +670,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
/* TODO: something useful -- this is a stub */
function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, ws/*:Worksheet*/) {
if(cell.v === undefined) return "";
if(cell.v === undefined) return;
var vv = "";
switch(cell.t) {
case 'b': vv = cell.v ? "1" : "0"; break;
@ -769,9 +776,26 @@ function write_LEGACYDRAWING(ba, ws/*:Worksheet*/, idx/*:number*/, rels) {
}
}
function write_AUTOFILTER(ba, ws) {
function write_AUTOFILTER(ba, ws, wb, idx) {
if(!ws['!autofilter']) return;
write_record(ba, "BrtBeginAFilter", write_UncheckedRfX(safe_decode_range(ws['!autofilter'].ref)));
var data = ws['!autofilter'];
var ref = typeof data.ref === "string" ? data.ref : encode_range(data.ref);
/* Update FilterDatabase defined name for the worksheet */
if(!wb.Workbook) wb.Workbook = ({Sheets:[]}/*:any*/);
if(!wb.Workbook.Names) wb.Workbook.Names = [];
var names/*: Array<any> */ = wb.Workbook.Names;
var range = decode_range(ref);
if(range.s.r == range.e.r) { range.e.r = decode_range(ws["!ref"]).e.r; ref = encode_range(range); }
for(var i = 0; i < names.length; ++i) {
var name = names[i];
if(name.Name != '_xlnm._FilterDatabase') continue;
if(name.Sheet != idx) continue;
name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref; break;
}
if(i == names.length) names.push({ Name: '_xlnm._FilterDatabase', Sheet: idx, Ref: "'" + wb.SheetNames[idx] + "'!" + ref });
write_record(ba, "BrtBeginAFilter", write_UncheckedRfX(safe_decode_range(ref)));
/* *FILTERCOLUMN */
/* [SORTSTATE] */
/* BrtEndAFilter */
@ -828,7 +852,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
write_SHEETPROTECT(ba, ws);
/* *([BrtRangeProtectionIso] BrtRangeProtection) */
/* [SCENMAN] */
write_AUTOFILTER(ba, ws);
write_AUTOFILTER(ba, ws, wb, idx);
/* [SORTSTATE] */
/* [DCON] */
/* [USERSHVIEWS] */

View File

@ -1,17 +1,24 @@
function parse_numCache(data/*:string*/)/*:[Array<number>, string]*/ {
var col/*:Array<number>*/ = [];
RELS.CHART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
RELS.CHARTEX = "http://schemas.microsoft.com/office/2014/relationships/chartEx";
function parse_Cache(data/*:string*/)/*:[Array<number|string>, string, ?string]*/ {
var col/*:Array<number|string>*/ = [];
var num = data.match(/^<c:numCache>/);
var f;
/* 21.2.2.150 pt CT_NumVal */
(data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg)||[]).forEach(function(pt) {
var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
if(!q) return;
col[+q[1]] = +q[2];
col[+q[1]] = num ? +q[2] : q[2];
});
/* 21.2.2.71 formatCode CT_Xstring */
var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["","General"])[1]);
return [col, nf];
(data.match(/<c:f>(.*?)<\/c:f>/mg)||[]).forEach(function(F) { f = F.replace(/<.*?>/g,""); });
return [col, nf, f];
}
/* 21.2 DrawingML - Charts */
@ -25,7 +32,7 @@ function parse_chart(data/*:?string*/, name/*:string*/, opts, rels, wb, csheet)
/* 21.2.2.120 numCache CT_NumData */
(data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm)||[]).forEach(function(nc) {
var cache = parse_numCache(nc);
var cache = parse_Cache(nc);
refguess.s.r = refguess.s.c = 0;
refguess.e.c = C;
col = encode_col(C);

View File

@ -10,7 +10,7 @@ function parse_cs_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*::, them
if(!data) return data;
/* 18.3.1.12 chartsheet CT_ChartSheet */
if(!rels) rels = {'!id':{}};
var s = {'!type':"chart", '!chart':null, '!rel':""};
var s = ({'!type':"chart", '!chart':null, '!rel':""}/*:any*/);
var m;
/* 18.3.1.83 sheetPr CT_ChartsheetPr */

View File

@ -22,7 +22,9 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
case '<fileVersion/>': case '</fileVersion>': break;
/* 18.2.12 fileSharing CT_FileSharing ? */
case '<fileSharing': case '<fileSharing/>': break;
case '<fileSharing':
break;
case '<fileSharing/>': break;
/* 18.2.28 workbookPr CT_WorkbookPr ? */
case '<workbookPr':
@ -40,7 +42,8 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
case '</workbookPr>': break;
/* 18.2.29 workbookProtection CT_WorkbookProtection ? */
case '<workbookProtection': break;
case '<workbookProtection':
break;
case '<workbookProtection/>': break;
/* 18.2.1 bookViews CT_BookViews ? */
@ -102,7 +105,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
/* 18.2.4 customWorkbookViews CT_CustomWorkbookViews ? */
case '<customWorkbookViews>': case '</customWorkbookViews>': case '<customWorkbookViews': break;
/* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
/* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
case '<customWorkbookView': case '</customWorkbookView>': break;
/* 18.2.18 pivotCaches CT_PivotCaches ? */
@ -115,7 +118,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
/* 18.2.23 smartTagTypes CT_SmartTagTypes ? */
case '<smartTagTypes': case '<smartTagTypes>': case '</smartTagTypes>': break;
/* 18.2.22 smartTagType CT_SmartTagType ? */
/* 18.2.22 smartTagType CT_SmartTagType ? */
case '<smartTagType': break;
/* 18.2.24 webPublishing CT_WebPublishing ? */
@ -131,7 +134,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break;
/* 18.2.7 ext CT_Extension + */
/* 18.2.7 ext CT_Extension + */
case '<ext': pass=true; break; //TODO: check with versions of excel
case '</ext>': pass=false; break;

View File

@ -47,9 +47,9 @@ function parse_cc(data, name/*:string*/, opts) {
return parse_cc_xml((data/*:any*/), name, opts);
}
function parse_xlink(data, name/*:string*/, opts) {
if(name.slice(-4)===".bin") return parse_xlink_bin((data/*:any*/), name, opts);
return parse_xlink_xml((data/*:any*/), name, opts);
function parse_xlink(data, rel, name/*:string*/, opts) {
if(name.slice(-4)===".bin") return parse_xlink_bin((data/*:any*/), rel, name, opts);
return parse_xlink_xml((data/*:any*/), rel, name, opts);
}
function write_wb(wb, name/*:string*/, opts) {

View File

@ -108,7 +108,7 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
break;
case 'String':
cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml));
cell.v = xml.indexOf("<") > -1 ? unescapexml(ss) : cell.r;
cell.v = xml.indexOf("<") > -1 ? unescapexml(ss||xml) : cell.r;
break;
case 'DateTime':
if(xml.slice(-1) != "Z") xml += "Z";
@ -356,9 +356,10 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
case 'Sub': break;
case 'Sup': break;
case 'Span': break;
case 'Border': break;
case 'Alignment': break;
case 'Alignment':
break;
case 'Borders': break;
case 'Border': break;
case 'Font':
if(Rn[0].slice(-2) === "/>") break;
else if(Rn[1]==="/") ss += str.slice(fidx, Rn.index);
@ -425,6 +426,14 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
case 'Name': break;
case 'DataValidation':
if(Rn[1]==='/'){
if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));
} else {
if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
}
break;
case 'ComponentOptions':
case 'DocumentProperties':
case 'CustomDocumentProperties':
@ -435,7 +444,6 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
case 'MapInfo':
case 'PageBreaks':
case 'QueryTable':
case 'DataValidation':
case 'Sorting':
case 'Schema':
case 'data':
@ -498,6 +506,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
case 'WindowTopY': break;
case 'TabRatio': break;
case 'ProtectStructure': break;
case 'ProtectWindow': break;
case 'ProtectWindows': break;
case 'ActiveSheet': break;
case 'DisplayInkNotes': break;
@ -579,6 +588,19 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
Workbook.Views[0].RTL = true;
break;
case 'FreezePanes': break;
case 'FrozenNoSplit': break;
case 'SplitHorizontal':
case 'SplitVertical':
break;
case 'DoNotDisplayGridlines':
break;
case 'TopRowBottomPane': break;
case 'LeftColumnRightPane': break;
case 'Unsynced': break;
case 'Print': break;
case 'Panes': break;
@ -599,20 +621,13 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
case 'ActiveCol': break;
case 'ActivePane': break;
case 'TopRowVisible': break;
case 'TopRowBottomPane': break;
case 'LeftColumnVisible': break;
case 'LeftColumnRightPane': break;
case 'FitToPage': break;
case 'RangeSelection': break;
case 'PaperSizeIndex': break;
case 'PageLayoutZoom': break;
case 'PageBreakZoom': break;
case 'FilterOn': break;
case 'DoNotDisplayGridlines': break;
case 'SplitHorizontal': break;
case 'SplitVertical': break;
case 'FreezePanes': break;
case 'FrozenNoSplit': break;
case 'FitWidth': break;
case 'FitHeight': break;
case 'CommentsLayout': break;
@ -755,9 +770,38 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
default: seen = false;
} break;
case 'DataValidation':
switch(Rn[3]) {
case 'Range': break;
case 'Type': break;
case 'Min': break;
case 'Max': break;
case 'Sort': break;
case 'Descending': break;
case 'Order': break;
case 'CaseSensitive': break;
case 'Value': break;
case 'ErrorStyle': break;
case 'ErrorMessage': break;
case 'ErrorTitle': break;
case 'InputMessage': break;
case 'InputTitle': break;
case 'ComboHide': break;
case 'InputHide': break;
case 'Condition': break;
case 'Qualifier': break;
case 'UseBlank': break;
case 'Value1': break;
case 'Value2': break;
case 'Format': break;
case 'CellRangeList': break;
default: seen = false;
} break;
case 'Sorting':
case 'ConditionalFormatting':
case 'DataValidation':
switch(Rn[3]) {
case 'Range': break;
case 'Type': break;
@ -817,6 +861,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
}
if(seen) break;
/* CustomDocumentProperties */
if(Rn[3].match(/!\[CDATA/)) break;
if(!state[state.length-1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
if(state[state.length-1][0]==='CustomDocumentProperties') {
if(Rn[0].slice(-2) === "/>") break;
@ -1045,7 +1090,7 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
var t = "", p = "";
switch(cell.t) {
case 'z': return "";
case 'z': if(!opts.sheetStubs) return ""; break;
case 'n': t = 'Number'; p = String(cell.v); break;
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
case 'e': t = 'Error'; p = BErr[cell.v]; break;
@ -1057,7 +1102,7 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
attr["ss:StyleID"] = "s" + (21+os);
attr["ss:Index"] = addr.c + 1;
var _v = (cell.v != null ? p : "");
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
var m = cell.t == 'z' ? "" : ('<Data ss:Type="' + t + '">' + _v + '</Data>');
if((cell.c||[]).length > 0) m += write_ws_xlml_comment(cell.c);

View File

@ -34,7 +34,7 @@ function parse_compobj(obj/*:CFBEntry*/) {
- 2.4.61 ContinueFrt11
- 2.4.62 ContinueFrt12
*/
function slurp(R, blob, length/*:number*/, opts) {
function slurp(R, blob, length/*:number*/, opts)/*:any*/ {
var l = length;
var bufs = [];
var d = blob.slice(blob.l,blob.l+l);
@ -104,16 +104,16 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
var sst/*:SST*/ = ([]/*:any*/);
var cur_sheet = "";
var Preamble = {};
var lastcell, last_cell = "", cc, cmnt, rngC, rngR;
var lastcell, last_cell = "", cc/*:Cell*/, cmnt, rngC, rngR;
var sharedf = {};
var arrayf/*:Array<[Range, string]>*/ = [];
var temp_val/*:Cell*/;
var country;
var cell_valid = true;
var XFs = []; /* XF records */
var palette = [];
var palette/*:Array<[number, number, number]>*/ = [];
var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false}, Views:[{}] }/*:any*/), wsprops = {};
var get_rgb = function getrgb(icv) {
var get_rgb = function getrgb(icv/*:number*/)/*:[number, number, number]*/ {
if(icv < 8) return XLSIcv[icv];
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
return XLSIcv[icv];
@ -214,10 +214,11 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
if(R.r == 12){ blob.l += 10; length -= 10; } // skip FRT
}
//console.error(R,blob.l,length,blob.length);
var val;
if(R.n === 'EOF') val = R.f(blob, length, opts);
else val = slurp(R, blob, length, opts);
var val/*:any*/ = ({}/*:any*/);
if(R.n === 'EOF') val = /*::(*/R.f(blob, length, opts)/*:: :any)*/;
else val = /*::(*/slurp(R, blob, length, opts)/*:: :any)*/;
var Rn = R.n;
/*:: val = (val:any); */
if(file_depth == 0 && Rn != 'BOF') continue;
/* nested switch statements to workaround V8 128 limit */
switch(Rn) {
@ -236,13 +237,14 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'WriteAccess': opts.lastuser = val; break;
case 'FileSharing': break; //TODO
case 'CodePage':
var cpval = Number(val);
/* overrides based on test cases */
switch(val) {
case 0x5212: val = 1200; break;
case 0x8000: val = 10000; break;
case 0x8001: val = 1252; break;
switch(cpval) {
case 0x5212: cpval = 1200; break;
case 0x8000: cpval = 10000; break;
case 0x8001: cpval = 1252; break;
}
set_cp(opts.codepage = val);
set_cp(opts.codepage = cpval);
seen_codepage = true;
break;
case 'RRTabId': opts.rrtabid = val; break;
@ -537,9 +539,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
if(!cc) {
if(options.dense) {
if(!out[val[0].r]) out[val[0].r] = [];
cc = out[val[0].r][val[0].c] = {t:"z"};
cc = out[val[0].r][val[0].c] = ({t:"z"}/*:any*/);
} else {
cc = out[encode_cell(val[0])] = {t:"z"};
cc = out[encode_cell(val[0])] = ({t:"z"}/*:any*/);
}
range.e.r = Math.max(range.e.r, val[0].r);
range.s.r = Math.min(range.s.r, val[0].r);
@ -734,7 +736,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
case 'BuiltInFnGroupCount': /* 2.4.30 0x0E or 0x10 but excel 2011 generates 0x11? */ break;
/* View Stuff */
case 'Window1': case 'HideObj': case 'GridSet': case 'Guts':
case 'UserBView': case 'UserSViewBegin': case 'UserSViewEnd':
case 'UserBView': case 'UserSViewBegin': case 'UserSViewEnd': break;
case 'Pane': break;
default: switch(R.n) { /* nested */
/* Chart */

View File

@ -594,6 +594,7 @@ var XLSBRecordEnum = {
/*::[*/0x02A6/*::]*/: { n:"BrtSheetProtectionIso" },
/*::[*/0x02A7/*::]*/: { n:"BrtCsProtectionIso" },
/*::[*/0x02A8/*::]*/: { n:"BrtRangeProtectionIso" },
/*::[*/0x02A9/*::]*/: { n:"BrtDValList" },
/*::[*/0x0400/*::]*/: { n:"BrtRwDescent" },
/*::[*/0x0401/*::]*/: { n:"BrtKnownFonts" },
/*::[*/0x0402/*::]*/: { n:"BrtBeginSXTupleSet" },

View File

@ -143,19 +143,27 @@ function write_ws_biff8_hlinks(ba/*:BufArray*/, ws) {
function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
var os = 16 + get_cell_style(opts.cellXfs, cell, opts);
if(cell.v != null) switch(cell.t) {
if(cell.v == null && !cell.bf) {
write_biff_rec(ba, "Blank", write_XLSCell(R, C, os));
return;
}
if(cell.bf) write_biff_rec(ba, "Formula", write_Formula(cell, R, C, opts, os));
else switch(cell.t) {
case 'd': case 'n':
var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
/* TODO: emit RK as appropriate */
write_biff_rec(ba, "Number", write_Number(R, C, v, os, opts));
return;
case 'b': case 'e': write_biff_rec(ba, 0x0205, write_BoolErr(R, C, cell.v, os, opts, cell.t)); return;
break;
case 'b': case 'e':
write_biff_rec(ba, 0x0205, write_BoolErr(R, C, cell.v, os, opts, cell.t));
break;
/* TODO: codepage, sst */
case 's': case 'str':
write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts));
return;
break;
default:
write_biff_rec(ba, "Blank", write_XLSCell(R, C, os));
}
write_biff_rec(ba, "Blank", write_XLSCell(R, C, os));
}
/* [MS-XLS] 2.1.7.20.5 */
@ -176,7 +184,7 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
}
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
/* ... */
/* [Uncalced] Index */
write_biff_rec(ba, "CalcMode", writeuint16(1));
write_biff_rec(ba, "CalcCount", writeuint16(100));
write_biff_rec(ba, "CalcRefMode", writebool(true));
@ -187,7 +195,9 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
write_biff_rec(ba, "PrintGrid", writebool(false));
write_biff_rec(ba, "GridSet", writeuint16(1));
write_biff_rec(ba, "Guts", write_Guts([0,0]));
/* ... */
/* DefaultRowHeight WsBool [Sync] [LPr] [HorizontalPageBreaks] [VerticalPageBreaks] */
/* Header (string) */
/* Footer (string) */
write_biff_rec(ba, "HCenter", writebool(false));
write_biff_rec(ba, "VCenter", writebool(false));
/* ... */
@ -212,13 +222,13 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
if(b8 && _WB.Views) write_biff_rec(ba, "Window2", write_Window2(_WB.Views[0]));
/* ... */
if(b8 && (ws['!merges']||[]).length) write_biff_rec(ba, "MergeCells", write_MergeCells(ws['!merges']));
/* ... */
/* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */
if(b8) write_ws_biff8_hlinks(ba, ws);
/* ... */
/* [DVAL] */
write_biff_rec(ba, "CodeName", write_XLUnicodeString(cname, opts));
/* ... */
/* *WebPub *CellWatch [SheetExt] */
if(b8) write_FEAT(ba, ws);
/* ... */
/* *FEAT11 *RECORD12 */
write_biff_rec(ba, "EOF");
return ba.end();
}
@ -238,16 +248,22 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
if(b5) write_biff_rec(A, "ToolbarEnd");
write_biff_rec(A, "InterfaceEnd");
write_biff_rec(A, "WriteAccess", write_WriteAccess("SheetJS", opts));
/* [FileSharing] */
write_biff_rec(A, "CodePage", writeuint16(b8 ? 0x04b0 : 0x04E4));
/* *2047 Lel */
if(b8) write_biff_rec(A, "DSF", writeuint16(0));
if(b8) write_biff_rec(A, "Excel9File");
write_biff_rec(A, "RRTabId", write_RRTabId(wb.SheetNames.length));
if(b8 && wb.vbaraw) write_biff_rec(A, "ObProj");
/* [ObNoMacros] */
if(b8 && wb.vbaraw) {
write_biff_rec(A, "ObProj");
var cname/*:string*/ = _wb.CodeName || "ThisWorkbook";
write_biff_rec(A, "CodeName", write_XLUnicodeString(cname, opts));
}
write_biff_rec(A, "BuiltInFnGroupCount", writeuint16(0x11));
/* *FnGroupName *FnGrp12 */
/* *Lbl */
/* [OleObjectSize] */
write_biff_rec(A, "WinProtect", writebool(false));
write_biff_rec(A, "Protect", writebool(false));
write_biff_rec(A, "Password", writeuint16(0));
@ -269,8 +285,11 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
var a = A.end();
var C = buf_array();
/* METADATA [MTRSettings] [ForceFullCalculation] */
if(b8) write_biff_rec(C, "Country", write_Country());
/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */
/* BIFF8: [SST *Continue] ExtSST */
/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */
write_biff_rec(C, "EOF");
var c = C.end();
@ -308,10 +327,15 @@ function write_biff8_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
o.revssf = evert_num(wb.SSF); o.revssf[wb.SSF[65535]] = 0;
o.ssf = wb.SSF;
}
o.cellXfs = [];
o.Strings = /*::((*/[]/*:: :any):SST)*/; o.Strings.Count = 0; o.Strings.Unique = 0;
fix_write_opts(o);
o.cellXfs = [];
get_cell_style(o.cellXfs, {}, {revssf:{"General":0}});
if(!wb.Props) wb.Props = {};
for(var i = 0; i < wb.SheetNames.length; ++i) bufs[bufs.length] = write_ws_biff8(i, o, wb);
bufs.unshift(write_biff8_global(wb, bufs, o));
return __toBuffer([bufs]);

View File

@ -4,6 +4,7 @@ var HTML_ = (function() {
var opts = _opts || {};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
str = str.replace(/<!--.*?-->/g, "");
var mtch/*:any*/ = str.match(/<table/i);
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
var mtch2/*:any*/ = str.match(/<\/table/i);
@ -81,7 +82,7 @@ var HTML_ = (function() {
if(CS > 1) sp.colspan = CS;
sp.t = cell && cell.t || 'z';
if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
sp.id = "sjs-" + coord;
sp.id = (o.id || "sjs") + "-" + coord;
oo.push(writextag('td', w, sp));
}
var preamble = "<tr>";
@ -126,7 +127,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
var range/*:Range*/ = {s:{r:0,c:0},e:{r:0,c:0}};
var merges/*:Array<Range>*/ = [], midx = 0;
var rowinfo/*:Array<RowInfo>*/ = [];
var _R = 0, R = 0, _C, C, RS, CS;
var _R = 0, R = 0, _C = 0, C = 0, RS = 0, CS = 0;
for(; _R < rows.length && R < sheetRows; ++_R) {
var row/*:HTMLTableRowElement*/ = rows[_R];
if (is_dom_element_hidden(row)) {

View File

@ -225,7 +225,7 @@ var parse_content_xml = (function() {
if(Rn[1]==='/'){
if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;
comment.t = textp;
if(textR.length) comment.R = textR;
if(textR.length) /*::(*/comment/*:: :any)*/.R = textR;
comment.a = creator;
comments.push(comment);
}
@ -544,7 +544,7 @@ var parse_content_xml = (function() {
SheetNames: SheetNames,
Workbook: WB
}/*:any*/);
if(opts.bookSheets) delete out.Sheets;
if(opts.bookSheets) delete /*::(*/out/*:: :any)*/.Sheets;
return out;
};
})();

View File

@ -31,8 +31,20 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
break;
case 'macro': _ws = parse_ms(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
default: throw new Error("Unrecognized sheet type " + stype);
}
sheets[sheet] = _ws;
/* scan rels for comments */
var comments = [];
if(sheetRels && sheetRels[sheet]) keys(sheetRels[sheet]).forEach(function(n) {
if(sheetRels[sheet][n].Type == RELS.CMNT) {
var dfile = resolve_path(sheetRels[sheet][n].Target, path);
comments = parse_cmnt(getzipdata(zip, dfile, true), dfile, opts);
if(!comments || !comments.length) return;
sheet_insert_comments(_ws, comments);
}
});
} catch(e) { if(opts.WTF) throw e; }
}
@ -78,7 +90,10 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
}
/*var externbooks = */dir.links.map(function(link) {
return parse_xlink(getzipdata(zip, strip_front_slash(link)), link, opts);
try {
var rels = parse_rels(getzipstr(zip, get_rels_path(strip_front_slash(link))), link);
return parse_xlink(getzipdata(zip, strip_front_slash(link)), rels, link, opts);
} catch(e) {}
});
var wb = parse_wb(getzipdata(zip, strip_front_slash(dir.workbooks[0])), dir.workbooks[0], opts);
@ -152,8 +167,6 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
safe_parse_sheet(zip, path, relsPath, props.SheetNames[i], i, sheetRels, sheets, stype, opts, wb, themes, styles);
}
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
out = ({
Directory: dir,
Workbook: wb,

View File

@ -69,6 +69,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), opts);
var d = data, n = [0,0,0,0], str = false;
var o = opts||{};
if(o.cellStyles) { o.cellNF = true; }
_ssfopts = {};
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";

View File

@ -25,10 +25,10 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
default: throw new Error("Unrecognized type " + o.type);
}
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: {"nodebuffer": "buffer", "string": "binary"}[oopts.type] || oopts.type}) : z.generate(oopts);
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type}) : z.generate(oopts);
if(o.password && typeof encrypt_agile !== 'undefined') return write_cfb_ctr(encrypt_agile(out, o.password), o);
if(o.type === "file") return write_dl(o.file, out);
return o.type == "string" ? utf8read(out) : out;
return o.type == "string" ? utf8read(/*::(*/out/*:: :any)*/) : out;
}
function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
@ -46,7 +46,6 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
// $FlowIgnore
if(has_buf) return Buffer_from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
@ -61,7 +60,6 @@ function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
// $FlowIgnore
if(has_buf) return Buffer_from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
@ -86,8 +84,10 @@ function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ {
}
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
reset_cp();
check_wb(wb);
var o = opts||{};
if(o.cellStyles) { o.cellNF = true; }
if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSync(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }
switch(o.bookType || 'xlsb') {
case 'xml':

View File

@ -206,8 +206,10 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
var v = JS[k];
var t = 'z';
var z = "";
var ref = encode_cell({c:_C + C,r:_R + R + offset});
cell = utils.sheet_get_cell(ws, ref);
if(v && typeof v === 'object' && !(v instanceof Date)){
ws[encode_cell({c:_C + C,r:_R + R + offset})] = v;
ws[ref] = v;
} else {
if(typeof v == 'number') t = 'n';
else if(typeof v == 'boolean') t = 'b';
@ -215,9 +217,14 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
else if(v instanceof Date) {
t = 'd';
if(!o.cellDates) { t = 'n'; v = datenum(v); }
z = o.dateNF || SSF._table[14];
z = (o.dateNF || SSF._table[14]);
}
if(!cell) ws[ref] = cell = ({t:t, v:v}/*:any*/);
else {
cell.t = t; cell.v = v;
delete cell.w; delete cell.R;
if(z) cell.z = z;
}
ws[encode_cell({c:_C + C,r:_R + R + offset})] = cell = ({t:t, v:v}/*:any*/);
if(z) cell.z = z;
}
});

View File

@ -7,12 +7,21 @@ function get_default(x/*:any*/, y/*:any*/, z/*:any*/)/*:any*/ { return x[y] != n
/* get cell, creating a stub if necessary */
function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ {
/* A1 cell address */
if(typeof R == "string") return ws[R] || (ws[R] = {t:'z'});
if(typeof R == "string") {
/* dense */
if(Array.isArray(ws)) {
var RC = decode_cell(R);
if(!ws[RC.r]) ws[RC.r] = [];
return ws[RC.r][RC.c] || (ws[RC.r][RC.c] = {t:'z'});
}
return ws[R] || (ws[R] = {t:'z'});
}
/* cell address object */
if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R));
/* R and C are 0-based indices */
return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0}));
}
utils.sheet_get_cell = ws_get_cell_stub;
/* find sheet index for given name / validate index */
function wb_sheet_idx(wb/*:Workbook*/, sh/*:number|string*/) {

2
dist/LICENSE generated vendored
View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (C) 2012-present SheetJS LLC
Copyright (C) 2012-present SheetJS LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

32
dist/xlsx.core.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.core.min.map generated vendored

File diff suppressed because one or more lines are too long

600
dist/xlsx.extendscript.js generated vendored

File diff suppressed because it is too large Load Diff

34
dist/xlsx.full.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.full.min.map generated vendored

File diff suppressed because one or more lines are too long

600
dist/xlsx.js generated vendored

File diff suppressed because it is too large Load Diff

26
dist/xlsx.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.min.map generated vendored

File diff suppressed because one or more lines are too long

12
dist/xlsx.mini.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.mini.min.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -64,6 +64,11 @@ function zip_add_file(zip, path, content) {
else zip.file(path, content);
}
function zip_new() {
return CFB.utils.cfb_new();
}
function zip_read(d, o) {
var zip;
switch(o.type) {
@ -75,12 +80,8 @@ function zip_read(d, o) {
return zip;
}
function zip_new() {
return CFB.utils.cfb_new();
}
function resolve_path(path/*:string*/, base/*:string*/)/*:string*/ {
if(path.charAt(0) == "/") return path.slice(1);
var result = base.split('/');
if(base.slice(-1) != "/") result.pop(); // folder path
var target = path.split('/');

View File

@ -156,6 +156,7 @@ declare class Date {
constructor(): void;
constructor(timestamp: number): void;
constructor(dateString: string): void;
constructor(dateObject: Date): void;
constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
getDate(): number;
getDay(): number;

View File

@ -0,0 +1,10 @@
<script src="xlsx.mini.min.js"></script>
<script type="module">
import * as S from "../dist/mjs/index.mjs";
function assert(x) { if(!x) throw "assert failed"; }
assert(S != null);
S.set_XLSX(XLSX);
assert(S.get_XLSX() == XLSX);
assert(S.get_XLSX().version);
</script>

View File

@ -0,0 +1 @@
<script src="parcel.js"></script>

View File

@ -0,0 +1,9 @@
<script src="xlsx.mini.min.js"></script>
<script src="S.js"></script>
<script>
function assert(x) { if(!x) throw "assert failed"; }
assert(S != null);
S.set_XLSX(XLSX);
assert(S.get_XLSX() == XLSX);
assert(S.get_XLSX().version);
</script>

View File

@ -2052,9 +2052,7 @@ describe('sylk', function() {
assert.equal(get_cell(X.read(str, {type:"string"}).Sheets.Sheet1, "A1").v, A1);
assert.equal(get_cell(X.read(str.replace(//, "\x96"), {type:"binary", codepage:1252}).Sheets.Sheet1, "A1").v, A1);
if(typeof Buffer !== 'undefined' && !browser) {
// $FlowIgnore
assert.equal(get_cell(X.read(Buffer_from(str), {type:"buffer", codepage:65001}).Sheets.Sheet1, "A1").v, A1);
// $FlowIgnore
assert.equal(get_cell(X.read(Buffer_from(str.replace(//, "\x96"), "binary"), {type:"buffer", codepage:1252}).Sheets.Sheet1, "A1").v, A1);
}
} : null);

View File

@ -9,6 +9,7 @@
"paths": { "xlsx": ["."] },
"types": [],
"noEmit": true,
"strictFunctionTypes": true,
"forceConsistentCasingInFileNames": true
}
}

View File

@ -1,12 +1,14 @@
{
"extends": "dtslint/dtslint.json",
"rules": {
"no-implicit-dependencies": false,
"whitespace": false,
"no-sparse-arrays": false,
"only-arrow-functions": false,
"no-consecutive-blank-lines": false,
"prefer-conditional-expression": false,
"one-variable-per-declaration": false,
"strict-export-declare-modifiers": false,
"prefer-template": false
}
}

File diff suppressed because it is too large Load Diff

600
xlsx.js generated

File diff suppressed because it is too large Load Diff

View File

@ -135,7 +135,6 @@ function new_unsafe_buf(len/*:number*/) {
}
var s2a = function s2a(s/*:string*/)/*:any*/ {
// $FlowIgnore
if(has_buf) return Buffer_from(s, "binary");
return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; });
};
@ -2901,6 +2900,11 @@ function zip_add_file(zip, path, content) {
else zip.file(path, content);
}
function zip_new() {
return CFB.utils.cfb_new();
}
function zip_read(d, o) {
var zip;
switch(o.type) {
@ -2912,12 +2916,8 @@ function zip_read(d, o) {
return zip;
}
function zip_new() {
return CFB.utils.cfb_new();
}
function resolve_path(path/*:string*/, base/*:string*/)/*:string*/ {
if(path.charAt(0) == "/") return path.slice(1);
var result = base.split('/');
if(base.slice(-1) != "/") result.pop(); // folder path
var target = path.split('/');
@ -2931,6 +2931,7 @@ function resolve_path(path/*:string*/, base/*:string*/)/*:string*/ {
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s?[\/\?]?>/g;
if(!(XML_HEADER.match(tagregex))) tagregex = /<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
@ -3084,11 +3085,9 @@ if(has_buf) {
};
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer_from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
// $FlowIgnore
utf8write = function(data) { return Buffer_from(data, 'utf8').toString("binary"); };
}
@ -3108,7 +3107,19 @@ var htmldecode/*:{(s:string):string}*/ = (function() {
['quot', '"'], ['apos', "'"], ['gt', '>'], ['lt', '<'], ['amp', '&']
].map(function(x/*:[string, string]*/) { return [new RegExp('&' + x[0] + ';', "g"), x[1]]; });
return function htmldecode(str/*:string*/)/*:string*/ {
var o = str.replace(/^[\t\n\r ]+/, "").replace(/[\t\n\r ]+$/,"").replace(/[\t\n\r ]+/g, " ").replace(/<\s*[bB][rR]\s*\/?>/g,"\n").replace(/<[^>]*>/g,"");
var o = str
// Remove new lines and spaces from start of content
.replace(/^[\t\n\r ]+/, "")
// Remove new lines and spaces from end of content
.replace(/[\t\n\r ]+$/,"")
// Added line which removes any white space characters after and before html tags
.replace(/>\s+/g,">").replace(/\s+</g,"<")
// Replace remaining new lines and spaces with space
.replace(/[\t\n\r ]+/g, " ")
// Replace <br> tags with new lines
.replace(/<\s*[bB][rR]\s*\/?>/g,"\n")
// Strip HTML elements
.replace(/<[^>]*>/g,"");
for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
return o;
};
@ -3515,8 +3526,8 @@ function encode_cell_xls(c/*:CellAddress*/, biff/*:number*/)/*:string*/ {
if(c.cRel && c.c < 0) { c = dup(c); c.c += (biff > 8) ? 0x4000 : 0x100; }
if(c.rRel && c.r < 0) { c = dup(c); c.r += (biff > 8) ? 0x100000 : ((biff > 5) ? 0x10000 : 0x4000); }
var s = encode_cell(c);
if(c.cRel === 0) s = fix_col(s);
if(c.rRel === 0) s = fix_row(s);
if(!c.cRel && c.cRel != null) s = fix_col(s);
if(!c.rRel && c.rRel != null) s = fix_row(s);
return s;
}
@ -3539,7 +3550,7 @@ function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d
function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); }
function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
function encode_col(col/*:number*/)/*:string*/ { if(col < 0) throw new Error("invalid column " + col); var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); }
function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); }
@ -3860,11 +3871,11 @@ var XLSFillPattern = [
'gray0625'
];
function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
function rgbify(arr/*:Array<number>*/)/*:Array<[number, number, number]>*/ { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
/* [MS-XLS] 2.5.161 */
/* [MS-XLSB] 2.5.75 Icv */
var XLSIcv = rgbify([
var _XLSIcv = rgbify([
/* Color Constants */
0x000000,
0xFFFFFF,
@ -3956,7 +3967,7 @@ var XLSIcv = rgbify([
0x000000, /* 0x50 icvInfoBk ?? */
0x000000 /* 0x51 icvInfoText ?? */
]);
var XLSIcv = dup(_XLSIcv);
/* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */
/* 12.3 Part Summary <SpreadsheetML> */
/* 14.2 Part Summary <DrawingML> */
@ -3985,12 +3996,18 @@ var ct2type/*{[string]:string}*/ = ({
"application/vnd.ms-excel.pivotTable": "TODO",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO",
/* Chart Objects */
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
/* Chart Colors */
"application/vnd.ms-office.chartcolorstyle+xml": "TODO",
/* Chart Style */
"application/vnd.ms-office.chartstyle+xml": "TODO",
/* Chart Advanced */
"application/vnd.ms-office.chartex+xml": "TODO",
/* Calculation Chain */
"application/vnd.ms-excel.calcChain": "calcchains",
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
@ -4081,7 +4098,6 @@ var ct2type/*{[string]:string}*/ = ({
/* Drawing */
"application/vnd.openxmlformats-officedocument.drawing+xml": "drawings",
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO",
@ -4190,6 +4206,7 @@ var CTYPE_DEFAULTS = [
['xml', 'application/xml'],
['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'],
['vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'],
['data', 'application/vnd.openxmlformats-officedocument.model+data'],
/* from test files */
['bmp', 'image/bmp'],
['png', 'image/png'],
@ -4209,6 +4226,8 @@ function write_ct(ct, opts)/*:string*/ {
o[o.length] = (XML_HEADER);
o[o.length] = (CTYPE_XML_ROOT);
o = o.concat(CTYPE_DEFAULTS);
/* only write first instance */
var f1 = function(w) {
if(ct[w] && ct[w].length > 0) {
v = ct[w][0];
@ -4218,6 +4237,8 @@ function write_ct(ct, opts)/*:string*/ {
}));
}
};
/* book type-specific */
var f2 = function(w) {
(ct[w]||[]).forEach(function(v) {
o[o.length] = (writextag('Override', null, {
@ -4226,6 +4247,8 @@ function write_ct(ct, opts)/*:string*/ {
}));
});
};
/* standard type */
var f3 = function(t) {
(ct[t]||[]).forEach(function(v) {
o[o.length] = (writextag('Override', null, {
@ -4234,6 +4257,7 @@ function write_ct(ct, opts)/*:string*/ {
}));
});
};
f1('workbooks');
f2('sheets');
f2('charts');
@ -4252,6 +4276,9 @@ var RELS = ({
SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
HLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
VML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
XPATH: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath",
XMISS: "http://schemas.microsoft.com/office/2006/relationships/xlExternalLinkPath/xlPathMissing",
XLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
VBA: "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
}/*:any*/);
@ -4300,14 +4327,16 @@ function write_rels(rels)/*:string*/ {
return o.join("");
}
function add_rels(rels, rId, f, type, relobj)/*:number*/ {
var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
if(!relobj) relobj = {};
if(!rels['!id']) rels['!id'] = {};
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
relobj.Id = 'rId' + rId;
relobj.Type = type;
relobj.Target = f;
if(relobj.Type == RELS.HLINK) relobj.TargetMode = "External";
if(targetmode) relobj.TargetMode = targetmode;
else if(RELS_EXTERN.indexOf(relobj.Type) > -1) relobj.TargetMode = "External";
if(rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId);
rels['!id'][relobj.Id] = relobj;
rels[('/' + relobj.Target).replace("//","/")] = relobj;
@ -4441,12 +4470,14 @@ function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) {
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Hojas de cálculo":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "Rangos con nombre":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
@ -4919,7 +4950,7 @@ function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<borders': case '<borders>': case '</borders>': break;
@ -4927,8 +4958,8 @@ function parse_borders(t, styles, themes, opts) {
/* 18.8.4 border CT_Border */
case '<border': case '<border>': case '<border/>':
border = {};
if (y.diagonalUp) { border.diagonalUp = y.diagonalUp; }
if (y.diagonalDown) { border.diagonalDown = y.diagonalDown; }
if(y.diagonalUp) border.diagonalUp = parsexmlbool(y.diagonalUp);
if(y.diagonalDown) border.diagonalDown = parsexmlbool(y.diagonalDown);
styles.Borders.push(border);
break;
case '</border>': break;
@ -4974,7 +5005,8 @@ function parse_borders(t, styles, themes, opts) {
case '</end>': break;
/* 18.8.? color CT_Color */
case '<color': case '<color>': break;
case '<color': case '<color>':
break;
case '<color/>': case '</color>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
@ -4993,7 +5025,7 @@ function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fills': case '<fills>': case '</fills>': break;
@ -5031,7 +5063,7 @@ function parse_fills(t, styles, themes, opts) {
if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.fgColor.rgb = y.rgb.slice(-6);
if(y.rgb != null) fill.fgColor.rgb = y.rgb.slice(-6);
break;
case '<fgColor/>': case '</fgColor>': break;
@ -5059,7 +5091,7 @@ function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fonts': case '<fonts>': case '</fonts>': break;
@ -5159,6 +5191,10 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
@ -5216,7 +5252,7 @@ function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(strip_ns(y[0])) {
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
@ -5242,13 +5278,19 @@ function parse_cellXfs(t, styles, opts) {
if(y.horizontal) alignment.horizontal = y.horizontal;
if(y.textRotation != null) alignment.textRotation = y.textRotation;
if(y.indent) alignment.indent = y.indent;
if(y.wrapText) alignment.wrapText = y.wrapText;
if(y.wrapText) alignment.wrapText = parsexmlbool(y.wrapText);
xf.alignment = alignment;
break;
case '</alignment>': break;
/* 18.8.33 protection CT_CellProtection */
case '<protection': case '</protection>': case '<protection/>': break;
case '<protection':
break;
case '</protection>': case '<protection/>': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -5264,7 +5306,9 @@ function parse_cellXfs(t, styles, opts) {
function write_cellXfs(cellXfs)/*:string*/ {
var o/*:Array<string>*/ = [];
o[o.length] = (writextag('cellXfs',null));
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
cellXfs.forEach(function(c) {
o[o.length] = (writextag('xf', null, c));
});
o[o.length] = ("</cellXfs>");
if(o.length === 2) return "";
o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");
@ -5440,6 +5484,7 @@ function parse_theme_xml(data/*:string*/, opts) {
function write_theme(Themes, opts)/*:string*/ {
if(opts && opts.themeXLSX) return opts.themeXLSX;
if(Themes && typeof Themes.raw == "string") return Themes.raw;
var o = [XML_HEADER];
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
o[o.length] = '<a:themeElements>';
@ -5609,13 +5654,13 @@ function write_theme(Themes, opts)/*:string*/ {
return o.join("");
}
/* 18.14 Supplementary Workbook Data */
function parse_xlink_xml(/*::data, name:string, _opts*/) {
function parse_xlink_xml(/*::data, rel, name:string, _opts*/) {
//var opts = _opts || {};
//if(opts.WTF) throw "XLSX External Link";
}
/* [MS-XLSB] 2.1.7.25 External Link */
function parse_xlink_bin(data, name/*:string*/, _opts) {
function parse_xlink_bin(data, rel, name/*:string*/, _opts) {
if(!data) return data;
var opts = _opts || {};
@ -5659,9 +5704,11 @@ function parse_xlink_bin(data, name/*:string*/, _opts) {
}
}, opts);
}
/* 20.5 DrawingML - SpreadsheetML Drawing */
RELS.IMG = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
RELS.DRAW = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
/* 20.5 DrawingML - SpreadsheetML Drawing */
/* 20.5.2.35 wsDr CT_Drawing */
function parse_drawing(data, rels/*:any*/) {
if(!data) return "??";
/*
@ -5727,25 +5774,7 @@ function write_comments_vml(rId/*:number*/, comments) {
RELS.CMNT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
for(var i = 0; i != dirComments.length; ++i) {
var canonicalpath=dirComments[i];
var comments=parse_cmnt(getzipdata(zip, canonicalpath.replace(/^\//,''), true), canonicalpath, opts);
if(!comments || !comments.length) continue;
// find the sheets targeted by these comments
var sheetNames = keys(sheets);
for(var j = 0; j != sheetNames.length; ++j) {
var sheetName = sheetNames[j];
var rels = sheetRels[sheetName];
if(rels) {
var rel = rels[canonicalpath];
if(rel) insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
}
}
}
}
function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*/) {
function sheet_insert_comments(sheet, comments/*:Array<RawComment>*/) {
var dense = Array.isArray(sheet);
var cell/*:Cell*/;
comments.forEach(function(comment) {
@ -5755,7 +5784,7 @@ function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*
cell = sheet[r.r][r.c];
} else cell = sheet[comment.ref];
if (!cell) {
cell = {};
cell = ({t:"z"}/*:any*/);
if(dense) sheet[r.r][r.c] = cell;
else sheet[comment.ref] = cell;
var range = safe_decode_range(sheet["!ref"]||"BDWGO1000001:A1");
@ -5862,14 +5891,21 @@ function parse_ms_bin(/*::data:any, opts, idx:number, rels, wb, themes, styles*/
function parse_ms_xml(/*::data:any, opts, idx:number, rels, wb, themes, styles*/)/*:Worksheet*/ { return {'!type':'macro'}; }
/* TODO: it will be useful to parse the function str */
var rc_to_a1 = (function(){
var rcregex = /(^|[^A-Za-z])R(\[?)(-?\d+|)\]?C(\[?)(-?\d+|)\]?/g;
var rcregex = /(^|[^A-Za-z_])R(\[?-?\d+\]|[1-9]\d*|)C(\[?-?\d+\]|[1-9]\d*|)(?![A-Za-z0-9_])/g;
var rcbase/*:Cell*/ = ({r:0,c:0}/*:any*/);
function rcfunc($$,$1,$2,$3,$4,$5) {
var R = $3.length>0?parseInt($3,10)|0:0, C = $5.length>0?parseInt($5,10)|0:0;
if(C<0 && $4.length === 0) C=0;
function rcfunc($$,$1,$2,$3) {
var cRel = false, rRel = false;
if($4.length > 0 || $5.length == 0) cRel = true; if(cRel) C += rcbase.c; else --C;
if($2.length > 0 || $3.length == 0) rRel = true; if(rRel) R += rcbase.r; else --R;
if($2.length == 0) rRel = true;
else if($2.charAt(0) == "[") { rRel = true; $2 = $2.slice(1, -1); }
if($3.length == 0) cRel = true;
else if($3.charAt(0) == "[") { cRel = true; $3 = $3.slice(1, -1); }
var R = $2.length>0?parseInt($2,10)|0:0, C = $3.length>0?parseInt($3,10)|0:0;
if(cRel) C += rcbase.c; else --C;
if(rRel) R += rcbase.r; else --R;
return $1 + (cRel ? "" : "$") + encode_col(C) + (rRel ? "" : "$") + encode_row(R);
}
return function rc_to_a1(fstr/*:string*/, base/*:Cell*/)/*:string*/ {
@ -6057,9 +6093,11 @@ var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g
var marginregex= /<(?:\w:)?pageMargins[^>]*\/>/g;
var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;
/* 18.3 Worksheets */
function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
if(!data) return data;
if(!rels) rels = {'!id':{}};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
/* 18.3.1.99 worksheet CT_Worksheet */
@ -6078,7 +6116,6 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
/* 18.3.1.35 dimension CT_SheetDimension */
// $FlowIgnore
var ridx = (data1.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
if(ridx > 0) {
var ref = data1.slice(ridx,ridx+50).match(dimregex);
@ -6151,18 +6188,18 @@ function parse_ws_xml_sheetpr(sheetPr/*:string*/, s, wb/*:WBWBProps*/, idx/*:num
}
/* 18.3.1.85 sheetProtection CT_SheetProtection */
var sheetprot_deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
var sheetprot_deftrue = [
"formatColumns", "formatRows", "formatCells",
"insertColumns", "insertRows", "insertHyperlinks",
"deleteColumns", "deleteRows",
"sort", "autoFilter", "pivotTables"
];
function write_ws_xml_protection(sp)/*:string*/ {
// algorithmName, hashValue, saltValue, spinCountpassword
var o = ({sheet:1}/*:any*/);
var deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
var deftrue = [
"formatColumns", "formatRows", "formatCells",
"insertColumns", "insertRows", "insertHyperlinks",
"deleteColumns", "deleteRows",
"sort", "autoFilter", "pivotTables"
];
deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
sheetprot_deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
sheetprot_deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
/* TODO: algorithm */
if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
return writextag('sheetProtection', null, o);
@ -6222,7 +6259,6 @@ function parse_ws_xml_cols(columns, cols) {
while(colm <= colM) columns[colm++] = dup(coll);
}
}
function write_ws_xml_cols(ws, cols)/*:string*/ {
var o = ["<cols>"], col;
for(var i = 0; i != cols.length; ++i) {
@ -6239,7 +6275,7 @@ function parse_ws_xml_autofilter(data/*:string*/) {
}
function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
var ref = typeof data.ref == "string" ? data.ref : encode_range(data.ref);
if(!wb.Workbook) wb.Workbook = {};
if(!wb.Workbook) wb.Workbook = ({Sheets:[]}/*:any*/);
if(!wb.Workbook.Names) wb.Workbook.Names = [];
var names/*: Array<any> */ = wb.Workbook.Names;
var range = decode_range(ref);
@ -6256,21 +6292,21 @@ function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
/* 18.3.1.88 sheetViews CT_SheetViews */
/* 18.3.1.87 sheetView CT_SheetView */
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/>/;
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/;
function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
(data.match(sviewregex)||[]).forEach(function(r/*:string*/) {
if(!wb.Views) wb.Views = [{}];
(data.match(sviewregex)||[]).forEach(function(r/*:string*/, i/*:number*/) {
var tag = parsexmltag(r);
if(parsexmlbool(tag.rightToLeft)) {
if(!wb.Views) wb.Views = [{}];
if(!wb.Views[0]) wb.Views[0] = {};
wb.Views[0].RTL = true;
}
// $FlowIgnore
if(!wb.Views[i]) wb.Views[i] = {};
// $FlowIgnore
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
});
}
function write_ws_xml_sheetviews(ws, opts, idx, wb)/*:string*/ {
var sview = {workbookViewId:"0"};
var sview = ({workbookViewId:"0"}/*:any*/);
// $FlowIgnore
if( (((wb||{}).Workbook||{}).Views||[])[0] ) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
if((((wb||{}).Workbook||{}).Views||[])[0]) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
return writextag("sheetViews", writextag("sheetView", null, sview), {});
}
@ -6278,12 +6314,12 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string
if(cell.v === undefined && cell.f === undefined || cell.t === 'z') return "";
var vv = "";
var oldt = cell.t, oldv = cell.v;
switch(cell.t) {
if(cell.t !== "z") switch(cell.t) {
case 'b': vv = cell.v ? "1" : "0"; break;
case 'n': vv = ''+cell.v; break;
case 'e': vv = BErr[cell.v]; break;
case 'd':
if(opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
if(opts && opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
else {
cell = dup(cell);
cell.t = 'n';
@ -6358,6 +6394,8 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
/* 18.3.1.4 c CT_Cell */
cells = x.slice(ri).split(cellregex);
for(var rslice = 0; rslice != cells.length; ++rslice) if(cells[rslice].trim().charAt(0) != "<") break;
cells = cells.slice(rslice);
for(ri = 0; ri != cells.length; ++ri) {
x = cells[ri].trim();
if(x.length === 0) continue;
@ -6439,7 +6477,10 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
case 'inlineStr':
cref = d.match(isregex);
p.t = 's';
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
if(cref != null && (sstr = parse_si(cref[1]))) {
p.v = sstr.t;
if(opts.cellHTML) p.h = sstr.h;
} else p.v = "";
break;
case 'b': p.v = parsexmlbool(p.v); break;
case 'd':
@ -6453,6 +6494,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
}
/* formatting */
fmtid = fillid = 0;
cf = null;
if(do_format && tag.s !== undefined) {
cf = styles.CellXf[tag.s];
if(cf != null) {
@ -6587,9 +6629,9 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
/* dataValidations */
var relc = -1, rel, rId = -1;
if(ws['!links'].length > 0) {
if(/*::(*/ws['!links']/*::||[])*/.length > 0) {
o[o.length] = "<hyperlinks>";
ws['!links'].forEach(function(l) {
/*::(*/ws['!links']/*::||[])*/.forEach(function(l) {
if(!l[1].Target) return;
rel = ({"ref":l[0]}/*:any*/);
if(l[1].Target.charAt(0) != "#") {
@ -6608,7 +6650,6 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
if (ws['!margins'] != null) o[o.length] = write_ws_xml_margins(ws['!margins']);
/* pageSetup */
//var hfidx = o.length;
o[o.length] = "";
/* rowBreaks */
@ -6620,7 +6661,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
/* smartTags */
if(ws['!drawing'].length > 0) {
if(/*::(*/ws['!drawing']/*::||[])*/.length > 0) {
rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW);
o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId});
}
@ -6643,20 +6684,27 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
return o.join("");
}
function parse_numCache(data/*:string*/)/*:[Array<number>, string]*/ {
var col/*:Array<number>*/ = [];
RELS.CHART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
RELS.CHARTEX = "http://schemas.microsoft.com/office/2014/relationships/chartEx";
function parse_Cache(data/*:string*/)/*:[Array<number|string>, string, ?string]*/ {
var col/*:Array<number|string>*/ = [];
var num = data.match(/^<c:numCache>/);
var f;
/* 21.2.2.150 pt CT_NumVal */
(data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg)||[]).forEach(function(pt) {
var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
if(!q) return;
col[+q[1]] = +q[2];
col[+q[1]] = num ? +q[2] : q[2];
});
/* 21.2.2.71 formatCode CT_Xstring */
var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["","General"])[1]);
return [col, nf];
(data.match(/<c:f>(.*?)<\/c:f>/mg)||[]).forEach(function(F) { f = F.replace(/<.*?>/g,""); });
return [col, nf, f];
}
/* 21.2 DrawingML - Charts */
@ -6670,7 +6718,7 @@ function parse_chart(data/*:?string*/, name/*:string*/, opts, rels, wb, csheet)
/* 21.2.2.120 numCache CT_NumData */
(data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm)||[]).forEach(function(nc) {
var cache = parse_numCache(nc);
var cache = parse_Cache(nc);
refguess.s.r = refguess.s.c = 0;
refguess.e.c = C;
col = encode_col(C);
@ -6696,7 +6744,7 @@ function parse_cs_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*::, them
if(!data) return data;
/* 18.3.1.12 chartsheet CT_ChartSheet */
if(!rels) rels = {'!id':{}};
var s = {'!type':"chart", '!chart':null, '!rel':""};
var s = ({'!type':"chart", '!chart':null, '!rel':""}/*:any*/);
var m;
/* 18.3.1.83 sheetPr CT_ChartsheetPr */
@ -6958,7 +7006,9 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
case '<fileVersion/>': case '</fileVersion>': break;
/* 18.2.12 fileSharing CT_FileSharing ? */
case '<fileSharing': case '<fileSharing/>': break;
case '<fileSharing':
break;
case '<fileSharing/>': break;
/* 18.2.28 workbookPr CT_WorkbookPr ? */
case '<workbookPr':
@ -6976,7 +7026,8 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
case '</workbookPr>': break;
/* 18.2.29 workbookProtection CT_WorkbookProtection ? */
case '<workbookProtection': break;
case '<workbookProtection':
break;
case '<workbookProtection/>': break;
/* 18.2.1 bookViews CT_BookViews ? */
@ -7038,7 +7089,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
/* 18.2.4 customWorkbookViews CT_CustomWorkbookViews ? */
case '<customWorkbookViews>': case '</customWorkbookViews>': case '<customWorkbookViews': break;
/* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
/* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
case '<customWorkbookView': case '</customWorkbookView>': break;
/* 18.2.18 pivotCaches CT_PivotCaches ? */
@ -7051,7 +7102,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
/* 18.2.23 smartTagTypes CT_SmartTagTypes ? */
case '<smartTagTypes': case '<smartTagTypes>': case '</smartTagTypes>': break;
/* 18.2.22 smartTagType CT_SmartTagType ? */
/* 18.2.22 smartTagType CT_SmartTagType ? */
case '<smartTagType': break;
/* 18.2.24 webPublishing CT_WebPublishing ? */
@ -7067,7 +7118,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break;
/* 18.2.7 ext CT_Extension + */
/* 18.2.7 ext CT_Extension + */
case '<ext': pass=true; break; //TODO: check with versions of excel
case '</ext>': pass=false; break;
@ -7219,9 +7270,9 @@ function parse_cc(data, name/*:string*/, opts) {
return parse_cc_xml((data/*:any*/), name, opts);
}
function parse_xlink(data, name/*:string*/, opts) {
if(name.slice(-4)===".bin") return parse_xlink_bin((data/*:any*/), name, opts);
return parse_xlink_xml((data/*:any*/), name, opts);
function parse_xlink(data, rel, name/*:string*/, opts) {
if(name.slice(-4)===".bin") return parse_xlink_bin((data/*:any*/), rel, name, opts);
return parse_xlink_xml((data/*:any*/), rel, name, opts);
}
function write_wb(wb, name/*:string*/, opts) {
@ -7259,6 +7310,7 @@ var HTML_ = (function() {
var opts = _opts || {};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
str = str.replace(/<!--.*?-->/g, "");
var mtch/*:any*/ = str.match(/<table/i);
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
var mtch2/*:any*/ = str.match(/<\/table/i);
@ -7336,7 +7388,7 @@ var HTML_ = (function() {
if(CS > 1) sp.colspan = CS;
sp.t = cell && cell.t || 'z';
if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
sp.id = "sjs-" + coord;
sp.id = (o.id || "sjs") + "-" + coord;
oo.push(writextag('td', w, sp));
}
var preamble = "<tr>";
@ -7381,7 +7433,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
var range/*:Range*/ = {s:{r:0,c:0},e:{r:0,c:0}};
var merges/*:Array<Range>*/ = [], midx = 0;
var rowinfo/*:Array<RowInfo>*/ = [];
var _R = 0, R = 0, _C, C, RS, CS;
var _R = 0, R = 0, _C = 0, C = 0, RS = 0, CS = 0;
for(; _R < rows.length && R < sheetRows; ++_R) {
var row/*:HTMLTableRowElement*/ = rows[_R];
if (is_dom_element_hidden(row)) {
@ -7549,8 +7601,20 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
break;
case 'macro': _ws = parse_ms(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
default: throw new Error("Unrecognized sheet type " + stype);
}
sheets[sheet] = _ws;
/* scan rels for comments */
var comments = [];
if(sheetRels && sheetRels[sheet]) keys(sheetRels[sheet]).forEach(function(n) {
if(sheetRels[sheet][n].Type == RELS.CMNT) {
var dfile = resolve_path(sheetRels[sheet][n].Target, path);
comments = parse_cmnt(getzipdata(zip, dfile, true), dfile, opts);
if(!comments || !comments.length) return;
sheet_insert_comments(_ws, comments);
}
});
} catch(e) { if(opts.WTF) throw e; }
}
@ -7596,7 +7660,10 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
}
/*var externbooks = */dir.links.map(function(link) {
return parse_xlink(getzipdata(zip, strip_front_slash(link)), link, opts);
try {
var rels = parse_rels(getzipstr(zip, get_rels_path(strip_front_slash(link))), link);
return parse_xlink(getzipdata(zip, strip_front_slash(link)), rels, link, opts);
} catch(e) {}
});
var wb = parse_wb(getzipdata(zip, strip_front_slash(dir.workbooks[0])), dir.workbooks[0], opts);
@ -7670,8 +7737,6 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
safe_parse_sheet(zip, path, relsPath, props.SheetNames[i], i, sheetRels, sheets, stype, opts, wb, themes, styles);
}
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
out = ({
Directory: dir,
Workbook: wb,
@ -7948,6 +8013,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), opts);
var d = data, n = [0,0,0,0], str = false;
var o = opts||{};
if(o.cellStyles) { o.cellNF = true; }
_ssfopts = {};
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
@ -7961,7 +8027,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
}
switch((n = firstbyte(d, o))[0]) {
case 0xD0: return read_cfb(CFB.read(d, o), o);
case 0x09: return parse_xlscfb(d, o);
case 0x09: if(n[1] <= 0x04) return parse_xlscfb(d, o); break;
case 0x3C: return parse_xlml(d, o);
case 0x49: if(n[1] === 0x44) return read_wb_ID(d, o); break;
case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break;
@ -8008,10 +8074,10 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
default: throw new Error("Unrecognized type " + o.type);
}
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: {"nodebuffer": "buffer", "string": "binary"}[oopts.type] || oopts.type}) : z.generate(oopts);
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type}) : z.generate(oopts);
if(o.password && typeof encrypt_agile !== 'undefined') return write_cfb_ctr(encrypt_agile(out, o.password), o);
if(o.type === "file") return write_dl(o.file, out);
return o.type == "string" ? utf8read(out) : out;
return o.type == "string" ? utf8read(/*::(*/out/*:: :any)*/) : out;
}
function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
@ -8029,7 +8095,6 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
// $FlowIgnore
if(has_buf) return Buffer_from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
@ -8044,7 +8109,6 @@ function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
// $FlowIgnore
if(has_buf) return Buffer_from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
@ -8069,8 +8133,10 @@ function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ {
}
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
reset_cp();
check_wb(wb);
var o = opts||{};
if(o.cellStyles) { o.cellNF = true; }
if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSync(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }
switch(o.bookType || 'xlsb') {
case 'xml':
@ -8185,6 +8251,7 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) {
if(o.header === 1) header = 1;
else if(o.header === "A") header = 2;
else if(Array.isArray(o.header)) header = 3;
else if(o.header == null) header = 0;
switch(typeof range) {
case 'string': r = safe_decode_range(range); break;
case 'number': r = safe_decode_range(sheet["!ref"]); r.s.r = range; break;
@ -8339,8 +8406,10 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
var v = JS[k];
var t = 'z';
var z = "";
var ref = encode_cell({c:_C + C,r:_R + R + offset});
cell = utils.sheet_get_cell(ws, ref);
if(v && typeof v === 'object' && !(v instanceof Date)){
ws[encode_cell({c:_C + C,r:_R + R + offset})] = v;
ws[ref] = v;
} else {
if(typeof v == 'number') t = 'n';
else if(typeof v == 'boolean') t = 'b';
@ -8348,9 +8417,14 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
else if(v instanceof Date) {
t = 'd';
if(!o.cellDates) { t = 'n'; v = datenum(v); }
z = o.dateNF || SSF._table[14];
z = (o.dateNF || SSF._table[14]);
}
if(!cell) ws[ref] = cell = ({t:t, v:v}/*:any*/);
else {
cell.t = t; cell.v = v;
delete cell.w; delete cell.R;
if(z) cell.z = z;
}
ws[encode_cell({c:_C + C,r:_R + R + offset})] = cell = ({t:t, v:v}/*:any*/);
if(z) cell.z = z;
}
});
@ -8401,12 +8475,21 @@ function get_default(x/*:any*/, y/*:any*/, z/*:any*/)/*:any*/ { return x[y] != n
/* get cell, creating a stub if necessary */
function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ {
/* A1 cell address */
if(typeof R == "string") return ws[R] || (ws[R] = {t:'z'});
if(typeof R == "string") {
/* dense */
if(Array.isArray(ws)) {
var RC = decode_cell(R);
if(!ws[RC.r]) ws[RC.r] = [];
return ws[RC.r][RC.c] || (ws[RC.r][RC.c] = {t:'z'});
}
return ws[R] || (ws[R] = {t:'z'});
}
/* cell address object */
if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R));
/* R and C are 0-based indices */
return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0}));
}
utils.sheet_get_cell = ws_get_cell_stub;
/* find sheet index for given name / validate index */
function wb_sheet_idx(wb/*:Workbook*/, sh/*:number|string*/) {

View File

@ -135,7 +135,6 @@ function new_unsafe_buf(len) {
}
var s2a = function s2a(s) {
// $FlowIgnore
if(has_buf) return Buffer_from(s, "binary");
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
};
@ -2822,6 +2821,11 @@ function zip_add_file(zip, path, content) {
else zip.file(path, content);
}
function zip_new() {
return CFB.utils.cfb_new();
}
function zip_read(d, o) {
var zip;
switch(o.type) {
@ -2833,12 +2837,8 @@ function zip_read(d, o) {
return zip;
}
function zip_new() {
return CFB.utils.cfb_new();
}
function resolve_path(path, base) {
if(path.charAt(0) == "/") return path.slice(1);
var result = base.split('/');
if(base.slice(-1) != "/") result.pop(); // folder path
var target = path.split('/');
@ -2852,6 +2852,7 @@ function resolve_path(path, base) {
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s?[\/\?]?>/g;
if(!(XML_HEADER.match(tagregex))) tagregex = /<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag, skip_root) {
@ -3005,11 +3006,9 @@ if(has_buf) {
};
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer_from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
// $FlowIgnore
utf8write = function(data) { return Buffer_from(data, 'utf8').toString("binary"); };
}
@ -3029,7 +3028,19 @@ var htmldecode = (function() {
['quot', '"'], ['apos', "'"], ['gt', '>'], ['lt', '<'], ['amp', '&']
].map(function(x) { return [new RegExp('&' + x[0] + ';', "g"), x[1]]; });
return function htmldecode(str) {
var o = str.replace(/^[\t\n\r ]+/, "").replace(/[\t\n\r ]+$/,"").replace(/[\t\n\r ]+/g, " ").replace(/<\s*[bB][rR]\s*\/?>/g,"\n").replace(/<[^>]*>/g,"");
var o = str
// Remove new lines and spaces from start of content
.replace(/^[\t\n\r ]+/, "")
// Remove new lines and spaces from end of content
.replace(/[\t\n\r ]+$/,"")
// Added line which removes any white space characters after and before html tags
.replace(/>\s+/g,">").replace(/\s+</g,"<")
// Replace remaining new lines and spaces with space
.replace(/[\t\n\r ]+/g, " ")
// Replace <br> tags with new lines
.replace(/<\s*[bB][rR]\s*\/?>/g,"\n")
// Strip HTML elements
.replace(/<[^>]*>/g,"");
for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
return o;
};
@ -3431,8 +3442,8 @@ function encode_cell_xls(c, biff) {
if(c.cRel && c.c < 0) { c = dup(c); c.c += (biff > 8) ? 0x4000 : 0x100; }
if(c.rRel && c.r < 0) { c = dup(c); c.r += (biff > 8) ? 0x100000 : ((biff > 5) ? 0x10000 : 0x4000); }
var s = encode_cell(c);
if(c.cRel === 0) s = fix_col(s);
if(c.rRel === 0) s = fix_row(s);
if(!c.cRel && c.cRel != null) s = fix_col(s);
if(!c.rRel && c.rRel != null) s = fix_row(s);
return s;
}
@ -3455,7 +3466,7 @@ function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
function unfix_row(cstr) { return cstr.replace(/\$(\d+)$/,"$1"); }
function decode_col(colstr) { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
function encode_col(col) { if(col < 0) throw new Error("invalid column " + col); var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
function fix_col(cstr) { return cstr.replace(/^([A-Z])/,"$$$1"); }
function unfix_col(cstr) { return cstr.replace(/^\$([A-Z])/,"$1"); }
@ -3775,7 +3786,7 @@ function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&2
/* [MS-XLS] 2.5.161 */
/* [MS-XLSB] 2.5.75 Icv */
var XLSIcv = rgbify([
var _XLSIcv = rgbify([
/* Color Constants */
0x000000,
0xFFFFFF,
@ -3867,7 +3878,7 @@ var XLSIcv = rgbify([
0x000000, /* 0x50 icvInfoBk ?? */
0x000000 /* 0x51 icvInfoText ?? */
]);
var XLSIcv = dup(_XLSIcv);
/* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */
/* 12.3 Part Summary <SpreadsheetML> */
/* 14.2 Part Summary <DrawingML> */
@ -3896,12 +3907,18 @@ var ct2type/*{[string]:string}*/ = ({
"application/vnd.ms-excel.pivotTable": "TODO",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO",
/* Chart Objects */
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
/* Chart Colors */
"application/vnd.ms-office.chartcolorstyle+xml": "TODO",
/* Chart Style */
"application/vnd.ms-office.chartstyle+xml": "TODO",
/* Chart Advanced */
"application/vnd.ms-office.chartex+xml": "TODO",
/* Calculation Chain */
"application/vnd.ms-excel.calcChain": "calcchains",
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
@ -3992,7 +4009,6 @@ var ct2type/*{[string]:string}*/ = ({
/* Drawing */
"application/vnd.openxmlformats-officedocument.drawing+xml": "drawings",
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO",
"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO",
@ -4101,6 +4117,7 @@ var CTYPE_DEFAULTS = [
['xml', 'application/xml'],
['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'],
['vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'],
['data', 'application/vnd.openxmlformats-officedocument.model+data'],
/* from test files */
['bmp', 'image/bmp'],
['png', 'image/png'],
@ -4120,6 +4137,8 @@ function write_ct(ct, opts) {
o[o.length] = (XML_HEADER);
o[o.length] = (CTYPE_XML_ROOT);
o = o.concat(CTYPE_DEFAULTS);
/* only write first instance */
var f1 = function(w) {
if(ct[w] && ct[w].length > 0) {
v = ct[w][0];
@ -4129,6 +4148,8 @@ function write_ct(ct, opts) {
}));
}
};
/* book type-specific */
var f2 = function(w) {
(ct[w]||[]).forEach(function(v) {
o[o.length] = (writextag('Override', null, {
@ -4137,6 +4158,8 @@ function write_ct(ct, opts) {
}));
});
};
/* standard type */
var f3 = function(t) {
(ct[t]||[]).forEach(function(v) {
o[o.length] = (writextag('Override', null, {
@ -4145,6 +4168,7 @@ function write_ct(ct, opts) {
}));
});
};
f1('workbooks');
f2('sheets');
f2('charts');
@ -4163,6 +4187,9 @@ var RELS = ({
SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
HLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
VML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
XPATH: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath",
XMISS: "http://schemas.microsoft.com/office/2006/relationships/xlExternalLinkPath/xlPathMissing",
XLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
VBA: "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
});
@ -4211,14 +4238,16 @@ function write_rels(rels) {
return o.join("");
}
function add_rels(rels, rId, f, type, relobj) {
var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
function add_rels(rels, rId, f, type, relobj, targetmode) {
if(!relobj) relobj = {};
if(!rels['!id']) rels['!id'] = {};
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
relobj.Id = 'rId' + rId;
relobj.Type = type;
relobj.Target = f;
if(relobj.Type == RELS.HLINK) relobj.TargetMode = "External";
if(targetmode) relobj.TargetMode = targetmode;
else if(RELS_EXTERN.indexOf(relobj.Type) > -1) relobj.TargetMode = "External";
if(rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId);
rels['!id'][relobj.Id] = relobj;
rels[('/' + relobj.Target).replace("//","/")] = relobj;
@ -4352,12 +4381,14 @@ function load_props_pairs(HP, TOP, props, opts) {
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Hojas de cálculo":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "Rangos con nombre":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
@ -4830,7 +4861,7 @@ function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<borders': case '<borders>': case '</borders>': break;
@ -4838,8 +4869,8 @@ function parse_borders(t, styles, themes, opts) {
/* 18.8.4 border CT_Border */
case '<border': case '<border>': case '<border/>':
border = {};
if (y.diagonalUp) { border.diagonalUp = y.diagonalUp; }
if (y.diagonalDown) { border.diagonalDown = y.diagonalDown; }
if(y.diagonalUp) border.diagonalUp = parsexmlbool(y.diagonalUp);
if(y.diagonalDown) border.diagonalDown = parsexmlbool(y.diagonalDown);
styles.Borders.push(border);
break;
case '</border>': break;
@ -4885,7 +4916,8 @@ function parse_borders(t, styles, themes, opts) {
case '</end>': break;
/* 18.8.? color CT_Color */
case '<color': case '<color>': break;
case '<color': case '<color>':
break;
case '<color/>': case '</color>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
@ -4904,7 +4936,7 @@ function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fills': case '<fills>': case '</fills>': break;
@ -4942,7 +4974,7 @@ function parse_fills(t, styles, themes, opts) {
if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
/* Excel uses ARGB strings */
if(y.rgb) fill.fgColor.rgb = y.rgb.slice(-6);
if(y.rgb != null) fill.fgColor.rgb = y.rgb.slice(-6);
break;
case '<fgColor/>': case '</fgColor>': break;
@ -4970,7 +5002,7 @@ function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fonts': case '<fonts>': case '</fonts>': break;
@ -5070,6 +5102,10 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
@ -5127,7 +5163,7 @@ function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
(t[0].match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(strip_ns(y[0])) {
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
@ -5153,13 +5189,19 @@ function parse_cellXfs(t, styles, opts) {
if(y.horizontal) alignment.horizontal = y.horizontal;
if(y.textRotation != null) alignment.textRotation = y.textRotation;
if(y.indent) alignment.indent = y.indent;
if(y.wrapText) alignment.wrapText = y.wrapText;
if(y.wrapText) alignment.wrapText = parsexmlbool(y.wrapText);
xf.alignment = alignment;
break;
case '</alignment>': break;
/* 18.8.33 protection CT_CellProtection */
case '<protection': case '</protection>': case '<protection/>': break;
case '<protection':
break;
case '</protection>': case '<protection/>': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -5175,7 +5217,9 @@ function parse_cellXfs(t, styles, opts) {
function write_cellXfs(cellXfs) {
var o = [];
o[o.length] = (writextag('cellXfs',null));
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
cellXfs.forEach(function(c) {
o[o.length] = (writextag('xf', null, c));
});
o[o.length] = ("</cellXfs>");
if(o.length === 2) return "";
o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");
@ -5351,6 +5395,7 @@ function parse_theme_xml(data, opts) {
function write_theme(Themes, opts) {
if(opts && opts.themeXLSX) return opts.themeXLSX;
if(Themes && typeof Themes.raw == "string") return Themes.raw;
var o = [XML_HEADER];
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
o[o.length] = '<a:themeElements>';
@ -5526,7 +5571,7 @@ function parse_xlink_xml() {
}
/* [MS-XLSB] 2.1.7.25 External Link */
function parse_xlink_bin(data, name, _opts) {
function parse_xlink_bin(data, rel, name, _opts) {
if(!data) return data;
var opts = _opts || {};
@ -5570,9 +5615,11 @@ function parse_xlink_bin(data, name, _opts) {
}
}, opts);
}
/* 20.5 DrawingML - SpreadsheetML Drawing */
RELS.IMG = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
RELS.DRAW = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
/* 20.5 DrawingML - SpreadsheetML Drawing */
/* 20.5.2.35 wsDr CT_Drawing */
function parse_drawing(data, rels) {
if(!data) return "??";
/*
@ -5638,25 +5685,7 @@ function write_comments_vml(rId, comments) {
RELS.CMNT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
for(var i = 0; i != dirComments.length; ++i) {
var canonicalpath=dirComments[i];
var comments=parse_cmnt(getzipdata(zip, canonicalpath.replace(/^\//,''), true), canonicalpath, opts);
if(!comments || !comments.length) continue;
// find the sheets targeted by these comments
var sheetNames = keys(sheets);
for(var j = 0; j != sheetNames.length; ++j) {
var sheetName = sheetNames[j];
var rels = sheetRels[sheetName];
if(rels) {
var rel = rels[canonicalpath];
if(rel) insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
}
}
}
}
function insertCommentsIntoSheet(sheetName, sheet, comments) {
function sheet_insert_comments(sheet, comments) {
var dense = Array.isArray(sheet);
var cell;
comments.forEach(function(comment) {
@ -5666,7 +5695,7 @@ function insertCommentsIntoSheet(sheetName, sheet, comments) {
cell = sheet[r.r][r.c];
} else cell = sheet[comment.ref];
if (!cell) {
cell = {};
cell = ({t:"z"});
if(dense) sheet[r.r][r.c] = cell;
else sheet[comment.ref] = cell;
var range = safe_decode_range(sheet["!ref"]||"BDWGO1000001:A1");
@ -5773,14 +5802,21 @@ function parse_ms_bin() { return {'!type':'macro'}; }
function parse_ms_xml() { return {'!type':'macro'}; }
/* TODO: it will be useful to parse the function str */
var rc_to_a1 = (function(){
var rcregex = /(^|[^A-Za-z])R(\[?)(-?\d+|)\]?C(\[?)(-?\d+|)\]?/g;
var rcregex = /(^|[^A-Za-z_])R(\[?-?\d+\]|[1-9]\d*|)C(\[?-?\d+\]|[1-9]\d*|)(?![A-Za-z0-9_])/g;
var rcbase = ({r:0,c:0});
function rcfunc($$,$1,$2,$3,$4,$5) {
var R = $3.length>0?parseInt($3,10)|0:0, C = $5.length>0?parseInt($5,10)|0:0;
if(C<0 && $4.length === 0) C=0;
function rcfunc($$,$1,$2,$3) {
var cRel = false, rRel = false;
if($4.length > 0 || $5.length == 0) cRel = true; if(cRel) C += rcbase.c; else --C;
if($2.length > 0 || $3.length == 0) rRel = true; if(rRel) R += rcbase.r; else --R;
if($2.length == 0) rRel = true;
else if($2.charAt(0) == "[") { rRel = true; $2 = $2.slice(1, -1); }
if($3.length == 0) cRel = true;
else if($3.charAt(0) == "[") { cRel = true; $3 = $3.slice(1, -1); }
var R = $2.length>0?parseInt($2,10)|0:0, C = $3.length>0?parseInt($3,10)|0:0;
if(cRel) C += rcbase.c; else --C;
if(rRel) R += rcbase.r; else --R;
return $1 + (cRel ? "" : "$") + encode_col(C) + (rRel ? "" : "$") + encode_row(R);
}
return function rc_to_a1(fstr, base) {
@ -5968,9 +6004,11 @@ var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g
var marginregex= /<(?:\w:)?pageMargins[^>]*\/>/g;
var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;
/* 18.3 Worksheets */
function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
if(!data) return data;
if(!rels) rels = {'!id':{}};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
/* 18.3.1.99 worksheet CT_Worksheet */
@ -5989,7 +6027,6 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
/* 18.3.1.35 dimension CT_SheetDimension */
// $FlowIgnore
var ridx = (data1.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
if(ridx > 0) {
var ref = data1.slice(ridx,ridx+50).match(dimregex);
@ -6062,18 +6099,18 @@ function parse_ws_xml_sheetpr(sheetPr, s, wb, idx) {
}
/* 18.3.1.85 sheetProtection CT_SheetProtection */
var sheetprot_deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
var sheetprot_deftrue = [
"formatColumns", "formatRows", "formatCells",
"insertColumns", "insertRows", "insertHyperlinks",
"deleteColumns", "deleteRows",
"sort", "autoFilter", "pivotTables"
];
function write_ws_xml_protection(sp) {
// algorithmName, hashValue, saltValue, spinCountpassword
var o = ({sheet:1});
var deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
var deftrue = [
"formatColumns", "formatRows", "formatCells",
"insertColumns", "insertRows", "insertHyperlinks",
"deleteColumns", "deleteRows",
"sort", "autoFilter", "pivotTables"
];
deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
sheetprot_deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
sheetprot_deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
/* TODO: algorithm */
if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
return writextag('sheetProtection', null, o);
@ -6133,7 +6170,6 @@ function parse_ws_xml_cols(columns, cols) {
while(colm <= colM) columns[colm++] = dup(coll);
}
}
function write_ws_xml_cols(ws, cols) {
var o = ["<cols>"], col;
for(var i = 0; i != cols.length; ++i) {
@ -6150,7 +6186,7 @@ function parse_ws_xml_autofilter(data) {
}
function write_ws_xml_autofilter(data, ws, wb, idx) {
var ref = typeof data.ref == "string" ? data.ref : encode_range(data.ref);
if(!wb.Workbook) wb.Workbook = {};
if(!wb.Workbook) wb.Workbook = ({Sheets:[]});
if(!wb.Workbook.Names) wb.Workbook.Names = [];
var names = wb.Workbook.Names;
var range = decode_range(ref);
@ -6167,21 +6203,21 @@ function write_ws_xml_autofilter(data, ws, wb, idx) {
/* 18.3.1.88 sheetViews CT_SheetViews */
/* 18.3.1.87 sheetView CT_SheetView */
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/>/;
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/;
function parse_ws_xml_sheetviews(data, wb) {
(data.match(sviewregex)||[]).forEach(function(r) {
if(!wb.Views) wb.Views = [{}];
(data.match(sviewregex)||[]).forEach(function(r, i) {
var tag = parsexmltag(r);
if(parsexmlbool(tag.rightToLeft)) {
if(!wb.Views) wb.Views = [{}];
if(!wb.Views[0]) wb.Views[0] = {};
wb.Views[0].RTL = true;
}
// $FlowIgnore
if(!wb.Views[i]) wb.Views[i] = {};
// $FlowIgnore
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
});
}
function write_ws_xml_sheetviews(ws, opts, idx, wb) {
var sview = {workbookViewId:"0"};
var sview = ({workbookViewId:"0"});
// $FlowIgnore
if( (((wb||{}).Workbook||{}).Views||[])[0] ) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
if((((wb||{}).Workbook||{}).Views||[])[0]) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
return writextag("sheetViews", writextag("sheetView", null, sview), {});
}
@ -6189,12 +6225,12 @@ function write_ws_xml_cell(cell, ref, ws, opts) {
if(cell.v === undefined && cell.f === undefined || cell.t === 'z') return "";
var vv = "";
var oldt = cell.t, oldv = cell.v;
switch(cell.t) {
if(cell.t !== "z") switch(cell.t) {
case 'b': vv = cell.v ? "1" : "0"; break;
case 'n': vv = ''+cell.v; break;
case 'e': vv = BErr[cell.v]; break;
case 'd':
if(opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
if(opts && opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
else {
cell = dup(cell);
cell.t = 'n';
@ -6269,6 +6305,8 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
/* 18.3.1.4 c CT_Cell */
cells = x.slice(ri).split(cellregex);
for(var rslice = 0; rslice != cells.length; ++rslice) if(cells[rslice].trim().charAt(0) != "<") break;
cells = cells.slice(rslice);
for(ri = 0; ri != cells.length; ++ri) {
x = cells[ri].trim();
if(x.length === 0) continue;
@ -6350,7 +6388,10 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
case 'inlineStr':
cref = d.match(isregex);
p.t = 's';
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
if(cref != null && (sstr = parse_si(cref[1]))) {
p.v = sstr.t;
if(opts.cellHTML) p.h = sstr.h;
} else p.v = "";
break;
case 'b': p.v = parsexmlbool(p.v); break;
case 'd':
@ -6364,6 +6405,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
}
/* formatting */
fmtid = fillid = 0;
cf = null;
if(do_format && tag.s !== undefined) {
cf = styles.CellXf[tag.s];
if(cf != null) {
@ -6500,7 +6542,7 @@ function write_ws_xml(idx, opts, wb, rels) {
var relc = -1, rel, rId = -1;
if(ws['!links'].length > 0) {
o[o.length] = "<hyperlinks>";
ws['!links'].forEach(function(l) {
ws['!links'].forEach(function(l) {
if(!l[1].Target) return;
rel = ({"ref":l[0]});
if(l[1].Target.charAt(0) != "#") {
@ -6519,7 +6561,6 @@ function write_ws_xml(idx, opts, wb, rels) {
if (ws['!margins'] != null) o[o.length] = write_ws_xml_margins(ws['!margins']);
/* pageSetup */
//var hfidx = o.length;
o[o.length] = "";
/* rowBreaks */
@ -6554,20 +6595,27 @@ function write_ws_xml(idx, opts, wb, rels) {
if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
return o.join("");
}
function parse_numCache(data) {
RELS.CHART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
RELS.CHARTEX = "http://schemas.microsoft.com/office/2014/relationships/chartEx";
function parse_Cache(data) {
var col = [];
var num = data.match(/^<c:numCache>/);
var f;
/* 21.2.2.150 pt CT_NumVal */
(data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg)||[]).forEach(function(pt) {
var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
if(!q) return;
col[+q[1]] = +q[2];
col[+q[1]] = num ? +q[2] : q[2];
});
/* 21.2.2.71 formatCode CT_Xstring */
var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["","General"])[1]);
return [col, nf];
(data.match(/<c:f>(.*?)<\/c:f>/mg)||[]).forEach(function(F) { f = F.replace(/<.*?>/g,""); });
return [col, nf, f];
}
/* 21.2 DrawingML - Charts */
@ -6581,7 +6629,7 @@ function parse_chart(data, name, opts, rels, wb, csheet) {
/* 21.2.2.120 numCache CT_NumData */
(data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm)||[]).forEach(function(nc) {
var cache = parse_numCache(nc);
var cache = parse_Cache(nc);
refguess.s.r = refguess.s.c = 0;
refguess.e.c = C;
col = encode_col(C);
@ -6607,7 +6655,7 @@ function parse_cs_xml(data, opts, idx, rels, wb) {
if(!data) return data;
/* 18.3.1.12 chartsheet CT_ChartSheet */
if(!rels) rels = {'!id':{}};
var s = {'!type':"chart", '!chart':null, '!rel':""};
var s = ({'!type':"chart", '!chart':null, '!rel':""});
var m;
/* 18.3.1.83 sheetPr CT_ChartsheetPr */
@ -6869,7 +6917,9 @@ function parse_wb_xml(data, opts) {
case '<fileVersion/>': case '</fileVersion>': break;
/* 18.2.12 fileSharing CT_FileSharing ? */
case '<fileSharing': case '<fileSharing/>': break;
case '<fileSharing':
break;
case '<fileSharing/>': break;
/* 18.2.28 workbookPr CT_WorkbookPr ? */
case '<workbookPr':
@ -6887,7 +6937,8 @@ function parse_wb_xml(data, opts) {
case '</workbookPr>': break;
/* 18.2.29 workbookProtection CT_WorkbookProtection ? */
case '<workbookProtection': break;
case '<workbookProtection':
break;
case '<workbookProtection/>': break;
/* 18.2.1 bookViews CT_BookViews ? */
@ -6949,7 +7000,7 @@ function parse_wb_xml(data, opts) {
/* 18.2.4 customWorkbookViews CT_CustomWorkbookViews ? */
case '<customWorkbookViews>': case '</customWorkbookViews>': case '<customWorkbookViews': break;
/* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
/* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
case '<customWorkbookView': case '</customWorkbookView>': break;
/* 18.2.18 pivotCaches CT_PivotCaches ? */
@ -6962,7 +7013,7 @@ function parse_wb_xml(data, opts) {
/* 18.2.23 smartTagTypes CT_SmartTagTypes ? */
case '<smartTagTypes': case '<smartTagTypes>': case '</smartTagTypes>': break;
/* 18.2.22 smartTagType CT_SmartTagType ? */
/* 18.2.22 smartTagType CT_SmartTagType ? */
case '<smartTagType': break;
/* 18.2.24 webPublishing CT_WebPublishing ? */
@ -6978,7 +7029,7 @@ function parse_wb_xml(data, opts) {
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break;
/* 18.2.7 ext CT_Extension + */
/* 18.2.7 ext CT_Extension + */
case '<ext': pass=true; break; //TODO: check with versions of excel
case '</ext>': pass=false; break;
@ -7128,9 +7179,9 @@ function parse_cc(data, name, opts) {
return parse_cc_xml((data), name, opts);
}
function parse_xlink(data, name, opts) {
if(name.slice(-4)===".bin") return parse_xlink_bin((data), name, opts);
return parse_xlink_xml((data), name, opts);
function parse_xlink(data, rel, name, opts) {
if(name.slice(-4)===".bin") return parse_xlink_bin((data), rel, name, opts);
return parse_xlink_xml((data), rel, name, opts);
}
function write_wb(wb, name, opts) {
@ -7168,6 +7219,7 @@ var HTML_ = (function() {
var opts = _opts || {};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var ws = opts.dense ? ([]) : ({});
str = str.replace(/<!--.*?-->/g, "");
var mtch = str.match(/<table/i);
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
var mtch2 = str.match(/<\/table/i);
@ -7245,7 +7297,7 @@ var HTML_ = (function() {
if(CS > 1) sp.colspan = CS;
sp.t = cell && cell.t || 'z';
if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
sp.id = "sjs-" + coord;
sp.id = (o.id || "sjs") + "-" + coord;
oo.push(writextag('td', w, sp));
}
var preamble = "<tr>";
@ -7290,7 +7342,7 @@ function parse_dom_table(table, _opts) {
var range = {s:{r:0,c:0},e:{r:0,c:0}};
var merges = [], midx = 0;
var rowinfo = [];
var _R = 0, R = 0, _C, C, RS, CS;
var _R = 0, R = 0, _C = 0, C = 0, RS = 0, CS = 0;
for(; _R < rows.length && R < sheetRows; ++_R) {
var row = rows[_R];
if (is_dom_element_hidden(row)) {
@ -7458,8 +7510,20 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st
break;
case 'macro': _ws = parse_ms(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
default: throw new Error("Unrecognized sheet type " + stype);
}
sheets[sheet] = _ws;
/* scan rels for comments */
var comments = [];
if(sheetRels && sheetRels[sheet]) keys(sheetRels[sheet]).forEach(function(n) {
if(sheetRels[sheet][n].Type == RELS.CMNT) {
var dfile = resolve_path(sheetRels[sheet][n].Target, path);
comments = parse_cmnt(getzipdata(zip, dfile, true), dfile, opts);
if(!comments || !comments.length) return;
sheet_insert_comments(_ws, comments);
}
});
} catch(e) { if(opts.WTF) throw e; }
}
@ -7505,7 +7569,10 @@ function parse_zip(zip, opts) {
}
/*var externbooks = */dir.links.map(function(link) {
return parse_xlink(getzipdata(zip, strip_front_slash(link)), link, opts);
try {
var rels = parse_rels(getzipstr(zip, get_rels_path(strip_front_slash(link))), link);
return parse_xlink(getzipdata(zip, strip_front_slash(link)), rels, link, opts);
} catch(e) {}
});
var wb = parse_wb(getzipdata(zip, strip_front_slash(dir.workbooks[0])), dir.workbooks[0], opts);
@ -7579,8 +7646,6 @@ function parse_zip(zip, opts) {
safe_parse_sheet(zip, path, relsPath, props.SheetNames[i], i, sheetRels, sheets, stype, opts, wb, themes, styles);
}
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
out = ({
Directory: dir,
Workbook: wb,
@ -7852,6 +7917,7 @@ function readSync(data, opts) {
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), opts);
var d = data, n = [0,0,0,0], str = false;
var o = opts||{};
if(o.cellStyles) { o.cellNF = true; }
_ssfopts = {};
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
@ -7865,7 +7931,7 @@ function readSync(data, opts) {
}
switch((n = firstbyte(d, o))[0]) {
case 0xD0: return read_cfb(CFB.read(d, o), o);
case 0x09: return parse_xlscfb(d, o);
case 0x09: if(n[1] <= 0x04) return parse_xlscfb(d, o); break;
case 0x3C: return parse_xlml(d, o);
case 0x49: if(n[1] === 0x44) return read_wb_ID(d, o); break;
case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break;
@ -7932,7 +7998,6 @@ function write_string_type(out, opts, bom) {
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
// $FlowIgnore
if(has_buf) return Buffer_from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
@ -7947,7 +8012,6 @@ function write_stxt_type(out, opts) {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
// $FlowIgnore
if(has_buf) return Buffer_from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
@ -7972,8 +8036,10 @@ function write_binary_type(out, opts) {
}
function writeSync(wb, opts) {
reset_cp();
check_wb(wb);
var o = opts||{};
if(o.cellStyles) { o.cellNF = true; }
if(o.type == "array") { o.type = "binary"; var out = (writeSync(wb, o)); o.type = "array"; return s2ab(out); }
switch(o.bookType || 'xlsb') {
case 'xml':
@ -8082,6 +8148,7 @@ function sheet_to_json(sheet, opts) {
if(o.header === 1) header = 1;
else if(o.header === "A") header = 2;
else if(Array.isArray(o.header)) header = 3;
else if(o.header == null) header = 0;
switch(typeof range) {
case 'string': r = safe_decode_range(range); break;
case 'number': r = safe_decode_range(sheet["!ref"]); r.s.r = range; break;
@ -8236,8 +8303,10 @@ function sheet_add_json(_ws, js, opts) {
var v = JS[k];
var t = 'z';
var z = "";
var ref = encode_cell({c:_C + C,r:_R + R + offset});
cell = utils.sheet_get_cell(ws, ref);
if(v && typeof v === 'object' && !(v instanceof Date)){
ws[encode_cell({c:_C + C,r:_R + R + offset})] = v;
ws[ref] = v;
} else {
if(typeof v == 'number') t = 'n';
else if(typeof v == 'boolean') t = 'b';
@ -8245,9 +8314,14 @@ function sheet_add_json(_ws, js, opts) {
else if(v instanceof Date) {
t = 'd';
if(!o.cellDates) { t = 'n'; v = datenum(v); }
z = o.dateNF || SSF._table[14];
z = (o.dateNF || SSF._table[14]);
}
if(!cell) ws[ref] = cell = ({t:t, v:v});
else {
cell.t = t; cell.v = v;
delete cell.w; delete cell.R;
if(z) cell.z = z;
}
ws[encode_cell({c:_C + C,r:_R + R + offset})] = cell = ({t:t, v:v});
if(z) cell.z = z;
}
});
@ -8298,12 +8372,21 @@ function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); }
/* get cell, creating a stub if necessary */
function ws_get_cell_stub(ws, R, C) {
/* A1 cell address */
if(typeof R == "string") return ws[R] || (ws[R] = {t:'z'});
if(typeof R == "string") {
/* dense */
if(Array.isArray(ws)) {
var RC = decode_cell(R);
if(!ws[RC.r]) ws[RC.r] = [];
return ws[RC.r][RC.c] || (ws[RC.r][RC.c] = {t:'z'});
}
return ws[R] || (ws[R] = {t:'z'});
}
/* cell address object */
if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R));
/* R and C are 0-based indices */
return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0}));
}
utils.sheet_get_cell = ws_get_cell_stub;
/* find sheet index for given name / validate index */
function wb_sheet_idx(wb, sh) {