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.
package/xlsx.js CHANGED
@@ -4,7 +4,7 @@
4
4
  /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false, Int8Array:false */
5
5
  var XLSX = {};
6
6
  function make_xlsx_lib(XLSX){
7
- XLSX.version = '0.21.3';
7
+ XLSX.version = '0.21.4';
8
8
  var current_codepage = 1200, current_ansi = 1252;
9
9
  /*global cptable:true, window */
10
10
  var $cptable;
@@ -3872,7 +3872,7 @@ function escapexmltag(text){ return escapexml(text).replace(/ /g,"_x0020_"); }
3872
3872
  var htmlcharegex = /[\u0000-\u001f]/g;
3873
3873
  function escapehtml(text){
3874
3874
  var s = text + '';
3875
- 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) + ";"; });
3875
+ 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) + ";"; });
3876
3876
  }
3877
3877
 
3878
3878
  function escapexlml(text){
@@ -5675,6 +5675,7 @@ var RELS = ({
5675
5675
  MS: "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet",
5676
5676
  IMG: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
5677
5677
  DRAW: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
5678
+ TABLE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
5678
5679
  XLMETA: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
5679
5680
  TCMNT: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",
5680
5681
  PEOPLE: "http://schemas.microsoft.com/office/2017/10/relationships/person",
@@ -11138,6 +11139,9 @@ function resolve_style_obj_color(obj, themes) {
11138
11139
 
11139
11140
  /* 18.3.1.13 width calculations */
11140
11141
  /* [MS-OI29500] 2.1.595 Column Width & Formatting */
11142
+ /* The file format does not store MDW directly. Seven is the Office-compatible
11143
+ * fallback when Normal-font metrics are unavailable. A single stored column
11144
+ * width is ambiguous and must not change the scale for the rest of a sheet. */
11141
11145
  var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
11142
11146
  function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
11143
11147
  function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
@@ -11971,6 +11975,47 @@ function parse_dxfs(t, styles, themes, opts) {
11971
11975
  });
11972
11976
  }
11973
11977
 
11978
+ function parse_tableStyles(t, styles, opts) {
11979
+ styles.TableStyles = {styles:[]};
11980
+ var tableStyle = null, pass = false;
11981
+ (t.match(tagregex)||[]).forEach(function(x) {
11982
+ var y = parsexmltag(x), tag = strip_ns(y[0]);
11983
+ switch(tag) {
11984
+ case '<tableStyles': case '<tableStyles>':
11985
+ if(y.defaultTableStyle) styles.TableStyles.defaultTableStyle = utf8read(unescapexml(y.defaultTableStyle));
11986
+ if(y.defaultPivotStyle) styles.TableStyles.defaultPivotStyle = utf8read(unescapexml(y.defaultPivotStyle));
11987
+ break;
11988
+ case '<tableStyles/>': case '</tableStyles>': break;
11989
+ case '<tableStyle': case '<tableStyle>': case '<tableStyle/>':
11990
+ if(styles.TableStyles.styles.length >= TABLE_STYLE_MAX_TABLES) {
11991
+ tableStyle = null;
11992
+ break;
11993
+ }
11994
+ tableStyle = {
11995
+ name:utf8read(unescapexml(y.name || "")),
11996
+ pivot:y.pivot != null ? parsexmlbool(y.pivot) : false,
11997
+ table:y.table != null ? parsexmlbool(y.table) : true,
11998
+ elements:[]
11999
+ };
12000
+ styles.TableStyles.styles.push(tableStyle);
12001
+ if(tag.slice(-2) == "/>") tableStyle = null;
12002
+ break;
12003
+ case '</tableStyle>': tableStyle = null; break;
12004
+ case '<tableStyleElement': case '<tableStyleElement>': case '<tableStyleElement/>':
12005
+ if(tableStyle && tableStyle.elements.length < 64 && table_style_element_type(y.type) && y.dxfId != null) tableStyle.elements.push({
12006
+ type:y.type,
12007
+ dxfId:parseInt(y.dxfId, 10),
12008
+ size:y.size != null ? Math.max(1, parseInt(y.size, 10) || 1) : 1
12009
+ });
12010
+ break;
12011
+ case '<extLst': case '<extLst>': case '</extLst>': break;
12012
+ case '<ext': pass = true; break;
12013
+ case '</ext>': pass = false; break;
12014
+ default: if(opts && opts.WTF && !pass) throw new Error('unrecognized ' + y[0] + ' in tableStyles');
12015
+ }
12016
+ });
12017
+ }
12018
+
11974
12019
  function parse_colors(t, styles, themes, opts) {
11975
12020
  styles.Colors = {indexedColors:[], mruColors:[], themeColors:[]};
11976
12021
  var target = null, pass = false;
@@ -12049,6 +12094,7 @@ return function parse_sty_xml(data, themes, opts) {
12049
12094
  if((t=str_match_xml_ns(data, "dxfs"))) parse_dxfs(t[0], styles, themes, opts);
12050
12095
 
12051
12096
  /* 18.8.42 tableStyles CT_TableStyles ? */
12097
+ if((t=str_match_xml_ns(data, "tableStyles"))) parse_tableStyles(t[0], styles, opts);
12052
12098
  /* 18.8.11 colors CT_Colors ? */
12053
12099
  if((t=str_match_xml_ns(data, "colors"))) parse_colors(t[0], styles, themes, opts);
12054
12100
 
@@ -16574,7 +16620,11 @@ function validate_merges(ws, opts) {
16574
16620
  errors.push({code:"E_MERGE_OVERLAP", message:"Merge ranges overlap", index:i, other:j, range:enc, otherRange:encode_range(merges[j])});
16575
16621
  }
16576
16622
  }
16577
- if(errors.length && opts && opts.WTF) throw new Error(errors[0].message + " (" + (errors[0].range || errors[0].index) + ")");
16623
+ if(errors.length && opts && opts.WTF) {
16624
+ var err = new Error(errors[0].message + " (" + (errors[0].range || errors[0].index) + ")");
16625
+ err.code = errors[0].code;
16626
+ throw err;
16627
+ }
16578
16628
  return errors;
16579
16629
  }
16580
16630
 
@@ -16584,6 +16634,312 @@ function check_ws(ws, sname, i) {
16584
16634
  if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
16585
16635
  }
16586
16636
  }
16637
+ var TABLE_STYLE_MAX_TABLES = 1024;
16638
+ var TABLE_STYLE_MAX_COLUMNS = 16384;
16639
+ var TABLE_STYLE_MAX_XML_LENGTH = 5 * 1024 * 1024;
16640
+ var TABLE_STYLE_ELEMENT_TYPES = {
16641
+ wholeTable:true, headerRow:true, totalRow:true,
16642
+ firstColumn:true, lastColumn:true,
16643
+ firstRowStripe:true, secondRowStripe:true,
16644
+ firstColumnStripe:true, secondColumnStripe:true,
16645
+ firstHeaderCell:true, lastHeaderCell:true,
16646
+ firstTotalCell:true, lastTotalCell:true
16647
+ };
16648
+
16649
+ function table_style_safe_key(key) {
16650
+ return key != "__proto__" && key != "constructor" && key != "prototype";
16651
+ }
16652
+
16653
+ function table_style_element_type(type) {
16654
+ return Object.prototype.hasOwnProperty.call(TABLE_STYLE_ELEMENT_TYPES, type);
16655
+ }
16656
+
16657
+ function table_style_attr(y, name) {
16658
+ if(y[name] != null) return y[name];
16659
+ return y[name.toLowerCase()];
16660
+ }
16661
+
16662
+ function table_style_bool(y, name, fallback) {
16663
+ var value = table_style_attr(y, name);
16664
+ return value == null ? fallback : parsexmlbool(value);
16665
+ }
16666
+
16667
+ function table_style_int(y, name) {
16668
+ var value = table_style_attr(y, name);
16669
+ if(value == null || value === "") return void 0;
16670
+ value = parseInt(value, 10);
16671
+ return isFinite(value) && value >= 0 ? value : void 0;
16672
+ }
16673
+
16674
+ function table_style_merge(target, source) {
16675
+ if(!source) return target;
16676
+ if(!target) target = {};
16677
+ keys(source).forEach(function(k) {
16678
+ if(!table_style_safe_key(k)) return;
16679
+ var value = source[k];
16680
+ if(value && typeof value == "object" && !Array.isArray(value)) {
16681
+ target[k] = table_style_merge(
16682
+ target[k] && typeof target[k] == "object" && !Array.isArray(target[k]) ? table_style_merge({}, target[k]) : {},
16683
+ value
16684
+ );
16685
+ } else target[k] = value;
16686
+ });
16687
+ return target;
16688
+ }
16689
+
16690
+ function table_style_color(themes, theme, tint) {
16691
+ return style_color_from_attrs({theme:String(theme), tint:String(tint || 0)}, themes);
16692
+ }
16693
+
16694
+ function table_style_fill(color) {
16695
+ return {fill:{patternType:"solid", fgColor:color}};
16696
+ }
16697
+
16698
+ function table_style_font(color, bold) {
16699
+ var font = {};
16700
+ if(color) font.color = color;
16701
+ if(bold) font.bold = 1;
16702
+ return {font:font};
16703
+ }
16704
+
16705
+ function table_style_border(side, color, style) {
16706
+ var border = {}, out = {border:border};
16707
+ border[side] = {style:style || "thin", color:color};
16708
+ return out;
16709
+ }
16710
+
16711
+ function table_style_accent(themes, index) {
16712
+ var position = (index - 1) % 7;
16713
+ /* The first style in each seven-style family is neutral. The remaining
16714
+ * six entries use the workbook's accent1..accent6 colors. */
16715
+ return table_style_color(themes, position ? 3 + position : 1, 0);
16716
+ }
16717
+
16718
+ function built_in_table_style_rules(name, themes) {
16719
+ var match = /^TableStyle(Light|Medium|Dark)(\d+)$/i.exec(name || "");
16720
+ if(!match) return null;
16721
+ var family = match[1].toLowerCase(), index = parseInt(match[2], 10);
16722
+ var maximum = family == "light" ? 21 : family == "medium" ? 28 : 11;
16723
+ if(index < 1 || index > maximum) return null;
16724
+ var accent = table_style_accent(themes, index);
16725
+ var white = table_style_color(themes, 0, 0);
16726
+ var dark = table_style_color(themes, 1, 0);
16727
+ var rules = {};
16728
+
16729
+ if(family == "light") {
16730
+ rules.headerRow = table_style_merge(
16731
+ table_style_font(accent, true),
16732
+ table_style_border("bottom", accent, "medium")
16733
+ );
16734
+ rules.totalRow = table_style_merge(
16735
+ table_style_font(accent, true),
16736
+ table_style_border("top", accent, "double")
16737
+ );
16738
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.9));
16739
+ rules.firstColumnStripe = rules.firstRowStripe;
16740
+ } else if(family == "medium") {
16741
+ var group = Math.floor((index - 1) / 7);
16742
+ rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
16743
+ rules.totalRow = table_style_merge(
16744
+ table_style_font(accent, true),
16745
+ table_style_border("top", accent, "double")
16746
+ );
16747
+ if(group == 1) {
16748
+ /* Medium 8..14 use two theme-derived body fills. This is the family
16749
+ * used by Excel's TableStyleMedium13. */
16750
+ rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.8));
16751
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.6));
16752
+ rules.firstColumnStripe = rules.firstRowStripe;
16753
+ } else if(group == 2) {
16754
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
16755
+ rules.firstColumnStripe = rules.firstRowStripe;
16756
+ rules.wholeTable = table_style_border("bottom", table_style_color(themes, accent.theme, 0.4), "thin");
16757
+ } else if(group == 3) {
16758
+ rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.9));
16759
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.7));
16760
+ rules.firstColumnStripe = rules.firstRowStripe;
16761
+ } else {
16762
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
16763
+ rules.firstColumnStripe = rules.firstRowStripe;
16764
+ }
16765
+ } else {
16766
+ rules.wholeTable = table_style_merge(table_style_fill(dark), table_style_font(white, false));
16767
+ rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
16768
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, -0.35));
16769
+ rules.firstColumnStripe = rules.firstRowStripe;
16770
+ rules.totalRow = table_style_merge(
16771
+ table_style_font(white, true),
16772
+ table_style_border("top", accent, "double")
16773
+ );
16774
+ }
16775
+
16776
+ rules.firstColumn = table_style_font(null, true);
16777
+ rules.lastColumn = table_style_font(null, true);
16778
+ return rules;
16779
+ }
16780
+
16781
+ function custom_table_style_rules(name, styles) {
16782
+ var tableStyles = styles && styles.TableStyles;
16783
+ if(!tableStyles || !tableStyles.styles) return null;
16784
+ for(var i = 0; i < tableStyles.styles.length; ++i) {
16785
+ var tableStyle = tableStyles.styles[i];
16786
+ if(tableStyle.name != name) continue;
16787
+ var rules = Object.create(null);
16788
+ (tableStyle.elements || []).forEach(function(element) {
16789
+ if(!table_style_element_type(element.type)) return;
16790
+ var dxf = styles.Dxfs && styles.Dxfs[element.dxfId];
16791
+ if(dxf) rules[element.type] = {style:dup(dxf), size:element.size || 1};
16792
+ });
16793
+ return rules;
16794
+ }
16795
+ return null;
16796
+ }
16797
+
16798
+ function parse_table_xml(data, path, themes, styles, opts) {
16799
+ if(!data || data.length > TABLE_STYLE_MAX_XML_LENGTH) return null;
16800
+ data = remove_doctype(str_remove_ng(data, "<!--", "-->"));
16801
+ var table = {columns:[]}, column = null, pass = false;
16802
+ (data.match(tagregex)||[]).forEach(function(x) {
16803
+ var y = parsexmltag(x), tag = strip_ns(y[0]);
16804
+ switch(tag) {
16805
+ case '<table': case '<table>':
16806
+ table.id = table_style_int(y, "id");
16807
+ table.name = utf8read(unescapexml(table_style_attr(y, "name") || ""));
16808
+ table.displayName = utf8read(unescapexml(table_style_attr(y, "displayName") || table.name));
16809
+ table.ref = table_style_attr(y, "ref") || "";
16810
+ table.headerRowCount = table_style_int(y, "headerRowCount");
16811
+ table.totalsRowCount = table_style_int(y, "totalsRowCount");
16812
+ table.totalsRowShown = table_style_bool(y, "totalsRowShown", false);
16813
+ table.headerRowDxfId = table_style_int(y, "headerRowDxfId");
16814
+ table.dataDxfId = table_style_int(y, "dataDxfId");
16815
+ table.totalsRowDxfId = table_style_int(y, "totalsRowDxfId");
16816
+ table.path = path;
16817
+ break;
16818
+ case '<tableColumn': case '<tableColumn>': case '<tableColumn/>':
16819
+ if(table.columns.length >= TABLE_STYLE_MAX_COLUMNS) {
16820
+ column = null;
16821
+ break;
16822
+ }
16823
+ column = {
16824
+ id:table_style_int(y, "id"),
16825
+ name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
16826
+ headerRowDxfId:table_style_int(y, "headerRowDxfId"),
16827
+ dataDxfId:table_style_int(y, "dataDxfId"),
16828
+ totalsRowDxfId:table_style_int(y, "totalsRowDxfId")
16829
+ };
16830
+ table.columns.push(column);
16831
+ if(tag.slice(-2) == "/>" ) column = null;
16832
+ break;
16833
+ case '</tableColumn>': column = null; break;
16834
+ case '<tableStyleInfo': case '<tableStyleInfo>': case '<tableStyleInfo/>':
16835
+ table.styleInfo = {
16836
+ name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
16837
+ showFirstColumn:table_style_bool(y, "showFirstColumn", false),
16838
+ showLastColumn:table_style_bool(y, "showLastColumn", false),
16839
+ showRowStripes:table_style_bool(y, "showRowStripes", false),
16840
+ showColumnStripes:table_style_bool(y, "showColumnStripes", false)
16841
+ };
16842
+ break;
16843
+ case '<extLst': case '<extLst>': case '</extLst>': break;
16844
+ case '<ext': pass = true; break;
16845
+ case '</ext>': pass = false; break;
16846
+ default: if(opts && opts.WTF && !pass) {
16847
+ /* Table formulas and filter metadata are intentionally preserved by
16848
+ * the raw XML parser but do not affect visual style resolution. */
16849
+ if(/^<\/?(?:tableColumns|autoFilter|sortState|calculatedColumnFormula|totalsRowFormula|xmlColumnPr)/.test(tag)) break;
16850
+ }
16851
+ }
16852
+ });
16853
+ if(!table.ref) return null;
16854
+ try {
16855
+ table.range = safe_decode_range(table.ref);
16856
+ if(table.range.s.r < 0 || table.range.s.c < 0 || table.range.e.r > 1048575 || table.range.e.c > 16383) return null;
16857
+ } catch(e) { return null; }
16858
+ var styleName = table.styleInfo && table.styleInfo.name;
16859
+ table.styleRules = custom_table_style_rules(styleName, styles) || built_in_table_style_rules(styleName, themes) || {};
16860
+ table.dxfs = styles && styles.Dxfs ? styles.Dxfs : [];
16861
+ return table;
16862
+ }
16863
+
16864
+ function parse_sheet_tables(sheet, zip, path, rels, opts, themes, styles) {
16865
+ if(!sheet || !rels || !rels['!id'] || !opts || !opts.cellStyles) return;
16866
+ var tables = [], seen = Object.create(null);
16867
+ keys(rels['!id']).forEach(function(id) {
16868
+ if(tables.length >= TABLE_STYLE_MAX_TABLES) return;
16869
+ var rel = rels['!id'][id];
16870
+ if(!rel || rel.TargetMode == "External" || typeof rel.Target != "string" || !rel.Target ||
16871
+ (rel.Type != RELS.TABLE && !/\/table$/.test(rel.Type || ""))) return;
16872
+ var tablePath = resolve_path(rel.Target, path);
16873
+ if(seen[tablePath]) return;
16874
+ seen[tablePath] = true;
16875
+ var table = parse_table_xml(getzipstr(zip, tablePath, true), tablePath, themes, styles, opts);
16876
+ if(table) tables.push(table);
16877
+ });
16878
+ if(tables.length) sheet['!tables'] = tables;
16879
+ }
16880
+
16881
+ function table_style_rule_value(rule) {
16882
+ return rule && rule.style ? rule.style : rule;
16883
+ }
16884
+
16885
+ function table_style_stripe_rule(first, second, offset) {
16886
+ var firstSize = first && first.size || 1, secondSize = second && second.size || 1;
16887
+ var period = firstSize + secondSize;
16888
+ if(!period) return null;
16889
+ return offset % period < firstSize ? first : second;
16890
+ }
16891
+
16892
+ function table_style_dxf(table, id) {
16893
+ return id == null || !table.dxfs ? null : table.dxfs[id];
16894
+ }
16895
+
16896
+ function resolve_table_cell_style(ws, row, col, baseStyle) {
16897
+ var tables = ws && ws['!tables'];
16898
+ var resolved = baseStyle ? table_style_merge({}, baseStyle) : {};
16899
+ if(!tables || !tables.length) return keys(resolved).length ? resolved : void 0;
16900
+ for(var i = 0; i < tables.length; ++i) {
16901
+ var table = tables[i], range = table.range;
16902
+ if(!range || row < range.s.r || row > range.e.r || col < range.s.c || col > range.e.c) continue;
16903
+ var rules = table.styleRules || {}, info = table.styleInfo || {};
16904
+ var rowOffset = row - range.s.r, colOffset = col - range.s.c;
16905
+ var headerRows = table.headerRowCount == null ? 1 : table.headerRowCount;
16906
+ var totalRows = table.totalsRowCount != null ? table.totalsRowCount : table.totalsRowShown ? 1 : 0;
16907
+ var dataStart = headerRows, dataEnd = range.e.r - range.s.r - totalRows;
16908
+ var isHeader = rowOffset < headerRows;
16909
+ var isTotal = totalRows > 0 && rowOffset > dataEnd;
16910
+ var dataOffset = rowOffset - dataStart;
16911
+ var column = table.columns && table.columns[colOffset];
16912
+
16913
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.wholeTable));
16914
+ if(!isHeader && !isTotal && dataOffset >= 0) {
16915
+ if(info.showRowStripes) resolved = table_style_merge(resolved, table_style_rule_value(
16916
+ table_style_stripe_rule(rules.firstRowStripe, rules.secondRowStripe, dataOffset)
16917
+ ));
16918
+ if(info.showColumnStripes) resolved = table_style_merge(resolved, table_style_rule_value(
16919
+ table_style_stripe_rule(rules.firstColumnStripe, rules.secondColumnStripe, colOffset)
16920
+ ));
16921
+ }
16922
+ if(info.showFirstColumn && col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstColumn));
16923
+ if(info.showLastColumn && col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastColumn));
16924
+ if(isHeader) {
16925
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.headerRow));
16926
+ if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstHeaderCell));
16927
+ if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastHeaderCell));
16928
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.headerRowDxfId));
16929
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.headerRowDxfId));
16930
+ } else if(isTotal) {
16931
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.totalRow));
16932
+ if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstTotalCell));
16933
+ if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastTotalCell));
16934
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.totalsRowDxfId));
16935
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.totalsRowDxfId));
16936
+ } else {
16937
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.dataDxfId));
16938
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.dataDxfId));
16939
+ }
16940
+ }
16941
+ return keys(resolved).length ? resolved : void 0;
16942
+ }
16587
16943
  function parse_ws_xml_dim(ws, s) {
16588
16944
  var d = safe_decode_range(s);
16589
16945
  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);
