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 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 vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

34
dist/xlsx.full.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

600
dist/xlsx.js vendored

File diff suppressed because it is too large Load Diff

26
dist/xlsx.min.js vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.min.map vendored

File diff suppressed because one or more lines are too long

12
dist/xlsx.mini.min.js vendored

File diff suppressed because one or more lines are too long

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

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) {