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.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  /*exported XLSX */
4
4
  /*global process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
5
5
  var XLSX = {};
6
- XLSX.version = '0.21.3';
6
+ XLSX.version = '0.21.4';
7
7
  var current_codepage = 1200, current_ansi = 1252;
8
8
  /*:: declare var cptable:any; */
9
9
  /*global cptable:true, window */
@@ -3945,7 +3945,7 @@ function escapexmltag(text/*:string*/)/*:string*/{ return escapexml(text).replac
3945
3945
  var htmlcharegex = /[\u0000-\u001f]/g;
3946
3946
  function escapehtml(text/*:string*/)/*:string*/{
3947
3947
  var s = text + '';
3948
- 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) + ";"; });
3948
+ 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) + ";"; });
3949
3949
  }
3950
3950
 
3951
3951
  function escapexlml(text/*:string*/)/*:string*/{
@@ -5755,6 +5755,7 @@ var RELS = ({
5755
5755
  MS: "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet",
5756
5756
  IMG: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
5757
5757
  DRAW: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
5758
+ TABLE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
5758
5759
  XLMETA: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
5759
5760
  TCMNT: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",
5760
5761
  PEOPLE: "http://schemas.microsoft.com/office/2017/10/relationships/person",
@@ -11224,6 +11225,9 @@ function resolve_style_obj_color(obj, themes) {
11224
11225
 
11225
11226
  /* 18.3.1.13 width calculations */
11226
11227
  /* [MS-OI29500] 2.1.595 Column Width & Formatting */
11228
+ /* The file format does not store MDW directly. Seven is the Office-compatible
11229
+ * fallback when Normal-font metrics are unavailable. A single stored column
11230
+ * width is ambiguous and must not change the scale for the rest of a sheet. */
11227
11231
  var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
11228
11232
  function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
11229
11233
  function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
@@ -12057,6 +12061,47 @@ function parse_dxfs(t, styles, themes, opts) {
12057
12061
  });
12058
12062
  }
12059
12063
 
12064
+ function parse_tableStyles(t, styles, opts) {
12065
+ styles.TableStyles = {styles:[]};
12066
+ var tableStyle = null, pass = false;
12067
+ (t.match(tagregex)||[]).forEach(function(x) {
12068
+ var y = parsexmltag(x), tag = strip_ns(y[0]);
12069
+ switch(tag) {
12070
+ case '<tableStyles': case '<tableStyles>':
12071
+ if(y.defaultTableStyle) styles.TableStyles.defaultTableStyle = utf8read(unescapexml(y.defaultTableStyle));
12072
+ if(y.defaultPivotStyle) styles.TableStyles.defaultPivotStyle = utf8read(unescapexml(y.defaultPivotStyle));
12073
+ break;
12074
+ case '<tableStyles/>': case '</tableStyles>': break;
12075
+ case '<tableStyle': case '<tableStyle>': case '<tableStyle/>':
12076
+ if(styles.TableStyles.styles.length >= TABLE_STYLE_MAX_TABLES) {
12077
+ tableStyle = null;
12078
+ break;
12079
+ }
12080
+ tableStyle = {
12081
+ name:utf8read(unescapexml(y.name || "")),
12082
+ pivot:y.pivot != null ? parsexmlbool(y.pivot) : false,
12083
+ table:y.table != null ? parsexmlbool(y.table) : true,
12084
+ elements:[]
12085
+ };
12086
+ styles.TableStyles.styles.push(tableStyle);
12087
+ if(tag.slice(-2) == "/>") tableStyle = null;
12088
+ break;
12089
+ case '</tableStyle>': tableStyle = null; break;
12090
+ case '<tableStyleElement': case '<tableStyleElement>': case '<tableStyleElement/>':
12091
+ if(tableStyle && tableStyle.elements.length < 64 && table_style_element_type(y.type) && y.dxfId != null) tableStyle.elements.push({
12092
+ type:y.type,
12093
+ dxfId:parseInt(y.dxfId, 10),
12094
+ size:y.size != null ? Math.max(1, parseInt(y.size, 10) || 1) : 1
12095
+ });
12096
+ break;
12097
+ case '<extLst': case '<extLst>': case '</extLst>': break;
12098
+ case '<ext': pass = true; break;
12099
+ case '</ext>': pass = false; break;
12100
+ default: if(opts && opts.WTF && !pass) throw new Error('unrecognized ' + y[0] + ' in tableStyles');
12101
+ }
12102
+ });
12103
+ }
12104
+
12060
12105
  function parse_colors(t, styles, themes, opts) {
12061
12106
  styles.Colors = {indexedColors:[], mruColors:[], themeColors:[]};
12062
12107
  var target = null, pass = false;
@@ -12135,6 +12180,7 @@ return function parse_sty_xml(data, themes, opts) {
12135
12180
  if((t=str_match_xml_ns(data, "dxfs"))) parse_dxfs(t[0], styles, themes, opts);
12136
12181
 
12137
12182
  /* 18.8.42 tableStyles CT_TableStyles ? */
12183
+ if((t=str_match_xml_ns(data, "tableStyles"))) parse_tableStyles(t[0], styles, opts);
12138
12184
  /* 18.8.11 colors CT_Colors ? */
12139
12185
  if((t=str_match_xml_ns(data, "colors"))) parse_colors(t[0], styles, themes, opts);
12140
12186
 
@@ -16663,7 +16709,11 @@ function validate_merges(ws/*:Worksheet*/, opts/*:?any*/) {
16663
16709
  errors.push({code:"E_MERGE_OVERLAP", message:"Merge ranges overlap", index:i, other:j, range:enc, otherRange:encode_range(merges[j])});
16664
16710
  }
16665
16711
  }
16666
- if(errors.length && opts && opts.WTF) throw new Error(errors[0].message + " (" + (errors[0].range || errors[0].index) + ")");
16712
+ if(errors.length && opts && opts.WTF) {
16713
+ var err/*:any*/ = new Error(errors[0].message + " (" + (errors[0].range || errors[0].index) + ")");
16714
+ err.code = errors[0].code;
16715
+ throw err;
16716
+ }
16667
16717
  return errors;
16668
16718
  }
16669
16719
 
@@ -16787,7 +16837,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
16787
16837
  if(columns.length > 0) s["!cols"] = columns;
16788
16838
  if(merges.length > 0) {
16789
16839
  s["!merges"] = merges;
16790
- var mergeErrors = validate_merges(s, {WTF: !!(opts && (opts.WTF || opts.validateMerges))});
16840
+ var mergeErrors = validate_merges(s, {WTF: !!(opts && opts.validateMerges)});
16791
16841
  if(mergeErrors.length) s["!mergeErrors"] = mergeErrors;
16792
16842
  }
16793
16843
  if(rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
@@ -16902,7 +16952,8 @@ function parse_ws_xml_cols(columns, cols) {
16902
16952
  var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
16903
16953
  if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
16904
16954
  delete coll.min; delete coll.max; coll.width = +coll.width;
16905
- /* OOXML widths share the workbook Normal-font MDW; do not infer a different scale per sheet. */
16955
+ /* OOXML widths share the workbook Normal-font MDW. Do not infer it from
16956
+ * one ambiguous stored width or leak another worksheet's scale. */
16906
16957
  if(!seencol && coll.width) { seencol = true; MDW = DEF_MDW; }
16907
16958
  process_col(coll);
16908
16959
  while(colm <= colM) columns[colm++] = dup(coll);
@@ -17325,7 +17376,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
17325
17376
  /* customSheetViews */
17326
17377
 
17327
17378
  if(ws['!merges'] != null && ws['!merges'].length > 0) {
17328
- validate_merges(ws, {WTF:true});
17379
+ validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
17329
17380
  o[o.length] = (write_ws_xml_merges(ws['!merges']));
17330
17381
  }
17331
17382
 
@@ -17390,6 +17441,312 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
17390
17441
  if(o.length>1) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
17391
17442
  return o.join("");
17392
17443
  }
17444
+ var TABLE_STYLE_MAX_TABLES = 1024;
17445
+ var TABLE_STYLE_MAX_COLUMNS = 16384;
17446
+ var TABLE_STYLE_MAX_XML_LENGTH = 5 * 1024 * 1024;
17447
+ var TABLE_STYLE_ELEMENT_TYPES = {
17448
+ wholeTable:true, headerRow:true, totalRow:true,
17449
+ firstColumn:true, lastColumn:true,
17450
+ firstRowStripe:true, secondRowStripe:true,
17451
+ firstColumnStripe:true, secondColumnStripe:true,
17452
+ firstHeaderCell:true, lastHeaderCell:true,
17453
+ firstTotalCell:true, lastTotalCell:true
17454
+ };
17455
+
17456
+ function table_style_safe_key(key) {
17457
+ return key != "__proto__" && key != "constructor" && key != "prototype";
17458
+ }
17459
+
17460
+ function table_style_element_type(type) {
17461
+ return Object.prototype.hasOwnProperty.call(TABLE_STYLE_ELEMENT_TYPES, type);
17462
+ }
17463
+
17464
+ function table_style_attr(y, name) {
17465
+ if(y[name] != null) return y[name];
17466
+ return y[name.toLowerCase()];
17467
+ }
17468
+
17469
+ function table_style_bool(y, name, fallback) {
17470
+ var value = table_style_attr(y, name);
17471
+ return value == null ? fallback : parsexmlbool(value);
17472
+ }
17473
+
17474
+ function table_style_int(y, name) {
17475
+ var value = table_style_attr(y, name);
17476
+ if(value == null || value === "") return void 0;
17477
+ value = parseInt(value, 10);
17478
+ return isFinite(value) && value >= 0 ? value : void 0;
17479
+ }
17480
+
17481
+ function table_style_merge(target, source) {
17482
+ if(!source) return target;
17483
+ if(!target) target = {};
17484
+ keys(source).forEach(function(k) {
17485
+ if(!table_style_safe_key(k)) return;
17486
+ var value = source[k];
17487
+ if(value && typeof value == "object" && !Array.isArray(value)) {
17488
+ target[k] = table_style_merge(
17489
+ target[k] && typeof target[k] == "object" && !Array.isArray(target[k]) ? table_style_merge({}, target[k]) : {},
17490
+ value
17491
+ );
17492
+ } else target[k] = value;
17493
+ });
17494
+ return target;
17495
+ }
17496
+
17497
+ function table_style_color(themes, theme, tint) {
17498
+ return style_color_from_attrs({theme:String(theme), tint:String(tint || 0)}, themes);
17499
+ }
17500
+
17501
+ function table_style_fill(color) {
17502
+ return {fill:{patternType:"solid", fgColor:color}};
17503
+ }
17504
+
17505
+ function table_style_font(color, bold) {
17506
+ var font = {};
17507
+ if(color) font.color = color;
17508
+ if(bold) font.bold = 1;
17509
+ return {font:font};
17510
+ }
17511
+
17512
+ function table_style_border(side, color, style) {
17513
+ var border = {}, out = {border:border};
17514
+ border[side] = {style:style || "thin", color:color};
17515
+ return out;
17516
+ }
17517
+
17518
+ function table_style_accent(themes, index) {
17519
+ var position = (index - 1) % 7;
17520
+ /* The first style in each seven-style family is neutral. The remaining
17521
+ * six entries use the workbook's accent1..accent6 colors. */
17522
+ return table_style_color(themes, position ? 3 + position : 1, 0);
17523
+ }
17524
+
17525
+ function built_in_table_style_rules(name, themes) {
17526
+ var match = /^TableStyle(Light|Medium|Dark)(\d+)$/i.exec(name || "");
17527
+ if(!match) return null;
17528
+ var family = match[1].toLowerCase(), index = parseInt(match[2], 10);
17529
+ var maximum = family == "light" ? 21 : family == "medium" ? 28 : 11;
17530
+ if(index < 1 || index > maximum) return null;
17531
+ var accent = table_style_accent(themes, index);
17532
+ var white = table_style_color(themes, 0, 0);
17533
+ var dark = table_style_color(themes, 1, 0);
17534
+ var rules = {};
17535
+
17536
+ if(family == "light") {
17537
+ rules.headerRow = table_style_merge(
17538
+ table_style_font(accent, true),
17539
+ table_style_border("bottom", accent, "medium")
17540
+ );
17541
+ rules.totalRow = table_style_merge(
17542
+ table_style_font(accent, true),
17543
+ table_style_border("top", accent, "double")
17544
+ );
17545
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.9));
17546
+ rules.firstColumnStripe = rules.firstRowStripe;
17547
+ } else if(family == "medium") {
17548
+ var group = Math.floor((index - 1) / 7);
17549
+ rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
17550
+ rules.totalRow = table_style_merge(
17551
+ table_style_font(accent, true),
17552
+ table_style_border("top", accent, "double")
17553
+ );
17554
+ if(group == 1) {
17555
+ /* Medium 8..14 use two theme-derived body fills. This is the family
17556
+ * used by Excel's TableStyleMedium13. */
17557
+ rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.8));
17558
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.6));
17559
+ rules.firstColumnStripe = rules.firstRowStripe;
17560
+ } else if(group == 2) {
17561
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
17562
+ rules.firstColumnStripe = rules.firstRowStripe;
17563
+ rules.wholeTable = table_style_border("bottom", table_style_color(themes, accent.theme, 0.4), "thin");
17564
+ } else if(group == 3) {
17565
+ rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.9));
17566
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.7));
17567
+ rules.firstColumnStripe = rules.firstRowStripe;
17568
+ } else {
17569
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
17570
+ rules.firstColumnStripe = rules.firstRowStripe;
17571
+ }
17572
+ } else {
17573
+ rules.wholeTable = table_style_merge(table_style_fill(dark), table_style_font(white, false));
17574
+ rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
17575
+ rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, -0.35));
17576
+ rules.firstColumnStripe = rules.firstRowStripe;
17577
+ rules.totalRow = table_style_merge(
17578
+ table_style_font(white, true),
17579
+ table_style_border("top", accent, "double")
17580
+ );
17581
+ }
17582
+
17583
+ rules.firstColumn = table_style_font(null, true);
17584
+ rules.lastColumn = table_style_font(null, true);
17585
+ return rules;
17586
+ }
17587
+
17588
+ function custom_table_style_rules(name, styles) {
17589
+ var tableStyles = styles && styles.TableStyles;
17590
+ if(!tableStyles || !tableStyles.styles) return null;
17591
+ for(var i = 0; i < tableStyles.styles.length; ++i) {
17592
+ var tableStyle = tableStyles.styles[i];
17593
+ if(tableStyle.name != name) continue;
17594
+ var rules = Object.create(null);
17595
+ (tableStyle.elements || []).forEach(function(element) {
17596
+ if(!table_style_element_type(element.type)) return;
17597
+ var dxf = styles.Dxfs && styles.Dxfs[element.dxfId];
17598
+ if(dxf) rules[element.type] = {style:dup(dxf), size:element.size || 1};
17599
+ });
17600
+ return rules;
17601
+ }
17602
+ return null;
17603
+ }
17604
+
17605
+ function parse_table_xml(data, path, themes, styles, opts) {
17606
+ if(!data || data.length > TABLE_STYLE_MAX_XML_LENGTH) return null;
17607
+ data = remove_doctype(str_remove_ng(data, "<!--", "-->"));
17608
+ var table = {columns:[]}, column = null, pass = false;
17609
+ (data.match(tagregex)||[]).forEach(function(x) {
17610
+ var y = parsexmltag(x), tag = strip_ns(y[0]);
17611
+ switch(tag) {
17612
+ case '<table': case '<table>':
17613
+ table.id = table_style_int(y, "id");
17614
+ table.name = utf8read(unescapexml(table_style_attr(y, "name") || ""));
17615
+ table.displayName = utf8read(unescapexml(table_style_attr(y, "displayName") || table.name));
17616
+ table.ref = table_style_attr(y, "ref") || "";
17617
+ table.headerRowCount = table_style_int(y, "headerRowCount");
17618
+ table.totalsRowCount = table_style_int(y, "totalsRowCount");
17619
+ table.totalsRowShown = table_style_bool(y, "totalsRowShown", false);
17620
+ table.headerRowDxfId = table_style_int(y, "headerRowDxfId");
17621
+ table.dataDxfId = table_style_int(y, "dataDxfId");
17622
+ table.totalsRowDxfId = table_style_int(y, "totalsRowDxfId");
17623
+ table.path = path;
17624
+ break;
17625
+ case '<tableColumn': case '<tableColumn>': case '<tableColumn/>':
17626
+ if(table.columns.length >= TABLE_STYLE_MAX_COLUMNS) {
17627
+ column = null;
17628
+ break;
17629
+ }
17630
+ column = {
17631
+ id:table_style_int(y, "id"),
17632
+ name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
17633
+ headerRowDxfId:table_style_int(y, "headerRowDxfId"),
17634
+ dataDxfId:table_style_int(y, "dataDxfId"),
17635
+ totalsRowDxfId:table_style_int(y, "totalsRowDxfId")
17636
+ };
17637
+ table.columns.push(column);
17638
+ if(tag.slice(-2) == "/>" ) column = null;
17639
+ break;
17640
+ case '</tableColumn>': column = null; break;
17641
+ case '<tableStyleInfo': case '<tableStyleInfo>': case '<tableStyleInfo/>':
17642
+ table.styleInfo = {
17643
+ name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
17644
+ showFirstColumn:table_style_bool(y, "showFirstColumn", false),
17645
+ showLastColumn:table_style_bool(y, "showLastColumn", false),
17646
+ showRowStripes:table_style_bool(y, "showRowStripes", false),
17647
+ showColumnStripes:table_style_bool(y, "showColumnStripes", false)
17648
+ };
17649
+ break;
17650
+ case '<extLst': case '<extLst>': case '</extLst>': break;
17651
+ case '<ext': pass = true; break;
17652
+ case '</ext>': pass = false; break;
17653
+ default: if(opts && opts.WTF && !pass) {
17654
+ /* Table formulas and filter metadata are intentionally preserved by
17655
+ * the raw XML parser but do not affect visual style resolution. */
17656
+ if(/^<\/?(?:tableColumns|autoFilter|sortState|calculatedColumnFormula|totalsRowFormula|xmlColumnPr)/.test(tag)) break;
17657
+ }
17658
+ }
17659
+ });
17660
+ if(!table.ref) return null;
17661
+ try {
17662
+ table.range = safe_decode_range(table.ref);
17663
+ if(table.range.s.r < 0 || table.range.s.c < 0 || table.range.e.r > 1048575 || table.range.e.c > 16383) return null;
17664
+ } catch(e) { return null; }
17665
+ var styleName = table.styleInfo && table.styleInfo.name;
17666
+ table.styleRules = custom_table_style_rules(styleName, styles) || built_in_table_style_rules(styleName, themes) || {};
17667
+ table.dxfs = styles && styles.Dxfs ? styles.Dxfs : [];
17668
+ return table;
17669
+ }
17670
+
17671
+ function parse_sheet_tables(sheet, zip, path, rels, opts, themes, styles) {
17672
+ if(!sheet || !rels || !rels['!id'] || !opts || !opts.cellStyles) return;
17673
+ var tables = [], seen = Object.create(null);
17674
+ keys(rels['!id']).forEach(function(id) {
17675
+ if(tables.length >= TABLE_STYLE_MAX_TABLES) return;
17676
+ var rel = rels['!id'][id];
17677
+ if(!rel || rel.TargetMode == "External" || typeof rel.Target != "string" || !rel.Target ||
17678
+ (rel.Type != RELS.TABLE && !/\/table$/.test(rel.Type || ""))) return;
17679
+ var tablePath = resolve_path(rel.Target, path);
17680
+ if(seen[tablePath]) return;
17681
+ seen[tablePath] = true;
17682
+ var table = parse_table_xml(getzipstr(zip, tablePath, true), tablePath, themes, styles, opts);
17683
+ if(table) tables.push(table);
17684
+ });
17685
+ if(tables.length) sheet['!tables'] = tables;
17686
+ }
17687
+
17688
+ function table_style_rule_value(rule) {
17689
+ return rule && rule.style ? rule.style : rule;
17690
+ }
17691
+
17692
+ function table_style_stripe_rule(first, second, offset) {
17693
+ var firstSize = first && first.size || 1, secondSize = second && second.size || 1;
17694
+ var period = firstSize + secondSize;
17695
+ if(!period) return null;
17696
+ return offset % period < firstSize ? first : second;
17697
+ }
17698
+
17699
+ function table_style_dxf(table, id) {
17700
+ return id == null || !table.dxfs ? null : table.dxfs[id];
17701
+ }
17702
+
17703
+ function resolve_table_cell_style(ws, row, col, baseStyle) {
17704
+ var tables = ws && ws['!tables'];
17705
+ var resolved = baseStyle ? table_style_merge({}, baseStyle) : {};
17706
+ if(!tables || !tables.length) return keys(resolved).length ? resolved : void 0;
17707
+ for(var i = 0; i < tables.length; ++i) {
17708
+ var table = tables[i], range = table.range;
17709
+ if(!range || row < range.s.r || row > range.e.r || col < range.s.c || col > range.e.c) continue;
17710
+ var rules = table.styleRules || {}, info = table.styleInfo || {};
17711
+ var rowOffset = row - range.s.r, colOffset = col - range.s.c;
17712
+ var headerRows = table.headerRowCount == null ? 1 : table.headerRowCount;
17713
+ var totalRows = table.totalsRowCount != null ? table.totalsRowCount : table.totalsRowShown ? 1 : 0;
17714
+ var dataStart = headerRows, dataEnd = range.e.r - range.s.r - totalRows;
17715
+ var isHeader = rowOffset < headerRows;
17716
+ var isTotal = totalRows > 0 && rowOffset > dataEnd;
17717
+ var dataOffset = rowOffset - dataStart;
17718
+ var column = table.columns && table.columns[colOffset];
17719
+
17720
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.wholeTable));
17721
+ if(!isHeader && !isTotal && dataOffset >= 0) {
17722
+ if(info.showRowStripes) resolved = table_style_merge(resolved, table_style_rule_value(
17723
+ table_style_stripe_rule(rules.firstRowStripe, rules.secondRowStripe, dataOffset)
17724
+ ));
17725
+ if(info.showColumnStripes) resolved = table_style_merge(resolved, table_style_rule_value(
17726
+ table_style_stripe_rule(rules.firstColumnStripe, rules.secondColumnStripe, colOffset)
17727
+ ));
17728
+ }
17729
+ if(info.showFirstColumn && col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstColumn));
17730
+ if(info.showLastColumn && col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastColumn));
17731
+ if(isHeader) {
17732
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.headerRow));
17733
+ if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstHeaderCell));
17734
+ if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastHeaderCell));
17735
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.headerRowDxfId));
17736
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.headerRowDxfId));
17737
+ } else if(isTotal) {
17738
+ resolved = table_style_merge(resolved, table_style_rule_value(rules.totalRow));
17739
+ if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstTotalCell));
17740
+ if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastTotalCell));
17741
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.totalsRowDxfId));
17742
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.totalsRowDxfId));
17743
+ } else {
17744
+ resolved = table_style_merge(resolved, table_style_dxf(table, table.dataDxfId));
17745
+ resolved = table_style_merge(resolved, table_style_dxf(table, column && column.dataDxfId));
17746
+ }
17747
+ }
17748
+ return keys(resolved).length ? resolved : void 0;
17749
+ }
17393
17750
 