@@ -16698,7 +17054,7 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
16698
17054
  if(columns.length > 0) s["!cols"] = columns;
16699
17055
  if(merges.length > 0) {
16700
17056
  s["!merges"] = merges;
16701
- var mergeErrors = validate_merges(s, {WTF: !!(opts && (opts.WTF || opts.validateMerges))});
17057
+ var mergeErrors = validate_merges(s, {WTF: !!(opts && opts.validateMerges)});
16702
17058
  if(mergeErrors.length) s["!mergeErrors"] = mergeErrors;
16703
17059
  }
16704
17060
  if(rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
@@ -16813,7 +17169,8 @@ function parse_ws_xml_cols(columns, cols) {
16813
17169
  var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
16814
17170
  if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
16815
17171
  delete coll.min; delete coll.max; coll.width = +coll.width;
16816
- /* OOXML widths share the workbook Normal-font MDW; do not infer a different scale per sheet. */
17172
+ /* OOXML widths share the workbook Normal-font MDW. Do not infer it from
17173
+ * one ambiguous stored width or leak another worksheet's scale. */
16817
17174
  if(!seencol && coll.width) { seencol = true; MDW = DEF_MDW; }
16818
17175
  process_col(coll);
16819
17176
  while(colm <= colM) columns[colm++] = dup(coll);
@@ -17236,7 +17593,7 @@ function write_ws_xml(idx, opts, wb, rels) {
17236
17593
  /* customSheetViews */
17237
17594
 
17238
17595
  if(ws['!merges'] != null && ws['!merges'].length > 0) {
17239
- validate_merges(ws, {WTF:true});
17596
+ validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
17240
17597
  o[o.length] = (write_ws_xml_merges(ws['!merges']));
17241
17598
  }
17242
17599
 
@@ -18722,7 +19079,6 @@ function check_wb(wb) {
18722
19079
  check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
18723
19080
  for(var i = 0; i < wb.SheetNames.length; ++i) {
18724
19081
  var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
18725
- if(!ws) throw new Error("Missing worksheet |" + wb.SheetNames[i] + "|");
18726
19082
  check_ws(ws, wb.SheetNames[i], i);
18727
19083
  }
18728
19084
  wb.SheetNames.forEach(function(n, i) {
@@ -21140,7 +21496,7 @@ function parse_workbook(blob, options) {
21140
21496
  };
21141
21497
  var finalize_sheet_visuals = function finalizesheetvisuals(ws) {
21142
21498
  if(ws["!merges"] && ws["!merges"].length) {
21143
- var mergeErrors = validate_merges(ws, {WTF: !!(options && (options.WTF || options.validateMerges))});
21499
+ var mergeErrors = validate_merges(ws, {WTF: !!(options && options.validateMerges)});
21144
21500
  if(mergeErrors.length) ws["!mergeErrors"] = mergeErrors;
21145
21501
  }
21146
21502
  if(drawings && (drawings.images.length || drawings.shapes.length || drawings.charts.length || drawings.raw.length)) ws["!drawings"] = drawings;
@@ -23695,7 +24051,7 @@ function write_ws_biff8(idx, opts, wb) {
23695
24051
  if(b8) write_biff_rec(ba, 0x023e /* Window2 */, write_Window2((_WB.Views||[])[0]));
23696
24052
  /* ... */
23697
24053
  if(b8 && (ws['!merges']||[]).length) {
23698
- validate_merges(ws, {WTF:true});
24054
+ validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
23699
24055
  write_biff_rec(ba, 0x00e5 /* MergeCells */, write_MergeCells(ws['!merges']));
23700
24056
  }
23701
24057
  /* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */
@@ -24084,6 +24440,7 @@ function make_html_row(ws, r, R, o) {
24084
24440
  if(cols[C] && cols[C].s) extend_style_obj(inherited, cols[C].s);
24085
24441
  if(row && row.s) extend_style_obj(inherited, row.s);
24086
24442
  if(cell && cell.s) extend_style_obj(inherited, cell.s);
24443
+ inherited = resolve_table_cell_style(ws, R, C, inherited) || inherited;
24087
24444
  if(keys(inherited).length) {
24088
24445
  stylecell = cell ? dup(cell) : {t:'z'};
24089
24446
  stylecell.s = inherited;
@@ -28210,6 +28567,7 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st
28210
28567
  case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
28211
28568
  default: throw new Error("Unrecognized sheet type " + stype);
28212
28569
  }
28570
+ if(stype == "sheet") parse_sheet_tables(_ws, zip, path, sheetRels[sheet], opts, themes, styles);
28213
28571
  sheet_map_set(sheets, sheet, _ws);
28214
28572
 
28215
28573
  /* scan rels for comments and threaded comments */
@@ -28230,7 +28588,9 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st
28230
28588
  if(tcomments && tcomments.length) sheet_insert_comments(_ws, tcomments, true, opts.people || []);
28231
28589
  if(stype == "sheet") parse_sheet_drawing(_ws, stype, zip, path, idx, opts, wb);
28232
28590
  parse_sheet_legacy_drawing(_ws, stype, zip, path, idx, opts, wb, comments);
28233
- } catch(e) { if(opts.WTF) throw e; }
28591
+ } catch(e) {
28592
+ if(opts.WTF || (opts.validateMerges && e && /^E_MERGE_/.test(e.code))) throw e;
28593
+ }
28234
28594
  }
28235
28595
 
28236
28596
  function strip_front_slash(x) { return x.charAt(0) == '/' ? x.slice(1) : x; }
@@ -29531,6 +29891,7 @@ var utils = {
29531
29891
  measure_text_width: measure_text_width,
29532
29892
  auto_fit_columns: auto_fit_columns,
29533
29893
  autofit_columns: auto_fit_columns,
29894
+ resolve_table_cell_style: resolve_table_cell_style,
29534
29895
  col_width_to_px: width2px,
29535
29896
  px_to_col_width: function(px) { return char2width(px2char(px)); },
29536
29897
  row_height_to_px: pt2px_browser,