styled-exceljs 0.21.3 → 0.21.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -160,7 +160,7 @@ var DO_NOT_EXPORT_CODEPAGE = true;
160
160
  /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false, Int8Array:false */
161
161
  var XLSX = {};
162
162
  function make_xlsx_lib(XLSX){
163
- XLSX.version = '0.21.3';
163
+ XLSX.version = '0.21.4';
164
164
  var current_codepage = 1200, current_ansi = 1252;
165
165
  /*global cptable:true, window */
166
166
  var $cptable;
@@ -4028,7 +4028,7 @@ function escapexmltag(text){ return escapexml(text).replace(/ /g,"_x0020_"); }
4028
4028
  var htmlcharegex = /[\u0000-\u001f]/g;
4029
4029
  function escapehtml(text){
4030
4030
  var s = text + '';
4031
- return s.replace(decregex, function(y) { return rencoding[y]; }).replace(/\n/g, "<br/>").replace(htmlcharegex,function(s) { return "&#x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + ";"; });
4031
+ return s.replace(decregex, function(y) { return rencoding[y]; }).replace(/\r\n|\r|\n/g, "<br/>").replace(htmlcharegex,function(s) { return "&#x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + ";"; });
4032
4032
  }
4033
4033
 
4034
4034
  function escapexlml(text){
@@ -5831,6 +5831,7 @@ var RELS = ({
5831
5831
  MS: "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet",
5832
5832
  IMG: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
5833
5833
  DRAW: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
5834
+ TABLE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
5834
5835
  XLMETA: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
5835
5836
  TCMNT: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",
5836
5837
  PEOPLE: "http://schemas.microsoft.com/office/2017/10/relationships/person",
@@ -11294,6 +11295,9 @@ function resolve_style_obj_color(obj, themes) {
11294
11295
 
11295
11296
  /* 18.3.1.13 width calculations */
11296
11297
  /* [MS-OI29500] 2.1.595 Column Width & Formatting */
11298
+ /* The file format does not store MDW directly. Seven is the Office-compatible
11299
+ * fallback when Normal-font metrics are unavailable. A single stored column
11300
+ * width is ambiguous and must not change the scale for the rest of a sheet. */
11297
11301
  var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
11298
11302
  function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
11299
11303
  function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
@@ -12127,6 +12131,47 @@ function parse_dxfs(t, styles, themes, opts) {
12127
12131
  });
12128
12132
  }
12129
12133
 
12134
+ function parse_tableStyles(t, styles, opts) {
12135
+ styles.TableStyles = {styles:[]};
12136
+ var tableStyle = null, pass = false;
12137
+ (t.match(tagregex)||[]).forEach(function(x) {
12138
+ var y = parsexmltag(x), tag = strip_ns(y[0]);
12139
+ switch(tag) {
12140
+ case '<tableStyles': case '<tableStyles>':
12141
+ if(y.defaultTableStyle) styles.TableStyles.defaultTableStyle = utf8read(unescapexml(y.defaultTableStyle));
12142
+ if(y.defaultPivotStyle) styles.TableStyles.defaultPivotStyle = utf8read(unescapexml(y.defaultPivotStyle));
12143
+ break;
12144
+ case '<tableStyles/>': case '</tableStyles>': break;
12145
+ case '<tableStyle': case '<tableStyle>': case '<tableStyle/>':
12146
+ if(styles.TableStyles.styles.length >= TABLE_STYLE_MAX_TABLES) {
12147
+ tableStyle = null;
12148
+ break;
12149
+ }
12150
+ tableStyle = {
12151
+ name:utf8read(unescapexml(y.name || "")),
12152
+ pivot:y.pivot != null ? parsexmlbool(y.pivot) : false,
12153
+ table:y.table != null ? parsexmlbool(y.table) : true,
12154
+ elements:[]
12155
+ };
12156
+ styles.TableStyles.styles.push(tableStyle);
12157
+ if(tag.slice(-2) == "/>") tableStyle = null;
12158
+ break;
12159
+ case '</tableStyle>': tableStyle = null; break;
12160
+ case '<tableStyleElement': case '<tableStyleElement>': case '<tableStyleElement/>':
12161
+ if(tableStyle && tableStyle.elements.length < 64 && table_style_element_type(y.type) && y.dxfId != null) tableStyle.elements.push({
12162
+ type:y.type,
12163
+ dxfId:parseInt(y.dxfId, 10),
12164
+ size:y.size != null ? Math.max(1, parseInt(y.size, 10) || 1) : 1
12165
+ });
12166
+ break;
12167
+ case '<extLst': case '<extLst>': case '</extLst>': break;
12168
+ case '<ext': pass = true; break;
12169
+ case '</ext>': pass = false; break;
12170
+ default: if(opts && opts.WTF && !pass) throw new Error('unrecognized ' + y[0] + ' in tableStyles');
12171
+ }
12172
+ });
12173
+ }
12174
+
12130
12175
  function parse_colors(t, styles, themes, opts) {
12131
12176
  styles.Colors = {indexedColors:[], mruColors:[], themeColors:[]};
12132
12177
  var target = null, pass = false;
@@ -12205,6 +12250,7 @@ return function parse_sty_xml(data, themes, opts) {
12205
12250
  if((t=str_match_xml_ns(data, "dxfs"))) parse_dxfs(t[0], styles, themes, opts);
12206
12251
 
12207
12252
  /* 18.8.42 tableStyles CT_TableStyles ? */
12253
+ if((t=str_match_xml_ns(data, "tableStyles"))) parse_tableStyles(t[0], styles, opts);
12208
12254
  /* 18.8.11 colors CT_Colors ? */
12209
12255
  if((t=str_match_xml_ns(data, "colors"))) parse_colors(t[0], styles, themes, opts);
12210
12256
 
@@ -16730,7 +16776,11 @@ function validate_merges(ws, opts) {
16730
16776
  errors.push({code:"E_MERGE_OVERLAP", message:"Merge ranges overlap", index:i, other:j, range:enc, otherRange:encode_range(merges[j])});
16731
16777
  }
16732
16778
  }
16733
- if(errors.length && opts && opts.WTF) throw new Error(errors[0].message + " (" + (errors[0].range || errors[0].index) + ")");
16779
+ if(errors.length && opts && opts.WTF) {
16780
+ var err = new Error(errors[0].message + " (" + (errors[0].range || errors[0].index) + ")");
16781
+ err.code = errors[0].code;
16782
+ throw err;
16783
+ }
16734
16784
  return errors;
16735
16785
  }
16736
16786
 
@@ -16740,6 +16790,312 @@ function check_ws(ws, sname, i) {
16740
16790
  if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
16741
16791
  }
16742
16792
  }
16793
+ var TABLE_STYLE_MAX_TABLES = 1024;
16794
+ var TABLE_STYLE_MAX_COLUMNS = 16384;
16795
+ var TABLE_STYLE_MAX_XML_LENGTH = 5 * 1024 * 1024;
16796
+ var TABLE_STYLE_ELEMENT_TYPES = {
16797
+ wholeTable:true, headerRow:true, totalRow:true,
16798
+ firstColumn:true, lastColumn:true,
16799
+ firstRowStripe:true, secondRowStripe:true,
16800
+ firstColumnStripe:true, secondColumnStripe:true,
16801
+ firstHeaderCell:true, lastHeaderCell:true,
16802
+ firstTotalCell:true, lastTotalCell:true
16803
+ };
16804
+
16805
+ function table_style_safe_key(key) {
16806
+ return key != "__proto__" && key != "constructor" && key != "prototype";
16807
+ }
16808
+
16809
+ function table_style_element_type(type) {
16810
+ return Object.prototype.hasOwnProperty.call(TABLE_STYLE_ELEMENT_TYPES, type);
16811
+ }
16812
+
16813
+ function table_style_attr(y, name) {
16814
+ if(y[name] != null) return y[name];
16815
+ return y[name.toLowerCase()];
16816
+ }
16817
+
16818
+ function table_style_bool(y, name, fallback) {
16819
+ var value = table_style_attr(y, name);
16820
+ return value == null ? fallback : parsexmlbool(value);
16821
+ }
16822
+
16823
+ function table_style_int(y, name) {
16824
+ var value = table_style_attr(y, name);
16825
+ if(value == null || value === "") return void 0;
16826
+ value = parseInt(value, 10);
16827
+ return isFinite(value) && value >= 0 ? value : void 0;
16828
+ }
16829
+
16830
+ function table_style_merge(target, source) {
16831
+ if(!source) return target;
16832
+ if(!target) target = {};
16833
+ keys(source).forEach(function(k) {
16834
+ if(!table_style_safe_key(k)) return;
16835
+ var value = source[k];
16836
+ if(value && typeof value == "object" && !Array.isArray(value)) {
16837
+ target[k] = table_style_merge(
16838
+ target[k] && typeof target[k] == "object" && !Array.isArray(target[k]) ? table_style_merge({}, target[k]) : {},
16839
+ value
16840
+ );
16841
+ } else target[k] = value;
16842
+ });
16843
+ return target;
16844
+ }
16845
+
16846
+ function table_style_color(themes, theme, tint) {
16847
+ return style_color_from_attrs({theme:String(theme), tint:String(tint || 0)}, themes);
16848
+ }
16849
+
16850
+ function table_style_fill(color) {
16851
+ return {fill:{patternType:"solid", fgColor:color}};
16852
+ }
16853
+
16854
+ function table_style_font(color, bold) {
16855
+ var font = {};
16856
+ if(color) font.color = color;
16857
+ if(bold) font.bold = 1;
16858
+ return {font:font};
16859
+ }
16860
+
16861
+ function table_style_border(side, color, style) {
16862
+ var border = {}, out = {border:border};
16863
+ border[side] = {style:style || "thin", color:color};
16864
+ return out;
16865
+ }
16866
+
16867
+ function table_style_accent(themes, index) {
16868
+ var position = (index - 1) % 7;
16869
+ /* The first style in each seven-style family is neutral. The remaining
16870
+ * six entries use the workbook's accent1..accent6 colors. */
16871
+ return table_style_color(themes, position ? 3 + position : 1, 0);
16872
+ }
16873
+
16874
+ function built_in_table_style_rules(name, themes) {
16875
+ var match = /^TableStyle(Light|Medium|Dark)(\d+)$/i.exec(name || "");
16876
+ if(!match) return null;
16877
+ var family = match[1].toLowerCase(), index = parseInt(match[2], 10);
16878
+ var maximum = family == "light" ? 21 : family == "medium" ? 28 : 11;
16879
+ if(index < 1 || index > maximum) return null;
16880
+ var accent = table_style_accent(themes, index);
16881
+ var white = table_style_color(themes, 0, 0);
16882
+ var dark = table_style_color(themes, 1, 0);
16883
+ var rules = {};
16884
+
16885
+ if(family == "light") {
16886
+ rules.headerRow = table_style_merge(
16887
+ table_style_font(accent, true),
16888
+ table_style_border("bottom", accent, "medium")
16889
+ );
16890
+ rules.totalRow = table_style_merge(
16891
+ table_style_font(accent, true),
16892
+ table_style_border("top", accent, "double")
16893
+ );
16894
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.9));
16895
+ rules.firstColumnStripe = rules.firstRowStripe;
16896
+ } else if(family == "medium") {
16897
+ var group = Math.floor((index - 1) / 7);
16898
+ rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
16899
+ rules.totalRow = table_style_merge(
16900
+ table_style_font(accent, true),
16901
+ table_style_border("top", accent, "double")
16902
+ );
16903
+ if(group == 1) {
16904
+ /* Medium 8..14 use two theme-derived body fills. This is the family
16905
+ * used by Excel's TableStyleMedium13. */
16906
+ rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.8));
16907
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.6));
16908
+ rules.firstColumnStripe = rules.firstRowStripe;
16909
+ } else if(group == 2) {
16910
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
16911
+ rules.firstColumnStripe = rules.firstRowStripe;
16912
+ rules.wholeTable = table_style_border("bottom", table_style_color(themes, accent.theme, 0.4), "thin");
16913
+ } else if(group == 3) {
16914
+ rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.9));
16915
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.7));
16916
+ rules.firstColumnStripe = rules.firstRowStripe;
16917
+ } else {
16918
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
16919
+ rules.firstColumnStripe = rules.firstRowStripe;
16920
+ }
16921
+ } else {
16922
+ rules.wholeTable = table_style_merge(table_style_fill(dark), table_style_font(white, false));
16923
+ rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
16924
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, -0.35));
16925
+ rules.firstColumnStripe = rules.firstRowStripe;
16926
+ rules.totalRow = table_style_merge(
16927
+ table_style_font(white, true),
16928
+ table_style_border("top", accent, "double")
16929
+ );
16930
+ }
16931
+
16932
+ rules.firstColumn = table_style_font(null, true);
16933
+ rules.lastColumn = table_style_font(null, true);
16934
+ return rules;
16935
+ }
16936
+
16937
+ function custom_table_style_rules(name, styles) {
16938
+ var tableStyles = styles && styles.TableStyles;
16939
+ if(!tableStyles || !tableStyles.styles) return null;
16940
+ for(var i = 0; i < tableStyles.styles.length; ++i) {
16941
+ var tableStyle = tableStyles.styles[i];
16942
+ if(tableStyle.name != name) continue;
16943
+ var rules = Object.create(null);
16944
+ (tableStyle.elements || []).forEach(function(element) {
16945
+ if(!table_style_element_type(element.type)) return;
16946
+ var dxf = styles.Dxfs && styles.Dxfs[element.dxfId];
16947
+ if(dxf) rules[element.type] = {style:dup(dxf), size:element.size || 1};
16948
+ });
16949
+ return rules;
16950
+ }
16951
+ return null;
16952
+ }
16953
+
16954
+ function parse_table_xml(data, path, themes, styles, opts) {
16955
+ if(!data || data.length > TABLE_STYLE_MAX_XML_LENGTH) return null;
16956
+ data = remove_doctype(str_remove_ng(data, "<!--", "-->"));
16957
+ var table = {columns:[]}, column = null, pass = false;
16958
+ (data.match(tagregex)||[]).forEach(function(x) {
16959
+ var y = parsexmltag(x), tag = strip_ns(y[0]);
16960
+ switch(tag) {
16961
+ case '<table': case '<table>':
16962
+ table.id = table_style_int(y, "id");
16963
+ table.name = utf8read(unescapexml(table_style_attr(y, "name") || ""));
16964
+ table.displayName = utf8read(unescapexml(table_style_attr(y, "displayName") || table.name));
16965
+ table.ref = table_style_attr(y, "ref") || "";
16966
+ table.headerRowCount = table_style_int(y, "headerRowCount");
16967
+ table.totalsRowCount = table_style_int(y, "totalsRowCount");
16968
+ table.totalsRowShown = table_style_bool(y, "totalsRowShown", false);
16969
+ table.headerRowDxfId = table_style_int(y, "headerRowDxfId");
16970
+ table.dataDxfId = table_style_int(y, "dataDxfId");
16971
+ table.totalsRowDxfId = table_style_int(y, "totalsRowDxfId");
16972
+ table.path = path;
16973
+ break;
16974
+ case '<tableColumn': case '<tableColumn>': case '<tableColumn/>':
16975
+ if(table.columns.length >= TABLE_STYLE_MAX_COLUMNS) {
16976
+ column = null;
16977
+ break;
16978
+ }
16979
+ column = {
16980
+ id:table_style_int(y, "id"),
16981
+ name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
16982
+ headerRowDxfId:table_style_int(y, "headerRowDxfId"),
16983
+ dataDxfId:table_style_int(y, "dataDxfId"),
16984
+ totalsRowDxfId:table_style_int(y, "totalsRowDxfId")
16985
+ };
16986
+ table.columns.push(column);
16987
+ if(tag.slice(-2) == "/>" ) column = null;
16988
+ break;
16989
+ case '</tableColumn>': column = null; break;
16990
+ case '<tableStyleInfo': case '<tableStyleInfo>': case '<tableStyleInfo/>':
16991
+ table.styleInfo = {
16992
+ name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
16993
+ showFirstColumn:table_style_bool(y, "showFirstColumn", false),
16994
+ showLastColumn:table_style_bool(y, "showLastColumn", false),
16995
+ showRowStripes:table_style_bool(y, "showRowStripes", false),
16996
+ showColumnStripes:table_style_bool(y, "showColumnStripes", false)
16997
+ };
16998
+ break;
16999
+ case '<extLst': case '<extLst>': case '</extLst>': break;
17000
+ case '<ext': pass = true; break;
17001
+ case '</ext>': pass = false; break;
17002
+ default: if(opts && opts.WTF && !pass) {
17003
+ /* Table formulas and filter metadata are intentionally preserved by
17004
+ * the raw XML parser but do not affect visual style resolution. */
17005
+ if(/^<\/?(?:tableColumns|autoFilter|sortState|calculatedColumnFormula|totalsRowFormula|xmlColumnPr)/.test(tag)) break;
17006
+ }
17007
+ }
17008
+ });
17009
+ if(!table.ref) return null;
17010
+ try {
17011
+ table.range = safe_decode_range(table.ref);
17012
+ if(table.range.s.r < 0 || table.range.s.c < 0 || table.range.e.r > 1048575 || table.range.e.c > 16383) return null;
17013
+ } catch(e) { return null; }
17014
+ var styleName = table.styleInfo && table.styleInfo.name;
17015
+ table.styleRules = custom_table_style_rules(styleName, styles) || built_in_table_style_rules(styleName, themes) || {};
17016
+ table.dxfs = styles && styles.Dxfs ? styles.Dxfs : [];
17017
+ return table;
17018
+ }
17019
+
17020
+ function parse_sheet_tables(sheet, zip, path, rels, opts, themes, styles) {
17021
+ if(!sheet || !rels || !rels['!id'] || !opts || !opts.cellStyles) return;
17022
+ var tables = [], seen = Object.create(null);
17023
+ keys(rels['!id']).forEach(function(id) {
17024
+ if(tables.length >= TABLE_STYLE_MAX_TABLES) return;
17025
+ var rel = rels['!id'][id];
17026
+ if(!rel || rel.TargetMode == "External" || typeof rel.Target != "string" || !rel.Target ||
17027
+ (rel.Type != RELS.TABLE && !/\/table$/.test(rel.Type || ""))) return;
17028
+ var tablePath = resolve_path(rel.Target, path);
17029
+ if(seen[tablePath]) return;
17030
+ seen[tablePath] = true;
17031
+ var table = parse_table_xml(getzipstr(zip, tablePath, true), tablePath, themes, styles, opts);
17032
+ if(table) tables.push(table);
17033
+ });
17034
+ if(tables.length) sheet['!tables'] = tables;
17035
+ }
17036
+
17037
+ function table_style_rule_value(rule) {
17038
+ return rule && rule.style ? rule.style : rule;
17039
+ }
17040
+
17041
+ function table_style_stripe_rule(first, second, offset) {
17042
+ var firstSize = first && first.size || 1, secondSize = second && second.size || 1;
17043
+ var period = firstSize + secondSize;
17044
+ if(!period) return null;
17045
+ return offset % period < firstSize ? first : second;
17046
+ }
17047
+
17048
+ function table_style_dxf(table, id) {
17049
+ return id == null || !table.dxfs ? null : table.dxfs[id];
17050
+ }
17051
+
17052
+ function resolve_table_cell_style(ws, row, col, baseStyle) {
17053
+ var tables = ws && ws['!tables'];
17054
+ var resolved = baseStyle ? table_style_merge({}, baseStyle) : {};
17055
+ if(!tables || !tables.length) return keys(resolved).length ? resolved : void 0;
17056
+ for(var i = 0; i < tables.length; ++i) {
17057
+ var table = tables[i], range = table.range;
17058
+ if(!range || row < range.s.r || row > range.e.r || col < range.s.c || col > range.e.c) continue;
17059
+ var rules = table.styleRules || {}, info = table.styleInfo || {};
17060
+ var rowOffset = row - range.s.r, colOffset = col - range.s.c;
17061
+ var headerRows = table.headerRowCount == null ? 1 : table.headerRowCount;
17062
+ var totalRows = table.totalsRowCount != null ? table.totalsRowCount : table.totalsRowShown ? 1 : 0;
17063
+ var dataStart = headerRows, dataEnd = range.e.r - range.s.r - totalRows;
17064
+ var isHeader = rowOffset < headerRows;
17065
+ var isTotal = totalRows > 0 && rowOffset > dataEnd;
17066
+ var dataOffset = rowOffset - dataStart;
17067
+ var column = table.columns && table.columns[colOffset];
17068
+
17069
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.wholeTable));
17070
+ if(!isHeader && !isTotal && dataOffset >= 0) {
17071
+ if(info.showRowStripes) resolved = table_style_merge(resolved, table_style_rule_value(
17072
+ table_style_stripe_rule(rules.firstRowStripe, rules.secondRowStripe, dataOffset)
17073
+ ));
17074
+ if(info.showColumnStripes) resolved = table_style_merge(resolved, table_style_rule_value(
17075
+ table_style_stripe_rule(rules.firstColumnStripe, rules.secondColumnStripe, colOffset)
17076
+ ));
17077
+ }
17078
+ if(info.showFirstColumn && col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstColumn));
17079
+ if(info.showLastColumn && col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastColumn));
17080
+ if(isHeader) {
17081
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.headerRow));
17082
+ if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstHeaderCell));
17083
+ if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastHeaderCell));
17084
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.headerRowDxfId));
17085
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.headerRowDxfId));
17086
+ } else if(isTotal) {
17087
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.totalRow));
17088
+ if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstTotalCell));
17089
+ if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastTotalCell));
17090
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.totalsRowDxfId));
17091
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.totalsRowDxfId));
17092
+ } else {
17093
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.dataDxfId));
17094
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.dataDxfId));
17095
+ }
17096
+ }
17097
+ return keys(resolved).length ? resolved : void 0;
17098
+ }
16743
17099
  function parse_ws_xml_dim(ws, s) {
16744
17100
  var d = safe_decode_range(s);
16745
17101
  if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
@@ -16854,7 +17210,7 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
16854
17210
  if(columns.length > 0) s["!cols"] = columns;
16855
17211
  if(merges.length > 0) {
16856
17212
  s["!merges"] = merges;
16857
- var mergeErrors = validate_merges(s, {WTF: !!(opts && (opts.WTF || opts.validateMerges))});
17213
+ var mergeErrors = validate_merges(s, {WTF: !!(opts && opts.validateMerges)});
16858
17214
  if(mergeErrors.length) s["!mergeErrors"] = mergeErrors;
16859
17215
  }
16860
17216
  if(rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
@@ -16969,7 +17325,8 @@ function parse_ws_xml_cols(columns, cols) {
16969
17325
  var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
16970
17326
  if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
16971
17327
  delete coll.min; delete coll.max; coll.width = +coll.width;
16972
- /* OOXML widths share the workbook Normal-font MDW; do not infer a different scale per sheet. */
17328
+ /* OOXML widths share the workbook Normal-font MDW. Do not infer it from
17329
+ * one ambiguous stored width or leak another worksheet's scale. */
16973
17330
  if(!seencol && coll.width) { seencol = true; MDW = DEF_MDW; }
16974
17331
  process_col(coll);
16975
17332
  while(colm <= colM) columns[colm++] = dup(coll);
@@ -17392,7 +17749,7 @@ function write_ws_xml(idx, opts, wb, rels) {
17392
17749
  /* customSheetViews */
17393
17750
 
17394
17751
  if(ws['!merges'] != null && ws['!merges'].length > 0) {
17395
- validate_merges(ws, {WTF:true});
17752
+ validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
17396
17753
  o[o.length] = (write_ws_xml_merges(ws['!merges']));
17397
17754
  }
17398
17755
 
@@ -18878,7 +19235,6 @@ function check_wb(wb) {
18878
19235
  check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
18879
19236
  for(var i = 0; i < wb.SheetNames.length; ++i) {
18880
19237
  var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
18881
- if(!ws) throw new Error("Missing worksheet |" + wb.SheetNames[i] + "|");
18882
19238
  check_ws(ws, wb.SheetNames[i], i);
18883
19239
  }
18884
19240
  wb.SheetNames.forEach(function(n, i) {
@@ -21296,7 +21652,7 @@ function parse_workbook(blob, options) {
21296
21652
  };
21297
21653
  var finalize_sheet_visuals = function finalizesheetvisuals(ws) {
21298
21654
  if(ws["!merges"] && ws["!merges"].length) {
21299
- var mergeErrors = validate_merges(ws, {WTF: !!(options && (options.WTF || options.validateMerges))});
21655
+ var mergeErrors = validate_merges(ws, {WTF: !!(options && options.validateMerges)});
21300
21656
  if(mergeErrors.length) ws["!mergeErrors"] = mergeErrors;
21301
21657
  }
21302
21658
  if(drawings && (drawings.images.length || drawings.shapes.length || drawings.charts.length || drawings.raw.length)) ws["!drawings"] = drawings;
@@ -23851,7 +24207,7 @@ function write_ws_biff8(idx, opts, wb) {
23851
24207
  if(b8) write_biff_rec(ba, 0x023e /* Window2 */, write_Window2((_WB.Views||[])[0]));
23852
24208
  /* ... */
23853
24209
  if(b8 && (ws['!merges']||[]).length) {
23854
- validate_merges(ws, {WTF:true});
24210
+ validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
23855
24211
  write_biff_rec(ba, 0x00e5 /* MergeCells */, write_MergeCells(ws['!merges']));
23856
24212
  }
23857
24213
  /* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */
@@ -24240,6 +24596,7 @@ function make_html_row(ws, r, R, o) {
24240
24596
  if(cols[C] && cols[C].s) extend_style_obj(inherited, cols[C].s);
24241
24597
  if(row && row.s) extend_style_obj(inherited, row.s);
24242
24598
  if(cell && cell.s) extend_style_obj(inherited, cell.s);
24599
+ inherited = resolve_table_cell_style(ws, R, C, inherited) || inherited;
24243
24600
  if(keys(inherited).length) {
24244
24601
  stylecell = cell ? dup(cell) : {t:'z'};
24245
24602
  stylecell.s = inherited;
@@ -28366,6 +28723,7 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st
28366
28723
  case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
28367
28724
  default: throw new Error("Unrecognized sheet type " + stype);
28368
28725
  }
28726
+ if(stype == "sheet") parse_sheet_tables(_ws, zip, path, sheetRels[sheet], opts, themes, styles);
28369
28727
  sheet_map_set(sheets, sheet, _ws);
28370
28728
 
28371
28729
  /* scan rels for comments and threaded comments */
@@ -28386,7 +28744,9 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st
28386
28744
  if(tcomments && tcomments.length) sheet_insert_comments(_ws, tcomments, true, opts.people || []);
28387
28745
  if(stype == "sheet") parse_sheet_drawing(_ws, stype, zip, path, idx, opts, wb);
28388
28746
  parse_sheet_legacy_drawing(_ws, stype, zip, path, idx, opts, wb, comments);
28389
- } catch(e) { if(opts.WTF) throw e; }
28747
+ } catch(e) {
28748
+ if(opts.WTF || (opts.validateMerges && e && /^E_MERGE_/.test(e.code))) throw e;
28749
+ }
28390
28750
  }
28391
28751
 
28392
28752
  function strip_front_slash(x) { return x.charAt(0) == '/' ? x.slice(1) : x; }
@@ -29687,6 +30047,7 @@ var utils = {
29687
30047
  measure_text_width: measure_text_width,
29688
30048
  auto_fit_columns: auto_fit_columns,
29689
30049
  autofit_columns: auto_fit_columns,
30050
+ resolve_table_cell_style: resolve_table_cell_style,
29690
30051
  col_width_to_px: width2px,
29691
30052
  px_to_col_width: function(px) { return char2width(px2char(px)); },
29692
30053
  row_height_to_px: pt2px_browser,