Compare commits
No commits in common. "master" and "master" have entirely different histories.
@ -4,8 +4,8 @@ The SheetJS Libraries should be free and clear to use in your projects. In
|
||||
order to maintain that, every contributor must be vigilant.
|
||||
|
||||
There have been many projects in the past that have been very lax regarding
|
||||
licensing. We are of the opinion that those are ticking timebombs and that no
|
||||
commercial product should depend on them.
|
||||
licensing, and we are of the opinion that those are ticking timebombs and that
|
||||
no commercial product should depend on them.
|
||||
|
||||
|
||||
# Required Reading
|
||||
@ -30,9 +30,10 @@ inbox is self-hosted.
|
||||
|
||||
# Opening Pull Requests
|
||||
|
||||
[Squash commits](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History)
|
||||
before opening a pull request, If the pull request addresses documentation or
|
||||
demos, add `[ci skip]` in the body or title of the commit message to skip tests.
|
||||
Before opening a pull request, [squash all commits into
|
||||
one](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History). If the pull
|
||||
request addresses documentation or demos, add `[ci skip]` in the body or title
|
||||
of your commit message to skip Travis checks.
|
||||
|
||||
# Pre-Contribution Checklist
|
||||
|
||||
@ -56,8 +57,8 @@ issue. If it is a particularly high-priority issue, please drop an email to
|
||||
Keep these in mind as you work:
|
||||
|
||||
- Your contributions are your original work. Take note of any resources you
|
||||
consult in the process. Be extra careful not to use unlicensed code on the
|
||||
Internet or code generated by a large language model or other AI tool.
|
||||
consult in the process (and be extra careful not to use unlicensed code on
|
||||
the internet.
|
||||
|
||||
- You are working on your own time. Unless they explicitly grant permission,
|
||||
your employer may be the ultimate owner of your IP
|
||||
|
@ -243,7 +243,6 @@ function SSF_large_exp(v/*:number*/)/*:string*/ {
|
||||
}
|
||||
|
||||
function SSF_general_num(v/*:number*/)/*:string*/ {
|
||||
if(!isFinite(v)) return isNaN(v) ? "#VALUE!" : "#DIV/0!";
|
||||
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
|
||||
|
||||
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
|
||||
@ -941,8 +940,6 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
|
||||
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;
|
||||
@ -979,8 +976,6 @@ 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(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
|
||||
return eval_fmt(f[1], v, o, f[0]);
|
||||
}
|
||||
function SSF_load(fmt/*:string*/, idx/*:?number*/)/*:number*/ {
|
||||
|
@ -145,6 +145,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
|
||||
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);
|
||||
if(dense) {
|
||||
if(!ws["!data"][__R]) ws["!data"][__R] = [];
|
||||
row = ws["!data"][__R];
|
||||
@ -167,11 +168,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
|
||||
else if(!o.sheetStubs) continue;
|
||||
else cell.t = 'z';
|
||||
}
|
||||
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; /*# DIV/0 */ }
|
||||
}
|
||||
else if(typeof cell.v === 'number') cell.t = 'n';
|
||||
else if(typeof cell.v === 'boolean') cell.t = 'b';
|
||||
else if(cell.v instanceof Date) {
|
||||
cell.z = o.dateNF || table_fmt[14];
|
||||
@ -195,3 +192,4 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
|
||||
return ws;
|
||||
}
|
||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
||||
|
||||
|
@ -123,8 +123,8 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
|
||||
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*/: 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 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
|
||||
case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
|
||||
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
|
||||
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
|
||||
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
|
||||
|
@ -1186,12 +1186,9 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
|
||||
o.push(writextag("Column",null,k));
|
||||
});
|
||||
var dense = ws["!data"] != null;
|
||||
var addr = {r:0,c:0};
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
|
||||
addr.r = R;
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
addr.c = C;
|
||||
var skip = false;
|
||||
for(mi = 0; mi != marr.length; ++mi) {
|
||||
if(marr[mi].s.c > C) continue;
|
||||
@ -1202,6 +1199,7 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
|
||||
break;
|
||||
}
|
||||
if(skip) continue;
|
||||
var addr = {r:R,c:C};
|
||||
var ref = encode_col(C) + encode_row(R), cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
|
||||
row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
|
||||
}
|
||||
@ -1225,7 +1223,7 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
|
||||
/* WorksheetOptions */
|
||||
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
|
||||
|
||||
if(ws && ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
|
||||
if(ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
|
||||
|
||||
return o.join("");
|
||||
}
|
||||
@ -1244,10 +1242,11 @@ function write_xlml(wb, opts)/*:string*/ {
|
||||
d.push(write_props_xlml(wb, opts));
|
||||
d.push(write_wb_xlml(wb, opts));
|
||||
d.push("");
|
||||
d.push(write_names_xlml(wb, opts));
|
||||
d.push("");
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i)
|
||||
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
|
||||
d[2] = write_sty_xlml(wb, opts);
|
||||
d[3] = write_names_xlml(wb, opts);
|
||||
return XML_HEADER + writextag("Workbook", d.join(""), {
|
||||
'xmlns': XLMLNS.ss,
|
||||
'xmlns:o': XLMLNS.o,
|
||||
|
@ -105,7 +105,7 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts,
|
||||
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.r, 0x3FFF);
|
||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||
}
|
||||
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
||||
var row = [], comments = [];
|
||||
@ -515,9 +515,9 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
var range = safe_decode_range(ws['!ref'] || "A1");
|
||||
var MAX_ROWS = b8 ? 65536 : 16384;
|
||||
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV" + MAX_ROWS);
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.r, MAX_ROWS-1);
|
||||
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
|
||||
}
|
||||
|
||||
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
|
||||
@ -552,11 +552,12 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
if(dense) row = ws["!data"][R] || [];
|
||||
rr = encode_row(R);
|
||||
for(C = range.s.c; C <= range.e.c; ++C) {
|
||||
var cell = dense ? row[C] : ws[cols[C] + rr];
|
||||
ref = cols[C] + rr;
|
||||
var cell = dense ? row[C] : ws[ref];
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff8_cell(ba, cell, R, C, opts, date1904);
|
||||
if(b8 && cell.l) ws['!links'].push([cols[C] + rr, cell.l]);
|
||||
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
|
||||
if(cell.c) comments.push([cell.c, R, C]);
|
||||
}
|
||||
}
|
||||
@ -700,9 +701,6 @@ function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
if(range.e.c > 255) { // note: 255 is IV
|
||||
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255). Data may be lost.");
|
||||
}
|
||||
if(range.e.r > 65535) {
|
||||
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond row 65536. Data may be lost.");
|
||||
}
|
||||
}
|
||||
|
||||
var o = opts || {};
|
||||
|
@ -104,7 +104,7 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) {
|
||||
}
|
||||
|
||||
var qreg = /"/g;
|
||||
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, w/*:number*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
|
||||
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
|
||||
var isempty = true;
|
||||
var row/*:Array<string>*/ = [], txt = "", rr = encode_row(R);
|
||||
var dense = sheet["!data"] != null;
|
||||
@ -117,7 +117,7 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr
|
||||
isempty = false;
|
||||
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
|
||||
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
|
||||
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
|
||||
if(txt == "ID") txt = '"ID"';
|
||||
} else if(val.f != null && !val.F) {
|
||||
isempty = false;
|
||||
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
|
||||
@ -144,7 +144,7 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
|
||||
var w = 0;
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
if ((rowinfo[R]||{}).hidden) continue;
|
||||
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
|
||||
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
|
||||
if(row == null) { continue; }
|
||||
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
|
||||
}
|
||||
|
158
bits/97_node.js
158
bits/97_node.js
@ -19,7 +19,7 @@ function write_csv_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
|
||||
while(R <= r.e.r) {
|
||||
++R;
|
||||
if ((rowinfo[R-1]||{}).hidden) continue;
|
||||
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, w, o);
|
||||
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
|
||||
if(row != null) {
|
||||
if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
|
||||
}
|
||||
@ -116,165 +116,9 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
|
||||
var stream = _Readable();
|
||||
var opts = o == null ? {} : o;
|
||||
if(!wb.SSF) wb.SSF = dup(table_fmt);
|
||||
if(wb.SSF) {
|
||||
make_ssf(); SSF_load_table(wb.SSF);
|
||||
// $FlowIgnore
|
||||
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
|
||||
opts.ssf = wb.SSF;
|
||||
opts.cellXfs = [];
|
||||
get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
|
||||
}
|
||||
|
||||
/* do one pass to determine styles since they must be added before tables */
|
||||
wb.SheetNames.forEach(function(n) {
|
||||
var ws = wb.Sheets[n];
|
||||
if(!ws || !ws["!ref"]) return;
|
||||
var range = decode_range(ws["!ref"]);
|
||||
var dense = ws["!data"] != null;
|
||||
var ddata = dense ? ws["!data"] : [];
|
||||
var addr = {r:0,c:0};
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
addr.r = R;
|
||||
if(dense && !ddata[R]) continue;
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
addr.c = C;
|
||||
var cell = dense ? ddata[R][C] : ws[encode_col(C) + encode_row(R)];
|
||||
if(!cell) continue;
|
||||
if(cell.t == "d" && cell.z == null) { cell = dup(cell); cell.z = table_fmt[14]; }
|
||||
void get_cell_style(opts.cellXfs, cell, opts);
|
||||
}
|
||||
}
|
||||
});
|
||||
var sty = write_sty_xlml(wb, opts);
|
||||
|
||||
var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
|
||||
|
||||
var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
|
||||
|
||||
stream._read = function() { switch(stage) {
|
||||
/* header */
|
||||
case 0: {
|
||||
stage = 1;
|
||||
stream.push(XML_HEADER);
|
||||
stream.push("<Workbook" + wxt_helper({
|
||||
'xmlns': XLMLNS.ss,
|
||||
'xmlns:o': XLMLNS.o,
|
||||
'xmlns:x': XLMLNS.x,
|
||||
'xmlns:ss': XLMLNS.ss,
|
||||
'xmlns:dt': XLMLNS.dt,
|
||||
'xmlns:html': XLMLNS.html
|
||||
}) + ">");
|
||||
} break;
|
||||
|
||||
/* preamble */
|
||||
case 1: {
|
||||
stage = 2;
|
||||
stream.push(write_props_xlml(wb, opts));
|
||||
stream.push(write_wb_xlml(wb, opts));
|
||||
} break;
|
||||
|
||||
/* style and name tables */
|
||||
case 2: {
|
||||
stage = 3;
|
||||
stream.push(sty);
|
||||
stream.push(write_names_xlml(wb, opts));
|
||||
} break;
|
||||
|
||||
/* worksheet preamble */
|
||||
case 3: {
|
||||
T = false;
|
||||
if(wsidx >= wb.SheetNames.length) { stage = -1; stream.push(""); break; }
|
||||
|
||||
stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
|
||||
|
||||
ws = wb.Sheets[wb.SheetNames[wsidx]];
|
||||
if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
|
||||
|
||||
var names = write_ws_xlml_names(ws, opts, wsidx, wb);
|
||||
if(names.length) stream.push("<Names>" + names + "</Names>");
|
||||
|
||||
if(!ws["!ref"]) return (stage = 5);
|
||||
range = safe_decode_range(ws["!ref"]);
|
||||
R = range.s.r;
|
||||
stage = 4;
|
||||
} break;
|
||||
|
||||
/* worksheet intramble */
|
||||
case 4: {
|
||||
if(R < 0 || R > range.e.r) { stream.push(T ? "</Table>" : ""); return void (stage = 5); }
|
||||
|
||||
if(R <= range.s.r) {
|
||||
if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
|
||||
process_col(n);
|
||||
var w = !!n.width;
|
||||
var p = col_obj_w(i, n);
|
||||
var k/*:any*/ = {"ss:Index":i+1};
|
||||
if(w) k['ss:Width'] = width2px(p.width);
|
||||
if(n.hidden) k['ss:Hidden']="1";
|
||||
if(!T) { T = true; stream.push("<Table>"); }
|
||||
stream.push(writextag("Column",null,k));
|
||||
});
|
||||
dense = ws["!data"] != null;
|
||||
if(dense) darr = ws["!data"];
|
||||
addr.r = addr.c = 0;
|
||||
}
|
||||
|
||||
/* process 10 rows per invocation */
|
||||
for(var cnt = 0; R <= range.e.r && cnt < 10; ++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) {
|
||||
addr.c = C;
|
||||
var skip = false;
|
||||
for(mi = 0; mi != marr.length; ++mi) {
|
||||
if(marr[mi].s.c > C) continue;
|
||||
if(marr[mi].s.r > R) continue;
|
||||
if(marr[mi].e.c < C) continue;
|
||||
if(marr[mi].e.r < R) continue;
|
||||
if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
|
||||
break;
|
||||
}
|
||||
if(skip) continue;
|
||||
var ref = encode_col(C) + encode_row(R), cell = dense ? darr[R][C] : ws[ref];
|
||||
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(""));
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
/* worksheet postamble */
|
||||
case 5: {
|
||||
stream.push(write_ws_xlml_wsopts(ws, opts, wsidx, wb));
|
||||
if(ws && ws["!autofilter"]) stream.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
|
||||
stream.push("</Worksheet>");
|
||||
wsidx++; R = -1;
|
||||
return void (stage = 3);
|
||||
}
|
||||
|
||||
/* footer */
|
||||
case -1: {
|
||||
stage = -2;
|
||||
stream.push("</Workbook>");
|
||||
} break;
|
||||
|
||||
/* exeunt */
|
||||
case -2: stream.push(null); break;
|
||||
}};
|
||||
return stream;
|
||||
}
|
||||
|
||||
var __stream = {
|
||||
to_json: write_json_stream,
|
||||
to_html: write_html_stream,
|
||||
to_csv: write_csv_stream,
|
||||
to_xlml: write_xlml_stream,
|
||||
set_readable: set_readable
|
||||
};
|
||||
|
@ -5,6 +5,6 @@ function pad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v;return t.length>=d?t
|
||||
function rpad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:t+fill(' ',d-t.length);}
|
||||
function pad0r1(v/*:any*/,d/*:number*/)/*:string*/{var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
var p2_32 = /*#__PURE__*/Math.pow(2,32);
|
||||
var p2_32 = Math.pow(2,32);
|
||||
function pad0r(v/*:any*/,d/*:number*/)/*:string*/{if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); }
|
||||
function isgeneral(s/*:string*/, i/*:?number*/)/*:boolean*/ { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }
|
||||
|
@ -1,5 +1,4 @@
|
||||
function init_table(t/*:any*/) {
|
||||
if(!t) t = {};
|
||||
t[0]= 'General';
|
||||
t[1]= '0';
|
||||
t[2]= '0.00';
|
||||
@ -29,7 +28,6 @@ function init_table(t/*:any*/) {
|
||||
t[48]= '##0.0E+0';
|
||||
t[49]= '@';
|
||||
t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
|
||||
return t;
|
||||
}
|
||||
|
||||
var table_fmt = {};
|
||||
|
@ -29,7 +29,6 @@ var general_fmt_num = (function make_general_fmt_num() {
|
||||
}
|
||||
|
||||
function general_fmt_num_base(v/*:number*/)/*:string*/ {
|
||||
if(!isFinite(v)) return isNaN(v) ? "#VALUE!" : "#DIV/0!";
|
||||
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
|
||||
|
||||
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
|
||||
|
@ -39,7 +39,7 @@ function write_num_f2(r/*:Array<string>*/, aval/*:number*/, sign/*:string*/)/*:s
|
||||
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
|
||||
}
|
||||
var dec1 = /^#*0*\.([0#]+)/;
|
||||
var closeparen = /\)[^)]*[0#]/;
|
||||
var closeparen = /\).*[0#]/;
|
||||
var phone = /\(###\) ###\\?-####/;
|
||||
function hashq(str/*:string*/)/*:string*/ {
|
||||
var o = "", cc;
|
||||
|
@ -4,8 +4,6 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
|
||||
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;
|
||||
@ -42,7 +40,5 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
|
||||
if(isgeneral(f[1])) return general_fmt(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(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
|
||||
return eval_fmt(f[1], v, o, f[0]);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
"dtslint": "^0.1.2",
|
||||
"mocha": "~2.5.3",
|
||||
"typescript": "2.2.0",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -12,7 +12,7 @@ function pad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v;return t.length>=d?t
|
||||
function rpad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:t+fill(' ',d-t.length);}
|
||||
function pad0r1(v/*:any*/,d/*:number*/)/*:string*/{var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
var p2_32 = /*#__PURE__*/Math.pow(2,32);
|
||||
var p2_32 = Math.pow(2,32);
|
||||
function pad0r(v/*:any*/,d/*:number*/)/*:string*/{if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); }
|
||||
function isgeneral(s/*:string*/, i/*:?number*/)/*:boolean*/ { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }
|
||||
/*::
|
||||
@ -42,7 +42,6 @@ var months/*:Array<Array<string> >*/ = [
|
||||
['D', 'Dec', 'December']
|
||||
];
|
||||
function init_table(t/*:any*/) {
|
||||
if(!t) t = {};
|
||||
t[0]= 'General';
|
||||
t[1]= '0';
|
||||
t[2]= '0.00';
|
||||
@ -72,7 +71,6 @@ function init_table(t/*:any*/) {
|
||||
t[48]= '##0.0E+0';
|
||||
t[49]= '@';
|
||||
t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
|
||||
return t;
|
||||
}
|
||||
|
||||
var table_fmt = {};
|
||||
@ -254,7 +252,6 @@ var general_fmt_num = (function make_general_fmt_num() {
|
||||
}
|
||||
|
||||
function general_fmt_num_base(v/*:number*/)/*:string*/ {
|
||||
if(!isFinite(v)) return isNaN(v) ? "#VALUE!" : "#DIV/0!";
|
||||
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
|
||||
|
||||
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
|
||||
@ -420,7 +417,7 @@ function write_num_f2(r/*:Array<string>*/, aval/*:number*/, sign/*:string*/)/*:s
|
||||
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
|
||||
}
|
||||
var dec1 = /^#*0*\.([0#]+)/;
|
||||
var closeparen = /\)[^)]*[0#]/;
|
||||
var closeparen = /\).*[0#]/;
|
||||
var phone = /\(###\) ###\\?-####/;
|
||||
function hashq(str/*:string*/)/*:string*/ {
|
||||
var o = "", cc;
|
||||
@ -954,8 +951,6 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
|
||||
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;
|
||||
@ -992,8 +987,6 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
|
||||
if(isgeneral(f[1])) return general_fmt(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(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
|
||||
return eval_fmt(f[1], v, o, f[0]);
|
||||
}
|
||||
function load_entry(fmt/*:string*/, idx/*:?number*/)/*:number*/ {
|
||||
|
@ -38,7 +38,6 @@ var months = [
|
||||
['D', 'Dec', 'December']
|
||||
];
|
||||
function init_table(t) {
|
||||
if(!t) t = {};
|
||||
t[0]= 'General';
|
||||
t[1]= '0';
|
||||
t[2]= '0.00';
|
||||
@ -68,7 +67,6 @@ function init_table(t) {
|
||||
t[48]= '##0.0E+0';
|
||||
t[49]= '@';
|
||||
t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
|
||||
return t;
|
||||
}
|
||||
|
||||
var table_fmt = {};
|
||||
@ -250,7 +248,6 @@ var general_fmt_num = (function make_general_fmt_num() {
|
||||
}
|
||||
|
||||
function general_fmt_num_base(v) {
|
||||
if(!isFinite(v)) return isNaN(v) ? "#VALUE!" : "#DIV/0!";
|
||||
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
|
||||
|
||||
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
|
||||
@ -415,7 +412,7 @@ function write_num_f2(r, aval, sign) {
|
||||
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
|
||||
}
|
||||
var dec1 = /^#*0*\.([0#]+)/;
|
||||
var closeparen = /\)[^)]*[0#]/;
|
||||
var closeparen = /\).*[0#]/;
|
||||
var phone = /\(###\) ###\\?-####/;
|
||||
function hashq(str) {
|
||||
var o = "", cc;
|
||||
@ -946,8 +943,6 @@ 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;
|
||||
@ -984,8 +979,6 @@ function format(fmt,v,o) {
|
||||
if(isgeneral(f[1])) return general_fmt(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(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
|
||||
return eval_fmt(f[1], v, o, f[0]);
|
||||
}
|
||||
function load_entry(fmt, idx) {
|
||||
|
@ -19,14 +19,4 @@ describe('oddities', function() {
|
||||
var chk = function(fmt){ return function(){ SSF.format(fmt,0); }; };
|
||||
bad.forEach(function(fmt){assert.throws(chk(fmt));});
|
||||
});
|
||||
it('should handle NaN values and infinities', function() {
|
||||
assert.equal(SSF.format('#,##0.0; (#,##0.0); "-"', NaN), " -");
|
||||
assert.equal(SSF.format('#,##0.0; (#,##0.0); "-"', Infinity), " -");
|
||||
assert.equal(SSF.format('#,##0.0; (#,##0.0); "-"', -Infinity), " -");
|
||||
["0.00", "General"].forEach(function(fmt) {
|
||||
assert.equal(SSF.format(fmt, NaN), "#VALUE!");
|
||||
assert.equal(SSF.format(fmt, Infinity), "#DIV/0!");
|
||||
assert.equal(SSF.format(fmt, -Infinity), "#DIV/0!");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
8
types/index.d.ts
vendored
8
types/index.d.ts
vendored
@ -24,12 +24,12 @@ export function readFile(filename: string, opts?: ParsingOptions): WorkBook;
|
||||
/** Attempts to parse data */
|
||||
export function read(data: any, opts?: ParsingOptions): WorkBook;
|
||||
/** Attempts to write or download workbook data to file */
|
||||
export function writeFile(data: WorkBook, filename: string, opts?: WritingOptions): void;
|
||||
export function writeFile(data: WorkBook, filename: string, opts?: WritingOptions): any;
|
||||
/** Attempts to write or download workbook data to XLSX file */
|
||||
export function writeFileXLSX(data: WorkBook, filename: string, opts?: WritingOptions): void;
|
||||
export function writeFileXLSX(data: WorkBook, filename: string, opts?: WritingOptions): any;
|
||||
/** Attempts to write or download workbook data to file asynchronously */
|
||||
type CBFunc = () => void;
|
||||
export function writeFileAsync(filename: string, data: WorkBook, opts: WritingOptions | CBFunc, cb?: CBFunc): void;
|
||||
export function writeFileAsync(filename: string, data: WorkBook, opts: WritingOptions | CBFunc, cb?: CBFunc): any;
|
||||
/** Attempts to write the workbook data */
|
||||
export function write(data: WorkBook, opts: WritingOptions): any;
|
||||
/** Attempts to write the workbook data as XLSX */
|
||||
@ -277,7 +277,7 @@ export interface WritingOptions extends CommonOptions {
|
||||
*/
|
||||
compression?: boolean;
|
||||
|
||||
/** Override theme XML when exporting to XLSX/XLSM/XLSB */
|
||||
/** Overwride theme XML when exporting to XLSX/XLSM/XLSB */
|
||||
themeXLSX?: string;
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user