NaN and Infinity error export

- `read` handle `Int8Array` (to support Java engines)
- `sheet_to_formulae` option to suppress values
- handle unexpected `<charset/>` (fixes #3143 h/t @dearzubi)
This commit is contained in:
SheetJS 2024-07-04 15:54:34 -04:00
parent 5ef49e2b96
commit 5a36cb423d
51 changed files with 2632 additions and 538 deletions

@ -4,6 +4,13 @@ This log is intended to keep track of backwards-incompatible changes, including
but not limited to API changes and file location changes. Minor behavioral
changes may not be included if they are not expected to break existing code.
## v0.20.3
* More precise treatment of infinite and NaN values
* XLML Streaming Write
* Parse `Int8Array` objects (for compatibility with JS engines in Java)
* CSV Export only quote leading ID (h/t @lako12)
## v0.20.2
* Reworked parsing methods to avoid slow regexes (CVE-2024-22363)

@ -152,8 +152,8 @@ test.ts: test.mts
node -pe 'var data = fs.readFileSync("'$<'", "utf8"); data.split("\n").map(function(l) { return l.replace(/^describe\((.*?)function\(\)/, "Deno.test($$1async function(t)").replace(/\b(?:it|describe)\((.*?)function\(\)/g, "await t.step($$1async function(t)").replace("assert.ok", "assert.assert"); }).join("\n")' > $@
.PHONY: test-bun
test-bun: testbun.mjs ## Run Bun test suite
bun $<
test-bun: test.test.mjs ## Run Bun test suite
bun test $<
.PHONY: test-deno
test-deno: test.ts ## Run Deno test suite

@ -1 +1 @@
XLSX.version = '0.20.2';
XLSX.version = '0.20.2strm';

@ -243,7 +243,7 @@ function SSF_large_exp(v/*:number*/)/*:string*/ {
}
function SSF_general_num(v/*:number*/)/*:string*/ {
if(!isFinite(v)) return isNaN(v) ? "#VALUE!" : "#DIV/0!";
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -979,7 +979,7 @@ function SSF_format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#VALUE!";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}

@ -42,7 +42,9 @@ type CFBFiles = {[n:string]:CFBEntry};
var CRC32 = /*#__PURE__*/(function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*::
type CRC32TableType = Array<number> | Int32Array;
*/
/*global Int32Array */
function signed_crc_table()/*:any*/ {
var c = 0, table/*:Array<number>*/ = new Array(256);
@ -80,7 +82,7 @@ var TT = slice_by_16_tables(T0);
var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ {
function crc32_bstr(bstr/*:string*/, seed/*:?number*/)/*:number*/ {
var C = seed/*:: ? 0 : 0 */ ^ -1;
for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
return ~C;
@ -1446,8 +1448,8 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -1458,7 +1460,7 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -1493,9 +1495,10 @@ function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);

@ -67,6 +67,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);

@ -32,6 +32,26 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*
}
return z;
}
function parsexmltagraw(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
var z = ({}/*:any*/);
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x/*:string*/)/*:string*/ { return x.replace(nsregex2, "<$1"); }
var encodings = {

@ -20,7 +20,8 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
/* control buffer usage for fixed-length buffers */
function buf_array()/*:BufArray*/ {
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
var o/*:Block*/ = (new_buf(sz)/*:any*/);
prep_blob(o, 0);
@ -49,10 +50,15 @@ function buf_array()/*:BufArray*/ {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 }/*:any*/);
}
function write_record(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/) {

@ -119,7 +119,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
var ws/*:Worksheet*/ = _ws || (dense ? ({"!data": []}) : ({}/*:any*/));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -144,23 +144,24 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data_R[C], t:"" }/*:any*/);
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
@ -185,7 +186,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr/*:any*/;
var cell_ref = encode_col(__C) + (__R + 1)/*:any*/;
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}

