styled-exceljs 0.21.3 → 0.21.5
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 +22 -0
- package/README.md +21 -0
- package/dist/xlsx.core.min.js +18 -18
- package/dist/xlsx.core.min.map +1 -1
- package/dist/xlsx.extendscript.js +388 -17
- 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 +42 -37
- package/types/index.d.ts +45 -3
- package/xlsx.js +388 -17
- package/xlsx.mjs +388 -17
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 */
|
|
@@ -1725,8 +1725,12 @@ sleuth_fat(difat_start, difat_sec_cnt, sectors, ssz, fat_addrs);
|
|
|
1725
1725
|
/** Chains */
|
|
1726
1726
|
var sector_list/*:SectorList*/ = make_sector_list(sectors, dir_start, fat_addrs, ssz);
|
|
1727
1727
|
|
|
1728
|
-
if(
|
|
1729
|
-
|
|
1728
|
+
if(!sector_list[dir_start]) throw new Error("CFB directory chain is missing");
|
|
1729
|
+
sector_list[dir_start].name = "!Directory";
|
|
1730
|
+
/* Some producers leave stale MiniFAT locations after removing all mini streams.
|
|
1731
|
+
* Require the chain only when a live directory entry actually uses it. */
|
|
1732
|
+
if(nmfs > 0 && sector_list[minifat_start]) sector_list[minifat_start].name = "!MiniFAT";
|
|
1733
|
+
if(!sector_list[fat_addrs[0]]) throw new Error("CFB FAT chain is missing");
|
|
1730
1734
|
sector_list[fat_addrs[0]].name = "!FAT";
|
|
1731
1735
|
sector_list.fat_addrs = fat_addrs;
|
|
1732
1736
|
sector_list.ssz = ssz;
|
|
@@ -1938,10 +1942,14 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector
|
|
|
1938
1942
|
if(mtime !== 0) o.mt = read_date(blob, blob.l-8);
|
|
1939
1943
|
o.start = blob.read_shift(4, 'i');
|
|
1940
1944
|
o.size = blob.read_shift(4, 'i');
|
|
1945
|
+
if(o.type === 0) { o.size = 0; o.start = ENDOFCHAIN; }
|
|
1941
1946
|
if(o.size < 0 && o.start < 0) { o.size = o.type = 0; o.start = ENDOFCHAIN; o.name = ""; }
|
|
1942
1947
|
if(o.type === 5) { /* root */
|
|
1943
|
-
minifat_store = o.start;
|
|
1944
|
-
if(
|
|
1948
|
+
minifat_store = o.size > 0 ? o.start : ENDOFCHAIN;
|
|
1949
|
+
if(o.size > 0 && nmfs > 0) {
|
|
1950
|
+
if(!sector_list[minifat_store]) throw new Error("CFB root mini stream is missing");
|
|
1951
|
+
sector_list[minifat_store].name = "!StreamData";
|
|
1952
|
+
}
|
|
1945
1953
|
/*minifat_size = o.size;*/
|
|
1946
1954
|
} else if(o.size >= 4096 /* MSCSZ */) {
|
|
1947
1955
|
o.storage = 'fat';
|
|
@@ -1951,8 +1959,11 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector
|
|
|
1951
1959
|
} else {
|
|
1952
1960
|
o.storage = 'minifat';
|
|
1953
1961
|
if(o.size < 0) o.size = 0;
|
|
1954
|
-
else if(
|
|
1955
|
-
|
|
1962
|
+
else if(o.type === 2 && o.size > 0) {
|
|
1963
|
+
if(nmfs < 1 || !sector_list[mini]) throw new Error("CFB MiniFAT chain is missing for stream: " + o.name);
|
|
1964
|
+
if(!sector_list[minifat_store]) throw new Error("CFB root mini stream is missing");
|
|
1965
|
+
o.content = get_mfat_entry(o, sector_list[minifat_store].data, sector_list[mini].data);
|
|
1966
|
+
if(o.content.length !== o.size) throw new Error("CFB mini stream is truncated: " + o.name);
|
|
1956
1967
|
}
|
|
1957
1968
|
}
|
|
1958
1969
|
if(o.content) prep_blob(o.content, 0);
|
|
@@ -3288,7 +3299,6 @@ exports.utils = {
|
|
|
3288
3299
|
|
|
3289
3300
|
return exports;
|
|
3290
3301
|
})();
|
|
3291
|
-
|
|
3292
3302
|
var _fs;
|
|
3293
3303
|
function set_fs(fs) { _fs = fs; }
|
|
3294
3304
|
|
|
@@ -3945,7 +3955,7 @@ function escapexmltag(text/*:string*/)/*:string*/{ return escapexml(text).replac
|
|
|
3945
3955
|
var htmlcharegex = /[\u0000-\u001f]/g;
|
|
3946
3956
|
function escapehtml(text/*:string*/)/*:string*/{
|
|
3947
3957
|
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) + ";"; });
|
|
3958
|
+
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
3959
|
}
|
|
3950
3960
|
|
|
3951
3961
|
function escapexlml(text/*:string*/)/*:string*/{
|
|
@@ -5755,6 +5765,7 @@ var RELS = ({
|
|
|
5755
5765
|
MS: "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet",
|
|
5756
5766
|
IMG: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
|
5757
5767
|
DRAW: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
|
|
5768
|
+
TABLE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
|
|
5758
5769
|
XLMETA: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
|
|
5759
5770
|
TCMNT: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",
|
|
5760
5771
|
PEOPLE: "http://schemas.microsoft.com/office/2017/10/relationships/person",
|
|
@@ -11224,6 +11235,9 @@ function resolve_style_obj_color(obj, themes) {
|
|
|
11224
11235
|
|
|
11225
11236
|
/* 18.3.1.13 width calculations */
|
|
11226
11237
|
/* [MS-OI29500] 2.1.595 Column Width & Formatting */
|
|
11238
|
+
/* The file format does not store MDW directly. Seven is the Office-compatible
|
|
11239
|
+
* fallback when Normal-font metrics are unavailable. A single stored column
|
|
11240
|
+
* width is ambiguous and must not change the scale for the rest of a sheet. */
|
|
11227
11241
|
var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
|
|
11228
11242
|
function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
|
|
11229
11243
|
function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
|
|
@@ -12057,6 +12071,47 @@ function parse_dxfs(t, styles, themes, opts) {
|
|
|
12057
12071
|
});
|
|
12058
12072
|
}
|
|
12059
12073
|
|
|
12074
|
+
function parse_tableStyles(t, styles, opts) {
|
|
12075
|
+
styles.TableStyles = {styles:[]};
|
|
12076
|
+
var tableStyle = null, pass = false;
|
|
12077
|
+
(t.match(tagregex)||[]).forEach(function(x) {
|
|
12078
|
+
var y = parsexmltag(x), tag = strip_ns(y[0]);
|
|
12079
|
+
switch(tag) {
|
|
12080
|
+
case '<tableStyles': case '<tableStyles>':
|
|
12081
|
+
if(y.defaultTableStyle) styles.TableStyles.defaultTableStyle = utf8read(unescapexml(y.defaultTableStyle));
|
|
12082
|
+
if(y.defaultPivotStyle) styles.TableStyles.defaultPivotStyle = utf8read(unescapexml(y.defaultPivotStyle));
|
|
12083
|
+
break;
|
|
12084
|
+
case '<tableStyles/>': case '</tableStyles>': break;
|
|
12085
|
+
case '<tableStyle': case '<tableStyle>': case '<tableStyle/>':
|
|
12086
|
+
if(styles.TableStyles.styles.length >= TABLE_STYLE_MAX_TABLES) {
|
|
12087
|
+
tableStyle = null;
|
|
12088
|
+
break;
|
|
12089
|
+
}
|
|
12090
|
+
tableStyle = {
|
|
12091
|
+
name:utf8read(unescapexml(y.name || "")),
|
|
12092
|
+
pivot:y.pivot != null ? parsexmlbool(y.pivot) : false,
|
|
12093
|
+
table:y.table != null ? parsexmlbool(y.table) : true,
|
|
12094
|
+
elements:[]
|
|
12095
|
+
};
|
|
12096
|
+
styles.TableStyles.styles.push(tableStyle);
|
|
12097
|
+
if(tag.slice(-2) == "/>") tableStyle = null;
|
|
12098
|
+
break;
|
|
12099
|
+
case '</tableStyle>': tableStyle = null; break;
|
|
12100
|
+
case '<tableStyleElement': case '<tableStyleElement>': case '<tableStyleElement/>':
|
|
12101
|
+
if(tableStyle && tableStyle.elements.length < 64 && table_style_element_type(y.type) && y.dxfId != null) tableStyle.elements.push({
|
|
12102
|
+
type:y.type,
|
|
12103
|
+
dxfId:parseInt(y.dxfId, 10),
|
|
12104
|
+
size:y.size != null ? Math.max(1, parseInt(y.size, 10) || 1) : 1
|
|
12105
|
+
});
|
|
12106
|
+
break;
|
|
12107
|
+
case '<extLst': case '<extLst>': case '</extLst>': break;
|
|
12108
|
+
case '<ext': pass = true; break;
|
|
12109
|
+
case '</ext>': pass = false; break;
|
|
12110
|
+
default: if(opts && opts.WTF && !pass) throw new Error('unrecognized ' + y[0] + ' in tableStyles');
|
|
12111
|
+
}
|
|
12112
|
+
});
|
|
12113
|
+
}
|
|
12114
|
+
|
|
12060
12115
|
function parse_colors(t, styles, themes, opts) {
|
|
12061
12116
|
styles.Colors = {indexedColors:[], mruColors:[], themeColors:[]};
|
|
12062
12117
|
var target = null, pass = false;
|
|
@@ -12135,6 +12190,7 @@ return function parse_sty_xml(data, themes, opts) {
|
|
|
12135
12190
|
if((t=str_match_xml_ns(data, "dxfs"))) parse_dxfs(t[0], styles, themes, opts);
|
|
12136
12191
|
|
|
12137
12192
|
/* 18.8.42 tableStyles CT_TableStyles ? */
|
|
12193
|
+
if((t=str_match_xml_ns(data, "tableStyles"))) parse_tableStyles(t[0], styles, opts);
|
|
12138
12194
|
/* 18.8.11 colors CT_Colors ? */
|
|
12139
12195
|
if((t=str_match_xml_ns(data, "colors"))) parse_colors(t[0], styles, themes, opts);
|
|
12140
12196
|
|
|
@@ -16663,7 +16719,11 @@ function validate_merges(ws/*:Worksheet*/, opts/*:?any*/) {
|
|
|
16663
16719
|
errors.push({code:"E_MERGE_OVERLAP", message:"Merge ranges overlap", index:i, other:j, range:enc, otherRange:encode_range(merges[j])});
|
|
16664
16720
|
}
|
|
16665
16721
|
}
|
|
16666
|
-
if(errors.length && opts && opts.WTF)
|
|
16722
|
+
if(errors.length && opts && opts.WTF) {
|
|
16723
|
+
var err/*:any*/ = new Error(errors[0].message + " (" + (errors[0].range || errors[0].index) + ")");
|
|
16724
|
+
err.code = errors[0].code;
|
|
16725
|
+
throw err;
|
|
16726
|
+
}
|
|
16667
16727
|
return errors;
|
|
16668
16728
|
}
|
|
16669
16729
|
|
|
@@ -16787,7 +16847,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
|
|
16787
16847
|
if(columns.length > 0) s["!cols"] = columns;
|
|
16788
16848
|
if(merges.length > 0) {
|
|
16789
16849
|
s["!merges"] = merges;
|
|
16790
|
-
var mergeErrors = validate_merges(s, {WTF: !!(opts &&
|
|
16850
|
+
var mergeErrors = validate_merges(s, {WTF: !!(opts && opts.validateMerges)});
|
|
16791
16851
|
if(mergeErrors.length) s["!mergeErrors"] = mergeErrors;
|
|
16792
16852
|
}
|
|
16793
16853
|
if(rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
|
|
@@ -16902,7 +16962,8 @@ function parse_ws_xml_cols(columns, cols) {
|
|
|
16902
16962
|
var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
|
|
16903
16963
|
if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
|
|
16904
16964
|
delete coll.min; delete coll.max; coll.width = +coll.width;
|
|
16905
|
-
/* OOXML widths share the workbook Normal-font MDW
|
|
16965
|
+
/* OOXML widths share the workbook Normal-font MDW. Do not infer it from
|
|
16966
|
+
* one ambiguous stored width or leak another worksheet's scale. */
|
|
16906
16967
|
if(!seencol && coll.width) { seencol = true; MDW = DEF_MDW; }
|
|
16907
16968
|
process_col(coll);
|
|
16908
16969
|
while(colm <= colM) columns[colm++] = dup(coll);
|
|
@@ -17325,7 +17386,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
|
|
17325
17386
|
/* customSheetViews */
|
|
17326
17387
|
|
|
17327
17388
|
if(ws['!merges'] != null && ws['!merges'].length > 0) {
|
|
17328
|
-
validate_merges(ws, {WTF:
|
|
17389
|
+
validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
|
|
17329
17390
|
o[o.length] = (write_ws_xml_merges(ws['!merges']));
|
|
17330
17391
|
}
|
|
17331
17392
|
|
|
@@ -17390,6 +17451,312 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
|
|
17390
17451
|
if(o.length>1) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
|
|
17391
17452
|
return o.join("");
|
|
17392
17453
|
}
|
|
17454
|
+
var TABLE_STYLE_MAX_TABLES = 1024;
|
|
17455
|
+
var TABLE_STYLE_MAX_COLUMNS = 16384;
|
|
17456
|
+
var TABLE_STYLE_MAX_XML_LENGTH = 5 * 1024 * 1024;
|
|
17457
|
+
var TABLE_STYLE_ELEMENT_TYPES = {
|
|
17458
|
+
wholeTable:true, headerRow:true, totalRow:true,
|
|
17459
|
+
firstColumn:true, lastColumn:true,
|
|
17460
|
+
firstRowStripe:true, secondRowStripe:true,
|
|
17461
|
+
firstColumnStripe:true, secondColumnStripe:true,
|
|
17462
|
+
firstHeaderCell:true, lastHeaderCell:true,
|
|
17463
|
+
firstTotalCell:true, lastTotalCell:true
|
|
17464
|
+
};
|
|
17465
|
+
|
|
17466
|
+
function table_style_safe_key(key) {
|
|
17467
|
+
return key != "__proto__" && key != "constructor" && key != "prototype";
|
|
17468
|
+
}
|
|
17469
|
+
|
|
17470
|
+
function table_style_element_type(type) {
|
|
17471
|
+
return Object.prototype.hasOwnProperty.call(TABLE_STYLE_ELEMENT_TYPES, type);
|
|
17472
|
+
}
|
|
17473
|
+
|
|
17474
|
+
function table_style_attr(y, name) {
|
|
17475
|
+
if(y[name] != null) return y[name];
|
|
17476
|
+
return y[name.toLowerCase()];
|
|
17477
|
+
}
|
|
17478
|
+
|
|
17479
|
+
function table_style_bool(y, name, fallback) {
|
|
17480
|
+
var value = table_style_attr(y, name);
|
|
17481
|
+
return value == null ? fallback : parsexmlbool(value);
|
|
17482
|
+
}
|
|
17483
|
+
|
|
17484
|
+
function table_style_int(y, name) {
|
|
17485
|
+
var value = table_style_attr(y, name);
|
|
17486
|
+
if(value == null || value === "") return void 0;
|
|
17487
|
+
value = parseInt(value, 10);
|
|
17488
|
+
return isFinite(value) && value >= 0 ? value : void 0;
|
|
17489
|
+
}
|
|
17490
|
+
|
|
17491
|
+
function table_style_merge(target, source) {
|
|
17492
|
+
if(!source) return target;
|
|
17493
|
+
if(!target) target = {};
|
|
17494
|
+
keys(source).forEach(function(k) {
|
|
17495
|
+
if(!table_style_safe_key(k)) return;
|
|
17496
|
+
var value = source[k];
|
|
17497
|
+
if(value && typeof value == "object" && !Array.isArray(value)) {
|
|
17498
|
+
target[k] = table_style_merge(
|
|
17499
|
+
target[k] && typeof target[k] == "object" && !Array.isArray(target[k]) ? table_style_merge({}, target[k]) : {},
|
|
17500
|
+
value
|
|
17501
|
+
);
|
|
17502
|
+
} else target[k] = value;
|
|
17503
|
+
});
|
|
17504
|
+
return target;
|
|
17505
|
+
}
|
|
17506
|
+
|
|
17507
|
+
function table_style_color(themes, theme, tint) {
|
|
17508
|
+
return style_color_from_attrs({theme:String(theme), tint:String(tint || 0)}, themes);
|
|
17509
|
+
}
|
|
17510
|
+
|
|
17511
|
+
function table_style_fill(color) {
|
|
17512
|
+
return {fill:{patternType:"solid", fgColor:color}};
|
|
17513
|
+
}
|
|
17514
|
+
|
|
17515
|
+
function table_style_font(color, bold) {
|
|
17516
|
+
var font = {};
|
|
17517
|
+
if(color) font.color = color;
|
|
17518
|
+
if(bold) font.bold = 1;
|
|
17519
|
+
return {font:font};
|
|
17520
|
+
}
|
|
17521
|
+
|
|
17522
|
+
function table_style_border(side, color, style) {
|
|
17523
|
+
var border = {}, out = {border:border};
|
|
17524
|
+
border[side] = {style:style || "thin", color:color};
|
|
17525
|
+
return out;
|
|
17526
|
+
}
|
|
17527
|
+
|
|
17528
|
+
function table_style_accent(themes, index) {
|
|
17529
|
+
var position = (index - 1) % 7;
|
|
17530
|
+
/* The first style in each seven-style family is neutral. The remaining
|
|
17531
|
+
* six entries use the workbook's accent1..accent6 colors. */
|
|
17532
|
+
return table_style_color(themes, position ? 3 + position : 1, 0);
|
|
17533
|
+
}
|
|
17534
|
+
|
|
17535
|
+
function built_in_table_style_rules(name, themes) {
|
|
17536
|
+
var match = /^TableStyle(Light|Medium|Dark)(\d+)$/i.exec(name || "");
|
|
17537
|
+
if(!match) return null;
|
|
17538
|
+
var family = match[1].toLowerCase(), index = parseInt(match[2], 10);
|
|
17539
|
+
var maximum = family == "light" ? 21 : family == "medium" ? 28 : 11;
|
|
17540
|
+
if(index < 1 || index > maximum) return null;
|
|
17541
|
+
var accent = table_style_accent(themes, index);
|
|
17542
|
+
var white = table_style_color(themes, 0, 0);
|
|
17543
|
+
var dark = table_style_color(themes, 1, 0);
|
|
17544
|
+
var rules = {};
|
|
17545
|
+
|
|
17546
|
+
if(family == "light") {
|
|
17547
|
+
rules.headerRow = table_style_merge(
|
|
17548
|
+
table_style_font(accent, true),
|
|
17549
|
+
table_style_border("bottom", accent, "medium")
|
|
17550
|
+
);
|
|
17551
|
+
rules.totalRow = table_style_merge(
|
|
17552
|
+
table_style_font(accent, true),
|
|
17553
|
+
table_style_border("top", accent, "double")
|
|
17554
|
+
);
|
|
17555
|
+
rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.9));
|
|
17556
|
+
rules.firstColumnStripe = rules.firstRowStripe;
|
|
17557
|
+
} else if(family == "medium") {
|
|
17558
|
+
var group = Math.floor((index - 1) / 7);
|
|
17559
|
+
rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
|
|
17560
|
+
rules.totalRow = table_style_merge(
|
|
17561
|
+
table_style_font(accent, true),
|
|
17562
|
+
table_style_border("top", accent, "double")
|
|
17563
|
+
);
|
|
17564
|
+
if(group == 1) {
|
|
17565
|
+
/* Medium 8..14 use two theme-derived body fills. This is the family
|
|
17566
|
+
* used by Excel's TableStyleMedium13. */
|
|
17567
|
+
rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.8));
|
|
17568
|
+
rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.6));
|
|
17569
|
+
rules.firstColumnStripe = rules.firstRowStripe;
|
|
17570
|
+
} else if(group == 2) {
|
|
17571
|
+
rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
|
|
17572
|
+
rules.firstColumnStripe = rules.firstRowStripe;
|
|
17573
|
+
rules.wholeTable = table_style_border("bottom", table_style_color(themes, accent.theme, 0.4), "thin");
|
|
17574
|
+
} else if(group == 3) {
|
|
17575
|
+
rules.wholeTable = table_style_fill(table_style_color(themes, accent.theme, 0.9));
|
|
17576
|
+
rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.7));
|
|
17577
|
+
rules.firstColumnStripe = rules.firstRowStripe;
|
|
17578
|
+
} else {
|
|
17579
|
+
rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, 0.8));
|
|
17580
|
+
rules.firstColumnStripe = rules.firstRowStripe;
|
|
17581
|
+
}
|
|
17582
|
+
} else {
|
|
17583
|
+
rules.wholeTable = table_style_merge(table_style_fill(dark), table_style_font(white, false));
|
|
17584
|
+
rules.headerRow = table_style_merge(table_style_fill(accent), table_style_font(white, true));
|
|
17585
|
+
rules.firstRowStripe = table_style_fill(table_style_color(themes, accent.theme, -0.35));
|
|
17586
|
+
rules.firstColumnStripe = rules.firstRowStripe;
|
|
17587
|
+
rules.totalRow = table_style_merge(
|
|
17588
|
+
table_style_font(white, true),
|
|
17589
|
+
table_style_border("top", accent, "double")
|
|
17590
|
+
);
|
|
17591
|
+
}
|
|
17592
|
+
|
|
17593
|
+
rules.firstColumn = table_style_font(null, true);
|
|
17594
|
+
rules.lastColumn = table_style_font(null, true);
|
|
17595
|
+
return rules;
|
|
17596
|
+
}
|
|
17597
|
+
|
|
17598
|
+
function custom_table_style_rules(name, styles) {
|
|
17599
|
+
var tableStyles = styles && styles.TableStyles;
|
|
17600
|
+
if(!tableStyles || !tableStyles.styles) return null;
|
|
17601
|
+
for(var i = 0; i < tableStyles.styles.length; ++i) {
|
|
17602
|
+
var tableStyle = tableStyles.styles[i];
|
|
17603
|
+
if(tableStyle.name != name) continue;
|
|
17604
|
+
var rules = Object.create(null);
|
|
17605
|
+
(tableStyle.elements || []).forEach(function(element) {
|
|
17606
|
+
if(!table_style_element_type(element.type)) return;
|
|
17607
|
+
var dxf = styles.Dxfs && styles.Dxfs[element.dxfId];
|
|
17608
|
+
if(dxf) rules[element.type] = {style:dup(dxf), size:element.size || 1};
|
|
17609
|
+
});
|
|
17610
|
+
return rules;
|
|
17611
|
+
}
|
|
17612
|
+
return null;
|
|
17613
|
+
}
|
|
17614
|
+
|
|
17615
|
+
function parse_table_xml(data, path, themes, styles, opts) {
|
|
17616
|
+
if(!data || data.length > TABLE_STYLE_MAX_XML_LENGTH) return null;
|
|
17617
|
+
data = remove_doctype(str_remove_ng(data, "<!--", "-->"));
|
|
17618
|
+
var table = {columns:[]}, column = null, pass = false;
|
|
17619
|
+
(data.match(tagregex)||[]).forEach(function(x) {
|
|
17620
|
+
var y = parsexmltag(x), tag = strip_ns(y[0]);
|
|
17621
|
+
switch(tag) {
|
|
17622
|
+
case '<table': case '<table>':
|
|
17623
|
+
table.id = table_style_int(y, "id");
|
|
17624
|
+
table.name = utf8read(unescapexml(table_style_attr(y, "name") || ""));
|
|
17625
|
+
table.displayName = utf8read(unescapexml(table_style_attr(y, "displayName") || table.name));
|
|
17626
|
+
table.ref = table_style_attr(y, "ref") || "";
|
|
17627
|
+
table.headerRowCount = table_style_int(y, "headerRowCount");
|
|
17628
|
+
table.totalsRowCount = table_style_int(y, "totalsRowCount");
|
|
17629
|
+
table.totalsRowShown = table_style_bool(y, "totalsRowShown", false);
|
|
17630
|
+
table.headerRowDxfId = table_style_int(y, "headerRowDxfId");
|
|
17631
|
+
table.dataDxfId = table_style_int(y, "dataDxfId");
|
|
17632
|
+
table.totalsRowDxfId = table_style_int(y, "totalsRowDxfId");
|
|
17633
|
+
table.path = path;
|
|
17634
|
+
break;
|
|
17635
|
+
case '<tableColumn': case '<tableColumn>': case '<tableColumn/>':
|
|
17636
|
+
if(table.columns.length >= TABLE_STYLE_MAX_COLUMNS) {
|
|
17637
|
+
column = null;
|
|
17638
|
+
break;
|
|
17639
|
+
}
|
|
17640
|
+
column = {
|
|
17641
|
+
id:table_style_int(y, "id"),
|
|
17642
|
+
name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
|
|
17643
|
+
headerRowDxfId:table_style_int(y, "headerRowDxfId"),
|
|
17644
|
+
dataDxfId:table_style_int(y, "dataDxfId"),
|
|
17645
|
+
totalsRowDxfId:table_style_int(y, "totalsRowDxfId")
|
|
17646
|
+
};
|
|
17647
|
+
table.columns.push(column);
|
|
17648
|
+
if(tag.slice(-2) == "/>" ) column = null;
|
|
17649
|
+
break;
|
|
17650
|
+
case '</tableColumn>': column = null; break;
|
|
17651
|
+
case '<tableStyleInfo': case '<tableStyleInfo>': case '<tableStyleInfo/>':
|
|
17652
|
+
table.styleInfo = {
|
|
17653
|
+
name:utf8read(unescapexml(table_style_attr(y, "name") || "")),
|
|
17654
|
+
showFirstColumn:table_style_bool(y, "showFirstColumn", false),
|
|
17655
|
+
showLastColumn:table_style_bool(y, "showLastColumn", false),
|
|
17656
|
+
showRowStripes:table_style_bool(y, "showRowStripes", false),
|
|
17657
|
+
showColumnStripes:table_style_bool(y, "showColumnStripes", false)
|
|
17658
|
+
};
|
|
17659
|
+
break;
|
|
17660
|
+
case '<extLst': case '<extLst>': case '</extLst>': break;
|
|
17661
|
+
case '<ext': pass = true; break;
|
|
17662
|
+
case '</ext>': pass = false; break;
|
|
17663
|
+
default: if(opts && opts.WTF && !pass) {
|
|
17664
|
+
/* Table formulas and filter metadata are intentionally preserved by
|
|
17665
|
+
* the raw XML parser but do not affect visual style resolution. */
|
|
17666
|
+
if(/^<\/?(?:tableColumns|autoFilter|sortState|calculatedColumnFormula|totalsRowFormula|xmlColumnPr)/.test(tag)) break;
|
|
17667
|
+
}
|
|
17668
|
+
}
|
|
17669
|
+
});
|
|
17670
|
+
if(!table.ref) return null;
|
|
17671
|
+
try {
|
|
17672
|
+
table.range = safe_decode_range(table.ref);
|
|
17673
|
+
if(table.range.s.r < 0 || table.range.s.c < 0 || table.range.e.r > 1048575 || table.range.e.c > 16383) return null;
|
|
17674
|
+
} catch(e) { return null; }
|
|
17675
|
+
var styleName = table.styleInfo && table.styleInfo.name;
|
|
17676
|
+
table.styleRules = custom_table_style_rules(styleName, styles) || built_in_table_style_rules(styleName, themes) || {};
|
|
17677
|
+
table.dxfs = styles && styles.Dxfs ? styles.Dxfs : [];
|
|
17678
|
+
return table;
|
|
17679
|
+
}
|
|
17680
|
+
|
|
17681
|
+
function parse_sheet_tables(sheet, zip, path, rels, opts, themes, styles) {
|
|
17682
|
+
if(!sheet || !rels || !rels['!id'] || !opts || !opts.cellStyles) return;
|
|
17683
|
+
var tables = [], seen = Object.create(null);
|
|
17684
|
+
keys(rels['!id']).forEach(function(id) {
|
|
17685
|
+
if(tables.length >= TABLE_STYLE_MAX_TABLES) return;
|
|
17686
|
+
var rel = rels['!id'][id];
|
|
17687
|
+
if(!rel || rel.TargetMode == "External" || typeof rel.Target != "string" || !rel.Target ||
|
|
17688
|
+
(rel.Type != RELS.TABLE && !/\/table$/.test(rel.Type || ""))) return;
|
|
17689
|
+
var tablePath = resolve_path(rel.Target, path);
|
|
17690
|
+
if(seen[tablePath]) return;
|
|
17691
|
+
seen[tablePath] = true;
|
|
17692
|
+
var table = parse_table_xml(getzipstr(zip, tablePath, true), tablePath, themes, styles, opts);
|
|
17693
|
+
if(table) tables.push(table);
|
|
17694
|
+
});
|
|
17695
|
+
if(tables.length) sheet['!tables'] = tables;
|
|
17696
|
+
}
|
|
17697
|
+
|
|
17698
|
+
function table_style_rule_value(rule) {
|
|
17699
|
+
return rule && rule.style ? rule.style : rule;
|
|
17700
|
+
}
|
|
17701
|
+
|
|
17702
|
+
function table_style_stripe_rule(first, second, offset) {
|
|
17703
|
+
var firstSize = first && first.size || 1, secondSize = second && second.size || 1;
|
|
17704
|
+
var period = firstSize + secondSize;
|
|
17705
|
+
if(!period) return null;
|
|
17706
|
+
return offset % period < firstSize ? first : second;
|
|
17707
|
+
}
|
|
17708
|
+
|
|
17709
|
+
function table_style_dxf(table, id) {
|
|
17710
|
+
return id == null || !table.dxfs ? null : table.dxfs[id];
|
|
17711
|
+
}
|
|
17712
|
+
|
|
17713
|
+
function resolve_table_cell_style(ws, row, col, baseStyle) {
|
|
17714
|
+
var tables = ws && ws['!tables'];
|
|
17715
|
+
var resolved = baseStyle ? table_style_merge({}, baseStyle) : {};
|
|
17716
|
+
if(!tables || !tables.length) return keys(resolved).length ? resolved : void 0;
|
|
17717
|
+
for(var i = 0; i < tables.length; ++i) {
|
|
17718
|
+
var table = tables[i], range = table.range;
|
|
17719
|
+
if(!range || row < range.s.r || row > range.e.r || col < range.s.c || col > range.e.c) continue;
|
|
17720
|
+
var rules = table.styleRules || {}, info = table.styleInfo || {};
|
|
17721
|
+
var rowOffset = row - range.s.r, colOffset = col - range.s.c;
|
|
17722
|
+
var headerRows = table.headerRowCount == null ? 1 : table.headerRowCount;
|
|
17723
|
+
var totalRows = table.totalsRowCount != null ? table.totalsRowCount : table.totalsRowShown ? 1 : 0;
|
|
17724
|
+
var dataStart = headerRows, dataEnd = range.e.r - range.s.r - totalRows;
|
|
17725
|
+
var isHeader = rowOffset < headerRows;
|
|
17726
|
+
var isTotal = totalRows > 0 && rowOffset > dataEnd;
|
|
17727
|
+
var dataOffset = rowOffset - dataStart;
|
|
17728
|
+
var column = table.columns && table.columns[colOffset];
|
|
17729
|
+
|
|
17730
|
+
resolved = table_style_merge(resolved, table_style_rule_value(rules.wholeTable));
|
|
17731
|
+
if(!isHeader && !isTotal && dataOffset >= 0) {
|
|
17732
|
+
if(info.showRowStripes) resolved = table_style_merge(resolved, table_style_rule_value(
|
|
17733
|
+
table_style_stripe_rule(rules.firstRowStripe, rules.secondRowStripe, dataOffset)
|
|
17734
|
+
));
|
|
17735
|
+
if(info.showColumnStripes) resolved = table_style_merge(resolved, table_style_rule_value(
|
|
17736
|
+
table_style_stripe_rule(rules.firstColumnStripe, rules.secondColumnStripe, colOffset)
|
|
17737
|
+
));
|
|
17738
|
+
}
|
|
17739
|
+
if(info.showFirstColumn && col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstColumn));
|
|
17740
|
+
if(info.showLastColumn && col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastColumn));
|
|
17741
|
+
if(isHeader) {
|
|
17742
|
+
resolved = table_style_merge(resolved, table_style_rule_value(rules.headerRow));
|
|
17743
|
+
if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstHeaderCell));
|
|
17744
|
+
if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastHeaderCell));
|
|
17745
|
+
resolved = table_style_merge(resolved, table_style_dxf(table, table.headerRowDxfId));
|
|
17746
|
+
resolved = table_style_merge(resolved, table_style_dxf(table, column && column.headerRowDxfId));
|
|
17747
|
+
} else if(isTotal) {
|
|
17748
|
+
resolved = table_style_merge(resolved, table_style_rule_value(rules.totalRow));
|
|
17749
|
+
if(col == range.s.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.firstTotalCell));
|
|
17750
|
+
if(col == range.e.c) resolved = table_style_merge(resolved, table_style_rule_value(rules.lastTotalCell));
|
|
17751
|
+
resolved = table_style_merge(resolved, table_style_dxf(table, table.totalsRowDxfId));
|
|
17752
|
+
resolved = table_style_merge(resolved, table_style_dxf(table, column && column.totalsRowDxfId));
|
|
17753
|
+
} else {
|
|
17754
|
+
resolved = table_style_merge(resolved, table_style_dxf(table, table.dataDxfId));
|
|
17755
|
+
resolved = table_style_merge(resolved, table_style_dxf(table, column && column.dataDxfId));
|
|
17756
|
+
}
|
|
17757
|
+
}
|
|
17758
|
+
return keys(resolved).length ? resolved : void 0;
|
|
17759
|
+
}
|
|
17393
17760
|
|
|
17394
17761
|
/* [MS-XLSB] 2.4.726 BrtRowHdr */
|
|
17395
17762
|
function parse_BrtRowHdr(data, length) {
|
|
@@ -18812,7 +19179,6 @@ function check_wb(wb) {
|
|
|
18812
19179
|
check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
|
|
18813
19180
|
for(var i = 0; i < wb.SheetNames.length; ++i) {
|
|
18814
19181
|
var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
|
|
18815
|
-
if(!ws) throw new Error("Missing worksheet |" + wb.SheetNames[i] + "|");
|
|
18816
19182
|
check_ws(ws, wb.SheetNames[i], i);
|
|
18817
19183
|
}
|
|
18818
19184
|
wb.SheetNames.forEach(function(n, i) {
|
|
@@ -21241,7 +21607,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|
|
21241
21607
|
};
|
|
21242
21608
|
var finalize_sheet_visuals = function finalizesheetvisuals(ws) {
|
|
21243
21609
|
if(ws["!merges"] && ws["!merges"].length) {
|
|
21244
|
-
var mergeErrors = validate_merges(ws, {WTF: !!(options &&
|
|
21610
|
+
var mergeErrors = validate_merges(ws, {WTF: !!(options && options.validateMerges)});
|
|
21245
21611
|
if(mergeErrors.length) ws["!mergeErrors"] = mergeErrors;
|
|
21246
21612
|
}
|
|
21247
21613
|
if(drawings && (drawings.images.length || drawings.shapes.length || drawings.charts.length || drawings.raw.length)) ws["!drawings"] = drawings;
|
|
@@ -23800,7 +24166,7 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
|
|
23800
24166
|
if(b8) write_biff_rec(ba, 0x023e /* Window2 */, write_Window2((_WB.Views||[])[0]));
|
|
23801
24167
|
/* ... */
|
|
23802
24168
|
if(b8 && (ws['!merges']||[]).length) {
|
|
23803
|
-
validate_merges(ws, {WTF:
|
|
24169
|
+
validate_merges(ws, {WTF: !!(opts && opts.validateMerges)});
|
|
23804
24170
|
write_biff_rec(ba, 0x00e5 /* MergeCells */, write_MergeCells(ws['!merges']));
|
|
23805
24171
|
}
|
|
23806
24172
|
/* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */
|
|
@@ -24189,6 +24555,7 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
|
|
|
24189
24555
|
if(cols[C] && cols[C].s) extend_style_obj(inherited, cols[C].s);
|
|
24190
24556
|
if(row && row.s) extend_style_obj(inherited, row.s);
|
|
24191
24557
|
if(cell && cell.s) extend_style_obj(inherited, cell.s);
|
|
24558
|
+
inherited = resolve_table_cell_style(ws, R, C, inherited) || inherited;
|
|
24192
24559
|
if(keys(inherited).length) {
|
|
24193
24560
|
stylecell = cell ? dup(cell) : {t:'z'};
|
|
24194
24561
|
stylecell.s = inherited;
|
|
@@ -28315,6 +28682,7 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
|
|
|
28315
28682
|
case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
|
|
28316
28683
|
default: throw new Error("Unrecognized sheet type " + stype);
|
|
28317
28684
|
}
|
|
28685
|
+
if(stype == "sheet") parse_sheet_tables(_ws, zip, path, sheetRels[sheet], opts, themes, styles);
|
|
28318
28686
|
sheet_map_set(sheets, sheet, _ws);
|
|
28319
28687
|
|
|
28320
28688
|
/* scan rels for comments and threaded comments */
|
|
@@ -28335,7 +28703,9 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
|
|
|
28335
28703
|
if(tcomments && tcomments.length) sheet_insert_comments(_ws, tcomments, true, opts.people || []);
|
|
28336
28704
|
if(stype == "sheet") parse_sheet_drawing(_ws, stype, zip, path, idx, opts, wb);
|
|
28337
28705
|
parse_sheet_legacy_drawing(_ws, stype, zip, path, idx, opts, wb, comments);
|
|
28338
|
-
} catch(e) {
|
|
28706
|
+
} catch(e) {
|
|
28707
|
+
if(opts.WTF || (opts.validateMerges && e && /^E_MERGE_/.test(e.code))) throw e;
|
|
28708
|
+
}
|
|
28339
28709
|
}
|
|
28340
28710
|
|
|
28341
28711
|
function strip_front_slash(x/*:string*/)/*:string*/ { return x.charAt(0) == '/' ? x.slice(1) : x; }
|
|
@@ -29647,6 +30017,7 @@ var utils/*:any*/ = {
|
|
|
29647
30017
|
measure_text_width: measure_text_width,
|
|
29648
30018
|
auto_fit_columns: auto_fit_columns,
|
|
29649
30019
|
autofit_columns: auto_fit_columns,
|
|
30020
|
+
resolve_table_cell_style: resolve_table_cell_style,
|
|
29650
30021
|
col_width_to_px: width2px,
|
|
29651
30022
|
px_to_col_width: function(px) { return char2width(px2char(px)); },
|
|
29652
30023
|
row_height_to_px: pt2px_browser,
|