17394
17751
  /* [MS-XLSB] 2.4.726 BrtRowHdr */
17395
17752
  function parse_BrtRowHdr(data, length) {
@@ -18812,7 +19169,6 @@ function check_wb(wb) {
18812
19169
  check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
18813
19170
  for(var i = 0; i < wb.SheetNames.length; ++i) {
18814
19171
  var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
18815
- if(!ws) throw new Error("Missing worksheet |" + wb.SheetNames[i] + "|");
18816
19172
  check_ws(ws, wb.SheetNames[i], i);
18817
19173
  }
18818
19174
  wb.SheetNames.forEach(function(n, i) {
@@ -21241,7 +21597,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
21241
21597
  };
21242
21598
  var finalize_sheet_visuals = function finalizesheetvisuals(ws) {
21243
21599
  if(ws["!merges"] && ws["!merges"].length) {
21244
- var mergeErrors = validate_merges(ws, {WTF: !!(options && (options.WTF || options.validateMerges))});
21600
+ var mergeErrors = validate_merges(ws, {WTF: !!(options && options.validateMerges)});
21245
21601
  if(mergeErrors.length) ws["!mergeErrors"] = mergeErrors;
21246
21602
  }
21247
21603
  if(drawings && (drawings.images.length || drawings.shapes.length || drawings.charts.length || drawings.raw.length)) ws["!drawings"] = drawings;
@@ -23800,7 +24156,7 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
23800
24156
  if(b8) write_biff_rec(ba, 0x023e /* Window2 */, write_Window2((_WB.Views||[])[0]));
23801
24157
  /* ... */
23802
24158
  if(b8 && (ws['!merges']||[]).length) {
23803
- validate_merges(ws, {WTF:true});
24159
+ validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
23804
24160
  write_biff_rec(ba, 0x00e5 /* MergeCells */, write_MergeCells(ws['!merges']));
23805
24161
  }
23806
24162
  /* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */
@@ -24189,6 +24545,7 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
24189
24545
  if(cols[C] && cols[C].s) extend_style_obj(inherited, cols[C].s);
24190
24546
  if(row && row.s) extend_style_obj(inherited, row.s);
24191
24547
  if(cell && cell.s) extend_style_obj(inherited, cell.s);
24548
+ inherited = resolve_table_cell_style(ws, R, C, inherited) || inherited;
24192
24549
  if(keys(inherited).length) {
24193
24550
  stylecell = cell ? dup(cell) : {t:'z'};
24194
24551
  stylecell.s = inherited;
@@ -28315,6 +28672,7 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
28315
28672
  case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
28316
28673
  default: throw new Error("Unrecognized sheet type " + stype);
28317
28674
  }
28675
+ if(stype == "sheet") parse_sheet_tables(_ws, zip, path, sheetRels[sheet], opts, themes, styles);
28318
28676
  sheet_map_set(sheets, sheet, _ws);
28319
28677
 
28320
28678
  /* scan rels for comments and threaded comments */
@@ -28335,7 +28693,9 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
28335
28693
  if(tcomments && tcomments.length) sheet_insert_comments(_ws, tcomments, true, opts.people || []);
28336
28694
  if(stype == "sheet") parse_sheet_drawing(_ws, stype, zip, path, idx, opts, wb);
28337
28695
  parse_sheet_legacy_drawing(_ws, stype, zip, path, idx, opts, wb, comments);
28338
- } catch(e) { if(opts.WTF) throw e; }
28696
+ } catch(e) {
28697
+ if(opts.WTF || (opts.validateMerges && e && /^E_MERGE_/.test(e.code))) throw e;
28698
+ }
28339
28699
  }
28340
28700
 
28341
28701
  function strip_front_slash(x/*:string*/)/*:string*/ { return x.charAt(0) == '/' ? x.slice(1) : x; }
@@ -29647,6 +30007,7 @@ var utils/*:any*/ = {
29647
30007
  measure_text_width: measure_text_width,
29648
30008
  auto_fit_columns: auto_fit_columns,
29649
30009
  autofit_columns: auto_fit_columns,
30010
+ resolve_table_cell_style: resolve_table_cell_style,
29650
30011
  col_width_to_px: width2px,
29651
30012
  px_to_col_width: function(px) { return char2width(px2char(px)); },
29652
30013
  row_height_to_px: pt2px_browser,