forked from sheetjs/sheetjs
version bump 0.16.3
- updated SSF to 0.11.2 - XLS write support for `bookSST`
This commit is contained in:
parent
5b1440a186
commit
768e1bdcf8
@ -47,7 +47,7 @@ before_install:
|
||||
- "npm install -g npm@4.3.0"
|
||||
- "npm install -g mocha@2.x voc"
|
||||
- "npm install blanket"
|
||||
- "npm install xlsjs"
|
||||
- "npm install word"
|
||||
- "npm install coveralls mocha-lcov-reporter"
|
||||
# note: jsdom 11.x expects node >= 6 but is missing engines.node
|
||||
- "npm install jsdom@11.x"
|
||||
|
22
README.md
22
README.md
@ -1713,7 +1713,7 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
for files employing other encryption methods.
|
||||
- WTF is mainly for development. By default, the parser will suppress read
|
||||
errors on single worksheets, allowing you to read from the worksheets that do
|
||||
parse properly. Setting `WTF:1` forces those errors to be thrown.
|
||||
parse properly. Setting `WTF:true` forces those errors to be thrown.
|
||||
|
||||
### Input Type
|
||||
|
||||
@ -2140,18 +2140,20 @@ For the example sheet:
|
||||
As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also
|
||||
produces CSV output. The function takes an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :----------- | :------: | :-------------------------------------------------- |
|
||||
|`FS` | `","` | "Field Separator" delimiter between fields |
|
||||
|`RS` | `"\n"` | "Record Separator" delimiter between rows |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`strip` | false | Remove trailing field separators in each record ** |
|
||||
|`blankrows` | true | Include blank lines in the CSV output |
|
||||
|`skipHidden` | false | Skips hidden rows/columns in the CSV output |
|
||||
|`forceQuotes` | false | Force quotes around fields |
|
||||
| Option Name | Default | Description |
|
||||
| :----------- | :------: | :------------------------------------------------- |
|
||||
|`FS` | `","` | "Field Separator" delimiter between fields |
|
||||
|`RS` | `"\n"` | "Record Separator" delimiter between rows |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`strip` | false | Remove trailing field separators in each record ** |
|
||||
|`blankrows` | true | Include blank lines in the CSV output |
|
||||
|`skipHidden` | false | Skips hidden rows/columns in the CSV output |
|
||||
|`forceQuotes` | false | Force quotes around fields |
|
||||
|
||||
- `strip` will remove trailing commas from each line under default `FS/RS`
|
||||
- `blankrows` must be set to `false` to skip blank lines.
|
||||
- Fields containing the record or field separator will automatically be wrapped
|
||||
in double quotes; `forceQuotes` forces all cells to be wrapped in quotes.
|
||||
|
||||
<details>
|
||||
<summary><b>Examples</b> (click to show)</summary>
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.16.2';
|
||||
XLSX.version = '0.16.3';
|
||||
|
193
bits/10_ssf.js
193
bits/10_ssf.js
@ -2,7 +2,7 @@
|
||||
/*jshint -W041 */
|
||||
var SSF/*:SSFModule*/ = ({}/*:any*/);
|
||||
var make_ssf = function make_ssf(SSF/*:SSFModule*/){
|
||||
SSF.version = '0.10.3';
|
||||
SSF.version = '0.11.2';
|
||||
function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; }
|
||||
function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; }
|
||||
function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
@ -69,11 +69,65 @@ function init_table(t/*:any*/) {
|
||||
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/*:Array<number>*/ = [];
|
||||
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/*:Array<string>*/ = [];
|
||||
|
||||
// 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/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ {
|
||||
var sgn = x < 0 ? -1 : 1;
|
||||
var B = x * sgn;
|
||||
@ -134,37 +188,64 @@ function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
||||
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/*:number*/)/*:string*/ { 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/*:number*/)/*:string*/ {
|
||||
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/*:string*/)/*:string*/ {
|
||||
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/*:string*/)/*:string*/ {
|
||||
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/*:number*/)/*:string*/ {
|
||||
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/*:number*/)/*:string*/ {
|
||||
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/*:number*/)/*:string*/ {
|
||||
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/*:any*/, opts/*:any*/) {
|
||||
switch(typeof v) {
|
||||
case 'string': return v;
|
||||
@ -178,7 +259,14 @@ function general_fmt(v/*:any*/, opts/*:any*/) {
|
||||
throw new Error("unsupported value in General format: " + v);
|
||||
}
|
||||
SSF._general = general_fmt;
|
||||
function fix_hijri(/*::date, o*/) { return 0; }
|
||||
function fix_hijri(date/*:Date*/, o/*:[number, number, number]*/) {
|
||||
/* 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/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:string*/ {
|
||||
var o="", ss=0, tt=0, y = val.y, out, outl = 0;
|
||||
@ -239,9 +327,10 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str
|
||||
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/*:string*/)/*:string*/ {
|
||||
@ -312,10 +401,9 @@ function hashq(str/*:string*/)/*:string*/ {
|
||||
}
|
||||
function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); }
|
||||
function dec(val/*:number*/, d/*:number*/)/*:number*/ {
|
||||
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/*:number*/, d/*:number*/)/*:number*/ {
|
||||
if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) {
|
||||
@ -323,7 +411,10 @@ function carry(val/*:number*/, d/*:number*/)/*:number*/ {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function flr(val/*:number*/)/*:string*/ { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); }
|
||||
function flr(val/*:number*/)/*:string*/ {
|
||||
if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0));
|
||||
return ""+Math.floor(val);
|
||||
}
|
||||
function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/ {
|
||||
if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
|
||||
var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");
|
||||
@ -546,7 +637,7 @@ function split_fmt(fmt/*:string*/)/*:Array<string>*/ {
|
||||
return out;
|
||||
}
|
||||
SSF._split = split_fmt;
|
||||
var abstime = /\[[HhMmSs]*\]/;
|
||||
var abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/;
|
||||
function fmt_is_date(fmt/*:string*/)/*:boolean*/ {
|
||||
var i = 0, /*cc = 0,*/ c = "", o = "";
|
||||
while(i < fmt.length) {
|
||||
@ -562,9 +653,10 @@ function fmt_is_date(fmt/*:string*/)/*:boolean*/ {
|
||||
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;
|
||||
@ -621,11 +713,12 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
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;
|
||||
@ -650,7 +743,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
}
|
||||
/* 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;
|
||||
@ -661,12 +754,14 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
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) {
|
||||
@ -685,6 +780,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
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:
|
||||
@ -699,6 +795,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
if(dt.S >= 60) { dt.S = 0; ++dt.M; }
|
||||
break;
|
||||
}
|
||||
|
||||
/* replace fields */
|
||||
var nstr = "", jj;
|
||||
for(i=0; i < out.length; ++i) {
|
||||
@ -709,7 +806,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
/*::if(!dt) throw "unreachable"; */
|
||||
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" ||
|
||||
@ -729,7 +826,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
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);
|
||||
@ -744,7 +841,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
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; }
|
||||
@ -756,7 +853,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
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) {
|
||||
@ -781,7 +878,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
}
|
||||
}
|
||||
}
|
||||
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';
|
||||
@ -838,6 +935,8 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
|
||||
case "number":
|
||||
if(fmt == 14 && o.dateNF) sfmt = o.dateNF;
|
||||
else sfmt = (o.table != null ? (o.table/*:any*/) : 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);
|
||||
|
@ -446,6 +446,21 @@ function parse_XLUnicodeRichExtendedString(blob) {
|
||||
current_codepage = cp;
|
||||
return z;
|
||||
}
|
||||
function write_XLUnicodeRichExtendedString(xlstr/*:: :XLString, opts*/) {
|
||||
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) {
|
||||
|
@ -266,6 +266,16 @@ function parse_SST(blob, length)/*:SST*/ {
|
||||
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/*:: :any)*/.parts = [header.length].concat(strs.map(function(str) { return str.length; }));
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.4.107 */
|
||||
function parse_ExtSST(blob, length) {
|
||||
@ -403,6 +413,12 @@ function parse_LabelSst(blob) {
|
||||
cell.isst = blob.read_shift(4);
|
||||
return cell;
|
||||
}
|
||||
function write_LabelSst(R/*:number*/, C/*:number*/, v/*:number*/, os/*:number*/ /*::, opts*/) {
|
||||
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) {
|
||||
|
@ -8,28 +8,28 @@ function write_biff_rec(ba/*:BufArray*/, type/*:number|string*/, payload, length
|
||||
if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload);
|
||||
}
|
||||
|
||||
//function write_biff_continue(ba/*:BufArray*/, type/*:number|string*/, payload, length/*:?number*/)/*:void*/ {
|
||||
// var len = length || (payload||[]).length || 0;
|
||||
// if(len <= 8224) return write_biff_rec(ba, type, payload, len);
|
||||
// var t/*:number*/ = +type || +XLSRE[/*::String(*/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/*:BufArray*/, type/*:number|string*/, payload, length/*:?number*/)/*:void*/ {
|
||||
var len = length || (payload||[]).length || 0;
|
||||
if(len <= 8224) return write_biff_rec(ba, type, payload, len);
|
||||
var t/*:number*/ = +type || +XLSRE[/*::String(*/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/*:number*/, c/*:number*/) {
|
||||
if(!out) out = new_buf(7);
|
||||
@ -182,7 +182,10 @@ function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n
|
||||
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));
|
||||
@ -311,7 +314,10 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
|
||||
/* 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();
|
||||
|
@ -135,4 +135,4 @@ deployments that use script tags to include the library.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
Some additional notes can be found in [NOTES.md](NOTES.md).
|
||||
Some additional notes can be found in [`NOTES.md`](NOTES.md).
|
||||
|
1
dist/jszip.js
generated
vendored
1
dist/jszip.js
generated
vendored
@ -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:
|
||||
|
32
dist/xlsx.core.min.js
generated
vendored
32
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
2
dist/xlsx.core.min.map
generated
vendored
File diff suppressed because one or more lines are too long
299
dist/xlsx.extendscript.js
generated
vendored
299
dist/xlsx.extendscript.js
generated
vendored
@ -174,6 +174,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:
|
||||
@ -9160,7 +9161,7 @@ module.exports = ZStream;
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.16.2';
|
||||
XLSX.version = '0.16.3';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true, window */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -9348,7 +9349,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;}
|
||||
@ -9412,11 +9413,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;
|
||||
@ -9477,37 +9532,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;
|
||||
@ -9521,7 +9603,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;
|
||||
@ -9581,9 +9670,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) {
|
||||
@ -9654,10 +9744,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) {
|
||||
@ -9665,7 +9754,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(/\)/,"");
|
||||
@ -9886,7 +9978,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) {
|
||||
@ -9902,9 +9994,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;
|
||||
@ -9961,11 +10054,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;
|
||||
@ -9990,7 +10084,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;
|
||||
@ -10001,12 +10095,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) {
|
||||
@ -10025,6 +10121,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:
|
||||
@ -10037,6 +10134,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) {
|
||||
@ -10046,7 +10144,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" ||
|
||||
@ -10066,7 +10164,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);
|
||||
@ -10081,7 +10179,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; }
|
||||
@ -10093,7 +10191,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) {
|
||||
@ -10118,7 +10216,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';
|
||||
@ -10175,6 +10273,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);
|
||||
@ -12737,7 +12837,7 @@ function encode_cell(cell) {
|
||||
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(":").map(decode_cell); return {s:x[0],e:x[x.length-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);
|
||||
@ -14697,6 +14797,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) {
|
||||
@ -15122,6 +15237,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) {
|
||||
@ -15259,6 +15384,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) {
|
||||
@ -15973,6 +16104,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 = [];
|
||||
@ -16225,6 +16357,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
|
||||
@ -16730,7 +16863,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;
|
||||
@ -28075,28 +28218,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);
|
||||
@ -28248,7 +28391,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, |