updating to 0.16.4

This commit is contained in:
SheetJS 2020-07-18 22:07:06 -04:00
parent bd30f3bf9c
commit 9e4abfa5aa
6 changed files with 400 additions and 148 deletions

View File

@ -17,6 +17,7 @@ Note: since JSZip 3 removed critical functionality, this version assigns to the
else if("function"==typeof define&&define.amd&&"undefined"==typeof DO_NOT_EXPORT_JSZIP){JSZipSync=e();define([],e);}
else{
var f;
"undefined"!=typeof globalThis?f=globalThis:
"undefined"!=typeof window?f=window:
"undefined"!=typeof global?f=global:
"undefined"!=typeof $ && $.global?f=$.global:

View File

@ -716,7 +716,7 @@ describe('output formats', function() {
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([['R',"\u2603"],["\u0BEE",2]]), "Sheet1");
if(T == 'string' && !fmt[2]) return assert.throws(function() {X.write(wb, {type: T, bookType:fmt[0], WTF:1});});
var out = X.write(wb, {type: T, bookType:fmt[0], WTF:1});
var nwb = X.read(out, {type: T, WTF:1});
var nwb = X.read(out, {type: T, PRN: fmt[0] == 'prn', WTF:1});
var nws = nwb.Sheets[nwb.SheetNames[0]];
assert.equal(get_cell(nws, "B2").v, 2);
assert.equal(get_cell(nws, "A1").v, "R");
@ -768,6 +768,19 @@ describe('API', function() {
]);
if(assert.deepEqual) assert.deepEqual(data.A2, { l: { Target: 'https://123.com' }, v: 'url', t: 's' });
});
it('decode_range', function() {
var _c = "ABC", _r = "123", _C = "DEF", _R = "456";
var r = X.utils.decode_range(_c + _r + ":" + _C + _R);
assert(r.s != r.e);
assert.equal(r.s.c, X.utils.decode_col(_c)); assert.equal(r.s.r, X.utils.decode_row(_r));
assert.equal(r.e.c, X.utils.decode_col(_C)); assert.equal(r.e.r, X.utils.decode_row(_R));
r = X.utils.decode_range(_c + _r);
assert(r.s != r.e);
assert.equal(r.s.c, X.utils.decode_col(_c)); assert.equal(r.s.r, X.utils.decode_row(_r));
assert.equal(r.e.c, X.utils.decode_col(_c)); assert.equal(r.e.r, X.utils.decode_row(_r));
});
});
function coreprop(props) {
@ -1422,13 +1435,14 @@ function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
}
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
var epoch = v.getTime();
if(date1904) epoch += 1462*24*60*60*1000;
if(date1904) epoch -= 1462*24*60*60*1000;
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
var good_pd = good_pd_date.getFullYear() == 2017;
function parseDate(str/*:string|Date*/)/*:Date*/ {
@ -1957,6 +1971,10 @@ describe('CSV', function() {
assert.equal(get_cell(sheet, "C1").t, 's');
assert.equal(get_cell(sheet, "C1").v, '100');
});
it('should interpret CRLF newlines', function() {
var wb = X.read("sep=&\r\n1&2&3\r\n4&5&6", {type: "string"});
assert.equal(wb.Sheets.Sheet1["!ref"], "A1:C2");
});
if(!browser || typeof cptable !== 'undefined') it('should honor codepage for binary strings', function() {
var data = "abc,def\nghi,j\xD3l";
[[1251, 'У'],[1252, 'Ó'], [1253, 'Σ'], [1254, 'Ó'], [1255, '׃'], [1256, 'س'], [10000, '”']].forEach(function(m) {
@ -2052,9 +2070,7 @@ describe('sylk', function() {
assert.equal(get_cell(X.read(str, {type:"string"}).Sheets.Sheet1, "A1").v, A1);
assert.equal(get_cell(X.read(str.replace(//, "\x96"), {type:"binary", codepage:1252}).Sheets.Sheet1, "A1").v, A1);
if(typeof Buffer !== 'undefined' && !browser) {
// $FlowIgnore
assert.equal(get_cell(X.read(Buffer_from(str), {type:"buffer", codepage:65001}).Sheets.Sheet1, "A1").v, A1);
// $FlowIgnore
assert.equal(get_cell(X.read(Buffer_from(str.replace(//, "\x96"), "binary"), {type:"buffer", codepage:1252}).Sheets.Sheet1, "A1").v, A1);
}
} : null);
@ -2303,6 +2319,20 @@ describe('corner cases', function() {
X.read(fs.readFileSync(dir + 'wtf_path.xlsx'), {WTF:1, type:TYPE});
X.read(fs.readFileSync(dir + 'wtf_path.xlsb'), {WTF:1, type:TYPE});
});
it("should quote unicode sheet names in formulae", function() {
var wb = X.read(fs.readFileSync(dir + "cross-sheet_formula_names.xlsb"), {WTF:1, type:TYPE});
assert.equal(wb.Sheets["Sheet1"]["A1"].f, "'a-b'!A1");
assert.equal(wb.Sheets["Sheet1"]["A2"].f, "'a#b'!A1");
assert.equal(wb.Sheets["Sheet1"]["A3"].f, "'a^b'!A1");
assert.equal(wb.Sheets["Sheet1"]["A4"].f, "'a%b'!A1");
assert.equal(wb.Sheets["Sheet1"]["A5"].f, "'a\u066ab'!A1");
assert.equal(wb.Sheets["Sheet1"]["A6"].f, "'☃️'!A1");
assert.equal(wb.Sheets["Sheet1"]["A7"].f, "'\ud83c\udf63'!A1");
assert.equal(wb.Sheets["Sheet1"]["A8"].f, "'a!!b'!A1");
assert.equal(wb.Sheets["Sheet1"]["A9"].f, "'a$b'!A1");
assert.equal(wb.Sheets["Sheet1"]["A10"].f, "'a!b'!A1");
assert.equal(wb.Sheets["Sheet1"]["A11"].f, "'a b'!A1");
});
});
describe('encryption', function() {
@ -2334,7 +2364,7 @@ describe('encryption', function() {
if(!browser || typeof cptable !== 'undefined')
describe('multiformat tests', function() {
var mfopts = opts;
var mft = fs.readFileSync('multiformat.lst','utf-8').split("\n").map(function(x) { return x.trim(); });
var mft = fs.readFileSync('multiformat.lst','utf-8').replace(/\r/g,"").split("\n").map(function(x) { return x.trim(); });
var csv = true, formulae = false;
mft.forEach(function(x) {
if(x.charAt(0)!="#") describe('MFT ' + x, function() {

File diff suppressed because one or more lines are too long

32
xlsx.core.min.js vendored

File diff suppressed because one or more lines are too long

34
xlsx.full.min.js vendored

File diff suppressed because one or more lines are too long

368
xlsx.js
View File

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
var XLSX = {};
function make_xlsx_lib(XLSX){
XLSX.version = '0.15.6';
XLSX.version = '0.16.4';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true, window */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
@ -192,7 +192,7 @@ var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g;
/*jshint -W041 */
var SSF = ({});
var make_ssf = function make_ssf(SSF){
SSF.version = '0.10.3';
SSF.version = '0.11.2';
function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; }
function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; }
function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
@ -256,11 +256,65 @@ function init_table(t) {
t[48]= '##0.0E+0';
t[49]= '@';
t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
t[65535]= 'General';
}
var table_fmt = {};
init_table(table_fmt);
/* Defaults determined by systematically testing in Excel 2019 */
/* These formats appear to default to other formats in the table */
var default_map = [];
var defi = 0;
// 5 -> 37 ... 8 -> 40
for(defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi;
// 23 -> 0 ... 26 -> 0
for(defi = 23; defi <= 26; ++defi) default_map[defi] = 0;
// 27 -> 14 ... 31 -> 14
for(defi = 27; defi <= 31; ++defi) default_map[defi] = 14;
// 50 -> 14 ... 58 -> 14
for(defi = 50; defi <= 58; ++defi) default_map[defi] = 14;
// 59 -> 1 ... 62 -> 4
for(defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58;
// 67 -> 9 ... 68 -> 10
for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58;
// 72 -> 14 ... 75 -> 17
for(defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58;
// 69 -> 12 ... 71 -> 14
for(defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57;
// 76 -> 20 ... 78 -> 22
for(defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56;
// 79 -> 45 ... 81 -> 47
for(defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34;
// 82 -> 0 ... 65536 -> 0 (omitted)
/* These formats technically refer to Accounting formats with no equivalent */
var default_str = [];
// 5 -- Currency, 0 decimal, black negative
default_str[5] = default_str[63] = '"$"#,##0_);\\("$"#,##0\\)';
// 6 -- Currency, 0 decimal, red negative
default_str[6] = default_str[64] = '"$"#,##0_);[Red]\\("$"#,##0\\)';
// 7 -- Currency, 2 decimal, black negative
default_str[7] = default_str[65] = '"$"#,##0.00_);\\("$"#,##0.00\\)';
// 8 -- Currency, 2 decimal, red negative
default_str[8] = default_str[66] = '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)';
// 41 -- Accounting, 0 decimal, No Symbol
default_str[41] = '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)';
// 42 -- Accounting, 0 decimal, $ Symbol
default_str[42] = '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)';
// 43 -- Accounting, 2 decimal, No Symbol
default_str[43] = '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)';
// 44 -- Accounting, 2 decimal, $ Symbol
default_str[44] = '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)';
function frac(x, D, mixed) {
var sgn = x < 0 ? -1 : 1;
var B = x * sgn;
@ -321,37 +375,64 @@ function datenum_local(v, date1904) {
else if(v >= base1904) epoch += 24*60*60*1000;
return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000);
}
/* The longest 32-bit integer text is "-4294967296", exactly 11 chars */
function general_fmt_int(v) { return v.toString(10); }
SSF._general_int = general_fmt_int;
/* ECMA-376 18.8.30 numFmt*/
/* Note: `toPrecision` uses standard form when prec > E and E >= -6 */
var general_fmt_num = (function make_general_fmt_num() {
var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/;
function gfn2(v) {
var w = (v<0?12:11);
var o = gfn5(v.toFixed(12)); if(o.length <= w) return o;
o = v.toPrecision(10); if(o.length <= w) return o;
return v.toExponential(5);
}
function gfn3(v) {
var o = v.toFixed(11).replace(gnr1,".$1");
if(o.length > (v<0?12:11)) o = v.toPrecision(6);
return o;
}
function gfn4(o) {
for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2");
return o;
}
function gfn5(o) {
return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o;
}
return function general_fmt_num(v) {
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
else if(Math.abs(V) <= 9) o = gfn2(v);
else if(V === 10) o = v.toFixed(10).substr(0,12);
else o = gfn3(v);
return gfn5(gfn4(o));
};})();
var trailing_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)$/;
function strip_decimal(o) {
return (o.indexOf(".") == -1) ? o : o.replace(trailing_zeroes_and_decimal, "$1");
}
/* General Exponential always shows 2 digits exp and trims the mantissa */
var mantissa_zeroes_and_decimal = /(?:\.0*|(\.\d*[1-9])0+)[Ee]/;
var exp_with_single_digit = /(E[+-])(\d)$/;
function normalize_exp(o) {
if(o.indexOf("E") == -1) return o;
return o.replace(mantissa_zeroes_and_decimal,"$1E").replace(exp_with_single_digit,"$10$2");
}
/* exponent >= -9 and <= 9 */
function small_exp(v) {
var w = (v<0?12:11);
var o = strip_decimal(v.toFixed(12)); if(o.length <= w) return o;
o = v.toPrecision(10); if(o.length <= w) return o;
return v.toExponential(5);
}
/* exponent >= 11 or <= -10 likely exponential */
function large_exp(v) {
var o = strip_decimal(v.toFixed(11));
return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o;
}
function general_fmt_num_base(v) {
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
else if(Math.abs(V) <= 9) o = small_exp(v);
else if(V === 10) o = v.toFixed(10).substr(0,12);
else o = large_exp(v);
return strip_decimal(normalize_exp(o.toUpperCase()));
}
return general_fmt_num_base;
})();
SSF._general_num = general_fmt_num;
/*
"General" rules:
- text is passed through ("@")
- booleans are rendered as TRUE/FALSE
- "up to 11 characters" displayed for numbers
- Default date format (code 14) used for Dates
TODO: technically the display depends on the width of the cell
*/
function general_fmt(v, opts) {
switch(typeof v) {
case 'string': return v;
@ -365,7 +446,14 @@ function general_fmt(v, opts) {
throw new Error("unsupported value in General format: " + v);
}
SSF._general = general_fmt;
function fix_hijri() { return 0; }
function fix_hijri(date, o) {
/* TODO: properly adjust y/m/d and */
o[0] -= 581;
var dow = date.getDay();
if(date < 60) dow = (dow + 6) % 7;
return dow;
}
//var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
/*jshint -W086 */
function write_date(type, fmt, val, ss0) {
var o="", ss=0, tt=0, y = val.y, out, outl = 0;
@ -425,9 +513,10 @@ if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100;
default: throw 'bad abstime format: ' + fmt;
} outl = fmt.length === 3 ? 1 : 2; break;
case 101: /* 'e' era */
out = y; outl = 1;
out = y; outl = 1; break;
}
if(outl > 0) return pad0(out, outl); else return "";
var outstr = outl > 0 ? pad0(out, outl) : "";
return outstr;
}
/*jshint +W086 */
function commaify(s) {
@ -498,10 +587,9 @@ function hashq(str) {
}
function rnd(val, d) { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); }
function dec(val, d) {
if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) {
return 0;
}
return Math.round((val-Math.floor(val))*Math.pow(10,d));
var _frac = val - Math.floor(val), dd = Math.pow(10,d);
if (d < ('' + Math.round(_frac * dd)).length) return 0;
return Math.round(_frac * dd);
}
function carry(val, d) {
if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) {
@ -509,7 +597,10 @@ function carry(val, d) {
}
return 0;
}
function flr(val) { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); }
function flr(val) {
if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0));
return ""+Math.floor(val);
}
function write_num_flt(type, fmt, val) {
if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");
@ -730,7 +821,7 @@ function split_fmt(fmt) {
return out;
}
SSF._split = split_fmt;
var abstime = /\[[HhMmSs]*\]/;
var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/;
function fmt_is_date(fmt) {
var i = 0, /*cc = 0,*/ c = "", o = "";
while(i < fmt.length) {
@ -746,9 +837,10 @@ function fmt_is_date(fmt) {
case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E':
/* falls through */
case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true;
case 'A': case 'a':
case 'A': case 'a': case '上':
if(fmt.substr(i, 3).toUpperCase() === "A/P") return true;
if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true;
if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true;
++i; break;
case '[':
o = c;
@ -805,11 +897,12 @@ function eval_fmt(fmt, v, opts, flen) {
if(c === 'm' && lst.toLowerCase() === 'h') c = 'M';
if(c === 'h') c = hr;
out[out.length] = {t:c, v:o}; lst = c; break;
case 'A': case 'a':
case 'A': case 'a': case '上':
var q={t:c, v:c};
if(dt==null) dt=parse_date_code(v, opts);
if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; }
else { q.t = "t"; ++i; }
if(dt==null && q.t === 'T') return "";
out[out.length] = q; lst = c; break;
@ -834,7 +927,7 @@ function eval_fmt(fmt, v, opts, flen) {
}
/* falls through */
case '0': case '#':
o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c;
o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c;
out[out.length] = {t:'n', v:o}; break;
case '?':
o = c; while(fmt.charAt(++i) === c) o+=c;
@ -845,12 +938,14 @@ function eval_fmt(fmt, v, opts, flen) {
o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i);
out[out.length] = {t:'D', v:o}; break;
case ' ': out[out.length] = {t:c, v:c}; ++i; break;
case "$": out[out.length] = {t:'t', v:'$'}; ++i; break;
case '$': out[out.length] = {t:'t', v:'$'}; ++i; break;
default:
if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);
out[out.length] = {t:'t', v:c}; ++i; break;
}
}
/* Scan for date/time parts */
var bt = 0, ss0 = 0, ssm;
for(i=out.length-1, lst='t'; i >= 0; --i) {
switch(out[i].t) {
@ -869,6 +964,7 @@ function eval_fmt(fmt, v, opts, flen) {
if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3;
}
}
/* time rounding depends on presence of minute / second / usec fields */
switch(bt) {
case 0: break;
case 1:
@ -881,6 +977,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
if(dt.S >= 60) { dt.S = 0; ++dt.M; }
break;
}
/* replace fields */
var nstr = "", jj;
for(i=0; i < out.length; ++i) {
@ -890,7 +987,7 @@ if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z':
out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
out[i].t = 't'; break;
case 'n': case '(': case '?':
case 'n': case '?':
jj = i+1;
while(out[jj] != null && (
(c=out[jj].t) === "?" || c === "D" ||
@ -910,7 +1007,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
if(nstr.length > 0) {
if(nstr.charCodeAt(0) == 40) /* '(' */ {
myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v);
ostr = write_num('(', nstr, myv);
ostr = write_num('n', nstr, myv);
} else {
myv = (v<0 && flen > 1 ? -v : v);
ostr = write_num('n', nstr, myv);
@ -925,7 +1022,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
var lasti=out.length;
if(decpt === out.length && ostr.indexOf("E") === -1) {
for(i=out.length-1; i>= 0;--i) {
if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue;
if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;
if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); }
else if(jj < 0) out[i].v = "";
else { out[i].v = ostr.substr(0, jj+1); jj = -1; }
@ -937,7 +1034,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
else if(decpt !== out.length && ostr.indexOf("E") === -1) {
jj = ostr.indexOf(".")-1;
for(i=decpt; i>= 0; --i) {
if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue;
if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;
j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1;
vv = out[i].v.substr(j+1);
for(; j>=0; --j) {
@ -962,7 +1059,7 @@ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
}
}
}
for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) {
for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) {
myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v);
out[i].v = write_num(out[i].t, out[i].v, myv);
out[i].t = 't';
@ -1019,6 +1116,8 @@ function format(fmt,v,o) {
case "number":
if(fmt == 14 && o.dateNF) sfmt = o.dateNF;
else sfmt = (o.table != null ? (o.table) : table_fmt)[fmt];
if(sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]];
if(sfmt == null) sfmt = default_str[fmt] || "General";
break;
}
if(isgeneral(sfmt,0)) return general_fmt(v, o);
@ -3122,9 +3221,12 @@ function writextag(f,g,h) { return '<' + f + ((h != null) ? wxt_helper(h) : "")
function write_w3cdtf(d, t) { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } return ""; }
function write_vt(s) {
function write_vt(s, xlsx) {
switch(typeof s) {
case 'string': return writextag('vt:lpwstr', escapexml(s));
case 'string':
var o = writextag('vt:lpwstr', escapexml(s));
if(xlsx) o = o.replace(/&quot;/g, "_x0022_");
return o;
case 'number': return writextag((s|0)==s?'vt:i4':'vt:r8', escapexml(String(s)));
case 'boolean': return writextag('vt:bool',s?'true':'false');
}
@ -3532,7 +3634,7 @@ var make_offcrypto = function(O, _crypto) {
t = S[i]; S[i] = S[j]; S[j] = t;
}
// $FlowIgnore
i = j = 0; var out = Buffer(data.length);
i = j = 0; var out = new_raw_buf(data.length);
for(c = 0; c != data.length; ++c) {
i = (i + 1)&255;
j = (j + S[i])%256;
@ -3561,9 +3663,24 @@ function fix_col(cstr) { return cstr.replace(/^([A-Z])/,"$$$1"); }
function unfix_col(cstr) { return cstr.replace(/^\$([A-Z])/,"$1"); }
function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); }
function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); }
function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; }
//function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
function decode_cell(cstr) {
var R = 0, C = 0;
for(var i = 0; i < cstr.length; ++i) {
var cc = cstr.charCodeAt(i);
if(cc >= 48 && cc <= 57) R = 10 * R + (cc - 48);
else if(cc >= 65 && cc <= 90) C = 26 * C + (cc - 64);
}
return { c: C - 1, r:R - 1 };
}
//function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); }
function encode_cell(cell) {
var col = cell.c + 1;
var s="";
for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s;
return s + (cell.r + 1);
}
function decode_range(range) { var x =range.split(":"); return {s:decode_cell(x[0]),e:decode_cell(x[x.length-1])}; }
function encode_range(cs,ce) {
if(typeof ce === 'undefined' || typeof ce === 'number') {
return encode_range(cs.s, cs.e);
@ -4878,7 +4995,7 @@ function parse_ext_props(data, p, opts) {
EXT_PROPS.forEach(function(f) {
var xml = (data.match(matchtag(f[0]))||[])[1];
switch(f[2]) {
case "string": p[f[1]] = unescapexml(xml||""); break;
case "string": if(xml) p[f[1]] = unescapexml(xml); break;
case "bool": p[f[1]] = xml === "true"; break;
case "raw":
var cur = data.match(new RegExp("<" + f[0] + "[^>]*>([\\s\\S]*?)<\/" + f[0] + ">"));
@ -4979,7 +5096,7 @@ function write_cust_props(cp) {
if(!cp) return o.join("");
var pid = 1;
keys(cp).forEach(function custprop(k) { ++pid;
o[o.length] = (writextag('property', write_vt(cp[k]), {
o[o.length] = (writextag('property', write_vt(cp[k], true), {
'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
'pid': pid,
'name': escapexml(k)
@ -5523,6 +5640,21 @@ function parse_XLUnicodeRichExtendedString(blob) {
current_codepage = cp;
return z;
}
function write_XLUnicodeRichExtendedString(xlstr) {
var str = (xlstr.t||""), nfmts = 1;
var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0));
hdr.write_shift(2, str.length);
hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01);
if(nfmts > 1) hdr.write_shift(2, nfmts);
var otext = new_buf(2 * str.length);
otext.write_shift(2 * str.length, str, 'utf16le');
var out = [hdr, otext];
return bconcat(out);
}
/* 2.5.296 XLUnicodeStringNoCch */
function parse_XLUnicodeStringNoCch(blob, cch, opts) {
@ -5948,6 +6080,16 @@ function parse_SST(blob, length) {
strs.Count = cnt; strs.Unique = ucnt;
return strs;
}
function write_SST(sst, opts) {
var header = new_buf(8);
header.write_shift(4, sst.Count);
header.write_shift(4, sst.Unique);
var strs = [];
for(var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts);
var o = bconcat([header].concat(strs));
o.parts = [header.length].concat(strs.map(function(str) { return str.length; }));
return o;
}
/* [MS-XLS] 2.4.107 */
function parse_ExtSST(blob, length) {
@ -6085,6 +6227,12 @@ function parse_LabelSst(blob) {
cell.isst = blob.read_shift(4);
return cell;
}
function write_LabelSst(R, C, v, os ) {
var o = new_buf(10);
write_XLSCell(R, C, os, o);
o.write_shift(4, v);
return o;
}
/* [MS-XLS] 2.4.148 */
function parse_Label(blob, length, opts) {
@ -6799,6 +6947,7 @@ var dbf_reverse_map = evert({
0xCA: 1254, 0xCB: 1253,
0x00: 20127
});
var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5];
/* TODO: find an actual specification */
function dbf_to_aoa(buf, opts) {
var out = [];
@ -7051,6 +7200,7 @@ function sheet_to_dbf(ws, opts) {
return ba.end();
}
return {
versions: DBF_SUPPORTED_VERSIONS,
to_workbook: dbf_to_workbook,
to_sheet: dbf_to_sheet,
from_sheet: sheet_to_dbf
@ -7556,7 +7706,17 @@ var PRN = (function() {
var ws = o.dense ? ([]) : ({});
var range = ({s: {c:0, r:0}, e: {c:0, r:0}});
if(str.slice(0,4) == "sep=" && str.charCodeAt(5) == 10) { sep = str.charAt(4); str = str.slice(6); }
if(str.slice(0,4) == "sep=") {
// If the line ends in \r\n
if(str.charCodeAt(5) == 13 && str.charCodeAt(6) == 10 ) {
sep = str.charAt(4); str = str.slice(7);
}
// If line ends in \r OR \n
else if(str.charCodeAt(5) == 13 || str.charCodeAt(5) == 10 ) {
//
sep = str.charAt(4); str = str.slice(6);
}
}
else sep = guess_sep(str.slice(0,1024));
var R = 0, C = 0, v = 0;
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0;
@ -7608,6 +7768,7 @@ var PRN = (function() {
}
function prn_to_sheet_str(str, opts) {
if(!(opts && opts.PRN)) return dsv_to_sheet_str(str, opts);
if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts);
return aoa_to_sheet(prn_to_aoa_str(str, opts), opts);
@ -11117,9 +11278,12 @@ var PtgBinOp = {
PtgPower: "^",
PtgSub: "-"
};
// List of invalid characters needs to be tested further
var quoteCharacters = new RegExp(/[^\w\u4E00-\u9FFF\u3040-\u30FF]/)
function formula_quote_sheet_name(sname, opts) {
if(!sname && !(opts && opts.biff <= 5 && opts.biff >= 2)) throw new Error("empty sheet name");
if(sname.indexOf(" ") > -1) return "'" + sname + "'";
if (quoteCharacters.test(sname)) return "'" + sname + "'";
return sname;
}
function get_ixti_raw(supbooks, ixti, opts) {
@ -14250,6 +14414,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
case 0x00AE: /* 'BrtCustomFilter' */
case 0x049C: /* 'BrtCustomFilter14' */
case 0x01F3: /* 'BrtDRef' */
case 0x01FB: /* 'BrtDXF' */
case 0x0226: /* 'BrtDrawing' */
case 0x00AB: /* 'BrtDynamicFilter' */
case 0x00A7: /* 'BrtFilter' */
@ -15617,7 +15782,7 @@ function xlml_normalize(d) {
/* TODO: Everything */
/* UOS uses CJK in tags */
var xlmlregex = /<(\/?)([^\s?>!\/:]*:|)([^\s?>:\/]+)[^>]*>/mg;
var xlmlregex = /<(\/?)([^\s?><!\/:]*:|)([^\s?<>:\/]+)(?:[\s?:\/][^>]*)?>/mg;
//var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
function parse_xlml_xml(d, _opts) {
var opts = _opts || {};
@ -18900,28 +19065,28 @@ function write_biff_rec(ba, type, payload, length) {
if(len > 0 && is_buf(payload)) ba.push(payload);
}
//function write_biff_continue(ba, type, payload, length) {
// var len = length || (payload||[]).length || 0;
// if(len <= 8224) return write_biff_rec(ba, type, payload, len);
// var t = +type || +XLSRE[type];
// if(isNaN(t)) return;
// var parts = payload.parts || [], sidx = 0;
// var i = 0, w = 0;
// while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; }
// var o = ba.next(4);
// o.write_shift(2, t);
// o.write_shift(2, w);
// ba.push(payload.slice(i, i + w));
// i += w;
// while(i < len) {
// o = ba.next(4);
// o.write_shift(2, 0x3c); // TODO: figure out correct continue type
// w = 0;
// while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; }
// o.write_shift(2, w);
// ba.push(payload.slice(i, i+w)); i+= w;
// }
//}
function write_biff_continue(ba, type, payload, length) {
var len = length || (payload||[]).length || 0;
if(len <= 8224) return write_biff_rec(ba, type, payload, len);
var t = +type || +XLSRE[type];
if(isNaN(t)) return;
var parts = payload.parts || [], sidx = 0;
var i = 0, w = 0;
while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; }
var o = ba.next(4);
o.write_shift(2, t);
o.write_shift(2, w);
ba.push(payload.slice(i, i + w));
i += w;
while(i < len) {
o = ba.next(4);
o.write_shift(2, 0x3c); // TODO: figure out correct continue type
w = 0;
while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; }
o.write_shift(2, w);
ba.push(payload.slice(i, i+w)); i+= w;
}
}
function write_BIFF2Cell(out, r, c) {
if(!out) out = new_buf(7);
@ -19073,7 +19238,10 @@ function write_ws_biff8_cell(ba, cell, R, C, opts) {
break;
/* TODO: codepage, sst */
case 's': case 'str':
write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts));
if(opts.bookSST) {
var isst = get_sst_id(opts.Strings, cell.v, opts.revStrings);
write_biff_rec(ba, "LabelSst", write_LabelSst(R, C, isst, os, opts));
} else write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts));
break;
default:
write_biff_rec(ba, "Blank", write_XLSCell(R, C, os));
@ -19202,7 +19370,10 @@ function write_biff8_global(wb, bufs, opts) {
/* METADATA [MTRSettings] [ForceFullCalculation] */
if(b8) write_biff_rec(C, "Country", write_Country());
/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */
/* BIFF8: [SST *Continue] ExtSST */
if(b8 && opts.Strings) write_biff_continue(C, "SST", write_SST(opts.Strings, opts));
/* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */
write_biff_rec(C, "EOF");
var c = C.end();
@ -19348,6 +19519,7 @@ var HTML_ = (function() {
sp.t = cell && cell.t || 'z';
if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
sp.id = (o.id || "sjs") + "-" + coord;
if(sp.t != "z") { sp.v = cell.v; if(cell.z != null) sp.z = cell.z; }
oo.push(writextag('td', w, sp));
}
var preamble = "<tr>";
@ -19370,8 +19542,8 @@ var HTML_ = (function() {
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
out.push("</table>" + footer);
return out.join("");
}
}
return {
to_workbook: html_to_book,
to_sheet: html_to_sheet,
@ -19403,7 +19575,8 @@ function parse_dom_table(table, _opts) {
for(_C = C = 0; _C < elts.length; ++_C) {
var elt = elts[_C];
if (opts.display && is_dom_element_hidden(elt)) continue;
var v = htmldecode(elt.innerHTML);
var v = elt.hasAttribute('v') ? elt.getAttribute('v') : htmldecode(elt.innerHTML);
var z = elt.getAttribute('z');
for(midx = 0; midx < merges.length; ++midx) {
var m = merges[midx];
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
@ -19425,7 +19598,8 @@ function parse_dom_table(table, _opts) {
o.z = opts.dateNF || SSF._table[14];
}
}
if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; }
if(o.z === undefined && z != null) o.z = z;
if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o;}
else ws[encode_cell({c:C, r:R})] = o;
if(range.e.c < C) range.e.c = C;
C += CS;
@ -20106,7 +20280,7 @@ var write_content_ods = (function() {
ct['office:value'] = (cell.v||0);
break;
case 's': case 'str':
textp = cell.v;
textp = cell.v == null ? "" : cell.v;
ct['office:value-type'] = "string";
break;
case 'd':
@ -20701,13 +20875,13 @@ f = "docProps/app.xml";
function firstbyte(f,o) {
var x = "";
switch((o||{}).type || "base64") {
case 'buffer': return [f[0], f[1], f[2], f[3]];
case 'base64': x = Base64.decode(f.slice(0,24)); break;
case 'buffer': return [f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]];
case 'base64': x = Base64.decode(f.slice(0,12)); break;
case 'binary': x = f; break;
case 'array': return [f[0], f[1], f[2], f[3]];
case 'array': return [f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]];
default: throw new Error("Unrecognized type " + (o && o.type || "undefined"));
}
return [x.charCodeAt(0), x.charCodeAt(1), x.charCodeAt(2), x.charCodeAt(3)];
return [x.charCodeAt(0), x.charCodeAt(1), x.charCodeAt(2), x.charCodeAt(3), x.charCodeAt(4), x.charCodeAt(5), x.charCodeAt(6), x.charCodeAt(7)];
}
function read_cfb(cfb, opts) {
@ -20781,7 +20955,7 @@ function readSync(data, opts) {
if(!vu.foo) {o=dup(o); o.type='array'; return readSync(ab2a(d), o);}
}
switch((n = firstbyte(d, o))[0]) {
case 0xD0: return read_cfb(CFB.read(d, o), o);
case 0xD0: if(n[1] === 0xCF && n[2] === 0x11 && n[3] === 0xE0 && n[4] === 0xA1 && n[5] === 0xB1 && n[6] === 0x1A && n[7] === 0xE1) return read_cfb(CFB.read(d, o), o); break;
case 0x09: if(n[1] <= 0x04) return parse_xlscfb(d, o); break;
case 0x3C: return parse_xlml(d, o);
case 0x49: if(n[1] === 0x44) return read_wb_ID(d, o); break;
@ -20794,7 +20968,7 @@ function readSync(data, opts) {
case 0x7B: if(n[1] === 0x5C && n[2] === 0x72 && n[3] === 0x74) return RTF.to_workbook(d, o); break;
case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
}
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
if(DBF.versions.indexOf(n[0]) > -1 && n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
return read_prn(data, d, o, str);
}
@ -20982,7 +21156,7 @@ function make_json_row(sheet, r, R, cols, header, hdr, dense, o) {
else if(raw && v === null) row[hdr[C]] = null;
else continue;
} else {
row[hdr[C]] = raw ? v : format_cell(val,v,o);
row[hdr[C]] = raw || (o.rawNumbers && val.t == "n") ? v : format_cell(val,v,o);
}
if(v != null) isempty = false;
}
@ -21047,8 +21221,8 @@ function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
if(val == null) txt = "";
else if(val.v != null) {
isempty = false;
txt = ''+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) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
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") txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
@ -21145,7 +21319,7 @@ function sheet_add_json(_ws, js, opts) {
var _range = safe_decode_range(ws['!ref']);
range.e.c = Math.max(range.e.c, _range.e.c);
range.e.r = Math.max(range.e.r, _range.e.r);
if(_R == -1) { _R = range.e.r + 1; range.e.r = _R + js.length - 1 + offset; }
if(_R == -1) { _R = _range.e.r + 1; range.e.r = _R + js.length - 1 + offset; }
}
var hdr = o.header || [], C = 0;
@ -21469,7 +21643,7 @@ if(typeof CFB !== "undefined") XLSX.CFB = CFB;
/*global define */
if(typeof exports !== 'undefined') make_xlsx_lib(exports);
else if(typeof module !== 'undefined' && module.exports) make_xlsx_lib(module.exports);
else if(typeof define === 'function' && define.amd) define('xlsx', function() { if(!XLSX.version) make_xlsx_lib(XLSX); return XLSX; });
else if(typeof define === 'function' && define.amd) define(function() { if(!XLSX.version) make_xlsx_lib(XLSX); return XLSX; });
else make_xlsx_lib(XLSX);
/*exported XLS, ODS */
var XLS = XLSX, ODS = XLSX;