@ -593,7 +593,7 @@ var SYLK = /*#__PURE__*/(function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -822,7 +822,7 @@ var ETH = /*#__PURE__*/(function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -865,11 +865,7 @@ var ETH = /*#__PURE__*/(function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -879,6 +875,19 @@ var ETH = /*#__PURE__*/(function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -910,6 +919,7 @@ var PRN = /*#__PURE__*/(function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -1027,6 +1037,8 @@ var PRN = /*#__PURE__*/(function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;

@ -598,7 +598,6 @@ var WK_ = /*#__PURE__*/(function() {
else console.error("WK1 bad formula parse |" + out.join("|") + "|");
}
function parse_cell_3(blob/*::, length*/) {
var o = [{c:0,r:0}, {t:'n',v:0}, 0];
o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];

@ -49,6 +49,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;

@ -220,6 +220,7 @@ function parse_fonts(t, styles, themes, opts) {
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': break;
/* 18.?.? color CT_Color */
case '<color':

@ -62,7 +62,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
var merges/*:Array<Range>*/ = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -521,16 +521,17 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*//*::, rels*/)/*:string*/ {
var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}

@ -847,12 +847,15 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
if(last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));
else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
} else if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else if(!isFinite(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
o.t = "e";
if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
}
} else {
if(last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));
else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
@ -874,23 +877,24 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
}
function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols/*:Array<string>*/ = [];
var range = safe_decode_range(ws['!ref'] || "A1"), rr = "", cols/*:Array<string>*/ = [];
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
write_record(ba, 0x0091 /* BrtBeginSheetData */);
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, row = dense ? ws["!data"][range.s.r] : [];
var cap = range.e.r;
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
for(var R = range.s.r; R <= cap; ++R) {
rr = encode_row(R);
if(dense) row = ws["!data"][R];
/* [ACCELLTABLE] */
/* BrtRowHdr */
write_row_header(ba, ws, range, R);
if(dense && !row) continue;
var last_seen = false;
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) { last_seen = false; continue; }
/* write cell */
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904);

@ -1144,7 +1144,13 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
var t = "", p = "";
switch(cell.t) {
case 'z': if(!opts.sheetStubs) return ""; break;
case 'n': t = 'Number'; p = String(cell.v); break;
case 'n': {
if(!isFinite(cell.v)) {
t = 'Error'; p = BErr[isNaN(cell.v) ? 0x24 : 0x07];
} else {
t = 'Number'; p = String(cell.v);
}
} break;
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
case 'e': t = 'Error'; p = BErr[cell.v]; break;
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || table_fmt[14]; break;

@ -48,6 +48,8 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -75,6 +77,10 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({}/*:any*/);
@ -185,6 +191,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -193,7 +200,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.

@ -247,7 +247,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
var Sheets = {}, SheetNames/*:Array<string>*/ = [];
var ws = ({}/*:any*/); if(opts.dense) ws["!data"] = [];
var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
var ctag = ({value:""}/*:any*/);
var ctag = ({value:""}/*:any*/), ctag2 = ({}/*:any*/);
var textp = "", textpidx = 0, textptag/*:: = {}*/, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
@ -341,6 +341,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({}/*:any*/);
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -394,6 +395,9 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;

@ -262,9 +262,22 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;

@ -75,6 +75,8 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), o);
if(typeof Uint8Array !== 'undefined' && data instanceof Uint8Array && !o.type) o.type = typeof Deno !== "undefined" ? "buffer" : "array";
var d = data, n = [0,0,0,0], str = false;
if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }

@ -159,7 +159,7 @@ function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
function sheet_to_formulae(sheet/*:Worksheet*/, opts/*:?Sheet2FormulaOpts*/)/*:Array<string>*/ {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols/*:Array<string>*/ = [], C;
@ -180,6 +180,7 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";

@ -119,6 +119,7 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
var stream = _Readable();
var opts = o == null ? {} : o;
var stride = +opts.stride || 10;
if(!wb.SSF) wb.SSF = dup(table_fmt);
if(wb.SSF) {
make_ssf(); SSF_load_table(wb.SSF);
@ -205,7 +206,7 @@ function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
/* worksheet intramble */
case 4: {
if(R < 0 || R > range.e.r) { stream.push(T ? "</Table>" : ""); return void (stage = 5); }
if(R < 0 || R > range.e.r) { if(T) stream.push("</Table>"); return void (stage = 5); }
if(R <= range.s.r) {
if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
@ -223,8 +224,8 @@ function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
addr.r = addr.c = 0;
}
/* process 10 rows per invocation */
for(var cnt = 0; R <= range.e.r && cnt < 10; ++R, ++cnt) {
/* process `stride` rows per invocation */
for(var cnt = 0; R <= range.e.r && cnt < stride; ++R, ++cnt) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
if(!(dense && !darr[R])) for(var C = range.s.c; C <= range.e.c; ++C) {
@ -243,10 +244,8 @@ function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
row.push(write_ws_xlml_cell(cell, ref, ws, opts, wsidx, wb, addr));
}
row.push("</Row>");
if(row.length > 2) {
if(!T) { T = true; stream.push("<Table>"); }
stream.push(row.join(""));
}
if(!T) { T = true; stream.push("<Table>"); }
stream.push(row.join(""));
}
} break;

33
dist/xlsx.core.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.core.min.map generated vendored

File diff suppressed because one or more lines are too long

375
dist/xlsx.extendscript.js generated vendored

@ -160,7 +160,7 @@ var DO_NOT_EXPORT_CODEPAGE = true;
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
var XLSX = {};
function make_xlsx_lib(XLSX){
XLSX.version = '0.20.2';
XLSX.version = '0.20.2strm';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true, window */
var $cptable;
@ -695,6 +695,7 @@ function SSF_large_exp(v) {
}
function SSF_general_num(v) {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -1388,6 +1389,8 @@ function choose_fmt(f, v) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -1424,6 +1427,8 @@ function SSF_format(fmt,v,o) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt, idx) {
@ -1547,7 +1552,6 @@ function SSF__load(fmt, idx) {
var CRC32 = (function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*global Int32Array */
function signed_crc_table() {
var c = 0, table = new Array(256);
@ -2946,8 +2950,8 @@ function parse_local_file(blob, csz, usz, o, EF) {
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -2958,7 +2962,7 @@ function parse_local_file(blob, csz, usz, o, EF) {
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -2993,9 +2997,10 @@ function write_zip(cfb, options) {
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
@ -3888,6 +3893,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
@ -3958,6 +3966,26 @@ function parsexmltag(tag, skip_root, skip_LC) {
}
return z;
}
function parsexmltagraw(tag, skip_root, skip_LC) {
var z = ({});
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x) { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -4464,7 +4492,8 @@ function recordhopper(data, cb, opts) {
/* control buffer usage for fixed-length buffers */
function buf_array() {
var bufs = [], blksz = has_buf ? 256 : 2048;
var bufs = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz) {
var o = (new_buf(sz));
prep_blob(o, 0);
@ -4493,10 +4522,15 @@ function buf_array() {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs });
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 });
}
function write_record(ba, type, payload, length) {
@ -4683,7 +4717,7 @@ function sheet_add_aoa(_ws, data, opts) {
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws = _ws || ({});
var ws = _ws || (dense ? ({"!data": []}) : ({}));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -4708,31 +4742,35 @@ function sheet_add_aoa(_ws, data, opts) {
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell = ({v: data[R][C] });
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell = ({v: data_R[C], t:"" });
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -4746,7 +4784,7 @@ function sheet_add_aoa(_ws, data, opts) {
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr;
var cell_ref = encode_col(__C) + (__R + 1);
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -4756,7 +4794,6 @@ function sheet_add_aoa(_ws, data, opts) {
return ws;
}
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
function parse_Int32LE(data) {
return data.read_shift(4, 'i');
}
@ -6338,8 +6375,8 @@ function parse_TypedPropertyValue(blob, type, _opts) {
case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
@ -8631,7 +8668,7 @@ var SYLK = (function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -8860,7 +8897,7 @@ var ETH = (function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -8903,11 +8940,7 @@ var ETH = (function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -8917,6 +8950,19 @@ var ETH = (function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -8948,6 +8994,7 @@ var PRN = (function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -9065,6 +9112,8 @@ var PRN = (function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -9764,7 +9813,6 @@ var WK_ = (function() {
else console.error("WK1 bad formula parse |" + out.join("|") + "|");
}
function parse_cell_3(blob) {
var o = [{c:0,r:0}, {t:'n',v:0}, 0];
o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];
@ -10999,6 +11047,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;
@ -11391,6 +11443,7 @@ function parse_fonts(t, styles, themes, opts) {
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': break;
/* 18.?.? color CT_Color */
case '<color':
@ -15920,7 +15973,7 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
var merges = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -16379,16 +16432,17 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles, wb) {
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}), row, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}