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/CHANGELOG.md +12 -0
- package/dist/xlsx.core.min.js +18 -18
- package/dist/xlsx.core.min.map +1 -1
- package/dist/xlsx.extendscript.js +371 -10
- package/dist/xlsx.full.min.js +19 -18
- package/dist/xlsx.full.min.map +1 -1
- package/dist/xlsx.mini.min.js +11 -10
- package/dist/xlsx.mini.min.map +1 -1
- package/docs/visual-fidelity.md +13 -0
- package/docs/visual-fidelity.zh-CN.md +11 -0
- package/package.json +41 -37
- package/types/index.d.ts +45 -3
- package/xlsx.js +371 -10
- package/xlsx.mjs +371 -10
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.
|
|
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)
|
|
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 &&
|
|
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
|
|
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:
|
|
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 &&
|
|
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:
|
|
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) {
|
|
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,
|