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`
pull/1665/head
SheetJS 3 years ago
parent b0d18ed6db
commit b7c0b0d914
  1. 3
      .flowconfig
  2. 1
      .github/FUNDING.yml
  3. 2
      LICENSE
  4. 8
      bin/xlsx.njs
  5. 1
      bits/05_buf.js
  6. 30
      bits/21_ziputils.js
  7. 3
      bits/22_xmlutils.js
  8. 4
      bits/25_cellutils.js
  9. 12
      bits/28_binstructs.js
  10. 6
      bits/29_xlsenum.js
  11. 15
      bits/30_ctype.js
  12. 9
      bits/31_rels.js
  13. 2
      bits/34_extprops.js
  14. 4
      bits/39_xlsbiff.js
  15. 12
      bits/40_harb.js
  16. 35
      bits/47_styxml.js
  17. 23
      bits/48_stybin.js
  18. 1
      bits/49_theme.js
  19. 4
      bits/53_externlink.js
  20. 4
      bits/54_drawing.js
  21. 22
      bits/56_cmntcommon.js
  22. 4
      bits/58_cmntbin.js
  23. 19
      bits/61_fcommon.js
  24. 38
      bits/63_fbin.js
  25. 61
      bits/67_wsxml.js
  26. 50
      bits/68_wsbin.js
  27. 17
      bits/69_chartxml.js
  28. 2
      bits/70_csheet.js
  29. 13
      bits/72_wbxml.js
  30. 6
      bits/74_xmlbin.js
  31. 73
      bits/75_xlml.js
  32. 32
      bits/76_xls.js
  33. 1
      bits/77_parsetab.js
  34. 50
      bits/78_writebiff.js
  35. 5
      bits/79_html.js
  36. 4
      bits/80_parseods.js
  37. 19
      bits/85_parsezip.js
  38. 1
      bits/87_read.js
  39. 8
      bits/88_write.js
  40. 13
      bits/90_utils.js
  41. 11
      bits/95_api.js
  42. 2
      dist/LICENSE
  43. 32
      dist/xlsx.core.min.js
  44. 2
      dist/xlsx.core.min.map
  45. 600
      dist/xlsx.extendscript.js
  46. 34
      dist/xlsx.full.min.js
  47. 2
      dist/xlsx.full.min.map
  48. 600
      dist/xlsx.js
  49. 26
      dist/xlsx.min.js
  50. 2
      dist/xlsx.min.map
  51. 12
      dist/xlsx.mini.min.js
  52. 2
      dist/xlsx.mini.min.map
  53. 11
      misc/21_ziputils.js
  54. 1
      misc/flowdeps.js
  55. 10
      packages/s/misc/module.html
  56. 1
      packages/s/misc/parcel.html
  57. 9
      packages/s/misc/standalone.html
  58. 2
      test.js
  59. 1
      types/tsconfig.json
  60. 2
      types/tslint.json
  61. 633
      xlsx.flow.js
  62. 600
      xlsx.js
  63. 311
      xlsx.mini.flow.js
  64. 297
      xlsx.mini.js

@ -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,2 +1,3 @@
github: SheetJSDev
custom: https://sheetjs.com
open_collective: s5s

@ -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.

@ -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]]]);
}
}
}

@ -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; });
};

@ -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('/');

@ -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"); };
}

@ -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;
}

@ -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,

@ -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);

@ -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');

@ -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;

@ -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":

@ -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 */

@ -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); };

@ -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("/>",">");

@ -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");

@ -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>';

@ -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 || {};

@ -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 "??";
/*

@ -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");

@ -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;

@ -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*/ {

@ -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 */

@ -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});
}

@ -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] */

@ -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 */