forked from sheetjs/sheetjs
version bump 0.20.0
This commit is contained in:
parent
36c5b7c0f5
commit
955543147d
.gitignore.npmignoreCHANGELOG.mdMakefile
bits
00_header.js01_version.js10_ssf.js11_ssfutils.js20_jsutils.js27_csfutils.js39_xlsbiff.js40_harb.js41_lotus.js55_vml.js63_fbin.js65_fods.js66_wscommon.js67_wsxml.js68_wsbin.js75_xlml.js76_xls.js77_parsetab.js78_writebiff.js79_html.js80_parseods.js81_writeods.js83_numbers.js90_utils.js
dist
xlsx.core.min.jsxlsx.core.min.mapxlsx.extendscript.jsxlsx.full.min.jsxlsx.full.min.mapxlsx.mini.min.jsxlsx.mini.min.map
modules
package.jsontest.jstest.mjstest.mtstest.tstestbun.mjstestnocp.tstests
types
xlsx.flow.jsxlsx.jsxlsx.mini.flow.jsxlsx.mini.jsxlsx.mjs
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,6 +28,7 @@ tmp
|
|||||||
*.[fF][mM][3tT]
|
*.[fF][mM][3tT]
|
||||||
*.[bB][iI][fF][fF][23458]
|
*.[bB][iI][fF][fF][23458]
|
||||||
*.[rR][tT][fF]
|
*.[rR][tT][fF]
|
||||||
|
*.[eE][tT]
|
||||||
*.[eE][tT][hH]
|
*.[eE][tT][hH]
|
||||||
*.[nN][uU][mM][bB][eE][rR][sS]
|
*.[nN][uU][mM][bB][eE][rR][sS]
|
||||||
*.[mM][oO][dD]
|
*.[mM][oO][dD]
|
||||||
|
@ -11,6 +11,7 @@ node_modules
|
|||||||
*.jsx
|
*.jsx
|
||||||
_book
|
_book
|
||||||
book.json
|
book.json
|
||||||
|
v8.log
|
||||||
tmp
|
tmp
|
||||||
*.[tT][xX][tT]
|
*.[tT][xX][tT]
|
||||||
*.[cC][sS][vV]
|
*.[cC][sS][vV]
|
||||||
@ -19,6 +20,7 @@ tmp
|
|||||||
*.[pP][mM][dD]*
|
*.[pP][mM][dD]*
|
||||||
*.[pP][dD][fF]
|
*.[pP][dD][fF]
|
||||||
*.[sS][lL][kK]
|
*.[sS][lL][kK]
|
||||||
|
*.[sS][yY][lL][kK]
|
||||||
*.socialcalc
|
*.socialcalc
|
||||||
*.[xX][lL][sSwWcCaAtTmMrR]
|
*.[xX][lL][sSwWcCaAtTmMrR]
|
||||||
*.[xX][lL][sSaAtT][xXmMbB]
|
*.[xX][lL][sSaAtT][xXmMbB]
|
||||||
@ -32,6 +34,7 @@ tmp
|
|||||||
*.[fF][mM][3tT]
|
*.[fF][mM][3tT]
|
||||||
*.[bB][iI][fF][fF][23458]
|
*.[bB][iI][fF][fF][23458]
|
||||||
*.[rR][tT][fF]
|
*.[rR][tT][fF]
|
||||||
|
*.[eE][tT]
|
||||||
*.[eE][tT][hH]
|
*.[eE][tT][hH]
|
||||||
*.[nN][uU][mM][bB][eE][rR][sS]
|
*.[nN][uU][mM][bB][eE][rR][sS]
|
||||||
*.[mM][oO][dD]
|
*.[mM][oO][dD]
|
||||||
|
@ -4,6 +4,10 @@ This log is intended to keep track of backwards-incompatible changes, including
|
|||||||
but not limited to API changes and file location changes. Minor behavioral
|
but not limited to API changes and file location changes. Minor behavioral
|
||||||
changes may not be included if they are not expected to break existing code.
|
changes may not be included if they are not expected to break existing code.
|
||||||
|
|
||||||
|
## v0.20.0
|
||||||
|
|
||||||
|
* Use UTC interpretation of Date objects for date cells (potentially breaking)
|
||||||
|
* API functions support UTC and local time value interpretations
|
||||||
* Export `NaN` values to `#NUM!` and infinite values to `#DIV/0!`
|
* Export `NaN` values to `#NUM!` and infinite values to `#DIV/0!`
|
||||||
|
|
||||||
## v0.19.3
|
## v0.19.3
|
||||||
|
15
Makefile
15
Makefile
@ -107,13 +107,13 @@ dist-deps: ## Copy dependencies for distribution
|
|||||||
.PHONY: aux
|
.PHONY: aux
|
||||||
aux: $(AUXTARGETS)
|
aux: $(AUXTARGETS)
|
||||||
|
|
||||||
BYTEFILEC=dist/xlsx.{full,core,mini}.min.js
|
BYTEFILEC=dist/xlsx.{full,core,mini}.min.js xlsx.mjs
|
||||||
BYTEFILER=dist/xlsx.extendscript.js xlsx.mjs
|
BYTEFILER=dist/xlsx.extendscript.js
|
||||||
.PHONY: bytes
|
.PHONY: bytes
|
||||||
bytes: ## Display minified and gzipped file sizes
|
bytes: ## Display minified and gzipped file sizes
|
||||||
@for i in $(BYTEFILEC); do npx printj "%-30s %7d %10d" $$i $$(wc -c < $$i) $$(gzip --best --stdout $$i | wc -c); done
|
@for i in $(BYTEFILEC); do npx printj "%-30s %7d %10d" $$i $$(wc -c < $$i) $$(gzip --best --stdout $$i | wc -c); done
|
||||||
@for i in $(BYTEFILER); do npx printj "%-30s %7d" $$i $$(wc -c < $$i); done
|
@for i in $(BYTEFILER); do npx printj "%-30s %7d" $$i $$(wc -c < $$i); done
|
||||||
@npx printj "%-30s %10d" "treeshake" "$$(npx esbuild@0.14.14 --bundle misc/import.js | wc -c)"
|
@npx printj "%-30s %10d" "treeshake" "$$(npx -y esbuild@0.14.14 --bundle misc/import.js | wc -c)"
|
||||||
|
|
||||||
|
|
||||||
.PHONY: git
|
.PHONY: git
|
||||||
@ -141,6 +141,10 @@ test mocha: test.js ## Run test suite
|
|||||||
#* To run tests for one format, make test_<fmt>
|
#* To run tests for one format, make test_<fmt>
|
||||||
#* To run the core test suite, make test_misc
|
#* To run the core test suite, make test_misc
|
||||||
|
|
||||||
|
.PHONY: testdot
|
||||||
|
testdot: test.js ## Run test suite using dot reporter
|
||||||
|
mocha -R dot -t 30000
|
||||||
|
|
||||||
.PHONY: test-esm
|
.PHONY: test-esm
|
||||||
test-esm: test.mjs ## Run Node ESM test suite
|
test-esm: test.mjs ## Run Node ESM test suite
|
||||||
npx -y mocha@9 -R spec -t 30000 $<
|
npx -y mocha@9 -R spec -t 30000 $<
|
||||||
@ -165,6 +169,11 @@ TESTFMT=$(patsubst %,test_%,$(FMT))
|
|||||||
$(TESTFMT): test_%:
|
$(TESTFMT): test_%:
|
||||||
FMTS=$* make test
|
FMTS=$* make test
|
||||||
|
|
||||||
|
TESTFMT=$(patsubst %,testdot_%,$(FMT))
|
||||||
|
.PHONY: $(TESTFMT)
|
||||||
|
$(TESTFMT): testdot_%:
|
||||||
|
FMTS=$* make testdot
|
||||||
|
|
||||||
TESTESMFMT=$(patsubst %,test-esm_%,$(FMT))
|
TESTESMFMT=$(patsubst %,test-esm_%,$(FMT))
|
||||||
.PHONY: $(TESTESMFMT)
|
.PHONY: $(TESTESMFMT)
|
||||||
$(TESTESMFMT): test-esm_%:
|
$(TESTESMFMT): test-esm_%:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||||
/* vim: set ts=2: */
|
/* vim: set ts=2: */
|
||||||
/*exported XLSX */
|
/*exported XLSX */
|
||||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Float32Array:false */
|
||||||
var XLSX = {};
|
var XLSX = {};
|
||||||
function make_xlsx_lib(XLSX){
|
function make_xlsx_lib(XLSX){
|
||||||
|
@ -1 +1 @@
|
|||||||
XLSX.version = '0.19.3';
|
XLSX.version = '0.20.0';
|
||||||
|
@ -203,15 +203,6 @@ function SSF_parse_date_code(v/*:number*/,opts/*:?any*/,b2/*:?boolean*/) {
|
|||||||
out.q = dow;
|
out.q = dow;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
var SSFbasedate = /*#__PURE__*/new Date(1899, 11, 31, 0, 0, 0);
|
|
||||||
var SSFdnthresh = /*#__PURE__*/SSFbasedate.getTime();
|
|
||||||
var SSFbase1904 = /*#__PURE__*/new Date(1900, 2, 1, 0, 0, 0);
|
|
||||||
function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
|
||||||
var epoch = /*#__PURE__*/v.getTime();
|
|
||||||
if(date1904) epoch -= 1461*24*60*60*1000;
|
|
||||||
else if(v >= SSFbase1904) epoch += 24*60*60*1000;
|
|
||||||
return (epoch - (SSFdnthresh + (/*#__PURE__*/v.getTimezoneOffset() - /*#__PURE__*/SSFbasedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000);
|
|
||||||
}
|
|
||||||
/* ECMA-376 18.8.30 numFmt*/
|
/* ECMA-376 18.8.30 numFmt*/
|
||||||
/* Note: `toPrecision` uses standard form when prec > E and E >= -6 */
|
/* Note: `toPrecision` uses standard form when prec > E and E >= -6 */
|
||||||
/* exponent >= -9 and <= 9 */
|
/* exponent >= -9 and <= 9 */
|
||||||
@ -269,7 +260,7 @@ function SSF_general(v/*:any*/, opts/*:any*/) {
|
|||||||
case 'undefined': return "";
|
case 'undefined': return "";
|
||||||
case 'object':
|
case 'object':
|
||||||
if(v == null) return "";
|
if(v == null) return "";
|
||||||
if(v instanceof Date) return SSF_format(14, datenum_local(v, opts && opts.date1904), opts);
|
if(v instanceof Date) return SSF_format(14, datenum(v, opts && opts.date1904), opts);
|
||||||
}
|
}
|
||||||
throw new Error("unsupported value in General format: " + v);
|
throw new Error("unsupported value in General format: " + v);
|
||||||
}
|
}
|
||||||
@ -957,7 +948,7 @@ function SSF_format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(SSF_isgeneral(sfmt,0)) return SSF_general(v, o);
|
if(SSF_isgeneral(sfmt,0)) return SSF_general(v, o);
|
||||||
if(v instanceof Date) v = datenum_local(v, o.date1904);
|
if(v instanceof Date) v = datenum(v, o.date1904);
|
||||||
var f = choose_fmt(sfmt, v);
|
var f = choose_fmt(sfmt, v);
|
||||||
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
|
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
|
||||||
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
|
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
|
||||||
|
@ -43,6 +43,7 @@ var dateNFregex = /[dD]+|[mM]+|[yYeE]+|[Hh]+|[Ss]+/g;
|
|||||||
function dateNF_regex(dateNF/*:string|number*/)/*:RegExp*/ {
|
function dateNF_regex(dateNF/*:string|number*/)/*:RegExp*/ {
|
||||||
var fmt = typeof dateNF == "number" ? table_fmt[dateNF] : dateNF;
|
var fmt = typeof dateNF == "number" ? table_fmt[dateNF] : dateNF;
|
||||||
fmt = fmt.replace(dateNFregex, "(\\d+)");
|
fmt = fmt.replace(dateNFregex, "(\\d+)");
|
||||||
|
dateNFregex.lastIndex = 0;
|
||||||
return new RegExp("^" + fmt + "$");
|
return new RegExp("^" + fmt + "$");
|
||||||
}
|
}
|
||||||
function dateNF_fix(str/*:string*/, dateNF/*:string*/, match/*:Array<string>*/)/*:string*/ {
|
function dateNF_fix(str/*:string*/, dateNF/*:string*/, match/*:Array<string>*/)/*:string*/ {
|
||||||
@ -55,6 +56,7 @@ function dateNF_fix(str/*:string*/, dateNF/*:string*/, match/*:Array<string>*/)/
|
|||||||
case 'm': if(H >= 0) M = v; else m = v; break;
|
case 'm': if(H >= 0) M = v; else m = v; break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
dateNFregex.lastIndex = 0;
|
||||||
if(S >= 0 && M == -1 && m >= 0) { M = m; m = -1; }
|
if(S >= 0 && M == -1 && m >= 0) { M = m; m = -1; }
|
||||||
var datestr = (("" + (Y>=0?Y: new Date().getFullYear())).slice(-4) + "-" + ("00" + (m>=1?m:1)).slice(-2) + "-" + ("00" + (d>=1?d:1)).slice(-2));
|
var datestr = (("" + (Y>=0?Y: new Date().getFullYear())).slice(-4) + "-" + ("00" + (m>=1?m:1)).slice(-2) + "-" + ("00" + (d>=1?d:1)).slice(-2));
|
||||||
if(datestr.length == 7) datestr = "0" + datestr;
|
if(datestr.length == 7) datestr = "0" + datestr;
|
||||||
|
@ -31,22 +31,19 @@ function evert_arr(obj/*:any*/)/*:EvertArrType*/ {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = /*#__PURE__*/new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
||||||
var epoch = /*#__PURE__*/v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = /*#__PURE__*/basedate.getTime() + (/*#__PURE__*/v.getTimezoneOffset() - /*#__PURE__*/basedate.getTimezoneOffset()) * 60000;
|
if(date1904) { res -= 1462; return res < -1402 ? res - 1 : res; }
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var refdate = /*#__PURE__*/new Date();
|
function numdate(v/*:number*/)/*:Date|number*/ {
|
||||||
var dnthresh = /*#__PURE__*/basedate.getTime() + (/*#__PURE__*/refdate.getTimezoneOffset() - /*#__PURE__*/basedate.getTimezoneOffset()) * 60000;
|
if(v >= 60 && v < 61) return v;
|
||||||
var refoffset = /*#__PURE__*/refdate.getTimezoneOffset();
|
|
||||||
function numdate(v/*:number*/)/*:Date*/ {
|
|
||||||
var out = new Date();
|
var out = new Date();
|
||||||
out.setTime(v * 24 * 60 * 60 * 1000 + dnthresh);
|
out.setTime((v>60 ? v : (v+1)) * 24 * 60 * 60 * 1000 + dnthresh);
|
||||||
if (out.getTimezoneOffset() !== refoffset) {
|
|
||||||
out.setTime(out.getTime() + (out.getTimezoneOffset() - refoffset) * 60000);
|
|
||||||
}
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,28 +74,22 @@ function parse_isodur(s) {
|
|||||||
return sec;
|
return sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
var good_pd_date_1 = /*#__PURE__*/new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
var good_pd_date = /*#__PURE__*/isNaN(/*#__PURE__*/good_pd_date_1.getFullYear()) ? /*#__PURE__*/new Date('2/19/17') : good_pd_date_1;
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
var good_pd = /*#__PURE__*/good_pd_date.getFullYear() == 2017;
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
/* parses a date as a local date */
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]], sans "Z"
|
||||||
function parseDate(str/*:string|Date*/, fixdate/*:?number*/)/*:Date*/ {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
|
||||||
if(good_pd) {
|
|
||||||
/*:: if(fixdate == null) fixdate = 0; */
|
|
||||||
if(fixdate > 0) d.setTime(d.getTime() + d.getTimezoneOffset() * 60 * 1000);
|
|
||||||
else if(fixdate < 0) d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
/* TODO: 1900-02-29T00:00:00.000 should return a flag to treat as a date code (affects xlml) */
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
m = str.match(pdre3);
|
||||||
var out = new Date(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0));
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
if(str.indexOf("Z") > -1) out = new Date(out.getTime() - out.getTimezoneOffset() * 60 * 1000);
|
var d = new Date(str);
|
||||||
return out;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cc2str(arr/*:Array<number>*/, debomit)/*:string*/ {
|
function cc2str(arr/*:Array<number>*/, debomit)/*:string*/ {
|
||||||
@ -170,32 +161,49 @@ function fuzzynum(s/*:string*/)/*:number*/ {
|
|||||||
|
|
||||||
/* NOTE: Chrome rejects bare times like 1:23 PM */
|
/* NOTE: Chrome rejects bare times like 1:23 PM */
|
||||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))\s+([ap])m?$/;
|
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))\s+([ap])m?$/;
|
||||||
|
var FDRE2 = /^([01]?\d|2[0-3])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))$/;
|
||||||
|
var FDISO = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)(\.\d+)?[Z]?$/; // YYYY-mm-dd(T or space)HH:MM:SS[.UUU][Z]
|
||||||
|
|
||||||
|
/* TODO: 1904 adjustment */
|
||||||
|
var utc_append_works = new Date("6/9/69 00:00 UTC").valueOf() == -17798400000;
|
||||||
function fuzzytime1(M) /*:Date*/ {
|
function fuzzytime1(M) /*:Date*/ {
|
||||||
/* TODO: 1904 adjustment, keep in sync with base date */
|
if(!M[2]) return new Date(Date.UTC(1899,11,31,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0));
|
||||||
if(!M[2]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
if(M[3]) {
|
||||||
if(M[3]) {
|
if(M[4]) return new Date(Date.UTC(1899,11,31,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000));
|
||||||
if(M[4]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
else return new Date(Date.UTC(1899,11,31,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000));
|
||||||
else return new Date(1899,11,30,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
}
|
||||||
}
|
else if(M[5]) return new Date(Date.UTC(1899,11,31, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0));
|
||||||
else if(M[5]) return new Date(1899,11,30, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
else return new Date(Date.UTC(1899,11,31,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0));
|
||||||
else return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
}
|
||||||
|
function fuzzytime2(M) /*:Date*/ {
|
||||||
|
if(!M[2]) return new Date(Date.UTC(1899,11,31,+M[1], 0, 0, 0));
|
||||||
|
if(M[3]) {
|
||||||
|
if(M[4]) return new Date(Date.UTC(1899,11,31,+M[1], +M[2], +M[4], parseFloat(M[3])*1000));
|
||||||
|
else return new Date(Date.UTC(1899,11,31,0, +M[1], +M[2], parseFloat(M[3])*1000));
|
||||||
|
}
|
||||||
|
else if(M[5]) return new Date(Date.UTC(1899,11,31, +M[1], +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0));
|
||||||
|
else return new Date(Date.UTC(1899,11,31,+M[1], +M[2], 0, 0));
|
||||||
}
|
}
|
||||||
var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
|
var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
|
||||||
function fuzzydate(s/*:string*/)/*:Date*/ {
|
function fuzzydate(s/*:string*/)/*:Date*/ {
|
||||||
|
// See issue 2863 -- this is technically not supported in Excel but is otherwise useful
|
||||||
|
if(FDISO.test(s)) return s.indexOf("Z") == -1 ? local_to_utc(new Date(s)) : new Date(s);
|
||||||
var lower = s.toLowerCase();
|
var lower = s.toLowerCase();
|
||||||
var lnos = lower.replace(/\s+/g, " ").trim();
|
var lnos = lower.replace(/\s+/g, " ").trim();
|
||||||
var M = lnos.match(FDRE1);
|
var M = lnos.match(FDRE1);
|
||||||
if(M) return fuzzytime1(M);
|
if(M) return fuzzytime1(M);
|
||||||
|
M = lnos.match(FDRE2);
|
||||||
var o = new Date(s), n = new Date(NaN);
|
if(M) return fuzzytime2(M);
|
||||||
|
M = lnos.match(pdre3);
|
||||||
|
if(M) return new Date(Date.UTC(+M[1], +M[2]-1, +M[3], +M[4], +M[5], ((M[6] && parseInt(M[6].slice(1), 10))|| 0), ((M[7] && parseInt(M[7].slice(1), 10))||0)));
|
||||||
|
var o = new Date(utc_append_works && s.indexOf("UTC") == -1 ? s + " UTC": s), n = new Date(NaN);
|
||||||
var y = o.getYear(), m = o.getMonth(), d = o.getDate();
|
var y = o.getYear(), m = o.getMonth(), d = o.getDate();
|
||||||
if(isNaN(d)) return n;
|
if(isNaN(d)) return n;
|
||||||
if(lower.match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) {
|
if(lower.match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) {
|
||||||
lower = lower.replace(/[^a-z]/g,"").replace(/([^a-z]|^)[ap]m?([^a-z]|$)/,"");
|
lower = lower.replace(/[^a-z]/g,"").replace(/([^a-z]|^)[ap]m?([^a-z]|$)/,"");
|
||||||
if(lower.length > 3 && lower_months.indexOf(lower) == -1) return n;
|
if(lower.length > 3 && lower_months.indexOf(lower) == -1) return n;
|
||||||
} else if(lower.replace(/[ap]m?/, "").match(/[a-z]/)) return n;
|
} else if(lower.replace(/[ap]m?/, "").match(/[a-z]/)) return n;
|
||||||
if(y < 0 || y > 8099 || s.match(/[^-0-9:,\/\\]/)) return n;
|
if(y < 0 || y > 8099 || s.match(/[^-0-9:,\/\\\ ]/)) return n;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,3 +216,10 @@ var split_regex = /*#__PURE__*/(function() {
|
|||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function utc_to_local(utc) {
|
||||||
|
return new Date(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate(), utc.getUTCHours(), utc.getUTCMinutes(), utc.getUTCSeconds(), utc.getUTCMilliseconds());
|
||||||
|
}
|
||||||
|
function local_to_utc(local) {
|
||||||
|
return new Date(Date.UTC(local.getFullYear(), local.getMonth(), local.getDate(), local.getHours(), local.getMinutes(), local.getSeconds(), local.getMilliseconds()));
|
||||||
|
}
|
||||||
|
@ -162,6 +162,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
|
|||||||
else if(typeof cell.v === 'boolean') cell.t = 'b';
|
else if(typeof cell.v === 'boolean') cell.t = 'b';
|
||||||
else if(cell.v instanceof Date) {
|
else if(cell.v instanceof Date) {
|
||||||
cell.z = o.dateNF || table_fmt[14];
|
cell.z = o.dateNF || table_fmt[14];
|
||||||
|
if(!o.UTC) cell.v = local_to_utc(cell.v);
|
||||||
if(o.cellDates) { cell.t = 'd'; cell.w = SSF_format(cell.z, datenum(cell.v, o.date1904)); }
|
if(o.cellDates) { cell.t = 'd'; cell.w = SSF_format(cell.z, datenum(cell.v, o.date1904)); }
|
||||||
else { cell.t = 'n'; cell.v = datenum(cell.v, o.date1904); cell.w = SSF_format(cell.z, cell.v); }
|
else { cell.t = 'n'; cell.v = datenum(cell.v, o.date1904); cell.w = SSF_format(cell.z, cell.v); }
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,20 @@
|
|||||||
/* [MS-XLS] 2.5.19 */
|
/* [MS-XLS] 2.5.19 */
|
||||||
function parse_XLSCell(blob/*::, length*/)/*:Cell*/ {
|
function parse_XLSCell(blob, length, opts)/*:Cell*/ {
|
||||||
var rw = blob.read_shift(2); // 0-indexed
|
var rw = blob.read_shift(2); // 0-indexed
|
||||||
var col = blob.read_shift(2);
|
var col = blob.read_shift(2);
|
||||||
var ixfe = blob.read_shift(2);
|
var ret = ({r:rw, c:col, ixfe:0}/*:any*/);
|
||||||
return ({r:rw, c:col, ixfe:ixfe}/*:any*/);
|
if(opts && opts.biff == 2 || length == 7) {
|
||||||
|
/* TODO: pass back flags */
|
||||||
|
var flags = blob.read_shift(1);
|
||||||
|
ret.ixfe = flags & 0x3F;
|
||||||
|
blob.l += 2;
|
||||||
|
/*
|
||||||
|
var ifntifmt = blob.read_shift(1);
|
||||||
|
var ifmt = ifntifmt & 0x3f, ifnt = ifntifmt >> 6;
|
||||||
|
var flags3 = blob.read_shift(1);
|
||||||
|
*/
|
||||||
|
} else ret.ixfe = blob.read_shift(2);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:?number*/, o) {
|
function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:?number*/, o) {
|
||||||
if(!o) o = new_buf(6);
|
if(!o) o = new_buf(6);
|
||||||
@ -228,6 +239,12 @@ function parse_WsBool(blob, length, opts) {
|
|||||||
|
|
||||||
/* [MS-XLS] 2.4.28 */
|
/* [MS-XLS] 2.4.28 */
|
||||||
function parse_BoundSheet8(blob, length, opts) {
|
function parse_BoundSheet8(blob, length, opts) {
|
||||||
|
var name = "";
|
||||||
|
if(opts.biff == 4) {
|
||||||
|
name = parse_ShortXLUnicodeString(blob, 0, opts);
|
||||||
|
if(name.length === 0) name = "Sheet1";
|
||||||
|
return { name:name };
|
||||||
|
}
|
||||||
var pos = blob.read_shift(4);
|
var pos = blob.read_shift(4);
|
||||||
var hidden = blob.read_shift(1) & 0x03;
|
var hidden = blob.read_shift(1) & 0x03;
|
||||||
var dt = blob.read_shift(1);
|
var dt = blob.read_shift(1);
|
||||||
@ -237,7 +254,7 @@ function parse_BoundSheet8(blob, length, opts) {
|
|||||||
case 2: dt = 'Chartsheet'; break;
|
case 2: dt = 'Chartsheet'; break;
|
||||||
case 6: dt = 'VBAModule'; break;
|
case 6: dt = 'VBAModule'; break;
|
||||||
}
|
}
|
||||||
var name = parse_ShortXLUnicodeString(blob, 0, opts);
|
name = parse_ShortXLUnicodeString(blob, 0, opts);
|
||||||
if(name.length === 0) name = "Sheet1";
|
if(name.length === 0) name = "Sheet1";
|
||||||
return { pos:pos, hs:hidden, dt:dt, name:name };
|
return { pos:pos, hs:hidden, dt:dt, name:name };
|
||||||
}
|
}
|
||||||
@ -408,8 +425,8 @@ function write_Font(data, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* [MS-XLS] 2.4.149 */
|
/* [MS-XLS] 2.4.149 */
|
||||||
function parse_LabelSst(blob) {
|
function parse_LabelSst(blob, length, opts) {
|
||||||
var cell = parse_XLSCell(blob);
|
var cell = parse_XLSCell(blob, length, opts);
|
||||||
cell.isst = blob.read_shift(4);
|
cell.isst = blob.read_shift(4);
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
@ -424,8 +441,7 @@ function write_LabelSst(R/*:number*/, C/*:number*/, v/*:number*/, os/*:number*/
|
|||||||
function parse_Label(blob, length, opts) {
|
function parse_Label(blob, length, opts) {
|
||||||
if(opts.biffguess && opts.biff == 2) opts.biff = 5;
|
if(opts.biffguess && opts.biff == 2) opts.biff = 5;
|
||||||
var target = blob.l + length;
|
var target = blob.l + length;
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, length, opts);
|
||||||
if(opts.biff == 2) blob.l++;
|
|
||||||
var str = parse_XLUnicodeString(blob, target - blob.l, opts);
|
var str = parse_XLUnicodeString(blob, target - blob.l, opts);
|
||||||
cell.val = str;
|
cell.val = str;
|
||||||
return cell;
|
return cell;
|
||||||
@ -459,6 +475,19 @@ function write_Format(i/*:number*/, f/*:string*/, opts, o) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
var parse_BIFF2Format = parse_XLUnicodeString2;
|
var parse_BIFF2Format = parse_XLUnicodeString2;
|
||||||
|
function write_BIFF2Format(f/*:string*/) {
|
||||||
|
var o = new_buf(1 + f.length);
|
||||||
|
o.write_shift(1, f.length);
|
||||||
|
o.write_shift(f.length, f, "sbcs");
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BIFF4Format(f/*:string*/) {
|
||||||
|
var o = new_buf(3 + f.length);
|
||||||
|
o.l += 2;
|
||||||
|
o.write_shift(1, f.length);
|
||||||
|
o.write_shift(f.length, f, "sbcs");
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
/* [MS-XLS] 2.4.90 */
|
/* [MS-XLS] 2.4.90 */
|
||||||
function parse_Dimensions(blob, length, opts) {
|
function parse_Dimensions(blob, length, opts) {
|
||||||
@ -582,6 +611,44 @@ function write_XF(data, ixfeP, opts, o) {
|
|||||||
o.write_shift(2, 0);
|
o.write_shift(2, 0);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
function parse_BIFF2XF(blob/*::, length, opts*/) {
|
||||||
|
var o = {};
|
||||||
|
o.ifnt = blob.read_shift(1); blob.l++; o.flags = blob.read_shift(1);
|
||||||
|
o.numFmtId = o.flags & 0x3F; o.flags>>=6;
|
||||||
|
o.fStyle = 0;
|
||||||
|
o.data = {}; // TODO
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BIFF2XF(xf) {
|
||||||
|
var o = new_buf(4);
|
||||||
|
o.l+=2;
|
||||||
|
o.write_shift(1, xf.numFmtId);
|
||||||
|
o.l++;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BIFF3XF(xf) {
|
||||||
|
var o = new_buf(12);
|
||||||
|
o.l++;
|
||||||
|
o.write_shift(1, xf.numFmtId);
|
||||||
|
o.l += 10;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
/* TODO: check other fields */
|
||||||
|
var write_BIFF4XF = write_BIFF3XF;
|
||||||
|
function parse_BIFF3XF(blob/*::, length, opts*/) {
|
||||||
|
var o = {};
|
||||||
|
o.ifnt = blob.read_shift(1); o.numFmtId = blob.read_shift(1); o.flags = blob.read_shift(2);
|
||||||
|
o.fStyle = (o.flags >> 2) & 0x01;
|
||||||
|
o.data = {}; // TODO
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_BIFF4XF(blob/*::, length, opts*/) {
|
||||||
|
var o = {};
|
||||||
|
o.ifnt = blob.read_shift(1); o.numFmtId = blob.read_shift(1); o.flags = blob.read_shift(2);
|
||||||
|
o.fStyle = (o.flags >> 2) & 0x01;
|
||||||
|
o.data = {}; // TODO
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
/* [MS-XLS] 2.4.134 */
|
/* [MS-XLS] 2.4.134 */
|
||||||
function parse_Guts(blob) {
|
function parse_Guts(blob) {
|
||||||
@ -602,8 +669,7 @@ function write_Guts(guts/*:Array<number>*/) {
|
|||||||
|
|
||||||
/* [MS-XLS] 2.4.24 */
|
/* [MS-XLS] 2.4.24 */
|
||||||
function parse_BoolErr(blob, length, opts) {
|
function parse_BoolErr(blob, length, opts) {
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, 6, opts);
|
||||||
if(opts.biff == 2 || length == 9) ++blob.l;
|
|
||||||
var val = parse_Bes(blob, 2);
|
var val = parse_Bes(blob, 2);
|
||||||
cell.val = val;
|
cell.val = val;
|
||||||
cell.t = (val === true || val === false) ? 'b' : 'e';
|
cell.t = (val === true || val === false) ? 'b' : 'e';
|
||||||
@ -619,7 +685,7 @@ function write_BoolErr(R/*:number*/, C/*:number*/, v, os/*:number*/, opts, t/*:s
|
|||||||
/* [MS-XLS] 2.4.180 Number */
|
/* [MS-XLS] 2.4.180 Number */
|
||||||
function parse_Number(blob, length, opts) {
|
function parse_Number(blob, length, opts) {
|
||||||
if(opts.biffguess && opts.biff == 2) opts.biff = 5;
|
if(opts.biffguess && opts.biff == 2) opts.biff = 5;
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, 6, opts);
|
||||||
var xnum = parse_Xnum(blob, 8);
|
var xnum = parse_Xnum(blob, 8);
|
||||||
cell.val = xnum;
|
cell.val = xnum;
|
||||||
return cell;
|
return cell;
|
||||||
@ -1029,43 +1095,50 @@ function parse_ImData(blob) {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function write_BIFF2Cell(out, r/*:number*/, c/*:number*/, ixfe/*:number*/, ifmt/*:number*/) {
|
||||||
|
if(!out) out = new_buf(7);
|
||||||
|
out.write_shift(2, r);
|
||||||
|
out.write_shift(2, c);
|
||||||
|
out.write_shift(1, ixfe||0/* & 0x3F */);
|
||||||
|
out.write_shift(1, ifmt||0/* & 0x3F */);
|
||||||
|
out.write_shift(1, 0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
/* BIFF2_??? where ??? is the name from [XLS] */
|
/* BIFF2_??? where ??? is the name from [XLS] */
|
||||||
function parse_BIFF2STR(blob, length, opts) {
|
function parse_BIFF2STR(blob, length, opts) {
|
||||||
if(opts.biffguess && opts.biff == 5) opts.biff = 2;
|
if(opts.biffguess && opts.biff == 5) opts.biff = 2;
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, 7, opts);
|
||||||
++blob.l;
|
|
||||||
var str = parse_XLUnicodeString2(blob, length-7, opts);
|
var str = parse_XLUnicodeString2(blob, length-7, opts);
|
||||||
cell.t = 'str';
|
cell.t = 'str';
|
||||||
cell.val = str;
|
cell.val = str;
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_BIFF2NUM(blob/*::, length*/) {
|
function parse_BIFF2NUM(blob, length, opts) {
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, 7, opts);
|
||||||
++blob.l;
|
|
||||||
var num = parse_Xnum(blob, 8);
|
var num = parse_Xnum(blob, 8);
|
||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
cell.val = num;
|
cell.val = num;
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
function write_BIFF2NUM(r/*:number*/, c/*:number*/, val/*:number*/) {
|
function write_BIFF2NUM(r/*:number*/, c/*:number*/, val/*:number*/, ixfe, ifmt) {
|
||||||
var out = new_buf(15);
|
var out = new_buf(15);
|
||||||
write_BIFF2Cell(out, r, c);
|
write_BIFF2Cell(out, r, c, ixfe||0, ifmt||0);
|
||||||
out.write_shift(8, val, 'f');
|
out.write_shift(8, val, 'f');
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_BIFF2INT(blob) {
|
function parse_BIFF2INT(blob, length, opts) {
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, 7, opts);
|
||||||
++blob.l;
|
|
||||||
var num = blob.read_shift(2);
|
var num = blob.read_shift(2);
|
||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
cell.val = num;
|
cell.val = num;
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
function write_BIFF2INT(r/*:number*/, c/*:number*/, val/*:number*/) {
|
function write_BIFF2INT(r/*:number*/, c/*:number*/, val/*:number*/, ixfe/*:number*/, ifmt/*:number*/) {
|
||||||
var out = new_buf(9);
|
var out = new_buf(9);
|
||||||
write_BIFF2Cell(out, r, c);
|
write_BIFF2Cell(out, r, c, ixfe||0, ifmt||0);
|
||||||
out.write_shift(2, val);
|
out.write_shift(2, val);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -1076,6 +1149,16 @@ function parse_BIFF2STRING(blob) {
|
|||||||
return blob.read_shift(cch, 'sbcs-cont');
|
return blob.read_shift(cch, 'sbcs-cont');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_BIFF2BOOLERR(blob, length, opts) {
|
||||||
|
var bestart = blob.l + 7;
|
||||||
|
var cell = parse_XLSCell(blob, 6, opts);
|
||||||
|
blob.l = bestart;
|
||||||
|
var val = parse_Bes(blob, 2);
|
||||||
|
cell.val = val;
|
||||||
|
cell.t = (val === true || val === false) ? 'b' : 'e';
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: convert to BIFF8 font struct */
|
/* TODO: convert to BIFF8 font struct */
|
||||||
function parse_BIFF2FONTXTRA(blob, length) {
|
function parse_BIFF2FONTXTRA(blob, length) {
|
||||||
blob.l += 6; // unknown
|
blob.l += 6; // unknown
|
||||||
@ -1089,7 +1172,7 @@ function parse_BIFF2FONTXTRA(blob, length) {
|
|||||||
/* TODO: parse rich text runs */
|
/* TODO: parse rich text runs */
|
||||||
function parse_RString(blob, length, opts) {
|
function parse_RString(blob, length, opts) {
|
||||||
var end = blob.l + length;
|
var end = blob.l + length;
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, 6, opts);
|
||||||
var cch = blob.read_shift(2);
|
var cch = blob.read_shift(2);
|
||||||
var str = parse_XLUnicodeStringNoCch(blob, cch, opts);
|
var str = parse_XLUnicodeStringNoCch(blob, cch, opts);
|
||||||
blob.l = end;
|
blob.l = end;
|
||||||
@ -1097,3 +1180,10 @@ function parse_RString(blob, length, opts) {
|
|||||||
cell.val = str;
|
cell.val = str;
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_BIFF4SheetInfo(blob/*::, length, opts*/) {
|
||||||
|
var flags = blob.read_shift(4);
|
||||||
|
var cch = blob.read_shift(1), name = blob.read_shift(cch, "sbcs");
|
||||||
|
if(name.length === 0) name = "Sheet1";
|
||||||
|
return { flags: flags, name:name };
|
||||||
|
}
|
@ -179,7 +179,10 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
|||||||
if(s.trim().length) out[R][C] = s.replace(/\s+$/,"");
|
if(s.trim().length) out[R][C] = s.replace(/\s+$/,"");
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
if(s.length === 8) out[R][C] = new Date(+s.slice(0,4), +s.slice(4,6)-1, +s.slice(6,8));
|
if(s.length === 8) {
|
||||||
|
out[R][C] = new Date(Date.UTC(+s.slice(0,4), +s.slice(4,6)-1, +s.slice(6,8), 0, 0, 0, 0));
|
||||||
|
if(!(opts && opts.UTC)) { out[R][C] = utc_to_local(out[R][C]); }
|
||||||
|
}
|
||||||
else out[R][C] = s;
|
else out[R][C] = s;
|
||||||
break;
|
break;
|
||||||
case 'F': out[R][C] = parseFloat(s.trim()); break;
|
case 'F': out[R][C] = parseFloat(s.trim()); break;
|
||||||
@ -202,7 +205,12 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
|||||||
// NOTE: dBASE specs appear to be incorrect
|
// NOTE: dBASE specs appear to be incorrect
|
||||||
out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400);
|
out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400);
|
||||||
break;
|
break;
|
||||||
case 'T': out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4)); break;
|
case 'T': {
|
||||||
|
var hi = dd.read_shift(4), lo = dd.read_shift(4);
|
||||||
|
if(hi == 0 && lo == 0) break;
|
||||||
|
out[R][C] = new Date((hi - 0x253D8C) * 0x5265C00 + lo);
|
||||||
|
if(!(opts && opts.UTC)) out[R][C] = utc_to_local(out[R][C]);
|
||||||
|
} break;
|
||||||
case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4 + (dd.read_shift(4, 'i')/1e4)*Math.pow(2,32); break;
|
case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4 + (dd.read_shift(4, 'i')/1e4)*Math.pow(2,32); break;
|
||||||
case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break;
|
case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break;
|
||||||
case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; }
|
case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; }
|
||||||
@ -473,10 +481,9 @@ var SYLK = /*#__PURE__*/(function() {
|
|||||||
else if(val === 'TRUE' || val === 'FALSE') { val = val === 'TRUE'; cell_t = "b"; }
|
else if(val === 'TRUE' || val === 'FALSE') { val = val === 'TRUE'; cell_t = "b"; }
|
||||||
else if(!isNaN(fuzzynum(val))) {
|
else if(!isNaN(fuzzynum(val))) {
|
||||||
val = fuzzynum(val); cell_t = "n";
|
val = fuzzynum(val); cell_t = "n";
|
||||||
if(next_cell_format !== null && fmt_is_date(next_cell_format) && opts.cellDates) { val = numdate(wb.Workbook.WBProps.date1904 ? val + 1462 : val); cell_t = "d"; }
|
if(next_cell_format !== null && fmt_is_date(next_cell_format) && opts.cellDates) {
|
||||||
} else if(!isNaN(fuzzydate(val).getDate())) {
|
val = numdate(wb.Workbook.WBProps.date1904 ? val + 1462 : val); cell_t = typeof val == "number" ? "n" : "d";
|
||||||
val = parseDate(val); cell_t = "d";
|
}
|
||||||
if(!opts.cellDates) { cell_t = "n"; val = datenum(val, wb.Workbook.WBProps.date1904); }
|
|
||||||
}
|
}
|
||||||
if(typeof $cptable !== 'undefined' && typeof val == "string" && ((opts||{}).type != "string") && (opts||{}).codepage) val = $cptable.utils.decode(opts.codepage, val);
|
if(typeof $cptable !== 'undefined' && typeof val == "string" && ((opts||{}).type != "string") && (opts||{}).codepage) val = $cptable.utils.decode(opts.codepage, val);
|
||||||
C_seen_K = true;
|
C_seen_K = true;
|
||||||
@ -577,7 +584,7 @@ var SYLK = /*#__PURE__*/(function() {
|
|||||||
return outwb;
|
return outwb;
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_ws_cell_sylk(cell/*:Cell*/, ws/*:Worksheet*/, R/*:number*/, C/*:number*//*::, opts*/)/*:string*/ {
|
function write_ws_cell_sylk(cell/*:Cell*/, ws/*:Worksheet*/, R/*:number*/, C/*:number*/, opts, date1904/*:boolean*/)/*:string*/ {
|
||||||
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
|
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
|
||||||
switch(cell.t) {
|
switch(cell.t) {
|
||||||
case 'n':
|
case 'n':
|
||||||
@ -585,7 +592,7 @@ var SYLK = /*#__PURE__*/(function() {
|
|||||||
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
|
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
|
||||||
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
|
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
|
||||||
case 'e': o += cell.w || cell.v; break;
|
case 'e': o += cell.w || cell.v; break;
|
||||||
case 'd': o += '"' + (cell.w || cell.v) + '"'; break;
|
case 'd': o += datenum(parseDate(cell.v, date1904), date1904); break;
|
||||||
case 's': o += '"' + (cell.v == null ? "" : String(cell.v)).replace(/"/g,"").replace(/;/g, ";;") + '"'; break;
|
case 's': o += '"' + (cell.v == null ? "" : String(cell.v)).replace(/"/g,"").replace(/;/g, ";;") + '"'; break;
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
@ -622,6 +629,7 @@ var SYLK = /*#__PURE__*/(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/, wb/*:?WorkBook*/)/*:string*/ {
|
function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/, wb/*:?WorkBook*/)/*:string*/ {
|
||||||
|
if(!opts) opts = {}; opts._formats = ["General"];
|
||||||
/* TODO: codepage */
|
/* TODO: codepage */
|
||||||
var preamble/*:Array<string>*/ = ["ID;PSheetJS;N;E"], o/*:Array<string>*/ = [];
|
var preamble/*:Array<string>*/ = ["ID;PSheetJS;N;E"], o/*:Array<string>*/ = [];
|
||||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||||
@ -629,34 +637,44 @@ var SYLK = /*#__PURE__*/(function() {
|
|||||||
var RS = "\r\n";
|
var RS = "\r\n";
|
||||||
var d1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
var d1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
||||||
|
|
||||||
|
var _lastfmt = "General";
|
||||||
preamble.push("P;PGeneral");
|
preamble.push("P;PGeneral");
|
||||||
|
/* Excel has been inconsistent in comment placement */
|
||||||
|
var R = r.s.r, C = r.s.c, p = [];
|
||||||
|
for(R = r.s.r; R <= r.e.r; ++R) {
|
||||||
|
if(dense && !ws["!data"][R]) continue;
|
||||||
|
p = [];
|
||||||
|
for(C = r.s.c; C <= r.e.c; ++C) {
|
||||||
|
cell = dense ? ws["!data"][R][C] : ws[encode_col(C) + encode_row(R)];
|
||||||
|
if(!cell || !cell.c) continue;
|
||||||
|
p.push(write_ws_cmnt_sylk(cell.c, R, C));
|
||||||
|
}
|
||||||
|
if(p.length) o.push(p.join(RS));
|
||||||
|
}
|
||||||
|
for(R = r.s.r; R <= r.e.r; ++R) {
|
||||||
|
if(dense && !ws["!data"][R]) continue;
|
||||||
|
p = [];
|
||||||
|
for(C = r.s.c; C <= r.e.c; ++C) {
|
||||||
|
cell = dense ? ws["!data"][R][C] : ws[encode_col(C) + encode_row(R)];
|
||||||
|
if(!cell || (cell.v == null && (!cell.f || cell.F))) continue;
|
||||||
|
if((cell.z||(cell.t == "d" ? table_fmt[14] : "General")) != _lastfmt) {
|
||||||
|
var ifmt = opts._formats.indexOf(cell.z);
|
||||||
|
if(ifmt == -1) { opts._formats.push(cell.z); ifmt = opts._formats.length - 1; preamble.push("P;P" + cell.z.replace(/;/g, ";;")); }
|
||||||
|
p.push("F;P" + ifmt + ";Y" + (R+1) + ";X" + (C+1));
|
||||||
|
}
|
||||||
|
p.push(write_ws_cell_sylk(cell, ws, R, C, opts, d1904));
|
||||||
|
}
|
||||||
|
o.push(p.join(RS));
|
||||||
|
}
|
||||||
|
|
||||||
preamble.push("F;P0;DG0G8;M255");
|
preamble.push("F;P0;DG0G8;M255");
|
||||||
if(ws['!cols']) write_ws_cols_sylk(preamble, ws['!cols']);
|
if(ws['!cols']) write_ws_cols_sylk(preamble, ws['!cols']);
|
||||||
if(ws['!rows']) write_ws_rows_sylk(preamble, ws['!rows']);
|
if(ws['!rows']) write_ws_rows_sylk(preamble, ws['!rows']);
|
||||||
|
|
||||||
preamble.push("B;Y" + (r.e.r - r.s.r + 1) + ";X" + (r.e.c - r.s.c + 1) + ";D" + [r.s.c,r.s.r,r.e.c,r.e.r].join(" "));
|
preamble.push("B;Y" + (r.e.r - r.s.r + 1) + ";X" + (r.e.c - r.s.c + 1) + ";D" + [r.s.c,r.s.r,r.e.c,r.e.r].join(" "));
|
||||||
preamble.push("O;L;D;B" + (d1904 ? ";V4" : "") + ";K47;G100 0.001");
|
preamble.push("O;L;D;B" + (d1904 ? ";V4" : "") + ";K47;G100 0.001");
|
||||||
/* Excel has been inconsistent in comment placement, */
|
|
||||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
delete opts._formats;
|
||||||
if(dense && !ws["!data"][R]) continue;
|
|
||||||
var p = [];
|
|
||||||
for(var C = r.s.c; C <= r.e.c; ++C) {
|
|
||||||
cell = dense ? ws["!data"][R][C] : ws[encode_col(C) + encode_row(R)];
|
|
||||||
if(!cell || !cell.c) continue;
|
|
||||||
p.push(write_ws_cmnt_sylk(cell.c, R, C)); // TODO: pass date1904 info
|
|
||||||
}
|
|
||||||
o.push(p.join(RS));
|
|
||||||
}
|
|
||||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
|
||||||
if(dense && !ws["!data"][R]) continue;
|
|
||||||
var p = [];
|
|
||||||
for(var C = r.s.c; C <= r.e.c; ++C) {
|
|
||||||
cell = dense ? ws["!data"][R][C] : ws[encode_col(C) + encode_row(R)];
|
|
||||||
if(!cell || (cell.v == null && (!cell.f || cell.F))) continue;
|
|
||||||
p.push(write_ws_cell_sylk(cell, ws, R, C, opts)); // TODO: pass date1904 info
|
|
||||||
}
|
|
||||||
o.push(p.join(RS));
|
|
||||||
}
|
|
||||||
return preamble.join(RS) + RS + o.join(RS) + RS + "E" + RS;
|
return preamble.join(RS) + RS + o.join(RS) + RS + "E" + RS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,7 +714,10 @@ var DIF = /*#__PURE__*/(function() {
|
|||||||
if(data === 'TRUE') arr[R][C] = true;
|
if(data === 'TRUE') arr[R][C] = true;
|
||||||
else if(data === 'FALSE') arr[R][C] = false;
|
else if(data === 'FALSE') arr[R][C] = false;
|
||||||
else if(!isNaN(fuzzynum(value))) arr[R][C] = fuzzynum(value);
|
else if(!isNaN(fuzzynum(value))) arr[R][C] = fuzzynum(value);
|
||||||
else if(!isNaN(fuzzydate(value).getDate())) arr[R][C] = parseDate(value);
|
else if(!isNaN(fuzzydate(value).getDate())) {
|
||||||
|
arr[R][C] = parseDate(value);
|
||||||
|
if(!(opts && opts.UTC)) { arr[R][C] = utc_to_local(arr[R][C]); }
|
||||||
|
}
|
||||||
else arr[R][C] = value;
|
else arr[R][C] = value;
|
||||||
++C; break;
|
++C; break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -977,9 +998,11 @@ var PRN = /*#__PURE__*/(function() {
|
|||||||
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0, startcc=str.charCodeAt(0);
|
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0, startcc=str.charCodeAt(0);
|
||||||
var _re/*:?RegExp*/ = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
|
var _re/*:?RegExp*/ = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
|
||||||
function finish_cell() {
|
function finish_cell() {
|
||||||
|
/* TODO: fuzzy parsers should pass back assumed number format */
|
||||||
var s = str.slice(start, end); if(s.slice(-1) == "\r") s = s.slice(0, -1);
|
var s = str.slice(start, end); if(s.slice(-1) == "\r") s = s.slice(0, -1);
|
||||||
var cell = ({}/*:any*/);
|
var cell = ({}/*:any*/);
|
||||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||||
|
if(o.cellText !== false) cell.w = s;
|
||||||
if(s.length === 0) cell.t = 'z';
|
if(s.length === 0) cell.t = 'z';
|
||||||
else if(o.raw) { cell.t = 's'; cell.v = s; }
|
else if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||||
else if(s.trim().length === 0) { cell.t = 's'; cell.v = s; }
|
else if(s.trim().length === 0) { cell.t = 's'; cell.v = s; }
|
||||||
@ -989,14 +1012,14 @@ var PRN = /*#__PURE__*/(function() {
|
|||||||
else { cell.t = 's'; cell.v = s; } }
|
else { cell.t = 's'; cell.v = s; } }
|
||||||
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
||||||
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
||||||
else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; if(o.cellText !== false) cell.w = s; cell.v = v; }
|
else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; cell.v = v; }
|
||||||
else if(!isNaN((v = fuzzydate(s)).getDate()) || _re && s.match(_re)) {
|
else if(!isNaN((v = fuzzydate(s)).getDate()) || _re && s.match(_re)) {
|
||||||
cell.z = o.dateNF || table_fmt[14];
|
cell.z = o.dateNF || table_fmt[14];
|
||||||
var k = 0;
|
if(_re && s.match(_re)){ var news=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); v = parseDate(news); if(o && o.UTC === false) v = utc_to_local(v); }
|
||||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; v = parseDate(s, k); }
|
else if(o && o.UTC === false) v = utc_to_local(v);
|
||||||
|
else if(o.cellText !== false && o.dateNF) cell.w = SSF_format(cell.z, v);
|
||||||
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
|
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
|
||||||
else { cell.t = 'n'; cell.v = datenum(v); }
|
else { cell.t = 'n'; cell.v = datenum(v); }
|
||||||
if(o.cellText !== false) cell.w = SSF_format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
|
|
||||||
if(!o.cellNF) delete cell.z;
|
if(!o.cellNF) delete cell.z;
|
||||||
} else {
|
} else {
|
||||||
cell.t = 's';
|
cell.t = 's';
|
||||||
|
137
bits/41_lotus.js
137
bits/41_lotus.js
@ -24,6 +24,22 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
throw "Unsupported type " + opts.type;
|
throw "Unsupported type " + opts.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOTE: this list intentionally starts at 1 */
|
||||||
|
var LOTUS_DATE_FMTS = [
|
||||||
|
"mmmm",
|
||||||
|
"dd-mmm-yyyy",
|
||||||
|
"dd-mmm",
|
||||||
|
"mmm-yyyy",
|
||||||
|
"@", // "text"?
|
||||||
|
"mm/dd",
|
||||||
|
"hh:mm:ss AM/PM", // 7
|
||||||
|
"hh:mm AM/PM",
|
||||||
|
"mm/dd/yyyy",
|
||||||
|
"mm/dd",
|
||||||
|
"hh:mm:ss",
|
||||||
|
"hh:mm" // 12
|
||||||
|
];
|
||||||
|
|
||||||
function lotus_to_workbook_buf(d, opts)/*:Workbook*/ {
|
function lotus_to_workbook_buf(d, opts)/*:Workbook*/ {
|
||||||
if(!d) return d;
|
if(!d) return d;
|
||||||
var o = opts || {};
|
var o = opts || {};
|
||||||
@ -34,6 +50,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
|
|
||||||
var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
|
var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
|
||||||
var sheetRows = o.sheetRows || 0;
|
var sheetRows = o.sheetRows || 0;
|
||||||
|
var lastcell = {};
|
||||||
|
|
||||||
if(d[4] == 0x51 && d[5] == 0x50 && d[6] == 0x57) return qpw_to_workbook_buf(d, opts);
|
if(d[4] == 0x51 && d[5] == 0x50 && d[6] == 0x57) return qpw_to_workbook_buf(d, opts);
|
||||||
if(d[2] == 0x00) {
|
if(d[2] == 0x00) {
|
||||||
@ -65,9 +82,9 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
case 0x0E: /* NUMBER */
|
case 0x0E: /* NUMBER */
|
||||||
case 0x10: /* FORMULA */
|
case 0x10: /* FORMULA */
|
||||||
/* TODO: actual translation of the format code */
|
/* TODO: actual translation of the format code */
|
||||||
if(RT == 0x0E && (val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
|
if((val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
|
||||||
val[1].z = o.dateNF || table_fmt[14];
|
val[1].z = o.dateNF || LOTUS_DATE_FMTS[(val[2] & 0x0F)-1] || table_fmt[14];
|
||||||
if(o.cellDates) { val[1].t = 'd'; val[1].v = numdate(val[1].v); }
|
if(o.cellDates) { val[1].v = numdate(val[1].v); val[1].t = typeof val[1].v == "number" ? 'n' : 'd'; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if(o.qpro) {
|
if(o.qpro) {
|
||||||
@ -86,15 +103,25 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
tmpcell.t = val[1].t; tmpcell.v = val[1].v;
|
tmpcell.t = val[1].t; tmpcell.v = val[1].v;
|
||||||
if(val[1].z != null) tmpcell.z = val[1].z;
|
if(val[1].z != null) tmpcell.z = val[1].z;
|
||||||
if(val[1].f != null) tmpcell.f = val[1].f;
|
if(val[1].f != null) tmpcell.f = val[1].f;
|
||||||
|
lastcell = tmpcell;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(o.dense) {
|
if(o.dense) {
|
||||||
if(!sdata[val[0].r]) sdata[val[0].r] = [];
|
if(!sdata[val[0].r]) sdata[val[0].r] = [];
|
||||||
sdata[val[0].r][val[0].c] = val[1];
|
sdata[val[0].r][val[0].c] = val[1];
|
||||||
} else s[encode_cell(val[0])] = val[1];
|
} else s[encode_cell(val[0])] = val[1];
|
||||||
|
lastcell = val[1];
|
||||||
break;
|
break;
|
||||||
case 0x5405: o.works2 = true; break;
|
case 0x5405: o.works2 = true; break;
|
||||||
default:
|
case 0x5402: {
|
||||||
|
/* TODO: enumerate all extended number formats */
|
||||||
|
if(val == 0x14a1) {
|
||||||
|
lastcell.z = "hh:mm:ss";
|
||||||
|
if(o.cellDates && lastcell.t == "n") {
|
||||||
|
lastcell.v = numdate(lastcell.v); lastcell.t = typeof lastcell.v == "number" ? 'n' : 'd';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}}, o);
|
}}, o);
|
||||||
} else if(d[2] == 0x1A || d[2] == 0x0E) {
|
} else if(d[2] == 0x1A || d[2] == 0x0E) {
|
||||||
o.Enum = WK3Enum;
|
o.Enum = WK3Enum;
|
||||||
@ -171,10 +198,17 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
var cell = dense ? (ws["!data"][R]||[])[C] : ws[cols[C] + rr];
|
var cell = dense ? (ws["!data"][R]||[])[C] : ws[cols[C] + rr];
|
||||||
if(!cell || cell.t == "z") continue;
|
if(!cell || cell.t == "z") continue;
|
||||||
/* TODO: formula records */
|
/* TODO: formula records */
|
||||||
if(cell.t == "n") {
|
switch(cell.t) {
|
||||||
if((cell.v|0)==cell.v && cell.v >= -32768 && cell.v <= 32767) write_biff_rec(ba, 0x0d, write_INTEGER(R, C, cell.v));
|
case "n":
|
||||||
else write_biff_rec(ba, 0x0e, write_NUMBER(R, C, cell.v));
|
if((cell.v|0)==cell.v && cell.v >= -32768 && cell.v <= 32767) write_biff_rec(ba, 0x0d, write_INTEGER(R, C, cell));
|
||||||
} else {
|
else write_biff_rec(ba, 0x0e, write_NUMBER(R, C, cell));
|
||||||
|
break;
|
||||||
|
case "d":
|
||||||
|
var dc = datenum(cell.v);
|
||||||
|
if((dc|0)==dc && dc >= -32768 && dc <= 32767) write_biff_rec(ba, 0x0d, write_INTEGER(R, C, {t:"n", v:dc, z:cell.z || table_fmt[14]}));
|
||||||
|
else write_biff_rec(ba, 0x0e, write_NUMBER(R, C, {t:"n", v:dc, z:cell.z || table_fmt[14]}));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
var str = format_cell(cell);
|
var str = format_cell(cell);
|
||||||
write_biff_rec(ba, 0x0F, write_LABEL(R, C, str.slice(0, 239)));
|
write_biff_rec(ba, 0x0F, write_LABEL(R, C, str.slice(0, 239)));
|
||||||
}
|
}
|
||||||
@ -308,11 +342,18 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_wk1_fmt(cell)/*:number*/ {
|
||||||
|
/* TODO: some fuzzy matching on the number format */
|
||||||
|
if(cell.z && fmt_is_date(cell.z)) {
|
||||||
|
return 0xf0 | (LOTUS_DATE_FMTS.indexOf(cell.z) + 1 || 2);
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
function parse_LABEL(blob, length, opts) {
|
function parse_LABEL(blob, length, opts) {
|
||||||
var tgt = blob.l + length;
|
var tgt = blob.l + length;
|
||||||
var o = parse_cell(blob, length, opts);
|
var o = parse_cell(blob, length, opts);
|
||||||
o[1].t = 's';
|
o[1].t = 's';
|
||||||
if(opts.vers == 0x5120) {
|
if((opts.vers & 0xFFFE) == 0x5120) { // WQ1 / WQ2
|
||||||
blob.l++;
|
blob.l++;
|
||||||
var len = blob.read_shift(1);
|
var len = blob.read_shift(1);
|
||||||
o[1].v = blob.read_shift(len, 'utf8');
|
o[1].v = blob.read_shift(len, 'utf8');
|
||||||
@ -354,12 +395,12 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
o[1].v = blob.read_shift(2, 'i');
|
o[1].v = blob.read_shift(2, 'i');
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
function write_INTEGER(R, C, v) {
|
function write_INTEGER(R, C, cell) {
|
||||||
var o = new_buf(7);
|
var o = new_buf(7);
|
||||||
o.write_shift(1, 0xFF);
|
o.write_shift(1, get_wk1_fmt(cell));
|
||||||
o.write_shift(2, C);
|
o.write_shift(2, C);
|
||||||
o.write_shift(2, R);
|
o.write_shift(2, R);
|
||||||
o.write_shift(2, v, 'i');
|
o.write_shift(2, cell.v, 'i');
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,12 +409,12 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
o[1].v = blob.read_shift(8, 'f');
|
o[1].v = blob.read_shift(8, 'f');
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
function write_NUMBER(R, C, v) {
|
function write_NUMBER(R, C, cell) {
|
||||||
var o = new_buf(13);
|
var o = new_buf(13);
|
||||||
o.write_shift(1, 0xFF);
|
o.write_shift(1, get_wk1_fmt(cell));
|
||||||
o.write_shift(2, C);
|
o.write_shift(2, C);
|
||||||
o.write_shift(2, R);
|
o.write_shift(2, R);
|
||||||
o.write_shift(8, v, 'f');
|
o.write_shift(8, cell.v, 'f');
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +467,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
0x33: ["FALSE", 0],
|
0x33: ["FALSE", 0],
|
||||||
0x34: ["TRUE", 0],
|
0x34: ["TRUE", 0],
|
||||||
0x35: ["RAND", 0],
|
0x35: ["RAND", 0],
|
||||||
// 0x36 DATE
|
0x36: ["DATE", 3],
|
||||||
// 0x37 NOW
|
// 0x37 NOW
|
||||||
// 0x38 PMT
|
// 0x38 PMT
|
||||||
// 0x39 PV
|
// 0x39 PV
|
||||||
@ -436,7 +477,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
// 0x3D MONTH
|
// 0x3D MONTH
|
||||||
// 0x3E YEAR
|
// 0x3E YEAR
|
||||||
0x3F: ["ROUND", 2],
|
0x3F: ["ROUND", 2],
|
||||||
// 0x40 TIME
|
0x40: ["TIME", 3],
|
||||||
// 0x41 HOUR
|
// 0x41 HOUR
|
||||||
// 0x42 MINUTE
|
// 0x42 MINUTE
|
||||||
// 0x43 SECOND
|
// 0x43 SECOND
|
||||||
@ -778,13 +819,24 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
/*::[*/0x0048/*::]*/: { n:"ACOMM" },
|
/*::[*/0x0048/*::]*/: { n:"ACOMM" },
|
||||||
/*::[*/0x0049/*::]*/: { n:"AMACRO" },
|
/*::[*/0x0049/*::]*/: { n:"AMACRO" },
|
||||||
/*::[*/0x004A/*::]*/: { n:"PARSE" },
|
/*::[*/0x004A/*::]*/: { n:"PARSE" },
|
||||||
|
// 0x0064
|
||||||
/*::[*/0x0066/*::]*/: { n:"PRANGES??" },
|
/*::[*/0x0066/*::]*/: { n:"PRANGES??" },
|
||||||
/*::[*/0x0067/*::]*/: { n:"RRANGES??" },
|
/*::[*/0x0067/*::]*/: { n:"RRANGES??" },
|
||||||
/*::[*/0x0068/*::]*/: { n:"FNAME??" },
|
/*::[*/0x0068/*::]*/: { n:"FNAME??" },
|
||||||
/*::[*/0x0069/*::]*/: { n:"MRANGES??" },
|
/*::[*/0x0069/*::]*/: { n:"MRANGES??" },
|
||||||
|
// 0x0096
|
||||||
|
// 0x0099
|
||||||
|
// 0x009A
|
||||||
|
// 0x009B
|
||||||
|
// 0x009C
|
||||||
|
// 0x00C0
|
||||||
|
// 0x00C7
|
||||||
|
// 0x00C9
|
||||||
/*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
/*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
||||||
|
// 0x00CD
|
||||||
/*::[*/0x00DE/*::]*/: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
|
/*::[*/0x00DE/*::]*/: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
|
||||||
/*::[*/0x00FF/*::]*/: { n:"BOF", f:parseuint16 },
|
/*::[*/0x00FF/*::]*/: { n:"BOF", f:parseuint16 },
|
||||||
|
/*::[*/0x5402/*::]*/: { n:"WKSNF", f:parseuint16 },
|
||||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -914,6 +966,24 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* TODO: fill out and verify this table across QP versions */
|
||||||
|
var QPWNFTable = {
|
||||||
|
/*::[*/0x05/*::*/: "dd-mmm-yy",
|
||||||
|
/*::[*/0x06/*::*/: "dd-mmm",
|
||||||
|
/*::[*/0x07/*::*/: "mmm-yy",
|
||||||
|
/*::[*/0x08/*::*/: "mm/dd/yy", // Long Date Intl
|
||||||
|
/*::[*/0x0A/*::*/: "hh:mm:ss AM/PM",
|
||||||
|
/*::[*/0x0B/*::*/: "hh:mm AM/PM",
|
||||||
|
/*::[*/0x0E/*::*/: "dd-mmm-yyyy",
|
||||||
|
/*::[*/0x0F/*::*/: "mmm-yyyy",
|
||||||
|
|
||||||
|
/*::[*/0x22/*::*/: "0.00",
|
||||||
|
/*::[*/0x32/*::*/: "0.00;[Red]0.00",
|
||||||
|
/*::[*/0x42/*::*/: "0.00;\(0.00\)",
|
||||||
|
/*::[*/0x52/*::*/: "0.00;[Red]\(0.00\)",
|
||||||
|
|
||||||
|
/*::[*/162/*::*/: '"$"#,##0;\\("$"#,##0\\)' // slightly different from SSF 5
|
||||||
|
};
|
||||||
/* QPW uses a different set of record types */
|
/* QPW uses a different set of record types */
|
||||||
function qpw_to_workbook_buf(d, opts)/*:Workbook*/ {
|
function qpw_to_workbook_buf(d, opts)/*:Workbook*/ {
|
||||||
prep_blob(d, 0);
|
prep_blob(d, 0);
|
||||||
@ -924,6 +994,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
var range = {s:{r:-1,c:-1}, e:{r:-1,c:-1}};
|
var range = {s:{r:-1,c:-1}, e:{r:-1,c:-1}};
|
||||||
var cnt = 0, type = 0, C = 0, R = 0;
|
var cnt = 0, type = 0, C = 0, R = 0;
|
||||||
var wb = { SheetNames: [], Sheets: {} };
|
var wb = { SheetNames: [], Sheets: {} };
|
||||||
|
var FMTS = [];
|
||||||
outer: while(d.l < d.length) {
|
outer: while(d.l < d.length) {
|
||||||
var RT = d.read_shift(2), length = d.read_shift(2);
|
var RT = d.read_shift(2), length = d.read_shift(2);
|
||||||
var p = d.slice(d.l, d.l + length);
|
var p = d.slice(d.l, d.l + length);
|
||||||
@ -934,6 +1005,22 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
break;
|
break;
|
||||||
case 0x02: /* EOF */ break outer;
|
case 0x02: /* EOF */ break outer;
|
||||||
|
|
||||||
|
case 0x08: /* NF */ break; // TODO: this is tied to custom number formats
|
||||||
|
|
||||||
|
case 0x0A: /* FORMATS */ {
|
||||||
|
var fcnt = p.read_shift(4);
|
||||||
|
var step = ((p.length - p.l)/ fcnt)|0;
|
||||||
|
for(var ifmt = 0; ifmt < fcnt; ++ifmt) {
|
||||||
|
var end = p.l + step;
|
||||||
|
var fmt = {};
|
||||||
|
p.l += 2;
|
||||||
|
fmt.numFmtId = p.read_shift(2);
|
||||||
|
if(QPWNFTable[fmt.numFmtId]) fmt.z = QPWNFTable[fmt.numFmtId];
|
||||||
|
p.l = end;
|
||||||
|
FMTS.push(fmt);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
/* TODO: The behavior here should be consistent with Numbers: QP Notebook ~ .TN.SheetArchive, QP Sheet ~ .TST.TableModelArchive */
|
/* TODO: The behavior here should be consistent with Numbers: QP Notebook ~ .TN.SheetArchive, QP Sheet ~ .TST.TableModelArchive */
|
||||||
case 0x0401: /* BON */ break;
|
case 0x0401: /* BON */ break;
|
||||||
case 0x0402: /* EON */ /* TODO: backfill missing sheets based on BON cnt */ break;
|
case 0x0402: /* EON */ /* TODO: backfill missing sheets based on BON cnt */ break;
|
||||||
@ -996,18 +1083,21 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
var CC = encode_col(C);
|
var CC = encode_col(C);
|
||||||
while(p.l < p.length) {
|
while(p.l < p.length) {
|
||||||
var cell = { t: "z" };
|
var cell = { t: "z" };
|
||||||
var flags = p.read_shift(1);
|
var flags = p.read_shift(1), fmtidx = -1;
|
||||||
if(flags & 0x80) p.l += 2;
|
if(flags & 0x80) fmtidx = p.read_shift(2);
|
||||||
var mul = (flags & 0x40) ? p.read_shift(2) - 1: 0;
|
var mul = (flags & 0x40) ? p.read_shift(2) - 1: 0;
|
||||||
switch(flags & 0x1F) {
|
switch(flags & 0x1F) {
|
||||||
|
case 0: break;
|
||||||
case 1: break;
|
case 1: break;
|
||||||
case 2: cell = { t: "n", v: p.read_shift(2) }; break;
|
case 2: cell = { t: "n", v: p.read_shift(2) }; break;
|
||||||
case 3: cell = { t: "n", v: p.read_shift(2, 'i') }; break;
|
case 3: cell = { t: "n", v: p.read_shift(2, 'i') }; break;
|
||||||
|
case 4: cell = { t: "n", v: parse_RkNumber(p) }; break;
|
||||||
case 5: cell = { t: "n", v: p.read_shift(8, 'f') }; break;
|
case 5: cell = { t: "n", v: p.read_shift(8, 'f') }; break;
|
||||||
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
||||||
case 8: cell = { t: "n", v: p.read_shift(8, 'f') }; p.l += 2; /* cell.f = formulae[p.read_shift(4)]; */ p.l += 4; break;
|
case 8: cell = { t: "n", v: p.read_shift(8, 'f') }; p.l += 2; /* cell.f = formulae[p.read_shift(4)]; */ p.l += 4; break;
|
||||||
default: throw "Unrecognized QPW cell type " + (flags & 0x1F);
|
default: throw "Unrecognized QPW cell type " + (flags & 0x1F);
|
||||||
}
|
}
|
||||||
|
if(fmtidx != -1 && (FMTS[fmtidx - 1]||{}).z) cell.z = FMTS[fmtidx-1].z;
|
||||||
var delta = 0;
|
var delta = 0;
|
||||||
if(flags & 0x20) switch(flags & 0x1F) {
|
if(flags & 0x20) switch(flags & 0x1F) {
|
||||||
case 2: delta = p.read_shift(2); break;
|
case 2: delta = p.read_shift(2); break;
|
||||||
@ -1016,10 +1106,14 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
default: throw "Unsupported delta for QPW cell type " + (flags & 0x1F);
|
default: throw "Unsupported delta for QPW cell type " + (flags & 0x1F);
|
||||||
}
|
}
|
||||||
if(!(!o.sheetStubs && cell.t == "z")) {
|
if(!(!o.sheetStubs && cell.t == "z")) {
|
||||||
|
var newcell = dup(cell);
|
||||||
|
if(cell.t == "n" && cell.z && fmt_is_date(cell.z) && o.cellDates) {
|
||||||
|
newcell.v = numdate(cell.v); newcell.t = typeof newcell.v == "number" ? 'n' : 'd';
|
||||||
|
}
|
||||||
if(s["!data"] != null) {
|
if(s["!data"] != null) {
|
||||||
if(!s["!data"][R]) s["!data"][R] = [];
|
if(!s["!data"][R]) s["!data"][R] = [];
|
||||||
s["!data"][R][C] = cell;
|
s["!data"][R][C] = newcell;
|
||||||
} else s[CC + encode_row(R)] = cell;
|
} else s[CC + encode_row(R)] = newcell;
|
||||||
}
|
}
|
||||||
++R; --cnt;
|
++R; --cnt;
|
||||||
while(mul-- > 0 && cnt >= 0) {
|
while(mul-- > 0 && cnt >= 0) {
|
||||||
@ -1034,6 +1128,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||||||
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
||||||
default: throw "Cannot apply repeat for QPW cell type " + (flags & 0x1F);
|
default: throw "Cannot apply repeat for QPW cell type " + (flags & 0x1F);
|
||||||
}
|
}
|
||||||
|
if(fmtidx != -1);
|
||||||
if(!(!o.sheetStubs && cell.t == "z")) {
|
if(!(!o.sheetStubs && cell.t == "z")) {
|
||||||
if(s["!data"] != null) {
|
if(s["!data"] != null) {
|
||||||
if(!s["!data"][R]) s["!data"][R] = [];
|
if(!s["!data"][R]) s["!data"][R] = [];
|
||||||
|
@ -5,6 +5,7 @@ function parse_vml(data/*:string*/, sheet, comments) {
|
|||||||
(data.match(shapevmlregex)||[]).forEach(function(m) {
|
(data.match(shapevmlregex)||[]).forEach(function(m) {
|
||||||
var type = "";
|
var type = "";
|
||||||
var hidden = true;
|
var hidden = true;
|
||||||
|
var aidx = -1;
|
||||||
var R = -1, C = -1;
|
var R = -1, C = -1;
|
||||||
m.replace(tagregex, function(x/*:string*/, idx/*:number*/) {
|
m.replace(tagregex, function(x/*:string*/, idx/*:number*/) {
|
||||||
var y = parsexmltag(x);
|
var y = parsexmltag(x);
|
||||||
|
@ -68,8 +68,7 @@ function write_FormulaValue(value) {
|
|||||||
/* [MS-XLS] 2.4.127 TODO */
|
/* [MS-XLS] 2.4.127 TODO */
|
||||||
function parse_Formula(blob, length, opts) {
|
function parse_Formula(blob, length, opts) {
|
||||||
var end = blob.l + length;
|
var end = blob.l + length;
|
||||||
var cell = parse_XLSCell(blob, 6);
|
var cell = parse_XLSCell(blob, 6, opts);
|
||||||
if(opts.biff == 2) ++blob.l;
|
|
||||||
var val = parse_FormulaValue(blob,8);
|
var val = parse_FormulaValue(blob,8);
|
||||||
var flags = blob.read_shift(1);
|
var flags = blob.read_shift(1);
|
||||||
if(opts.biff != 2) {
|
if(opts.biff != 2) {
|
||||||
@ -263,7 +262,7 @@ function write_XLSBFormulaRangeWS(_str, wb) {
|
|||||||
var sname = _str.slice(0, lastbang);
|
var sname = _str.slice(0, lastbang);
|
||||||
_str = _str.slice(lastbang+1);
|
_str = _str.slice(lastbang+1);
|
||||||
if(sname.charAt(0) == "'") sname = sname.slice(1, -1).replace(/''/g, "'");
|
if(sname.charAt(0) == "'") sname = sname.slice(1, -1).replace(/''/g, "'");
|
||||||
var parts = _str.split(":"); str = parts[0];
|
var parts = _str.split(":");
|
||||||
|
|
||||||
var out = new_buf(27);
|
var out = new_buf(27);
|
||||||
out.write_shift(4, 19);
|
out.write_shift(4, 19);
|
||||||
|
@ -31,6 +31,6 @@ function ods_to_csf_3D(r/*:string*/)/*:[string, string]*/ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function csf_to_ods_3D(r/*:string*/)/*:string*/ {
|
function csf_to_ods_3D(r/*:string*/)/*:string*/ {
|
||||||
return r.replace(/!/,".");
|
return r.replace(/!/,".").replace(/:/, ":.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ function get_cell_style(styles/*:Array<any>*/, cell/*:Cell*/, opts) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
function safe_format(p/*:Cell*/, fmtid/*:number*/, fillid/*:?number*/, opts, themes, styles) {
|
function safe_format(p/*:Cell*/, fmtid/*:number*/, fillid/*:?number*/, opts, themes, styles, date1904) {
|
||||||
try {
|
try {
|
||||||
if(opts.cellNF) p.z = table_fmt[fmtid];
|
if(opts.cellNF) p.z = table_fmt[fmtid];
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
@ -96,14 +96,14 @@ function safe_format(p/*:Cell*/, fmtid/*:number*/, fillid/*:?number*/, opts, the
|
|||||||
else p.w = SSF_general_num(p.v);
|
else p.w = SSF_general_num(p.v);
|
||||||
}
|
}
|
||||||
else if(p.t === 'd') {
|
else if(p.t === 'd') {
|
||||||
var dd = datenum(p.v);
|
var dd = datenum(p.v, !!date1904);
|
||||||
if((dd|0) === dd) p.w = dd.toString(10);
|
if((dd|0) === dd) p.w = dd.toString(10);
|
||||||
else p.w = SSF_general_num(dd);
|
else p.w = SSF_general_num(dd);
|
||||||
}
|
}
|
||||||
else if(p.v === undefined) return "";
|
else if(p.v === undefined) return "";
|
||||||
else p.w = SSF_general(p.v,_ssfopts);
|
else p.w = SSF_general(p.v,_ssfopts);
|
||||||
}
|
}
|
||||||
else if(p.t === 'd') p.w = SSF_format(fmtid,datenum(p.v),_ssfopts);
|
else if(p.t === 'd') p.w = SSF_format(fmtid,datenum(p.v, !!date1904),_ssfopts);
|
||||||
else p.w = SSF_format(fmtid,p.v,_ssfopts);
|
else p.w = SSF_format(fmtid,p.v,_ssfopts);
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
if(!opts.cellStyles) return;
|
if(!opts.cellStyles) return;
|
||||||
|
@ -55,7 +55,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 18.3.1.80 sheetData CT_SheetData ? */
|
/* 18.3.1.80 sheetData CT_SheetData ? */
|
||||||
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles);
|
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles, wb);
|
||||||
|
|
||||||
/* 18.3.1.2 autoFilter CT_AutoFilter */
|
/* 18.3.1.2 autoFilter CT_AutoFilter */
|
||||||
var afilter = data2.match(afregex);
|
var afilter = data2.match(afregex);
|
||||||
@ -76,6 +76,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
|||||||
if(margins) s['!margins'] = parse_ws_xml_margins(parsexmltag(margins[0]));
|
if(margins) s['!margins'] = parse_ws_xml_margins(parsexmltag(margins[0]));
|
||||||
|
|
||||||
/* legacyDrawing */
|
/* legacyDrawing */
|
||||||
|
var m;
|
||||||
if((m = data2.match(/legacyDrawing r:id="(.*?)"/))) s['!legrel'] = m[1];
|
if((m = data2.match(/legacyDrawing r:id="(.*?)"/))) s['!legrel'] = m[1];
|
||||||
|
|
||||||
if(opts && opts.nodim) refguess.s.c = refguess.s.r = 0;
|
if(opts && opts.nodim) refguess.s.c = refguess.s.r = 0;
|
||||||
@ -261,7 +262,7 @@ function write_ws_xml_sheetviews(ws, opts, idx, wb)/*:string*/ {
|
|||||||
return writextag("sheetViews", writextag("sheetView", null, sview), {});
|
return writextag("sheetViews", writextag("sheetView", null, sview), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string*/ {
|
function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts, idx, wb, date1904)/*:string*/ {
|
||||||
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
||||||
if((cell.v === undefined || cell.t === "z" && !(opts||{}).sheetStubs) && typeof cell.f !== "string" && typeof cell.z == "undefined") return "";
|
if((cell.v === undefined || cell.t === "z" && !(opts||{}).sheetStubs) && typeof cell.f !== "string" && typeof cell.z == "undefined") return "";
|
||||||
var vv = "";
|
var vv = "";
|
||||||
@ -274,11 +275,14 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string
|
|||||||
else vv = ''+cell.v; break;
|
else vv = ''+cell.v; break;
|
||||||
case 'e': vv = BErr[cell.v]; break;
|
case 'e': vv = BErr[cell.v]; break;
|
||||||
case 'd':
|
case 'd':
|
||||||
if(opts && opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
|
if(opts && opts.cellDates) {
|
||||||
else {
|
var _vv = parseDate(cell.v, date1904);
|
||||||
|
vv = _vv.toISOString();
|
||||||
|
if(_vv.getUTCFullYear() < 1900) vv = vv.slice(vv.indexOf("T") + 1).replace("Z","");
|
||||||
|
} else {
|
||||||
cell = dup(cell);
|
cell = dup(cell);
|
||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
vv = ''+(cell.v = datenum(parseDate(cell.v)));
|
vv = ''+(cell.v = datenum(parseDate(cell.v, date1904), date1904));
|
||||||
}
|
}
|
||||||
if(typeof cell.z === 'undefined') cell.z = table_fmt[14];
|
if(typeof cell.z === 'undefined') cell.z = table_fmt[14];
|
||||||
break;
|
break;
|
||||||
@ -321,7 +325,7 @@ var parse_ws_xml_data = /*#__PURE__*/(function() {
|
|||||||
var refregex = /ref=["']([^"']*)["']/;
|
var refregex = /ref=["']([^"']*)["']/;
|
||||||
var match_v = matchtag("v"), match_f = matchtag("f");
|
var match_v = matchtag("v"), match_f = matchtag("f");
|
||||||
|
|
||||||
return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, themes, styles) {
|
return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, themes, styles, wb) {
|
||||||
var ri = 0, x = "", cells/*:Array<string>*/ = [], cref/*:?Array<string>*/ = [], idx=0, i=0, cc=0, d="", p/*:any*/;
|
var ri = 0, x = "", cells/*:Array<string>*/ = [], cref/*:?Array<string>*/ = [], idx=0, i=0, cc=0, d="", p/*:any*/;
|
||||||
var tag, tagr = 0, tagc = 0;
|
var tag, tagr = 0, tagc = 0;
|
||||||
var sstr, ftag;
|
var sstr, ftag;
|
||||||
@ -332,6 +336,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||||||
var dense = s["!data"] != null;
|
var dense = s["!data"] != null;
|
||||||
var rows/*:Array<RowInfo>*/ = [], rowobj = {}, rowrite = false;
|
var rows/*:Array<RowInfo>*/ = [], rowobj = {}, rowrite = false;
|
||||||
var sheetStubs = !!opts.sheetStubs;
|
var sheetStubs = !!opts.sheetStubs;
|
||||||
|
var date1904 = !!((wb||{}).WBProps||{}).date1904;
|
||||||
for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
|
for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
|
||||||
x = marr[mt].trim();
|
x = marr[mt].trim();
|
||||||
var xlen = x.length;
|
var xlen = x.length;
|
||||||
@ -476,8 +481,8 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||||||
break;
|
break;
|
||||||
case 'b': p.v = parsexmlbool(p.v); break;
|
case 'b': p.v = parsexmlbool(p.v); break;
|
||||||
case 'd':
|
case 'd':
|
||||||
if(opts.cellDates) p.v = parseDate(p.v, 1);
|
if(opts.cellDates) p.v = parseDate(p.v, date1904);
|
||||||
else { p.v = datenum(parseDate(p.v, 1)); p.t = 'n'; }
|
else { p.v = datenum(parseDate(p.v, date1904), date1904); p.t = 'n'; }
|
||||||
break;
|
break;
|
||||||
/* error string in .w, number in .v */
|
/* error string in .w, number in .v */
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -496,8 +501,8 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
safe_format(p, fmtid, fillid, opts, themes, styles, date1904);
|
||||||
if(opts.cellDates && do_format && p.t == 'n' && fmt_is_date(table_fmt[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
if(opts.cellDates && do_format && p.t == 'n' && fmt_is_date(table_fmt[fmtid])) { p.v = numdate(p.v + (date1904 ? 1462 : 0)); p.t = typeof p.v == "number" ? 'n' : 'd'; }
|
||||||
if(tag.cm && opts.xlmeta) {
|
if(tag.cm && opts.xlmeta) {
|
||||||
var cm = (opts.xlmeta.Cell||[])[+tag.cm-1];
|
var cm = (opts.xlmeta.Cell||[])[+tag.cm-1];
|
||||||
if(cm && cm.type == 'XLDAPR') p.D = true;
|
if(cm && cm.type == 'XLDAPR') p.D = true;
|
||||||
@ -522,6 +527,7 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
|||||||
var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
|
var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
|
||||||
var dense = ws["!data"] != null;
|
var dense = ws["!data"] != null;
|
||||||
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
|
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
|
||||||
|
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
||||||
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
||||||
for(R = range.s.r; R <= range.e.r; ++R) {
|
for(R = range.s.r; R <= range.e.r; ++R) {
|
||||||
r = [];
|
r = [];
|
||||||
@ -530,7 +536,7 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
|||||||
ref = cols[C] + rr;
|
ref = cols[C] + rr;
|
||||||
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
|
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
|
||||||
if(_cell === undefined) continue;
|
if(_cell === undefined) continue;
|
||||||
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb)) != null) r.push(cell);
|
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
|
||||||
}
|
}
|
||||||
if(r.length > 0 || (rows && rows[R])) {
|
if(r.length > 0 || (rows && rows[R])) {
|
||||||
params = ({r:rr}/*:any*/);
|
params = ({r:rr}/*:any*/);
|
||||||
|
@ -542,6 +542,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
||||||
|
|
||||||
var cm, vm;
|
var cm, vm;
|
||||||
|
var date1904 = 1462 * +!!((wb||{}).WBProps||{}).date1904;
|
||||||
|
|
||||||
recordhopper(data, function ws_parse(val, RR, RT) {
|
recordhopper(data, function ws_parse(val, RR, RT) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
@ -585,7 +586,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
case 'str': p.t = 's'; p.v = val[1]; break;
|
case 'str': p.t = 's'; p.v = val[1]; break;
|
||||||
case 'is': p.t = 's'; p.v = val[1].t; break;
|
case 'is': p.t = 's'; p.v = val[1].t; break;
|
||||||
}
|
}
|
||||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.numFmtId,null,opts, themes, styles);
|
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.numFmtId,null,opts, themes, styles, date1904>0);
|
||||||
C = val[0].c == -1 ? C + 1 : val[0].c;
|
C = val[0].c == -1 ? C + 1 : val[0].c;
|
||||||
if(opts.dense) { if(!s["!data"][R]) s["!data"][R] = []; s["!data"][R][C] = p; }
|
if(opts.dense) { if(!s["!data"][R]) s["!data"][R] = []; s["!data"][R][C] = p; }
|
||||||
else s[encode_col(C) + rr] = p;
|
else s[encode_col(C) + rr] = p;
|
||||||
@ -606,7 +607,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
if(refguess.e.c < C) refguess.e.c = C;
|
if(refguess.e.c < C) refguess.e.c = C;
|
||||||
if(opts.cellDates && cf && p.t == 'n' && fmt_is_date(table_fmt[cf.numFmtId])) {
|
if(opts.cellDates && cf && p.t == 'n' && fmt_is_date(table_fmt[cf.numFmtId])) {
|
||||||
var _d = SSF_parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF_parse_date_code(p.v + date1904); if(_d) { p.t = 'd'; p.v = new Date(Date.UTC(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u)); }
|
||||||
}
|
}
|
||||||
if(cm) {
|
if(cm) {
|
||||||
if(cm.type == 'XLDAPR') p.D = true;
|
if(cm.type == 'XLDAPR') p.D = true;
|
||||||
@ -809,7 +810,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: something useful -- this is a stub */
|
/* TODO: something useful -- this is a stub */
|
||||||
function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, ws/*:Worksheet*/, last_seen/*:boolean*/)/*:boolean*/ {
|
function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, ws/*:Worksheet*/, last_seen/*:boolean*/, date1904/*:boolean*/)/*:boolean*/ {
|
||||||
var o/*:any*/ = ({r:R, c:C}/*:any*/);
|
var o/*:any*/ = ({r:R, c:C}/*:any*/);
|
||||||
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
|
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
|
||||||
if(cell.v === undefined) return false;
|
if(cell.v === undefined) return false;
|
||||||
@ -819,7 +820,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
|
|||||||
case 'd': // no BrtCellDate :(
|
case 'd': // no BrtCellDate :(
|
||||||
cell = dup(cell);
|
cell = dup(cell);
|
||||||
cell.z = cell.z || table_fmt[14];
|
cell.z = cell.z || table_fmt[14];
|
||||||
cell.v = datenum(parseDate(cell.v)); cell.t = 'n';
|
cell.v = datenum(parseDate(cell.v, date1904), date1904); cell.t = 'n';
|
||||||
break;
|
break;
|
||||||
/* falls through */
|
/* falls through */
|
||||||
case 'n': case 'e': vv = ''+cell.v; break;
|
case 'n': case 'e': vv = ''+cell.v; break;
|
||||||
@ -872,8 +873,9 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Workbook*/) {
|
function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols/*:Array<string>*/ = [];
|
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols/*:Array<string>*/ = [];
|
||||||
|
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
||||||
write_record(ba, 0x0091 /* BrtBeginSheetData */);
|
write_record(ba, 0x0091 /* BrtBeginSheetData */);
|
||||||
var dense = ws["!data"] != null;
|
var dense = ws["!data"] != null;
|
||||||
var cap = range.e.r;
|
var cap = range.e.r;
|
||||||
@ -891,7 +893,7 @@ function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Work
|
|||||||
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
|
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
|
||||||
if(!cell) { last_seen = false; continue; }
|
if(!cell) { last_seen = false; continue; }
|
||||||
/* write cell */
|
/* write cell */
|
||||||
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen);
|
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_record(ba, 0x0092 /* BrtEndSheetData */);
|
write_record(ba, 0x0092 /* BrtEndSheetData */);
|
||||||
|
@ -40,10 +40,10 @@ function xlml_parsexmltagobj(tag/*:string*/) {
|
|||||||
/* map from xlml named formats to SSF TODO: localize */
|
/* map from xlml named formats to SSF TODO: localize */
|
||||||
var XLMLFormatMap/*: {[string]:string}*/;
|
var XLMLFormatMap/*: {[string]:string}*/;
|
||||||
|
|
||||||
function xlml_format(format, value)/*:string*/ {
|
function xlml_format(format, value, date1904)/*:string*/ {
|
||||||
var fmt = XLMLFormatMap[format] || unescapexml(format);
|
var fmt = XLMLFormatMap[format] || unescapexml(format);
|
||||||
if(fmt === "General") return SSF_general(value);
|
if(fmt === "General") return SSF_general(value);
|
||||||
return SSF_format(fmt, value);
|
return SSF_format(fmt, value, {date1904: !!date1904});
|
||||||
}
|
}
|
||||||
|
|
||||||
function xlml_set_custprop(Custprops, key, cp, val/*:string*/) {
|
function xlml_set_custprop(Custprops, key, cp, val/*:string*/) {
|
||||||
@ -59,7 +59,7 @@ function xlml_set_custprop(Custprops, key, cp, val/*:string*/) {
|
|||||||
Custprops[unescapexml(key)] = oval;
|
Custprops[unescapexml(key)] = oval;
|
||||||
}
|
}
|
||||||
|
|
||||||
function safe_format_xlml(cell/*:Cell*/, nf, o) {
|
function safe_format_xlml(cell/*:Cell*/, nf, o, date1904) {
|
||||||
if(cell.t === 'z') return;
|
if(cell.t === 'z') return;
|
||||||
if(!o || o.cellText !== false) try {
|
if(!o || o.cellText !== false) try {
|
||||||
if(cell.t === 'e') { cell.w = cell.w || BErr[cell.v]; }
|
if(cell.t === 'e') { cell.w = cell.w || BErr[cell.v]; }
|
||||||
@ -70,13 +70,13 @@ function safe_format_xlml(cell/*:Cell*/, nf, o) {
|
|||||||
}
|
}
|
||||||
else cell.w = SSF_general(cell.v);
|
else cell.w = SSF_general(cell.v);
|
||||||
}
|
}
|
||||||
else cell.w = xlml_format(nf||"General", cell.v);
|
else cell.w = xlml_format(nf||"General", cell.v, date1904);
|
||||||
} catch(e) { if(o.WTF) throw e; }
|
} catch(e) { if(o.WTF) throw e; }
|
||||||
try {
|
try {
|
||||||
var z = XLMLFormatMap[nf]||nf||"General";
|
var z = XLMLFormatMap[nf]||nf||"General";
|
||||||
if(o.cellNF) cell.z = z;
|
if(o.cellNF) cell.z = z;
|
||||||
if(o.cellDates && cell.t == 'n' && fmt_is_date(z)) {
|
if(o.cellDates && cell.t == 'n' && fmt_is_date(z)) {
|
||||||
var _d = SSF_parse_date_code(cell.v); if(_d) { cell.t = 'd'; cell.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF_parse_date_code(cell.v + (date1904 ? 1462 : 0)); if(_d) { cell.t = 'd'; cell.v = new Date(Date.UTC(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u)); }
|
||||||
}
|
}
|
||||||
} catch(e) { if(o.WTF) throw e; }
|
} catch(e) { if(o.WTF) throw e; }
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ function process_style_xlml(styles, stag, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: there must exist some form of OSP-blessed spec */
|
/* TODO: there must exist some form of OSP-blessed spec */
|
||||||
function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, arrayf, o) {
|
function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, arrayf, o, date1904) {
|
||||||
var nf = "General", sid = cell.StyleID, S = {}; o = o || {};
|
var nf = "General", sid = cell.StyleID, S = {}; o = o || {};
|
||||||
var interiors = [];
|
var interiors = [];
|
||||||
var i = 0;
|
var i = 0;
|
||||||
@ -115,9 +115,8 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
|
|||||||
break;
|
break;
|
||||||
case 'DateTime':
|
case 'DateTime':
|
||||||
if(xml.slice(-1) != "Z") xml += "Z";
|
if(xml.slice(-1) != "Z") xml += "Z";
|
||||||
cell.v = (parseDate(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
|
cell.v = datenum(parseDate(xml, date1904), date1904);
|
||||||
if(cell.v !== cell.v) cell.v = unescapexml(xml);
|
if(cell.v !== cell.v) cell.v = unescapexml(xml);
|
||||||
else if(cell.v<60) cell.v = cell.v -1;
|
|
||||||
if(!nf || nf == "General") nf = "yyyy-mm-dd";
|
if(!nf || nf == "General") nf = "yyyy-mm-dd";
|
||||||
/* falls through */
|
/* falls through */
|
||||||
case 'Number':
|
case 'Number':
|
||||||
@ -130,7 +129,7 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
|
|||||||
else { cell.t = 's'; cell.v = xlml_fixstr(ss||xml); }
|
else { cell.t = 's'; cell.v = xlml_fixstr(ss||xml); }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
safe_format_xlml(cell, nf, o);
|
safe_format_xlml(cell, nf, o, date1904);
|
||||||
if(o.cellFormula !== false) {
|
if(o.cellFormula !== false) {
|
||||||
if(cell.Formula) {
|
if(cell.Formula) {
|
||||||
var fstr = unescapexml(cell.Formula);
|
var fstr = unescapexml(cell.Formula);
|
||||||
@ -232,7 +231,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(state[state.length-1][1]) break;
|
if(state[state.length-1][1]) break;
|
||||||
if(Rn[1]==='/') parse_xlml_data(str.slice(didx, Rn.index), ss, dtag, state[state.length-1][0]==/*"Comment"*/"comment"?comment:cell, {c:c,r:r}, styles, cstys[c], row, arrayf, opts);
|
if(Rn[1]==='/') parse_xlml_data(str.slice(didx, Rn.index), ss, dtag, state[state.length-1][0]==/*"Comment"*/"comment"?comment:cell, {c:c,r:r}, styles, cstys[c], row, arrayf, opts, Workbook.WBProps.date1904);
|
||||||
else { ss = ""; dtag = xlml_parsexmltag(Rn[0]); didx = Rn.index + Rn[0].length; }
|
else { ss = ""; dtag = xlml_parsexmltag(Rn[0]); didx = Rn.index + Rn[0].length; }
|
||||||
break;
|
break;
|
||||||
case 'cell' /*case 'Cell'*/:
|
case 'cell' /*case 'Cell'*/:
|
||||||
|
@ -77,7 +77,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) {
|
|||||||
var fmtid = 0;
|
var fmtid = 0;
|
||||||
try {
|
try {
|
||||||
fmtid = p.z || p.XF.numFmtId || 0;
|
fmtid = p.z || p.XF.numFmtId || 0;
|
||||||
if(opts.cellNF) p.z = table_fmt[fmtid];
|
if(opts.cellNF && p.z == null) p.z = table_fmt[fmtid];
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
if(!opts || opts.cellText !== false) try {
|
if(!opts || opts.cellText !== false) try {
|
||||||
if(p.t === 'e') { p.w = p.w || BErr[p.v]; }
|
if(p.t === 'e') { p.w = p.w || BErr[p.v]; }
|
||||||
@ -91,7 +91,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) {
|
|||||||
else p.w = SSF_format(fmtid,p.v, {date1904:!!date1904, dateNF: opts && opts.dateNF});
|
else p.w = SSF_format(fmtid,p.v, {date1904:!!date1904, dateNF: opts && opts.dateNF});
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
if(opts.cellDates && fmtid && p.t == 'n' && fmt_is_date(table_fmt[fmtid] || String(fmtid))) {
|
if(opts.cellDates && fmtid && p.t == 'n' && fmt_is_date(table_fmt[fmtid] || String(fmtid))) {
|
||||||
var _d = SSF_parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF_parse_date_code(p.v + (date1904 ? 1462 : 0)); if(_d) { p.t = 'd'; p.v = new Date(Date.UTC(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u)); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +119,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
var XFs = []; /* XF records */
|
var XFs = []; /* XF records */
|
||||||
var palette/*:Array<[number, number, number]>*/ = [];
|
var palette/*:Array<[number, number, number]>*/ = [];
|
||||||
var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false}, Views:[{}] }/*:any*/), wsprops = {};
|
var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false}, Views:[{}] }/*:any*/), wsprops = {};
|
||||||
|
var biff4w = false;
|
||||||
var get_rgb = function getrgb(icv/*:number*/)/*:[number, number, number]*/ {
|
var get_rgb = function getrgb(icv/*:number*/)/*:[number, number, number]*/ {
|
||||||
if(icv < 8) return XLSIcv[icv];
|
if(icv < 8) return XLSIcv[icv];
|
||||||
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
||||||
@ -134,7 +135,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if((t = rgb2Hex(get_rgb(xfd.icvBack)))) { line.s.bgColor = {rgb:t}; }
|
if((t = rgb2Hex(get_rgb(xfd.icvBack)))) { line.s.bgColor = {rgb:t}; }
|
||||||
};
|
};
|
||||||
var addcell = function addcell(cell/*:any*/, line/*:any*/, options/*:any*/) {
|
var addcell = function addcell(cell/*:any*/, line/*:any*/, options/*:any*/) {
|
||||||
if(file_depth > 1) return;
|
if(!biff4w && file_depth > 1) return;
|
||||||
if(options.sheetRows && cell.r >= options.sheetRows) return;
|
if(options.sheetRows && cell.r >= options.sheetRows) return;
|
||||||
if(options.cellStyles && line.XF && line.XF.data) process_cell_style(cell, line, options);
|
if(options.cellStyles && line.XF && line.XF.data) process_cell_style(cell, line, options);
|
||||||
delete line.ixfe; delete line.XF;
|
delete line.ixfe; delete line.XF;
|
||||||
@ -265,6 +266,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(!val.fBelow) (out["!outline"] || (out["!outline"] = {})).above = true;
|
if(!val.fBelow) (out["!outline"] || (out["!outline"] = {})).above = true;
|
||||||
if(!val.fRight) (out["!outline"] || (out["!outline"] = {})).left = true;
|
if(!val.fRight) (out["!outline"] || (out["!outline"] = {})).left = true;
|
||||||
break; // TODO
|
break; // TODO
|
||||||
|
case 0x0043: /* BIFF2XF */ case 0x0243: /* BIFF3XF */ case 0x0443: /* BIFF4XF */
|
||||||
case 0x00e0 /* XF */:
|
case 0x00e0 /* XF */:
|
||||||
XFs.push(val); break;
|
XFs.push(val); break;
|
||||||
case 0x01ae /* SupBook */:
|
case 0x01ae /* SupBook */:
|
||||||
@ -299,11 +301,11 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
case 0x0012 /* Protect */: out["!protect"] = val; break; /* for sheet or book */
|
case 0x0012 /* Protect */: out["!protect"] = val; break; /* for sheet or book */
|
||||||
case 0x0013 /* Password */: if(val !== 0 && opts.WTF) console.error("Password verifier: " + val); break;
|
case 0x0013 /* Password */: if(val !== 0 && opts.WTF) console.error("Password verifier: " + val); break;
|
||||||
case 0x0085 /* BoundSheet8 */: {
|
case 0x0085 /* BoundSheet8 */: {
|
||||||
Directory[val.pos] = val;
|
Directory[opts.biff == 4 ? opts.snames.length : val.pos] = val;
|
||||||
opts.snames.push(val.name);
|
opts.snames.push(val.name);
|
||||||
} break;
|
} break;
|
||||||
case 0x000a /* EOF */: {
|
case 0x000a /* EOF */: {
|
||||||
if(--file_depth) break;
|
if(--file_depth ? !biff4w : biff4w) break;
|
||||||
if(range.e) {
|
if(range.e) {
|
||||||
if(range.e.r > 0 && range.e.c > 0) {
|
if(range.e.r > 0 && range.e.c > 0) {
|
||||||
range.e.r--; range.e.c--;
|
range.e.r--; range.e.c--;
|
||||||
@ -342,13 +344,15 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
}[val.BIFFVer] || 8;
|
}[val.BIFFVer] || 8;
|
||||||
opts.biffguess = val.BIFFVer == 0;
|
opts.biffguess = val.BIFFVer == 0;
|
||||||
if(val.BIFFVer == 0 && val.dt == 0x1000) { opts.biff = 5; seen_codepage = true; set_cp(opts.codepage = 28591); }
|
if(val.BIFFVer == 0 && val.dt == 0x1000) { opts.biff = 5; seen_codepage = true; set_cp(opts.codepage = 28591); }
|
||||||
|
if(opts.biff == 4 && val.dt & 0x100) biff4w = true;
|
||||||
if(opts.biff == 8 && val.BIFFVer == 0 && val.dt == 16) opts.biff = 2;
|
if(opts.biff == 8 && val.BIFFVer == 0 && val.dt == 16) opts.biff = 2;
|
||||||
if(file_depth++) break;
|
if(file_depth++ && !biff4w) break;
|
||||||
out = ({}/*:any*/); if(options.dense) out["!data"] = [];
|
out = ({}/*:any*/); if(options.dense) out["!data"] = [];
|
||||||
|
|
||||||
if(opts.biff < 8 && !seen_codepage) { seen_codepage = true; set_cp(opts.codepage = options.codepage || 1252); }
|
if(opts.biff < 8 && !seen_codepage) { seen_codepage = true; set_cp(opts.codepage = options.codepage || 1252); }
|
||||||
|
if(opts.biff == 4 && biff4w) {
|
||||||
if(opts.biff < 5 || val.BIFFVer == 0 && val.dt == 0x1000) {
|
cur_sheet = (Directory[opts.snames.indexOf(cur_sheet)+1] || {name:""}).name;
|
||||||
|
} else if(opts.biff < 5 || val.BIFFVer == 0 && val.dt == 0x1000) {
|
||||||
if(cur_sheet === "") cur_sheet = "Sheet1";
|
if(cur_sheet === "") cur_sheet = "Sheet1";
|
||||||
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
||||||
/* fake BoundSheet8 */
|
/* fake BoundSheet8 */
|
||||||
@ -369,19 +373,19 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
case 0x0203 /* Number */: case 0x0003 /* BIFF2NUM */: case 0x0002 /* BIFF2INT */: {
|
case 0x0203 /* Number */: case 0x0003 /* BIFF2NUM */: case 0x0002 /* BIFF2INT */: {
|
||||||
if(out["!type"] == "chart") if(options.dense ? (out["!data"][val.r]||[])[val.c]: out[encode_col(val.c) + encode_row(val.r)]) ++val.c;
|
if(out["!type"] == "chart") if(options.dense ? (out["!data"][val.r]||[])[val.c]: out[encode_col(val.c) + encode_row(val.r)]) ++val.c;
|
||||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}/*:any*/);
|
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}/*:any*/);
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||||
} break;
|
} break;
|
||||||
case 0x0005: case 0x0205 /* BoolErr */: {
|
case 0x0005: case 0x0205 /* BoolErr */: {
|
||||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/);
|
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/);
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||||
} break;
|
} break;
|
||||||
case 0x027e /* RK */: {
|
case 0x027e /* RK */: {
|
||||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/);
|
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/);
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||||
} break;
|
} break;
|
||||||
@ -389,7 +393,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
for(var j = val.c; j <= val.C; ++j) {
|
for(var j = val.c; j <= val.C; ++j) {
|
||||||
var ixfe = val.rkrec[j-val.c][0];
|
var ixfe = val.rkrec[j-val.c][0];
|
||||||
temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/);
|
temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/);
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:j, r:val.r}, temp_val, options);
|
addcell({c:j, r:val.r}, temp_val, options);
|
||||||
}
|
}
|
||||||
@ -407,7 +411,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
else temp_val.F = ((options.dense ? (out["!data"][_fr]||[])[_fc]: out[_fe]) || {}).F;
|
else temp_val.F = ((options.dense ? (out["!data"][_fr]||[])[_fc]: out[_fe]) || {}).F;
|
||||||
} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||||
}
|
}
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell(val.cell, temp_val, options);
|
addcell(val.cell, temp_val, options);
|
||||||
last_formula = val;
|
last_formula = val;
|
||||||
@ -420,7 +424,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(options.cellFormula) {
|
if(options.cellFormula) {
|
||||||
temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
|
temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
|
||||||
}
|
}
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell(last_formula.cell, temp_val, options);
|
addcell(last_formula.cell, temp_val, options);
|
||||||
last_formula = null;
|
last_formula = null;
|
||||||
@ -451,13 +455,13 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
temp_val=make_cell(sst[val.isst].t, val.ixfe, 's');
|
temp_val=make_cell(sst[val.isst].t, val.ixfe, 's');
|
||||||
if(sst[val.isst].h) temp_val.h = sst[val.isst].h;
|
if(sst[val.isst].h) temp_val.h = sst[val.isst].h;
|
||||||
temp_val.XF = XFs[temp_val.ixfe];
|
temp_val.XF = XFs[temp_val.ixfe];
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||||
break;
|
break;
|
||||||
case 0x0201 /* Blank */: if(options.sheetStubs) {
|
case 0x0201 /* Blank */: if(options.sheetStubs) {
|
||||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/);
|
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/);
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||||
} break;
|
} break;
|
||||||
@ -465,7 +469,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
for(var _j = val.c; _j <= val.C; ++_j) {
|
for(var _j = val.c; _j <= val.C; ++_j) {
|
||||||
var _ixfe = val.ixfe[_j-val.c];
|
var _ixfe = val.ixfe[_j-val.c];
|
||||||
temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/);
|
temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/);
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:_j, r:val.r}, temp_val, options);
|
addcell({c:_j, r:val.r}, temp_val, options);
|
||||||
}
|
}
|
||||||
@ -474,7 +478,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
case 0x0204 /* Label */: case 0x0004 /* BIFF2STR */:
|
case 0x0204 /* Label */: case 0x0004 /* BIFF2STR */:
|
||||||
temp_val=make_cell(val.val, val.ixfe, 's');
|
temp_val=make_cell(val.val, val.ixfe, 's');
|
||||||
temp_val.XF = XFs[temp_val.ixfe];
|
temp_val.XF = XFs[temp_val.ixfe];
|
||||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
if(BIFF2Fmt > 0) temp_val.z = (temp_val.XF && temp_val.XF.numFmtId) && BIFF2FmtTable[temp_val.XF.numFmtId] || BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
|
||||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||||
break;
|
break;
|
||||||
@ -486,7 +490,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
sst = val;
|
sst = val;
|
||||||
} break;
|
} break;
|
||||||
case 0x041e /* Format */: { /* val = [id, fmt] */
|
case 0x041e /* Format */: { /* val = [id, fmt] */
|
||||||
if(opts.biff == 4) {
|
if(opts.biff >= 3 && opts.biff <= 4) {
|
||||||
BIFF2FmtTable[BIFF2Fmt++] = val[1];
|
BIFF2FmtTable[BIFF2Fmt++] = val[1];
|
||||||
for(var b4idx = 0; b4idx < BIFF2Fmt + 163; ++b4idx) if(table_fmt[b4idx] == val[1]) break;
|
for(var b4idx = 0; b4idx < BIFF2Fmt + 163; ++b4idx) if(table_fmt[b4idx] == val[1]) break;
|
||||||
if(b4idx >= 163) SSF__load(val[1], BIFF2Fmt + 163);
|
if(b4idx >= 163) SSF__load(val[1], BIFF2Fmt + 163);
|
||||||
|
@ -1221,7 +1221,7 @@ var XLSRecordEnum = {
|
|||||||
/*::[*/0x0002/*::]*/: { /* n:"BIFF2INT", */ f:parse_BIFF2INT },
|
/*::[*/0x0002/*::]*/: { /* n:"BIFF2INT", */ f:parse_BIFF2INT },
|
||||||
/*::[*/0x0003/*::]*/: { /* n:"BIFF2NUM", */ f:parse_BIFF2NUM },
|
/*::[*/0x0003/*::]*/: { /* n:"BIFF2NUM", */ f:parse_BIFF2NUM },
|
||||||
/*::[*/0x0004/*::]*/: { /* n:"BIFF2STR", */ f:parse_BIFF2STR },
|
/*::[*/0x0004/*::]*/: { /* n:"BIFF2STR", */ f:parse_BIFF2STR },
|
||||||
/*::[*/0x0005/*::]*/: { /* n:"BoolErr", */ f:parse_BoolErr },
|
/*::[*/0x0005/*::]*/: { /* n:"BIFF2BOOLERR", */ f:parse_BIFF2BOOLERR },
|
||||||
/*::[*/0x0007/*::]*/: { /* n:"String", */ f:parse_BIFF2STRING },
|
/*::[*/0x0007/*::]*/: { /* n:"String", */ f:parse_BIFF2STRING },
|
||||||
/*::[*/0x0008/*::]*/: { /* n:"BIFF2ROW", */ },
|
/*::[*/0x0008/*::]*/: { /* n:"BIFF2ROW", */ },
|
||||||
/*::[*/0x0009/*::]*/: { /* n:"BOF", */ f:parse_BOF },
|
/*::[*/0x0009/*::]*/: { /* n:"BOF", */ f:parse_BOF },
|
||||||
@ -1260,7 +1260,7 @@ var XLSRecordEnum = {
|
|||||||
|
|
||||||
/* - - - */
|
/* - - - */
|
||||||
/*::[*/0x0034/*::]*/: { /* n:"DDEObjName", */ },
|
/*::[*/0x0034/*::]*/: { /* n:"DDEObjName", */ },
|
||||||
/*::[*/0x0043/*::]*/: { /* n:"BIFF2XF", */ },
|
/*::[*/0x0043/*::]*/: { /* n:"BIFF2XF", */ f:parse_BIFF2XF },
|
||||||
/*::[*/0x0044/*::]*/: { /* n:"BIFF2XFINDEX", */ f:parseuint16 },
|
/*::[*/0x0044/*::]*/: { /* n:"BIFF2XFINDEX", */ f:parseuint16 },
|
||||||
/*::[*/0x0045/*::]*/: { /* n:"BIFF2FONTCLR", */ },
|
/*::[*/0x0045/*::]*/: { /* n:"BIFF2FONTCLR", */ },
|
||||||
/*::[*/0x0056/*::]*/: { /* n:"BIFF4FMTCNT", */ }, /* 16-bit cnt, similar to BIFF2 */
|
/*::[*/0x0056/*::]*/: { /* n:"BIFF4FMTCNT", */ }, /* 16-bit cnt, similar to BIFF2 */
|
||||||
@ -1272,7 +1272,7 @@ var XLSRecordEnum = {
|
|||||||
// 0x8A
|
// 0x8A
|
||||||
// 0x8B LH: alternate menu key flag (BIFF3/4)
|
// 0x8B LH: alternate menu key flag (BIFF3/4)
|
||||||
// 0x8E
|
// 0x8E
|
||||||
// 0x8F
|
/*::[*/0x008F/*::]*/: { /* n:"BIFF4SheetInfo", */ f:parse_BIFF4SheetInfo },
|
||||||
/*::[*/0x0091/*::]*/: { /* n:"Sub", */ },
|
/*::[*/0x0091/*::]*/: { /* n:"Sub", */ },
|
||||||
// 0x93 STYLE
|
// 0x93 STYLE
|
||||||
/*::[*/0x0094/*::]*/: { /* n:"LHRecord", */ },
|
/*::[*/0x0094/*::]*/: { /* n:"LHRecord", */ },
|
||||||
@ -1298,10 +1298,10 @@ var XLSRecordEnum = {
|
|||||||
/*::[*/0x0218/*::]*/: { /* n:"Lbl", */ f:parse_Lbl },
|
/*::[*/0x0218/*::]*/: { /* n:"Lbl", */ f:parse_Lbl },
|
||||||
/*::[*/0x0223/*::]*/: { /* n:"ExternName", */ f:parse_ExternName },
|
/*::[*/0x0223/*::]*/: { /* n:"ExternName", */ f:parse_ExternName },
|
||||||
/*::[*/0x0231/*::]*/: { /* n:"Font", */ },
|
/*::[*/0x0231/*::]*/: { /* n:"Font", */ },
|
||||||
/*::[*/0x0243/*::]*/: { /* n:"BIFF3XF", */ },
|
/*::[*/0x0243/*::]*/: { /* n:"BIFF3XF", */ f:parse_BIFF3XF },
|
||||||
/*::[*/0x0406/*::]*/: { /* n:"Formula", */ f:parse_Formula },
|
/*::[*/0x0406/*::]*/: { /* n:"Formula", */ f:parse_Formula },
|
||||||
/*::[*/0x0409/*::]*/: { /* n:"BOF", */ f:parse_BOF },
|
/*::[*/0x0409/*::]*/: { /* n:"BOF", */ f:parse_BOF },
|
||||||
/*::[*/0x0443/*::]*/: { /* n:"BIFF4XF", */ },
|
/*::[*/0x0443/*::]*/: { /* n:"BIFF4XF", */ f:parse_BIFF4XF },
|
||||||
/*::[*/0x086d/*::]*/: { /* n:"FeatInfo", */ },
|
/*::[*/0x086d/*::]*/: { /* n:"FeatInfo", */ },
|
||||||
/*::[*/0x0873/*::]*/: { /* n:"FeatInfo11", */ },
|
/*::[*/0x0873/*::]*/: { /* n:"FeatInfo11", */ },
|
||||||
/*::[*/0x0881/*::]*/: { /* n:"SXAddl12", */ },
|
/*::[*/0x0881/*::]*/: { /* n:"SXAddl12", */ },
|
||||||
|
@ -31,16 +31,7 @@ function write_biff_continue(ba/*:BufArray*/, type/*:number*/, payload, length/*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) {
|
function write_BIFF2BERR(r/*:number*/, c/*:number*/, val, t/*:string*/) {
|
||||||
if(!out) out = new_buf(7);
|
|
||||||
out.write_shift(2, r);
|
|
||||||
out.write_shift(2, c);
|
|
||||||
out.write_shift(2, 0);
|
|
||||||
out.write_shift(1, 0);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function write_BIFF2BERR(r/*:number*/, c/*:number*/, val, t/*:?string*/) {
|
|
||||||
var out = new_buf(9);
|
var out = new_buf(9);
|
||||||
write_BIFF2Cell(out, r, c);
|
write_BIFF2Cell(out, r, c);
|
||||||
write_Bes(val, t || 'b', out);
|
write_Bes(val, t || 'b', out);
|
||||||
@ -67,29 +58,48 @@ function write_comments_biff2(ba/*:BufArray*/, comments/*:Array<[Comment[], numb
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*//*::, opts*/) {
|
/* TODO: BIFF3/4 use different records -- see comments*/
|
||||||
|
function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, date1904/*:boolean*/) {
|
||||||
|
var ifmt = 0;
|
||||||
|
if(cell.z != null) {
|
||||||
|
ifmt = opts._BIFF2FmtTable.indexOf(cell.z);
|
||||||
|
if(ifmt == -1) { opts._BIFF2FmtTable.push(cell.z); ifmt = opts._BIFF2FmtTable.length - 1; }
|
||||||
|
}
|
||||||
|
var ixfe = 0;
|
||||||
|
if(cell.z != null) {
|
||||||
|
for(; ixfe < opts.cellXfs.length; ++ixfe) if(opts.cellXfs[ixfe].numFmtId == ifmt) break;
|
||||||
|
if(ixfe == opts.cellXfs.length) opts.cellXfs.push({numFmtId: ifmt});
|
||||||
|
}
|
||||||
if(cell.v != null) switch(cell.t) {
|
if(cell.v != null) switch(cell.t) {
|
||||||
case 'd': case 'n':
|
case 'd': case 'n':
|
||||||
var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
|
var v = cell.t == 'd' ? datenum(parseDate(cell.v, date1904), date1904) : cell.v;
|
||||||
if((v == (v|0)) && (v >= 0) && (v < 65536))
|
if(opts.biff == 2 && (v == (v|0)) && (v >= 0) && (v < 65536))
|
||||||
write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, v));
|
// 0x027E (RK) in BIFF3/4
|
||||||
|
write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, v, ixfe, ifmt));
|
||||||
else if(isNaN(v))
|
else if(isNaN(v))
|
||||||
|
// 0x0205 in BIFF3/4
|
||||||
write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, 0x24, "e")); // #NUM!
|
write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, 0x24, "e")); // #NUM!
|
||||||
else if(!isFinite(v))
|
else if(!isFinite(v))
|
||||||
|
// 0x0205 in BIFF3/4
|
||||||
write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, 0x07, "e")); // #DIV/0!
|
write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, 0x07, "e")); // #DIV/0!
|
||||||
else
|
else
|
||||||
write_biff_rec(ba, 0x0003, write_BIFF2NUM(R,C, v));
|
// 0x0203 in BIFF3/4
|
||||||
|
write_biff_rec(ba, 0x0003, write_BIFF2NUM(R,C, v, ixfe, ifmt));
|
||||||
return;
|
return;
|
||||||
case 'b': case 'e': write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t)); return;
|
case 'b': case 'e':
|
||||||
|
// 0x0205 in BIFF3/4
|
||||||
|
write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t)); return;
|
||||||
/* TODO: codepage, sst */
|
/* TODO: codepage, sst */
|
||||||
case 's': case 'str':
|
case 's': case 'str':
|
||||||
|
// 0x0204 in BIFF3/4
|
||||||
write_biff_rec(ba, 0x0004, write_BIFF2LABEL(R, C, cell.v == null ? "" : String(cell.v).slice(0,255)));
|
write_biff_rec(ba, 0x0004, write_BIFF2LABEL(R, C, cell.v == null ? "" : String(cell.v).slice(0,255)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 0x0201 in BIFF3/4
|
||||||
write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C));
|
write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C));
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Workbook*/) {
|
function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||||
var dense = ws["!data"] != null;
|
var dense = ws["!data"] != null;
|
||||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||||
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
||||||
@ -97,7 +107,9 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/
|
|||||||
range.e.c = Math.min(range.e.c, 0xFF);
|
range.e.c = Math.min(range.e.c, 0xFF);
|
||||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||||
}
|
}
|
||||||
|
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
||||||
var row = [], comments = [];
|
var row = [], comments = [];
|
||||||
|
/* TODO: 0x0000 / 0x0200 dimensions? */
|
||||||
for(var C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
for(var C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
||||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||||
if(dense) row = ws["!data"][R] || [];
|
if(dense) row = ws["!data"][R] || [];
|
||||||
@ -106,7 +118,7 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/
|
|||||||
var cell = dense ? row[C] : ws[cols[C] + rr];
|
var cell = dense ? row[C] : ws[cols[C] + rr];
|
||||||
if(!cell) continue;
|
if(!cell) continue;
|
||||||
/* write cell */
|
/* write cell */
|
||||||
write_ws_biff2_cell(ba, cell, R, C, opts);
|
write_ws_biff2_cell(ba, cell, R, C, opts, date1904);
|
||||||
if(cell.c) comments.push([cell.c, R, C]);
|
if(cell.c) comments.push([cell.c, R, C]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,14 +131,32 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/
|
|||||||
/* Based on test files */
|
/* Based on test files */
|
||||||
function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||||
var o = opts || {};
|
var o = opts || {};
|
||||||
|
|
||||||
var ba = buf_array();
|
var ba = buf_array();
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
|
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
|
||||||
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
|
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
|
||||||
write_biff_rec(ba, (o.biff == 4 ? 0x0409 : (o.biff == 3 ? 0x0209 : 0x0009)), write_BOF(wb, 0x10, o));
|
write_biff_rec(ba, (o.biff == 4 ? 0x0409 : (o.biff == 3 ? 0x0209 : 0x0009)), write_BOF(wb, 0x10, o));
|
||||||
/* ... */
|
if(((wb.Workbook||{}).WBProps||{}).date1904) write_biff_rec(ba, 0x0022, writebool(true));
|
||||||
write_ws_biff2(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
|
o.cellXfs = [{numFmtId: 0}];
|
||||||
/* ... */
|
o._BIFF2FmtTable/*:Array<string>*/ = ["General"]; o._Fonts = [];
|
||||||
|
var body = buf_array();
|
||||||
|
write_ws_biff2(body, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
|
||||||
|
|
||||||
|
o._BIFF2FmtTable.forEach(function(f) {
|
||||||
|
if(o.biff <= 3) write_biff_rec(ba, 0x001E, write_BIFF2Format(f));
|
||||||
|
else write_biff_rec(ba, 0x041E, write_BIFF4Format(f));
|
||||||
|
});
|
||||||
|
o.cellXfs.forEach(function(xf) {
|
||||||
|
switch(o.biff) {
|
||||||
|
case 2: write_biff_rec(ba, 0x0043, write_BIFF2XF(xf)); break;
|
||||||
|
case 3: write_biff_rec(ba, 0x0243, write_BIFF3XF(xf)); break;
|
||||||
|
case 4: write_biff_rec(ba, 0x0443, write_BIFF4XF(xf)); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
delete o._BIFF2FmtTable; delete o.cellXfs; delete o._Fonts;
|
||||||
|
|
||||||
|
ba.push(body.end());
|
||||||
write_biff_rec(ba, 0x000A);
|
write_biff_rec(ba, 0x000A);
|
||||||
return ba.end();
|
return ba.end();
|
||||||
}
|
}
|
||||||
@ -147,7 +177,7 @@ function write_MsoDrawingGroup() {
|
|||||||
{
|
{
|
||||||
buf.write_shift(4, b8oid);
|
buf.write_shift(4, b8oid);
|
||||||
buf.write_shift(4, b8ocnts.length+1);
|
buf.write_shift(4, b8ocnts.length+1);
|
||||||
buf.write_shift(4, b8ocnts.reduce(function(acc,x) { return acc+x[1]; }, 0));
|
var acc = 0; for(var i = 0; i < b8ocnts.length; ++i) acc += (b8ocnts[i] && b8ocnts[i][1] || 0); buf.write_shift(4, acc);
|
||||||
buf.write_shift(4, b8ocnts.length);
|
buf.write_shift(4, b8ocnts.length);
|
||||||
}
|
}
|
||||||
/* 2.2.46 OfficeArtIDCL + */
|
/* 2.2.46 OfficeArtIDCL + */
|
||||||
@ -185,7 +215,7 @@ function write_comments_biff8(ba/*:BufArray*/, comments/*:Array<[Comment[], numb
|
|||||||
var _oasc;
|
var _oasc;
|
||||||
comments.forEach(function(c, ci) {
|
comments.forEach(function(c, ci) {
|
||||||
var author = "";
|
var author = "";
|
||||||
var text = c[0].map(function(t) { if(t.a && !author) author = t.a; return t.t }).join("");
|
var text = c[0].map(function(t) { if(t.a && !author) author = t.a; return t.t; }).join("");
|
||||||
++b8oid;
|
++b8oid;
|
||||||
|
|
||||||
/* 2.2.14 OfficeArtSpContainer */
|
/* 2.2.14 OfficeArtSpContainer */
|
||||||
@ -336,7 +366,7 @@ function write_comments_biff8(ba/*:BufArray*/, comments/*:Array<[Comment[], numb
|
|||||||
/* [MS-ODRAW] 2.2.13 OfficeArtDgContainer */
|
/* [MS-ODRAW] 2.2.13 OfficeArtDgContainer */
|
||||||
{
|
{
|
||||||
var hdr = new_buf(80);
|
var hdr = new_buf(80);
|
||||||
hdr.write_shift(2, 0x0F)
|
hdr.write_shift(2, 0x0F);
|
||||||
hdr.write_shift(2, 0xF002);
|
hdr.write_shift(2, 0xF002);
|
||||||
hdr.write_shift(4, sz + hdr.length - 8);
|
hdr.write_shift(4, sz + hdr.length - 8);
|
||||||
/* [MS-ODRAW] 2.2.49 OfficeArtFDG */
|
/* [MS-ODRAW] 2.2.49 OfficeArtFDG */
|
||||||
@ -443,7 +473,7 @@ function write_ws_cols_biff8(ba, cols) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
|
function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, date1904/*:boolean*/) {
|
||||||
var os = 16 + get_cell_style(opts.cellXfs, cell, opts);
|
var os = 16 + get_cell_style(opts.cellXfs, cell, opts);
|
||||||
if(cell.v == null && !cell.bf) {
|
if(cell.v == null && !cell.bf) {
|
||||||
write_biff_rec(ba, 0x0201 /* Blank */, write_XLSCell(R, C, os));
|
write_biff_rec(ba, 0x0201 /* Blank */, write_XLSCell(R, C, os));
|
||||||
@ -452,7 +482,7 @@ function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n
|
|||||||
if(cell.bf) write_biff_rec(ba, 0x0006 /* Formula */, write_Formula(cell, R, C, opts, os));
|
if(cell.bf) write_biff_rec(ba, 0x0006 /* Formula */, write_Formula(cell, R, C, opts, os));
|
||||||
else switch(cell.t) {
|
else switch(cell.t) {
|
||||||
case 'd': case 'n':
|
case 'd': case 'n':
|
||||||
var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
|
var v = cell.t == 'd' ? datenum(parseDate(cell.v, date1904), date1904) : cell.v;
|
||||||
if(isNaN(v)) write_biff_rec(ba, 0x0205 /* BoolErr */, write_BoolErr(R, C, 0x24, os, opts, "e")); // #NUM!
|
if(isNaN(v)) write_biff_rec(ba, 0x0205 /* BoolErr */, write_BoolErr(R, C, 0x24, os, opts, "e")); // #NUM!
|
||||||
else if(!isFinite(v)) write_biff_rec(ba, 0x0205 /* BoolErr */, write_BoolErr(R, C, 0x07, os, opts, "e")); // #DIV/0!
|
else if(!isFinite(v)) write_biff_rec(ba, 0x0205 /* BoolErr */, write_BoolErr(R, C, 0x07, os, opts, "e")); // #DIV/0!
|
||||||
/* TODO: emit RK as appropriate */
|
/* TODO: emit RK as appropriate */
|
||||||
@ -513,6 +543,7 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
|||||||
write_biff_rec(ba, 0x0200 /* Dimensions */, write_Dimensions(range, opts));
|
write_biff_rec(ba, 0x0200 /* Dimensions */, write_Dimensions(range, opts));
|
||||||
/* ... */
|
/* ... */
|
||||||
|
|
||||||
|
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
||||||
if(b8) ws['!links'] = [];
|
if(b8) ws['!links'] = [];
|
||||||
var comments = [];
|
var comments = [];
|
||||||
var row = [];
|
var row = [];
|
||||||
@ -525,7 +556,7 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
|||||||
var cell = dense ? row[C] : ws[ref];
|
var cell = dense ? row[C] : ws[ref];
|
||||||
if(!cell) continue;
|
if(!cell) continue;
|
||||||
/* write cell */
|
/* write cell */
|
||||||
write_ws_biff8_cell(ba, cell, R, C, opts);
|
write_ws_biff8_cell(ba, cell, R, C, opts, date1904);
|
||||||
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
|
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
|
||||||
if(cell.c) comments.push([cell.c, R, C]);
|
if(cell.c) comments.push([cell.c, R, C]);
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,11 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
|
|||||||
else if(!isNaN(fuzzynum(m))) o = {t:'n', v:fuzzynum(m)};
|
else if(!isNaN(fuzzynum(m))) o = {t:'n', v:fuzzynum(m)};
|
||||||
else if(!isNaN(fuzzydate(m).getDate())) {
|
else if(!isNaN(fuzzydate(m).getDate())) {
|
||||||
o = ({t:'d', v:parseDate(m)}/*:any*/);
|
o = ({t:'d', v:parseDate(m)}/*:any*/);
|
||||||
|
if(opts.UTC === false) o.v = utc_to_local(o.v);
|
||||||
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
|
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
|
||||||
o.z = opts.dateNF || table_fmt[14];
|
o.z = opts.dateNF || table_fmt[14];
|
||||||
}
|
}
|
||||||
|
if(o.cellText !== false) o.w = m;
|
||||||
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
|
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
|
||||||
else ws[encode_cell({r:R, c:C})] = o;
|
else ws[encode_cell({r:R, c:C})] = o;
|
||||||
C += CS;
|
C += CS;
|
||||||
@ -81,7 +83,8 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
|
|||||||
if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
|
if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
|
||||||
else if(cell) {
|
else if(cell) {
|
||||||
sp["data-t"] = cell && cell.t || 'z';
|
sp["data-t"] = cell && cell.t || 'z';
|
||||||
if(cell.v != null) sp["data-v"] = cell.v;
|
// note: data-v is unaffected by the timezone interpretation
|
||||||
|
if(cell.v != null) sp["data-v"] = cell.v instanceof Date ? cell.v.toISOString() : cell.v;
|
||||||
if(cell.z != null) sp["data-z"] = cell.z;
|
if(cell.z != null) sp["data-z"] = cell.z;
|
||||||
if(cell.l && (cell.l.Target || "#").charAt(0) != "#") w = '<a href="' + escapehtml(cell.l.Target) +'">' + w + '</a>';
|
if(cell.l && (cell.l.Target || "#").charAt(0) != "#") w = '<a href="' + escapehtml(cell.l.Target) +'">' + w + '</a>';
|
||||||
}
|
}
|
||||||
@ -187,6 +190,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
|
|||||||
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
|
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
|
||||||
else if(!isNaN(fuzzydate(v).getDate())) {
|
else if(!isNaN(fuzzydate(v).getDate())) {
|
||||||
o = ({t:'d', v:parseDate(v)}/*:any*/);
|
o = ({t:'d', v:parseDate(v)}/*:any*/);
|
||||||
|
if(opts.UTC) o.v = local_to_utc(o.v);
|
||||||
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
|
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
|
||||||
o.z = opts.dateNF || table_fmt[14];
|
o.z = opts.dateNF || table_fmt[14];
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,6 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
|||||||
var creator = "", creatoridx = 0;
|
var creator = "", creatoridx = 0;
|
||||||
var isstub = false, intable = false;
|
var isstub = false, intable = false;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var baddate = 0;
|
|
||||||
xlmlregex.lastIndex = 0;
|
xlmlregex.lastIndex = 0;
|
||||||
str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||||
@ -370,19 +369,23 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
|||||||
/* 19.675.2 table:number-columns-repeated */
|
/* 19.675.2 table:number-columns-repeated */
|
||||||
if(ctag['number-columns-repeated']) colpeat = parseInt(ctag['number-columns-repeated'], 10);
|
if(ctag['number-columns-repeated']) colpeat = parseInt(ctag['number-columns-repeated'], 10);
|
||||||
|
|
||||||
/* 19.385 office:value-type */
|
/* 19.385 office:value-type TODO: verify ODS and UOS */
|
||||||
switch(q.t) {
|
switch(q.t) {
|
||||||
case 'boolean': q.t = 'b'; q.v = parsexmlbool(ctag['boolean-value']) || (+ctag['boolean-value'] >= 1); break;
|
case 'boolean': q.t = 'b'; q.v = parsexmlbool(ctag['boolean-value']) || (+ctag['boolean-value'] >= 1); break;
|
||||||
case 'float': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
case 'float': q.t = 'n'; q.v = parseFloat(ctag.value);
|
||||||
|
if(opts.cellDates && q.z && fmt_is_date(q.z)) { q.v = numdate(q.v + (WB.WBProps.date1904 ? 1462 : 0)); q.t = typeof q.v == "number" ? 'n' : 'd'; }
|
||||||
|
break;
|
||||||
case 'percentage': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
case 'percentage': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||||
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||||
case 'date': q.t = 'd'; q.v = parseDate(ctag['date-value']);
|
case 'date': q.t = 'd'; q.v = parseDate(ctag['date-value'], WB.WBProps.date1904);
|
||||||
if(!opts.cellDates) { q.t = 'n'; q.v = datenum(q.v, WB.WBProps.date1904) - baddate; }
|
if(!opts.cellDates) { q.t = 'n'; q.v = datenum(q.v, WB.WBProps.date1904); }
|
||||||
if(!q.z) q.z = 'm/d/yy'; break;
|
if(!q.z) q.z = 'm/d/yy'; break;
|
||||||
|
/* NOTE: for `time`, Excel ODS export incorrectly uses durations relative to 1900 epoch even if 1904 is specified */
|
||||||
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400;
|
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400;
|
||||||
if(opts.cellDates) { q.t = 'd'; q.v = numdate(q.v); }
|
if(opts.cellDates) { q.v = numdate(q.v); q.t = typeof q.v == "number" ? 'n' : 'd'; }
|
||||||
if(!q.z) q.z = 'HH:MM:SS'; break;
|
if(!q.z) q.z = 'HH:MM:SS'; break;
|
||||||
case 'number': q.t = 'n'; q.v = parseFloat(ctag['数据数值']); break;
|
case 'number': q.t = 'n'; q.v = parseFloat(ctag['数据数值']);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if(q.t === 'string' || q.t === 'text' || !q.t) {
|
if(q.t === 'string' || q.t === 'text' || !q.t) {
|
||||||
q.t = 's';
|
q.t = 's';
|
||||||
@ -579,9 +582,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
|||||||
case 'null-date': // 9.4.2 <table:null-date>
|
case 'null-date': // 9.4.2 <table:null-date>
|
||||||
tag = parsexmltag(Rn[0], false);
|
tag = parsexmltag(Rn[0], false);
|
||||||
switch(tag["date-value"]) {
|
switch(tag["date-value"]) {
|
||||||
case "1904-01-01": WB.WBProps.date1904 = true;
|
case "1904-01-01": WB.WBProps.date1904 = true; break;
|
||||||
/* falls through */
|
|
||||||
case "1900-01-01": baddate = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -99,7 +99,9 @@ function write_number_format_ods(nf/*:string*/, nfidx/*:string*/)/*:string*/ {
|
|||||||
while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
|
while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
|
||||||
payload += '<number:text>' + escapexml(c.slice(1).replace(/""/g, '"')) + '</number:text>';
|
payload += '<number:text>' + escapexml(c.slice(1).replace(/""/g, '"')) + '</number:text>';
|
||||||
break;
|
break;
|
||||||
case '/': payload += '<number:text>' + escapexml(c) + '</number:text>'; break;
|
case '\\': c = nf[++i];
|
||||||
|
payload += '<number:text>' + escapexml(c) + '</number:text>'; break;
|
||||||
|
case '/': case ':': payload += '<number:text>' + escapexml(c) + '</number:text>'; break;
|
||||||
default: console.error("unrecognized character " + c + " in ODF format " + nf);
|
default: console.error("unrecognized character " + c + " in ODF format " + nf);
|
||||||
}
|
}
|
||||||
if(!has_time) break j;
|
if(!has_time) break j;
|
||||||
@ -126,7 +128,7 @@ function write_number_format_ods(nf/*:string*/, nfidx/*:string*/)/*:string*/ {
|
|||||||
while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
|
while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
|
||||||
payload += '<number:text>' + escapexml(c.slice(1).replace(/""/g, '"')) + '</number:text>';
|
payload += '<number:text>' + escapexml(c.slice(1).replace(/""/g, '"')) + '</number:text>';
|
||||||
break;
|
break;
|
||||||
case '/': payload += '<number:text>' + escapexml(c) + '</number:text>'; break;
|
case '/': case ':': payload += '<number:text>' + escapexml(c) + '</number:text>'; break;
|
||||||
case "a":
|
case "a":
|
||||||
if(nf.slice(i, i+3).toLowerCase() == "a/p") { payload += '<number:am-pm/>'; i += 2; break; } // Note: ODF does not support A/P
|
if(nf.slice(i, i+3).toLowerCase() == "a/p") { payload += '<number:am-pm/>'; i += 2; break; } // Note: ODF does not support A/P
|
||||||
if(nf.slice(i, i+5).toLowerCase() == "am/pm") { payload += '<number:am-pm/>'; i += 4; break; }
|
if(nf.slice(i, i+5).toLowerCase() == "am/pm") { payload += '<number:am-pm/>'; i += 4; break; }
|
||||||
@ -182,10 +184,15 @@ function write_number_format_ods(nf/*:string*/, nfidx/*:string*/)/*:string*/ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function write_names_ods(Names, SheetNames, idx) {
|
function write_names_ods(Names, SheetNames, idx) {
|
||||||
var scoped = Names.filter(function(name) { return name.Sheet == (idx == -1 ? null : idx); });
|
//var scoped = Names.filter(function(name) { return name.Sheet == (idx == -1 ? null : idx); });
|
||||||
|
var scoped = []; for(var namei = 0; namei < Names.length; ++namei) {
|
||||||
|
var name = Names[namei];
|
||||||
|
if(!name) continue;
|
||||||
|
if(name.Sheet == (idx == -1 ? null : idx)) scoped.push(name);
|
||||||
|
}
|
||||||
if(!scoped.length) return "";
|
if(!scoped.length) return "";
|
||||||
return " <table:named-expressions>\n" + scoped.map(function(name) {
|
return " <table:named-expressions>\n" + scoped.map(function(name) {
|
||||||
var odsref = csf_to_ods_3D(name.Ref);
|
var odsref = (idx == -1 ? "$" : "") + csf_to_ods_3D(name.Ref);
|
||||||
return " " + writextag("table:named-range", null, {
|
return " " + writextag("table:named-range", null, {
|
||||||
"table:name": name.Name,
|
"table:name": name.Name,
|
||||||
"table:cell-range-address": odsref,
|
"table:cell-range-address": odsref,
|
||||||
@ -204,7 +211,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
|||||||
};
|
};
|
||||||
|
|
||||||
var null_cell_xml = ' <table:table-cell />\n';
|
var null_cell_xml = ' <table:table-cell />\n';
|
||||||
var write_ws = function(ws, wb/*:Workbook*/, i/*:number*/, opts, nfs)/*:string*/ {
|
var write_ws = function(ws, wb/*:Workbook*/, i/*:number*/, opts, nfs, date1904)/*:string*/ {
|
||||||
/* Section 9 Tables */
|
/* Section 9 Tables */
|
||||||
var o/*:Array<string>*/ = [];
|
var o/*:Array<string>*/ = [];
|
||||||
o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '" table:style-name="ta1">\n');
|
o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '" table:style-name="ta1">\n');
|
||||||
@ -264,9 +271,9 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
|||||||
ct['office:value-type'] = "string";
|
ct['office:value-type'] = "string";
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
textp = (cell.w||(parseDate(cell.v).toISOString()));
|
textp = (cell.w||(parseDate(cell.v, date1904).toISOString()));
|
||||||
ct['office:value-type'] = "date";
|
ct['office:value-type'] = "date";
|
||||||
ct['office:date-value'] = (parseDate(cell.v).toISOString());
|
ct['office:date-value'] = (parseDate(cell.v, date1904).toISOString());
|
||||||
ct['table:style-name'] = "ce1";
|
ct['table:style-name'] = "ce1";
|
||||||
break;
|
break;
|
||||||
//case 'e': // TODO: translate to ODS errors
|
//case 'e': // TODO: translate to ODS errors
|
||||||
@ -436,7 +443,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
|||||||
o.push(' <office:body>\n');
|
o.push(' <office:body>\n');
|
||||||
o.push(' <office:spreadsheet>\n');
|
o.push(' <office:spreadsheet>\n');
|
||||||
if(((wb.Workbook||{}).WBProps||{}).date1904) o.push(' <table:calculation-settings table:case-sensitive="false" table:search-criteria-must-apply-to-whole-cell="true" table:use-wildcards="true" table:use-regular-expressions="false" table:automatic-find-labels="false">\n <table:null-date table:date-value="1904-01-01"/>\n </table:calculation-settings>\n');
|
if(((wb.Workbook||{}).WBProps||{}).date1904) o.push(' <table:calculation-settings table:case-sensitive="false" table:search-criteria-must-apply-to-whole-cell="true" table:use-wildcards="true" table:use-regular-expressions="false" table:automatic-find-labels="false">\n <table:null-date table:date-value="1904-01-01"/>\n </table:calculation-settings>\n');
|
||||||
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts, nfs));
|
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts, nfs, ((wb.Workbook||{}).WBProps||{}).date1904));
|
||||||
if((wb.Workbook||{}).Names) o.push(write_names_ods(wb.Workbook.Names, wb.SheetNames, -1));
|
if((wb.Workbook||{}).Names) o.push(write_names_ods(wb.Workbook.Names, wb.SheetNames, -1));
|
||||||
o.push(' </office:spreadsheet>\n');
|
o.push(' </office:spreadsheet>\n');
|
||||||
o.push(' </office:body>\n');
|
o.push(' </office:body>\n');
|
||||||
|
@ -566,10 +566,10 @@ function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
|
|||||||
cell.w = cell.w.replace(/:(\d\d\d)$/, ".$1");
|
cell.w = cell.w.replace(/:(\d\d\d)$/, ".$1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function parse_old_storage(buf, lut, v) {
|
function parse_old_storage(buf, lut, v, opts) {
|
||||||
var dv = u8_to_dataview(buf);
|
var dv = u8_to_dataview(buf);
|
||||||
var flags = dv.getUint32(4, true);
|
var flags = dv.getUint32(4, true);
|
||||||
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
|
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dc = 0, dt = new Date(Date.UTC(2001, 0, 1));
|
||||||
var doff = v > 1 ? 12 : 8;
|
var doff = v > 1 ? 12 : 8;
|
||||||
if (flags & 2) {
|
if (flags & 2) {
|
||||||
zidx = dv.getUint32(doff, true);
|
zidx = dv.getUint32(doff, true);
|
||||||
@ -590,7 +590,7 @@ function parse_old_storage(buf, lut, v) {
|
|||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (flags & 64) {
|
if (flags & 64) {
|
||||||
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
|
dt.setTime(dt.getTime() + (dc = dv.getFloat64(doff, true)) * 1e3);
|
||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (v > 1) {
|
if (v > 1) {
|
||||||
@ -613,7 +613,12 @@ function parse_old_storage(buf, lut, v) {
|
|||||||
ret = { t: "s", v: lut.sst[sidx] };
|
ret = { t: "s", v: lut.sst[sidx] };
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
ret = { t: "d", v: dt };
|
{
|
||||||
|
if (opts == null ? void 0 : opts.cellDates)
|
||||||
|
ret = { t: "d", v: dt };
|
||||||
|
else
|
||||||
|
ret = { t: "n", v: dc / 86400 + 35430, z: table_fmt[14] };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
ret = { t: "b", v: ieee > 0 };
|
ret = { t: "b", v: ieee > 0 };
|
||||||
@ -644,12 +649,12 @@ function parse_old_storage(buf, lut, v) {
|
|||||||
ret.v /= 86400;
|
ret.v /= 86400;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
function parse_new_storage(buf, lut) {
|
function parse_new_storage(buf, lut, opts) {
|
||||||
var dv = u8_to_dataview(buf);
|
var dv = u8_to_dataview(buf);
|
||||||
var flags = dv.getUint32(4, true);
|
var flags = dv.getUint32(4, true);
|
||||||
var fields = dv.getUint32(8, true);
|
var fields = dv.getUint32(8, true);
|
||||||
var doff = 12;
|
var doff = 12;
|
||||||
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1), eidx = -1, fidx = -1;
|
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dc = 0, dt = new Date(Date.UTC(2001, 0, 1)), eidx = -1, fidx = -1;
|
||||||
if (fields & 1) {
|
if (fields & 1) {
|
||||||
d128 = readDecimal128LE(buf, doff);
|
d128 = readDecimal128LE(buf, doff);
|
||||||
doff += 16;
|
doff += 16;
|
||||||
@ -659,7 +664,7 @@ function parse_new_storage(buf, lut) {
|
|||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (fields & 4) {
|
if (fields & 4) {
|
||||||
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
|
dt.setTime(dt.getTime() + (dc = dv.getFloat64(doff, true)) * 1e3);
|
||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (fields & 8) {
|
if (fields & 8) {
|
||||||
@ -693,7 +698,12 @@ function parse_new_storage(buf, lut) {
|
|||||||
ret = { t: "s", v: lut.sst[sidx] };
|
ret = { t: "s", v: lut.sst[sidx] };
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
ret = { t: "d", v: dt };
|
{
|
||||||
|
if (opts == null ? void 0 : opts.cellDates)
|
||||||
|
ret = { t: "d", v: dt };
|
||||||
|
else
|
||||||
|
ret = { t: "n", v: dc / 86400 + 35430, z: table_fmt[14] };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
ret = { t: "b", v: ieee > 0 };
|
ret = { t: "b", v: ieee > 0 };
|
||||||
@ -744,10 +754,18 @@ function write_new_storage(cell, lut) {
|
|||||||
out[0] = 5;
|
out[0] = 5;
|
||||||
switch (cell.t) {
|
switch (cell.t) {
|
||||||
case "n":
|
case "n":
|
||||||
out[1] = 2;
|
if (cell.z && fmt_is_date(cell.z)) {
|
||||||
writeDecimal128LE(out, l, cell.v);
|
out[1] = 5;
|
||||||
fields |= 1;
|
dv.setFloat64(l, (numdate(cell.v + 1462).getTime() - Date.UTC(2001, 0, 1)) / 1e3, true);
|
||||||
l += 16;
|
fields |= 4;
|
||||||
|
l += 8;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
out[1] = 2;
|
||||||
|
writeDecimal128LE(out, l, cell.v);
|
||||||
|
fields |= 1;
|
||||||
|
l += 16;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "b":
|
case "b":
|
||||||
out[1] = 6;
|
out[1] = 6;
|
||||||
@ -780,6 +798,12 @@ function write_new_storage(cell, lut) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "d":
|
||||||
|
out[1] = 5;
|
||||||
|
dv.setFloat64(l, (cell.v.getTime() - Date.UTC(2001, 0, 1)) / 1e3, true);
|
||||||
|
fields |= 4;
|
||||||
|
l += 8;
|
||||||
|
break;
|
||||||
case "z":
|
case "z":
|
||||||
out[1] = 0;
|
out[1] = 0;
|
||||||
break;
|
break;
|
||||||
@ -796,7 +820,7 @@ function write_new_storage(cell, lut) {
|
|||||||
return out[subarray](0, l);
|
return out[subarray](0, l);
|
||||||
}
|
}
|
||||||
function write_old_storage(cell, lut) {
|
function write_old_storage(cell, lut) {
|
||||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0;
|
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0, s = "";
|
||||||
out[0] = 4;
|
out[0] = 4;
|
||||||
switch (cell.t) {
|
switch (cell.t) {
|
||||||
case "n":
|
case "n":
|
||||||
@ -805,7 +829,7 @@ function write_old_storage(cell, lut) {
|
|||||||
break;
|
break;
|
||||||
case "s":
|
case "s":
|
||||||
{
|
{
|
||||||
var s = cell.v == null ? "" : String(cell.v);
|
s = cell.v == null ? "" : String(cell.v);
|
||||||
if (cell.l) {
|
if (cell.l) {
|
||||||
var irsst = lut.rsst.findIndex(function(v) {
|
var irsst = lut.rsst.findIndex(function(v) {
|
||||||
var _a;
|
var _a;
|
||||||
@ -821,6 +845,10 @@ function write_old_storage(cell, lut) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "d":
|
||||||
|
break;
|
||||||
|
case "e":
|
||||||
|
break;
|
||||||
case "z":
|
case "z":
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -846,7 +874,7 @@ function write_old_storage(cell, lut) {
|
|||||||
break;
|
break;
|
||||||
case "s":
|
case "s":
|
||||||
{
|
{
|
||||||
var s = cell.v == null ? "" : String(cell.v);
|
s = cell.v == null ? "" : String(cell.v);
|
||||||
if (cell.l) {
|
if (cell.l) {
|
||||||
} else {
|
} else {
|
||||||
var isst = lut.sst.indexOf(s);
|
var isst = lut.sst.indexOf(s);
|
||||||
@ -859,6 +887,12 @@ function write_old_storage(cell, lut) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "d":
|
||||||
|
out[1] = 5;
|
||||||
|
dv.setFloat64(l, (cell.v.getTime() - Date.UTC(2001, 0, 1)) / 1e3, true);
|
||||||
|
fields |= 64;
|
||||||
|
l += 8;
|
||||||
|
break;
|
||||||
case "z":
|
case "z":
|
||||||
out[1] = 0;
|
out[1] = 0;
|
||||||
break;
|
break;
|
||||||
@ -868,16 +902,16 @@ function write_old_storage(cell, lut) {
|
|||||||
dv.setUint32(8, fields, true);
|
dv.setUint32(8, fields, true);
|
||||||
return out[subarray](0, l);
|
return out[subarray](0, l);
|
||||||
}
|
}
|
||||||
function parse_cell_storage(buf, lut) {
|
function parse_cell_storage(buf, lut, opts) {
|
||||||
switch (buf[0]) {
|
switch (buf[0]) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
return parse_old_storage(buf, lut, buf[0]);
|
return parse_old_storage(buf, lut, buf[0], opts);
|
||||||
case 5:
|
case 5:
|
||||||
return parse_new_storage(buf, lut);
|
return parse_new_storage(buf, lut, opts);
|
||||||
default:
|
default:
|
||||||
throw new Error("Unsupported payload version ".concat(buf[0]));
|
throw new Error("Unsupported payload version ".concat(buf[0]));
|
||||||
}
|
}
|
||||||
@ -1082,7 +1116,7 @@ function s5s_to_iwa_comment(s5s) {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
function parse_TST_TableModelArchive(M, root, ws) {
|
function parse_TST_TableModelArchive(M, root, ws, opts) {
|
||||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
||||||
var pb = parse_shallow(root.data);
|
var pb = parse_shallow(root.data);
|
||||||
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
|
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
|
||||||
@ -1121,7 +1155,7 @@ function parse_TST_TableModelArchive(M, root, ws) {
|
|||||||
var _tile = parse_TST_Tile(M, ref2);
|
var _tile = parse_TST_Tile(M, ref2);
|
||||||
_tile.data.forEach(function(row, R) {
|
_tile.data.forEach(function(row, R) {
|
||||||
row.forEach(function(buf, C) {
|
row.forEach(function(buf, C) {
|
||||||
var res = parse_cell_storage(buf, lut);
|
var res = parse_cell_storage(buf, lut, opts);
|
||||||
if (res) {
|
if (res) {
|
||||||
if (dense) {
|
if (dense) {
|
||||||
if (!dws["!data"][_R + R])
|
if (!dws["!data"][_R + R])
|
||||||
@ -1162,7 +1196,7 @@ function parse_TST_TableInfoArchive(M, root, opts) {
|
|||||||
var mtype = varint_to_i32(tableref[0].meta[1][0].data);
|
var mtype = varint_to_i32(tableref[0].meta[1][0].data);
|
||||||
if (mtype != 6001)
|
if (mtype != 6001)
|
||||||
throw new Error("6000 unexpected reference to ".concat(mtype));
|
throw new Error("6000 unexpected reference to ".concat(mtype));
|
||||||
parse_TST_TableModelArchive(M, tableref[0], out);
|
parse_TST_TableModelArchive(M, tableref[0], out, opts);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
function parse_TN_SheetArchive(M, root, opts) {
|
function parse_TN_SheetArchive(M, root, opts) {
|
||||||
@ -1185,6 +1219,7 @@ function parse_TN_SheetArchive(M, root, opts) {
|
|||||||
function parse_TN_DocumentArchive(M, root, opts) {
|
function parse_TN_DocumentArchive(M, root, opts) {
|
||||||
var _a;
|
var _a;
|
||||||
var out = book_new();
|
var out = book_new();
|
||||||
|
out.Workbook = { WBProps: { date1904: true } };
|
||||||
var pb = parse_shallow(root.data);
|
var pb = parse_shallow(root.data);
|
||||||
if ((_a = pb[2]) == null ? void 0 : _a[0])
|
if ((_a = pb[2]) == null ? void 0 : _a[0])
|
||||||
throw new Error("Keynote presentations are not supported");
|
throw new Error("Keynote presentations are not supported");
|
||||||
@ -1300,8 +1335,8 @@ function write_TST_TileRowInfo(data, lut, wide) {
|
|||||||
switch (data[C].t) {
|
switch (data[C].t) {
|
||||||
case "d":
|
case "d":
|
||||||
if (data[C].v instanceof Date) {
|
if (data[C].v instanceof Date) {
|
||||||
celload = write_new_storage({ t: "s", v: data[C].v.toISOString() }, lut);
|
celload = write_new_storage(data[C], lut);
|
||||||
_celload = write_old_storage({ t: "s", v: data[C].v.toISOString() }, lut);
|
_celload = write_old_storage(data[C], lut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
celload = write_new_storage(data[C], lut);
|
celload = write_new_storage(data[C], lut);
|
||||||
|
@ -24,7 +24,12 @@ function make_json_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Ar
|
|||||||
switch(val.t){
|
switch(val.t){
|
||||||
case 'z': if(v == null) break; continue;
|
case 'z': if(v == null) break; continue;
|
||||||
case 'e': v = (v == 0 ? null : void 0); break;
|
case 'e': v = (v == 0 ? null : void 0); break;
|
||||||
case 's': case 'd': case 'b': case 'n': break;
|
case 's': case 'b':
|
||||||
|
case 'n': if(!val.z || !fmt_is_date(val.z)) break;
|
||||||
|
v = numdate(v); // TODO: date1904 setting should also be stored in worksheet object
|
||||||
|
if(typeof v == "number") break;
|
||||||
|
/* falls through */
|
||||||
|
case 'd': if(!(o && o.UTC)) v = utc_to_local(v); break;
|
||||||
default: throw new Error('unrecognized type ' + val.t);
|
default: throw new Error('unrecognized type ' + val.t);
|
||||||
}
|
}
|
||||||
if(hdr[C] != null) {
|
if(hdr[C] != null) {
|
||||||
@ -234,6 +239,7 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
|
|||||||
else if(typeof v == 'string') t = 's';
|
else if(typeof v == 'string') t = 's';
|
||||||
else if(v instanceof Date) {
|
else if(v instanceof Date) {
|
||||||
t = 'd';
|
t = 'd';
|
||||||
|
if(!o.UTC) v = local_to_utc(v);
|
||||||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||||
z = (cell != null && cell.z && fmt_is_date(cell.z)) ? cell.z : (o.dateNF || table_fmt[14]);
|
z = (cell != null && cell.z && fmt_is_date(cell.z)) ? cell.z : (o.dateNF || table_fmt[14]);
|
||||||
}
|
}
|
||||||
|
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
2273
dist/xlsx.extendscript.js
generated
vendored
2273
dist/xlsx.extendscript.js
generated
vendored
File diff suppressed because it is too large
Load Diff
35
dist/xlsx.full.min.js
generated
vendored
35
dist/xlsx.full.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
generated
vendored
2
dist/xlsx.full.min.map
generated
vendored
File diff suppressed because one or more lines are too long
18
dist/xlsx.mini.min.js
generated
vendored
18
dist/xlsx.mini.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.mini.min.map
generated
vendored
2
dist/xlsx.mini.min.map
generated
vendored
File diff suppressed because one or more lines are too long
@ -566,10 +566,10 @@ function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
|
|||||||
cell.w = cell.w.replace(/:(\d\d\d)$/, ".$1");
|
cell.w = cell.w.replace(/:(\d\d\d)$/, ".$1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function parse_old_storage(buf, lut, v) {
|
function parse_old_storage(buf, lut, v, opts) {
|
||||||
var dv = u8_to_dataview(buf);
|
var dv = u8_to_dataview(buf);
|
||||||
var flags = dv.getUint32(4, true);
|
var flags = dv.getUint32(4, true);
|
||||||
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
|
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dc = 0, dt = new Date(Date.UTC(2001, 0, 1));
|
||||||
var doff = v > 1 ? 12 : 8;
|
var doff = v > 1 ? 12 : 8;
|
||||||
if (flags & 2) {
|
if (flags & 2) {
|
||||||
zidx = dv.getUint32(doff, true);
|
zidx = dv.getUint32(doff, true);
|
||||||
@ -590,7 +590,7 @@ function parse_old_storage(buf, lut, v) {
|
|||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (flags & 64) {
|
if (flags & 64) {
|
||||||
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
|
dt.setTime(dt.getTime() + (dc = dv.getFloat64(doff, true)) * 1e3);
|
||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (v > 1) {
|
if (v > 1) {
|
||||||
@ -613,7 +613,12 @@ function parse_old_storage(buf, lut, v) {
|
|||||||
ret = { t: "s", v: lut.sst[sidx] };
|
ret = { t: "s", v: lut.sst[sidx] };
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
ret = { t: "d", v: dt };
|
{
|
||||||
|
if (opts == null ? void 0 : opts.cellDates)
|
||||||
|
ret = { t: "d", v: dt };
|
||||||
|
else
|
||||||
|
ret = { t: "n", v: dc / 86400 + 35430, z: table_fmt[14] };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
ret = { t: "b", v: ieee > 0 };
|
ret = { t: "b", v: ieee > 0 };
|
||||||
@ -644,12 +649,12 @@ function parse_old_storage(buf, lut, v) {
|
|||||||
ret.v /= 86400;
|
ret.v /= 86400;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
function parse_new_storage(buf, lut) {
|
function parse_new_storage(buf, lut, opts) {
|
||||||
var dv = u8_to_dataview(buf);
|
var dv = u8_to_dataview(buf);
|
||||||
var flags = dv.getUint32(4, true);
|
var flags = dv.getUint32(4, true);
|
||||||
var fields = dv.getUint32(8, true);
|
var fields = dv.getUint32(8, true);
|
||||||
var doff = 12;
|
var doff = 12;
|
||||||
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1), eidx = -1, fidx = -1;
|
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dc = 0, dt = new Date(Date.UTC(2001, 0, 1)), eidx = -1, fidx = -1;
|
||||||
if (fields & 1) {
|
if (fields & 1) {
|
||||||
d128 = readDecimal128LE(buf, doff);
|
d128 = readDecimal128LE(buf, doff);
|
||||||
doff += 16;
|
doff += 16;
|
||||||
@ -659,7 +664,7 @@ function parse_new_storage(buf, lut) {
|
|||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (fields & 4) {
|
if (fields & 4) {
|
||||||
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
|
dt.setTime(dt.getTime() + (dc = dv.getFloat64(doff, true)) * 1e3);
|
||||||
doff += 8;
|
doff += 8;
|
||||||
}
|
}
|
||||||
if (fields & 8) {
|
if (fields & 8) {
|
||||||
@ -693,7 +698,12 @@ function parse_new_storage(buf, lut) {
|
|||||||
ret = { t: "s", v: lut.sst[sidx] };
|
ret = { t: "s", v: lut.sst[sidx] };
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
ret = { t: "d", v: dt };
|
{
|
||||||
|
if (opts == null ? void 0 : opts.cellDates)
|
||||||
|
ret = { t: "d", v: dt };
|
||||||
|
else
|
||||||
|
ret = { t: "n", v: dc / 86400 + 35430, z: table_fmt[14] };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
ret = { t: "b", v: ieee > 0 };
|
ret = { t: "b", v: ieee > 0 };
|
||||||
@ -744,10 +754,18 @@ function write_new_storage(cell, lut) {
|
|||||||
out[0] = 5;
|
out[0] = 5;
|
||||||
switch (cell.t) {
|
switch (cell.t) {
|
||||||
case "n":
|
case "n":
|
||||||
out[1] = 2;
|
if (cell.z && fmt_is_date(cell.z)) {
|
||||||
writeDecimal128LE(out, l, cell.v);
|
out[1] = 5;
|
||||||
fields |= 1;
|
dv.setFloat64(l, (numdate(cell.v + 1462).getTime() - Date.UTC(2001, 0, 1)) / 1e3, true);
|
||||||
l += 16;
|
fields |= 4;
|
||||||
|
l += 8;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
out[1] = 2;
|
||||||
|
writeDecimal128LE(out, l, cell.v);
|
||||||
|
fields |= 1;
|
||||||
|
l += 16;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "b":
|
case "b":
|
||||||
out[1] = 6;
|
out[1] = 6;
|
||||||
@ -780,6 +798,12 @@ function write_new_storage(cell, lut) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "d":
|
||||||
|
out[1] = 5;
|
||||||
|
dv.setFloat64(l, (cell.v.getTime() - Date.UTC(2001, 0, 1)) / 1e3, true);
|
||||||
|
fields |= 4;
|
||||||
|
l += 8;
|
||||||
|
break;
|
||||||
case "z":
|
case "z":
|
||||||
out[1] = 0;
|
out[1] = 0;
|
||||||
break;
|
break;
|
||||||
@ -796,7 +820,7 @@ function write_new_storage(cell, lut) {
|
|||||||
return out[subarray](0, l);
|
return out[subarray](0, l);
|
||||||
}
|
}
|
||||||
function write_old_storage(cell, lut) {
|
function write_old_storage(cell, lut) {
|
||||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0;
|
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0, s = "";
|
||||||
out[0] = 4;
|
out[0] = 4;
|
||||||
switch (cell.t) {
|
switch (cell.t) {
|
||||||
case "n":
|
case "n":
|
||||||
@ -805,7 +829,7 @@ function write_old_storage(cell, lut) {
|
|||||||
break;
|
break;
|
||||||
case "s":
|
case "s":
|
||||||
{
|
{
|
||||||
var s = cell.v == null ? "" : String(cell.v);
|
s = cell.v == null ? "" : String(cell.v);
|
||||||
if (cell.l) {
|
if (cell.l) {
|
||||||
var irsst = lut.rsst.findIndex(function(v) {
|
var irsst = lut.rsst.findIndex(function(v) {
|
||||||
var _a;
|
var _a;
|
||||||
@ -821,6 +845,10 @@ function write_old_storage(cell, lut) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "d":
|
||||||
|
break;
|
||||||
|
case "e":
|
||||||
|
break;
|
||||||
case "z":
|
case "z":
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -846,7 +874,7 @@ function write_old_storage(cell, lut) {
|
|||||||
break;
|
break;
|
||||||
case "s":
|
case "s":
|
||||||
{
|
{
|
||||||
var s = cell.v == null ? "" : String(cell.v);
|
s = cell.v == null ? "" : String(cell.v);
|
||||||
if (cell.l) {
|
if (cell.l) {
|
||||||
} else {
|
} else {
|
||||||
var isst = lut.sst.indexOf(s);
|
var isst = lut.sst.indexOf(s);
|
||||||
@ -859,6 +887,12 @@ function write_old_storage(cell, lut) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "d":
|
||||||
|
out[1] = 5;
|
||||||
|
dv.setFloat64(l, (cell.v.getTime() - Date.UTC(2001, 0, 1)) / 1e3, true);
|
||||||
|
fields |= 64;
|
||||||
|
l += 8;
|
||||||
|
break;
|
||||||
case "z":
|
case "z":
|
||||||
out[1] = 0;
|
out[1] = 0;
|
||||||
break;
|
break;
|
||||||
@ -868,16 +902,16 @@ function write_old_storage(cell, lut) {
|
|||||||
dv.setUint32(8, fields, true);
|
dv.setUint32(8, fields, true);
|
||||||
return out[subarray](0, l);
|
return out[subarray](0, l);
|
||||||
}
|
}
|
||||||
function parse_cell_storage(buf, lut) {
|
function parse_cell_storage(buf, lut, opts) {
|
||||||
switch (buf[0]) {
|
switch (buf[0]) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
return parse_old_storage(buf, lut, buf[0]);
|
return parse_old_storage(buf, lut, buf[0], opts);
|
||||||
case 5:
|
case 5:
|
||||||
return parse_new_storage(buf, lut);
|
return parse_new_storage(buf, lut, opts);
|
||||||
default:
|
default:
|
||||||
throw new Error("Unsupported payload version ".concat(buf[0]));
|
throw new Error("Unsupported payload version ".concat(buf[0]));
|
||||||
}
|
}
|
||||||
@ -1082,7 +1116,7 @@ function s5s_to_iwa_comment(s5s) {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
function parse_TST_TableModelArchive(M, root, ws) {
|
function parse_TST_TableModelArchive(M, root, ws, opts) {
|
||||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
||||||
var pb = parse_shallow(root.data);
|
var pb = parse_shallow(root.data);
|
||||||
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
|
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
|
||||||
@ -1121,7 +1155,7 @@ function parse_TST_TableModelArchive(M, root, ws) {
|
|||||||
var _tile = parse_TST_Tile(M, ref2);
|
var _tile = parse_TST_Tile(M, ref2);
|
||||||
_tile.data.forEach(function(row, R) {
|
_tile.data.forEach(function(row, R) {
|
||||||
row.forEach(function(buf, C) {
|
row.forEach(function(buf, C) {
|
||||||
var res = parse_cell_storage(buf, lut);
|
var res = parse_cell_storage(buf, lut, opts);
|
||||||
if (res) {
|
if (res) {
|
||||||
if (dense) {
|
if (dense) {
|
||||||
if (!dws["!data"][_R + R])
|
if (!dws["!data"][_R + R])
|
||||||
@ -1162,7 +1196,7 @@ function parse_TST_TableInfoArchive(M, root, opts) {
|
|||||||
var mtype = varint_to_i32(tableref[0].meta[1][0].data);
|
var mtype = varint_to_i32(tableref[0].meta[1][0].data);
|
||||||
if (mtype != 6001)
|
if (mtype != 6001)
|
||||||
throw new Error("6000 unexpected reference to ".concat(mtype));
|
throw new Error("6000 unexpected reference to ".concat(mtype));
|
||||||
parse_TST_TableModelArchive(M, tableref[0], out);
|
parse_TST_TableModelArchive(M, tableref[0], out, opts);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
function parse_TN_SheetArchive(M, root, opts) {
|
function parse_TN_SheetArchive(M, root, opts) {
|
||||||
@ -1185,6 +1219,7 @@ function parse_TN_SheetArchive(M, root, opts) {
|
|||||||
function parse_TN_DocumentArchive(M, root, opts) {
|
function parse_TN_DocumentArchive(M, root, opts) {
|
||||||
var _a;
|
var _a;
|
||||||
var out = book_new();
|
var out = book_new();
|
||||||
|
out.Workbook = { WBProps: { date1904: true } };
|
||||||
var pb = parse_shallow(root.data);
|
var pb = parse_shallow(root.data);
|
||||||
if ((_a = pb[2]) == null ? void 0 : _a[0])
|
if ((_a = pb[2]) == null ? void 0 : _a[0])
|
||||||
throw new Error("Keynote presentations are not supported");
|
throw new Error("Keynote presentations are not supported");
|
||||||
@ -1300,8 +1335,8 @@ function write_TST_TileRowInfo(data, lut, wide) {
|
|||||||
switch (data[C].t) {
|
switch (data[C].t) {
|
||||||
case "d":
|
case "d":
|
||||||
if (data[C].v instanceof Date) {
|
if (data[C].v instanceof Date) {
|
||||||
celload = write_new_storage({ t: "s", v: data[C].v.toISOString() }, lut);
|
celload = write_new_storage(data[C], lut);
|
||||||
_celload = write_old_storage({ t: "s", v: data[C].v.toISOString() }, lut);
|
_celload = write_old_storage(data[C], lut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
celload = write_new_storage(data[C], lut);
|
celload = write_new_storage(data[C], lut);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
/* these are type imports and do not show up in the generated JS */
|
/* these are type imports and do not show up in the generated JS */
|
||||||
import { CFB$Container, CFB$Entry } from 'cfb';
|
import { CFB$Container, CFB$Entry } from 'cfb';
|
||||||
import { WorkBook, WorkSheet, Range, CellObject, ParsingOptions, WritingOptions, DenseWorkSheet, Comments } from '../';
|
import { WorkBook, WorkSheet, Range, CellObject, ParsingOptions, WritingOptions, DenseWorkSheet, Comments } from '../';
|
||||||
import type { utils } from "../";
|
import type { utils, NumberFormat } from "../";
|
||||||
|
|
||||||
declare var encode_col: typeof utils.encode_col;
|
declare var encode_col: typeof utils.encode_col;
|
||||||
declare var encode_row: typeof utils.encode_row;
|
declare var encode_row: typeof utils.encode_row;
|
||||||
@ -12,6 +12,9 @@ declare var encode_range: typeof utils.encode_range;
|
|||||||
declare var book_new: typeof utils.book_new;
|
declare var book_new: typeof utils.book_new;
|
||||||
declare var book_append_sheet: typeof utils.book_append_sheet;
|
declare var book_append_sheet: typeof utils.book_append_sheet;
|
||||||
declare var decode_range: typeof utils.decode_range;
|
declare var decode_range: typeof utils.decode_range;
|
||||||
|
declare var numdate: (num: number) => Date;
|
||||||
|
declare var table_fmt: {[nf: number]: string};
|
||||||
|
declare function fmt_is_date(fmt: NumberFormat): boolean;
|
||||||
import * as _CFB from 'cfb';
|
import * as _CFB from 'cfb';
|
||||||
declare var CFB: typeof _CFB;
|
declare var CFB: typeof _CFB;
|
||||||
//<<import { utils } from "../../";
|
//<<import { utils } from "../../";
|
||||||
@ -487,11 +490,11 @@ function numbers_format_cell(cell: CellObject, t: number, flags: number, ofmt: P
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Parse "old storage" (version 0..4) */
|
/** Parse "old storage" (version 0..4) */
|
||||||
function parse_old_storage(buf: Uint8Array, lut: DataLUT, v: 0|1|2|3|4): CellObject | void {
|
function parse_old_storage(buf: Uint8Array, lut: DataLUT, v: 0|1|2|3|4, opts?: ParsingOptions): CellObject | void {
|
||||||
var dv = u8_to_dataview(buf);
|
var dv = u8_to_dataview(buf);
|
||||||
var flags = dv.getUint32(4, true);
|
var flags = dv.getUint32(4, true);
|
||||||
|
|
||||||
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
|
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dc = 0, dt = new Date(Date.UTC(2001, 0, 1));
|
||||||
var doff = (v > 1 ? 12 : 8);
|
var doff = (v > 1 ? 12 : 8);
|
||||||
if(flags & 0x0002) { zidx = dv.getUint32(doff, true); doff += 4;}
|
if(flags & 0x0002) { zidx = dv.getUint32(doff, true); doff += 4;}
|
||||||
doff += popcnt(flags & (v > 1 ? 0x0D8C : 0x018C)) * 4;
|
doff += popcnt(flags & (v > 1 ? 0x0D8C : 0x018C)) * 4;
|
||||||
@ -500,7 +503,7 @@ function parse_old_storage(buf: Uint8Array, lut: DataLUT, v: 0|1|2|3|4): CellObj
|
|||||||
doff += popcnt(flags & (v > 1 ? 0x3000 : 0x1000)) * 4;
|
doff += popcnt(flags & (v > 1 ? 0x3000 : 0x1000)) * 4;
|
||||||
if(flags & 0x0010) { sidx = dv.getUint32(doff, true); doff += 4; }
|
if(flags & 0x0010) { sidx = dv.getUint32(doff, true); doff += 4; }
|
||||||
if(flags & 0x0020) { ieee = dv.getFloat64(doff, true); doff += 8; }
|
if(flags & 0x0020) { ieee = dv.getFloat64(doff, true); doff += 8; }
|
||||||
if(flags & 0x0040) { dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1000); doff += 8; }
|
if(flags & 0x0040) { dt.setTime(dt.getTime() + (dc = dv.getFloat64(doff, true)) * 1000); doff += 8; }
|
||||||
|
|
||||||
if(v > 1) {
|
if(v > 1) {
|
||||||
flags = dv.getUint32(8, true) >>> 16;
|
flags = dv.getUint32(8, true) >>> 16;
|
||||||
@ -514,7 +517,10 @@ function parse_old_storage(buf: Uint8Array, lut: DataLUT, v: 0|1|2|3|4): CellObj
|
|||||||
case 0: return void 0; // return { t: "z" }; // blank?
|
case 0: return void 0; // return { t: "z" }; // blank?
|
||||||
case 2: ret = { t: "n", v: ieee }; break; // number
|
case 2: ret = { t: "n", v: ieee }; break; // number
|
||||||
case 3: ret = { t: "s", v: lut.sst[sidx] }; break; // string
|
case 3: ret = { t: "s", v: lut.sst[sidx] }; break; // string
|
||||||
case 5: ret = { t: "d", v: dt }; break; // date-time
|
case 5: { // date-time
|
||||||
|
if(opts?.cellDates) ret = { t: "d", v: dt };
|
||||||
|
else ret = ({ t: "n", v: dc/(86400)+35430, z: table_fmt[14]});
|
||||||
|
} break;
|
||||||
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
||||||
case 7: ret = { t: "n", v: ieee }; break; // duration in seconds
|
case 7: ret = { t: "n", v: ieee }; break; // duration in seconds
|
||||||
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
||||||
@ -534,19 +540,19 @@ function parse_old_storage(buf: Uint8Array, lut: DataLUT, v: 0|1|2|3|4): CellObj
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Parse "new storage" (version 5) */
|
/** Parse "new storage" (version 5) */
|
||||||
function parse_new_storage(buf: Uint8Array, lut: DataLUT): CellObject | void {
|
function parse_new_storage(buf: Uint8Array, lut: DataLUT, opts?: ParsingOptions): CellObject | void {
|
||||||
var dv = u8_to_dataview(buf);
|
var dv = u8_to_dataview(buf);
|
||||||
// TODO: bytes 2:3 appear to be unused?
|
// TODO: bytes 2:3 appear to be unused?
|
||||||
var flags = dv.getUint32(4, true);
|
var flags = dv.getUint32(4, true);
|
||||||
var fields = dv.getUint32(8, true);
|
var fields = dv.getUint32(8, true);
|
||||||
var doff = 12;
|
var doff = 12;
|
||||||
|
|
||||||
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1), eidx = -1, fidx = -1;
|
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dc = 0, dt = new Date(Date.UTC(2001, 0, 1)), eidx = -1, fidx = -1;
|
||||||
|
|
||||||
// 0x00001F data
|
// 0x00001F data
|
||||||
if(fields & 0x000001) { d128 = readDecimal128LE(buf, doff); doff += 16; }
|
if(fields & 0x000001) { d128 = readDecimal128LE(buf, doff); doff += 16; }
|
||||||
if(fields & 0x000002) { ieee = dv.getFloat64(doff, true); doff += 8; }
|
if(fields & 0x000002) { ieee = dv.getFloat64(doff, true); doff += 8; }
|
||||||
if(fields & 0x000004) { dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1000); doff += 8; }
|
if(fields & 0x000004) { dt.setTime(dt.getTime() + (dc = dv.getFloat64(doff, true)) * 1000); doff += 8; }
|
||||||
if(fields & 0x000008) { sidx = dv.getUint32(doff, true); doff += 4; }
|
if(fields & 0x000008) { sidx = dv.getUint32(doff, true); doff += 4; }
|
||||||
if(fields & 0x000010) { ridx = dv.getUint32(doff, true); doff += 4; }
|
if(fields & 0x000010) { ridx = dv.getUint32(doff, true); doff += 4; }
|
||||||
|
|
||||||
@ -564,7 +570,10 @@ function parse_new_storage(buf: Uint8Array, lut: DataLUT): CellObject | void {
|
|||||||
case 0: ret = { t: "z" }; break;
|
case 0: ret = { t: "z" }; break;
|
||||||
case 2: ret = { t: "n", v: d128 }; break; // number
|
case 2: ret = { t: "n", v: d128 }; break; // number
|
||||||
case 3: ret = { t: "s", v: lut.sst[sidx] }; break; // string
|
case 3: ret = { t: "s", v: lut.sst[sidx] }; break; // string
|
||||||
case 5: ret = { t: "d", v: dt }; break; // date-time
|
case 5: { // date-time
|
||||||
|
if(opts?.cellDates) ret = { t: "d", v: dt };
|
||||||
|
else ret = ({ t: "n", v: dc/(86400)+35430, z: table_fmt[14]});
|
||||||
|
} break;
|
||||||
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
||||||
case 7: ret = { t: "n", v: ieee }; break; // duration in "s", fixed later
|
case 7: ret = { t: "n", v: ieee }; break; // duration in "s", fixed later
|
||||||
case 8: ret = { t: "e", v: 0 }; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
case 8: ret = { t: "e", v: 0 }; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
||||||
@ -603,7 +612,11 @@ function write_new_storage(cell: CellObject, lut: DataLUT): Uint8Array {
|
|||||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0;
|
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0;
|
||||||
out[0] = 5;
|
out[0] = 5;
|
||||||
switch(cell.t) {
|
switch(cell.t) {
|
||||||
case "n": out[1] = 2; writeDecimal128LE(out, l, cell.v as number); fields |= 1; l += 16; break;
|
case "n": if(cell.z && fmt_is_date(cell.z)) {
|
||||||
|
out[1] = 5; dv.setFloat64(l, ((numdate((cell.v as number) + 1462)).getTime() - Date.UTC(2001, 0, 1))/1000, true); fields |= 4; l += 8; break
|
||||||
|
} else {
|
||||||
|
out[1] = 2; writeDecimal128LE(out, l, cell.v as number); fields |= 1; l += 16;
|
||||||
|
} break
|
||||||
case "b": out[1] = 6; dv.setFloat64(l, cell.v ? 1 : 0, true); fields |= 2; l += 8; break;
|
case "b": out[1] = 6; dv.setFloat64(l, cell.v ? 1 : 0, true); fields |= 2; l += 8; break;
|
||||||
case "s": {
|
case "s": {
|
||||||
var s = cell.v == null ? "" : String(cell.v);
|
var s = cell.v == null ? "" : String(cell.v);
|
||||||
@ -617,6 +630,8 @@ function write_new_storage(cell: CellObject, lut: DataLUT): Uint8Array {
|
|||||||
out[1] = 3; dv.setUint32(l, isst, true); fields |= 8; l += 4;
|
out[1] = 3; dv.setUint32(l, isst, true); fields |= 8; l += 4;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case "d": out[1] = 5; dv.setFloat64(l, ((cell.v as Date).getTime() - Date.UTC(2001, 0, 1))/1000, true); fields |= 4; l += 8; break;
|
||||||
|
|
||||||
case "z": out[1] = 0; break;
|
case "z": out[1] = 0; break;
|
||||||
default: throw "unsupported cell type " + cell.t;
|
default: throw "unsupported cell type " + cell.t;
|
||||||
}
|
}
|
||||||
@ -629,20 +644,22 @@ function write_new_storage(cell: CellObject, lut: DataLUT): Uint8Array {
|
|||||||
}
|
}
|
||||||
/** Write a cell "old storage" (version 4) */
|
/** Write a cell "old storage" (version 4) */
|
||||||
function write_old_storage(cell: CellObject, lut: DataLUT): Uint8Array {
|
function write_old_storage(cell: CellObject, lut: DataLUT): Uint8Array {
|
||||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0;
|
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, fields = 0, s = "";
|
||||||
out[0] = 4;
|
out[0] = 4;
|
||||||
/* note: rich text appears *before* comments */
|
/* note: rich text appears *before* comments */
|
||||||
switch(cell.t) {
|
switch(cell.t) {
|
||||||
case "n": break;
|
case "n": break;
|
||||||
case "b": break;
|
case "b": break;
|
||||||
case "s": {
|
case "s": {
|
||||||
var s = cell.v == null ? "" : String(cell.v);
|
s = cell.v == null ? "" : String(cell.v);
|
||||||
if(cell.l) {
|
if(cell.l) {
|
||||||
var irsst = lut.rsst.findIndex(v => v.v == s && v.l == cell.l?.Target);
|
var irsst = lut.rsst.findIndex(v => v.v == s && v.l == cell.l?.Target);
|
||||||
if(irsst == -1) lut.rsst[irsst = lut.rsst.length] = { v: s, l: cell.l.Target };
|
if(irsst == -1) lut.rsst[irsst = lut.rsst.length] = { v: s, l: cell.l.Target };
|
||||||
out[1] = 9; dv.setUint32(l, irsst, true); fields |= 0x200; l += 4;
|
out[1] = 9; dv.setUint32(l, irsst, true); fields |= 0x200; l += 4;
|
||||||
} else { }
|
} else { }
|
||||||
} break;
|
} break;
|
||||||
|
case "d": break;
|
||||||
|
case "e": break;
|
||||||
case "z": break;
|
case "z": break;
|
||||||
default: throw "unsupported cell type " + cell.t;
|
default: throw "unsupported cell type " + cell.t;
|
||||||
}
|
}
|
||||||
@ -654,13 +671,14 @@ function write_old_storage(cell: CellObject, lut: DataLUT): Uint8Array {
|
|||||||
case "n": out[1] = 2; dv.setFloat64(l, cell.v as number, true); fields |= 0x20; l += 8; break;
|
case "n": out[1] = 2; dv.setFloat64(l, cell.v as number, true); fields |= 0x20; l += 8; break;
|
||||||
case "b": out[1] = 6; dv.setFloat64(l, cell.v ? 1 : 0, true); fields |= 0x20; l += 8; break;
|
case "b": out[1] = 6; dv.setFloat64(l, cell.v ? 1 : 0, true); fields |= 0x20; l += 8; break;
|
||||||
case "s": {
|
case "s": {
|
||||||
var s = cell.v == null ? "" : String(cell.v);
|
s = cell.v == null ? "" : String(cell.v);
|
||||||
if(cell.l) { } else {
|
if(cell.l) { } else {
|
||||||
var isst = lut.sst.indexOf(s);
|
var isst = lut.sst.indexOf(s);
|
||||||
if(isst == -1) lut.sst[isst = lut.sst.length] = s;
|
if(isst == -1) lut.sst[isst = lut.sst.length] = s;
|
||||||
out[1] = 3; dv.setUint32(l, isst, true); fields |= 0x10; l += 4;
|
out[1] = 3; dv.setUint32(l, isst, true); fields |= 0x10; l += 4;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case "d": out[1] = 5; dv.setFloat64(l, ((cell.v as Date).getTime() - Date.UTC(2001, 0, 1))/1000, true); fields |= 0x40; l += 8; break;
|
||||||
case "z": out[1] = 0; break;
|
case "z": out[1] = 0; break;
|
||||||
default: throw "unsupported cell type " + cell.t;
|
default: throw "unsupported cell type " + cell.t;
|
||||||
}
|
}
|
||||||
@ -668,11 +686,11 @@ function write_old_storage(cell: CellObject, lut: DataLUT): Uint8Array {
|
|||||||
return out[subarray](0, l);
|
return out[subarray](0, l);
|
||||||
}
|
}
|
||||||
//<<export { write_new_storage, write_old_storage };
|
//<<export { write_new_storage, write_old_storage };
|
||||||
function parse_cell_storage(buf: Uint8Array, lut: DataLUT): CellObject | void {
|
function parse_cell_storage(buf: Uint8Array, lut: DataLUT, opts?: ParsingOptions): CellObject | void {
|
||||||
switch(buf[0]) {
|
switch(buf[0]) {
|
||||||
case 0: case 1:
|
case 0: case 1:
|
||||||
case 2: case 3: case 4: return parse_old_storage(buf, lut, buf[0]);
|
case 2: case 3: case 4: return parse_old_storage(buf, lut, buf[0], opts);
|
||||||
case 5: return parse_new_storage(buf, lut);
|
case 5: return parse_new_storage(buf, lut, opts);
|
||||||
default: throw new Error(`Unsupported payload version ${buf[0]}`);
|
default: throw new Error(`Unsupported payload version ${buf[0]}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -885,7 +903,7 @@ function s5s_to_iwa_comment(s5s: Comments): IWAComment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Parse .TST.TableModelArchive (6001) */
|
/** Parse .TST.TableModelArchive (6001) */
|
||||||
function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: WorkSheet) {
|
function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: WorkSheet, opts?: ParsingOptions) {
|
||||||
var pb = parse_shallow(root.data);
|
var pb = parse_shallow(root.data);
|
||||||
var range: Range = { s: {r:0, c:0}, e: {r:0, c:0} };
|
var range: Range = { s: {r:0, c:0}, e: {r:0, c:0} };
|
||||||
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
|
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
|
||||||
@ -918,7 +936,7 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
|
|||||||
var _tile = parse_TST_Tile(M, ref);
|
var _tile = parse_TST_Tile(M, ref);
|
||||||
_tile.data.forEach((row, R) => {
|
_tile.data.forEach((row, R) => {
|
||||||
row.forEach((buf, C) => {
|
row.forEach((buf, C) => {
|
||||||
var res = parse_cell_storage(buf, lut);
|
var res = parse_cell_storage(buf, lut, opts);
|
||||||
if(res) {
|
if(res) {
|
||||||
if(dense) {
|
if(dense) {
|
||||||
if(!dws["!data"][_R + R]) dws["!data"][_R + R] = [];
|
if(!dws["!data"][_R + R]) dws["!data"][_R + R] = [];
|
||||||
@ -959,7 +977,7 @@ function parse_TST_TableInfoArchive(M: MessageSpace, root: IWAMessage, opts?: Pa
|
|||||||
var tableref = M[parse_TSP_Reference(pb[2][0].data)];
|
var tableref = M[parse_TSP_Reference(pb[2][0].data)];
|
||||||
var mtype = varint_to_i32(tableref[0].meta[1][0].data);
|
var mtype = varint_to_i32(tableref[0].meta[1][0].data);
|
||||||
if(mtype != 6001) throw new Error(`6000 unexpected reference to ${mtype}`);
|
if(mtype != 6001) throw new Error(`6000 unexpected reference to ${mtype}`);
|
||||||
parse_TST_TableModelArchive(M, tableref[0], out);
|
parse_TST_TableModelArchive(M, tableref[0], out, opts);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,6 +1005,7 @@ function parse_TN_SheetArchive(M: MessageSpace, root: IWAMessage, opts?: Parsing
|
|||||||
/** Parse .TN.DocumentArchive */
|
/** Parse .TN.DocumentArchive */
|
||||||
function parse_TN_DocumentArchive(M: MessageSpace, root: IWAMessage, opts?: ParsingOptions): WorkBook {
|
function parse_TN_DocumentArchive(M: MessageSpace, root: IWAMessage, opts?: ParsingOptions): WorkBook {
|
||||||
var out = book_new();
|
var out = book_new();
|
||||||
|
out.Workbook = { WBProps: { date1904: true } };
|
||||||
var pb = parse_shallow(root.data);
|
var pb = parse_shallow(root.data);
|
||||||
if(pb[2]?.[0]) throw new Error("Keynote presentations are not supported");
|
if(pb[2]?.[0]) throw new Error("Keynote presentations are not supported");
|
||||||
|
|
||||||
@ -1093,10 +1112,9 @@ function write_TST_TileRowInfo(data: CellObject[], lut: DataLUT, wide: boolean):
|
|||||||
var celload: Uint8Array, _celload: Uint8Array;
|
var celload: Uint8Array, _celload: Uint8Array;
|
||||||
switch(data[C].t) {
|
switch(data[C].t) {
|
||||||
case "d":
|
case "d":
|
||||||
// TODO: write the actual date code
|
|
||||||
if(data[C].v instanceof Date) {
|
if(data[C].v instanceof Date) {
|
||||||
celload = write_new_storage({t: "s", v: (data[C].v as Date).toISOString()}, lut);
|
celload = write_new_storage(data[C], lut);
|
||||||
/*if(!wide)*/ _celload = write_old_storage({t: "s", v: (data[C].v as Date).toISOString()}, lut);
|
/*if(!wide)*/ _celload = write_old_storage(data[C], lut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* TODO: can esbuild preserve falls through comments ? */
|
/* TODO: can esbuild preserve falls through comments ? */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xlsx",
|
"name": "xlsx",
|
||||||
"version": "0.19.3",
|
"version": "0.20.0",
|
||||||
"author": "sheetjs",
|
"author": "sheetjs",
|
||||||
"description": "SheetJS Spreadsheet data parser and writer",
|
"description": "SheetJS Spreadsheet data parser and writer",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
129
test.js
129
test.js
@ -1554,7 +1554,7 @@ describe('write features', function() {
|
|||||||
["String", "123"],
|
["String", "123"],
|
||||||
["Number", 123],
|
["Number", 123],
|
||||||
["Boolean", true],
|
["Boolean", true],
|
||||||
["Date", new Date()],
|
["Date", new Date()]
|
||||||
], { cellDates: true });
|
], { cellDates: true });
|
||||||
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
||||||
var wb = X.utils.book_new();
|
var wb = X.utils.book_new();
|
||||||
@ -1571,28 +1571,30 @@ function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
||||||
var epoch = v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
|
if(date1904) return res - 1462;
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]] sans "Z"
|
||||||
function parseDate(str/*:string|Date*/)/*:Date*/ {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
|
||||||
if(good_pd) return d;
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
m = str.match(pdre3);
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
var d = new Date(str);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
||||||
@ -1816,7 +1818,7 @@ describe('roundtrip features', function() {
|
|||||||
];
|
];
|
||||||
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
||||||
data.forEach(function(row, i) {
|
data.forEach(function(row, i) {
|
||||||
Object.keys(row).forEach(function(k) { assert.equal(row[k], o[i][k]); });
|
Object.keys(row).forEach(function(k) { assert.equal(row[k].valueOf(), o[i][k].valueOf()); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2189,7 +2191,15 @@ describe('CSV', function() {
|
|||||||
assert.equal(cell.w, '2/19/14');
|
assert.equal(cell.w, '2/19/14');
|
||||||
});
|
});
|
||||||
it('should honor dateNF override', function() {
|
it('should honor dateNF override', function() {
|
||||||
var opts = ({type:"binary", dateNF:"YYYY-MM-DD"}/*:any*/);
|
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", cellNF: true}/*:any*/);
|
||||||
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
|
||||||
|
assert.equal(cell.z, "YYYY-MM-DD");
|
||||||
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.ok(cell.w == '14-02-19' || cell.w == "2/19/14");
|
||||||
|
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
|
||||||
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||||
@ -2203,10 +2213,18 @@ describe('CSV', function() {
|
|||||||
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 1);
|
assert.equal(cell.v.getMonth(), 1);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
opts = {type:"binary", cellDates:true, dateNF:'d/m/yy'};
|
opts.dateNF = 'd/m/yy';
|
||||||
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 2);
|
assert.equal(cell.v.getMonth(), 2);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts = {type:"binary", cellDates:true, dateNF:'m/d/yy', UTC: true};
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 1);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts.dateNF = 'd/m/yy';
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 2);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
});
|
});
|
||||||
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
||||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
||||||
@ -2236,7 +2254,8 @@ describe('CSV', function() {
|
|||||||
["3b", "3 b", "3 b-1"],
|
["3b", "3 b", "3 b-1"],
|
||||||
["3p", "3 P", "3 p-1"]
|
["3p", "3 P", "3 p-1"]
|
||||||
];
|
];
|
||||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
|
||||||
|
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
@ -2244,14 +2263,46 @@ describe('CSV', function() {
|
|||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: false}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
}
|
}
|
||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -2402,19 +2453,31 @@ describe('dbf', function() {
|
|||||||
['d11', dir + 'dbf/d11.dbf'],
|
['d11', dir + 'dbf/d11.dbf'],
|
||||||
['vfp3', dir + 'dbf/vfp3.dbf']
|
['vfp3', dir + 'dbf/vfp3.dbf']
|
||||||
]/*:any*/);
|
]/*:any*/);
|
||||||
|
var wbsfalse = ([]);
|
||||||
|
var wbstrue = ([]);
|
||||||
var bef = (function() {
|
var bef = (function() {
|
||||||
wbs = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), {type:TYPE})]; });
|
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: false })]; });
|
||||||
|
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: true })]; });
|
||||||
});
|
});
|
||||||
if(typeof before != 'undefined') before(bef);
|
if(typeof before != 'undefined') before(bef);
|
||||||
else it('before', bef);
|
else it('before', bef);
|
||||||
it(wbs[1][0], function() {
|
it(wbs[1][0], function() {
|
||||||
var ws = wbs[1][1].Sheets["Sheet1"];
|
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
|
||||||
[
|
[
|
||||||
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
|
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
|
||||||
["C2", "v", 12.345], ["D2", "v", 1234.1], ["E2", "w", "19170219"],
|
["E2", "v", 6260], ["E2", "w", "19170219"],
|
||||||
/* [F2", "w", "19170219"], */ ["G2", "v", 1231.4], ["H2", "v", 123234],
|
["F2", "v", 6260], ["F2", "w", "19170219"],
|
||||||
["I2", "v", true], ["L2", "v", "SheetJS"]
|
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
|
||||||
].forEach(function(r) { assert.equal(get_cell(ws, r[0])[r[1]], r[2]); });
|
].forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
|
||||||
|
});
|
||||||
|
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
|
||||||
|
[
|
||||||
|
["E2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["E2", "w", "19170219"],
|
||||||
|
["F2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["F2", "w", "19170219"]
|
||||||
|
].forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wstrue, r[0])[r[1]].valueOf(), r[2].valueOf());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
||||||
[ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ].forEach(function(r) {
|
[ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ].forEach(function(r) {
|
||||||
|
158
test.mjs
generated
158
test.mjs
generated
@ -1550,6 +1550,22 @@ describe('write features', function() {
|
|||||||
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
||||||
assert.equal(wb2.Workbook.Names.length, wb3.Workbook.Names.length);
|
assert.equal(wb2.Workbook.Names.length, wb3.Workbook.Names.length);
|
||||||
}); });
|
}); });
|
||||||
|
it('should handle non-string values for "s" cells', function() {[
|
||||||
|
"xlsx", "xlsb", "xls", "biff5", "biff2", "xlml", "numbers", "ods", "fods", "wk3", "csv", "txt", "sylk", "html", "dif", "dbf", "wk1", "rtf", "prn"
|
||||||
|
].forEach(function(fmt) {
|
||||||
|
if(fmt == "numbers" && !can_write_numbers) return;
|
||||||
|
var ws = X.utils.aoa_to_sheet([
|
||||||
|
["String", "123"],
|
||||||
|
["Number", 123],
|
||||||
|
["Boolean", true],
|
||||||
|
["Date", new Date()],
|
||||||
|
], { cellDates: true });
|
||||||
|
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
||||||
|
var wb = X.utils.book_new();
|
||||||
|
X.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: false, numbers:XLSX_ZAHL});
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: true, numbers:XLSX_ZAHL});
|
||||||
|
}); });
|
||||||
});
|
});
|
||||||
|
|
||||||
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
||||||
@ -1559,28 +1575,30 @@ function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
||||||
var epoch = v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
|
if(date1904) return res - 1462;
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]] sans "Z"
|
||||||
function parseDate(str/*:string|Date*/)/*:Date*/ {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
|
||||||
if(good_pd) return d;
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
m = str.match(pdre3);
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
var d = new Date(str);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
||||||
@ -1804,7 +1822,7 @@ describe('roundtrip features', function() {
|
|||||||
];
|
];
|
||||||
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
||||||
data.forEach(function(row, i) {
|
data.forEach(function(row, i) {
|
||||||
Object.keys(row).forEach(function(k) { assert.equal(row[k], o[i][k]); });
|
Object.keys(row).forEach(function(k) { assert.equal(row[k].valueOf(), o[i][k].valueOf()); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1891,6 +1909,21 @@ describe('invalid files', function() {
|
|||||||
wb.SheetNames.push(wb.SheetNames[0]);
|
wb.SheetNames.push(wb.SheetNames[0]);
|
||||||
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
||||||
});
|
});
|
||||||
|
it('should fail if sheet name is not valid', function() {
|
||||||
|
var names = [
|
||||||
|
"", // cannot be blank
|
||||||
|
"abcdefghijklmnopqrstuvwxyz1234567890", // cannot exceed 31 chars
|
||||||
|
"'sheetjs", "sheetjs'", // cannot start or end with apostrophe
|
||||||
|
"History", // cannot be History
|
||||||
|
"Sheet:JS", "Sheet]JS", "Sheet[JS", "Sheet*JS", // bad characters
|
||||||
|
"Sheet?JS", "Sheet\\JS", "Sheet\/JS"
|
||||||
|
];
|
||||||
|
names.forEach(function(n) { assert.throws(function() {
|
||||||
|
var wb = { SheetNames: [n], Sheets: {} };
|
||||||
|
wb.Sheets[n] = X.utils.aoa_to_sheet([["SheetJS"]]);
|
||||||
|
X.write(wb, {type:"binary", bookType:"xlsx"});
|
||||||
|
}); });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2162,7 +2195,15 @@ describe('CSV', function() {
|
|||||||
assert.equal(cell.w, '2/19/14');
|
assert.equal(cell.w, '2/19/14');
|
||||||
});
|
});
|
||||||
it('should honor dateNF override', function() {
|
it('should honor dateNF override', function() {
|
||||||
var opts = ({type:"binary", dateNF:"YYYY-MM-DD"}/*:any*/);
|
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", cellNF: true}/*:any*/);
|
||||||
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
|
||||||
|
assert.equal(cell.z, "YYYY-MM-DD");
|
||||||
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.ok(cell.w == '14-02-19' || cell.w == "2/19/14");
|
||||||
|
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
|
||||||
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||||
@ -2176,10 +2217,18 @@ describe('CSV', function() {
|
|||||||
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 1);
|
assert.equal(cell.v.getMonth(), 1);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
opts = {type:"binary", cellDates:true, dateNF:'d/m/yy'};
|
opts.dateNF = 'd/m/yy';
|
||||||
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 2);
|
assert.equal(cell.v.getMonth(), 2);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts = {type:"binary", cellDates:true, dateNF:'m/d/yy', UTC: true};
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 1);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts.dateNF = 'd/m/yy';
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 2);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
});
|
});
|
||||||
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
||||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
||||||
@ -2209,7 +2258,8 @@ describe('CSV', function() {
|
|||||||
["3b", "3 b", "3 b-1"],
|
["3b", "3 b", "3 b-1"],
|
||||||
["3p", "3 P", "3 p-1"]
|
["3p", "3 P", "3 p-1"]
|
||||||
];
|
];
|
||||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
|
||||||
|
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
@ -2217,14 +2267,46 @@ describe('CSV', function() {
|
|||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: false}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
}
|
}
|
||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -2375,19 +2457,31 @@ describe('dbf', function() {
|
|||||||
['d11', dir + 'dbf/d11.dbf'],
|
['d11', dir + 'dbf/d11.dbf'],
|
||||||
['vfp3', dir + 'dbf/vfp3.dbf']
|
['vfp3', dir + 'dbf/vfp3.dbf']
|
||||||
]/*:any*/);
|
]/*:any*/);
|
||||||
|
var wbsfalse = ([]);
|
||||||
|
var wbstrue = ([]);
|
||||||
var bef = (function() {
|
var bef = (function() {
|
||||||
wbs = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), {type:TYPE})]; });
|
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: false })]; });
|
||||||
|
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: true })]; });
|
||||||
});
|
});
|
||||||
if(typeof before != 'undefined') before(bef);
|
if(typeof before != 'undefined') before(bef);
|
||||||
else it('before', bef);
|
else it('before', bef);
|
||||||
it(wbs[1][0], function() {
|
it(wbs[1][0], function() {
|
||||||
var ws = wbs[1][1].Sheets["Sheet1"];
|
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
|
||||||
[
|
[
|
||||||
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
|
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
|
||||||
["C2", "v", 12.345], ["D2", "v", 1234.1], ["E2", "w", "19170219"],
|
["E2", "v", 6260], ["E2", "w", "19170219"],
|
||||||
/* [F2", "w", "19170219"], */ ["G2", "v", 1231.4], ["H2", "v", 123234],
|
["F2", "v", 6260], ["F2", "w", "19170219"],
|
||||||
["I2", "v", true], ["L2", "v", "SheetJS"]
|
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
|
||||||
].forEach(function(r) { assert.equal(get_cell(ws, r[0])[r[1]], r[2]); });
|
].forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
|
||||||
|
});
|
||||||
|
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
|
||||||
|
[
|
||||||
|
["E2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["E2", "w", "19170219"],
|
||||||
|
["F2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["F2", "w", "19170219"],
|
||||||
|
].forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wstrue, r[0])[r[1]].valueOf(), r[2].valueOf());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
||||||
[ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ].forEach(function(r) {
|
[ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ].forEach(function(r) {
|
||||||
|
163
test.mts
163
test.mts
@ -1006,7 +1006,7 @@ describe('parse features', function() {
|
|||||||
|
|
||||||
describe('sheetRows', function() {
|
describe('sheetRows', function() {
|
||||||
it('should use original range if not set', function() {
|
it('should use original range if not set', function() {
|
||||||
var opts = {type:TYPE};
|
var opts: X.ParsingOptions = {type:TYPE};
|
||||||
FSTPaths.map(function(p) { return X.read(fs.readFileSync(p), opts); }).forEach(function(wb) {
|
FSTPaths.map(function(p) { return X.read(fs.readFileSync(p), opts); }).forEach(function(wb) {
|
||||||
assert.equal(wb.Sheets["Text"]["!ref"],"A1:F49");
|
assert.equal(wb.Sheets["Text"]["!ref"],"A1:F49");
|
||||||
});
|
});
|
||||||
@ -1510,6 +1510,22 @@ describe('write features', function() {
|
|||||||
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
||||||
assert.equal(((wb2.Workbook as any).Names as any).length, ((wb3.Workbook as any).Names as any).length);
|
assert.equal(((wb2.Workbook as any).Names as any).length, ((wb3.Workbook as any).Names as any).length);
|
||||||
}); });
|
}); });
|
||||||
|
it('should handle non-string values for "s" cells', function() {([
|
||||||
|
"xlsx", "xlsb", "xls", "biff5", "biff2", "xlml", "numbers", "ods", "fods", "wk3", "csv", "txt", "sylk", "html", "dif", "dbf", "wk1", "rtf", "prn"
|
||||||
|
] as Array<X.BookType>).forEach(function(fmt) {
|
||||||
|
if(fmt == "numbers" && !can_write_numbers) return;
|
||||||
|
var ws = X.utils.aoa_to_sheet([
|
||||||
|
["String", "123"],
|
||||||
|
["Number", 123],
|
||||||
|
["Boolean", true],
|
||||||
|
["Date", new Date()],
|
||||||
|
], { cellDates: true });
|
||||||
|
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
||||||
|
var wb = X.utils.book_new();
|
||||||
|
X.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: false, numbers:XLSX_ZAHL});
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: true, numbers:XLSX_ZAHL});
|
||||||
|
}); });
|
||||||
});
|
});
|
||||||
|
|
||||||
function seq(end: number, start?: number): Array<number> {
|
function seq(end: number, start?: number): Array<number> {
|
||||||
@ -1519,28 +1535,30 @@ function seq(end: number, start?: number): Array<number> {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v: Date, date1904?: boolean): number {
|
function datenum(v: Date, date1904?: boolean): number {
|
||||||
var epoch = v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
|
if(date1904) return res - 1462;
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]] sans "Z"
|
||||||
function parseDate(str: string|Date): Date {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str: string|Date, date1904?: boolean): Date {
|
||||||
if(good_pd) return d;
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
m = str.match(pdre3);
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
var d = new Date(str);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
||||||
@ -1851,6 +1869,21 @@ describe('invalid files', function() {
|
|||||||
wb.SheetNames.push(wb.SheetNames[0]);
|
wb.SheetNames.push(wb.SheetNames[0]);
|
||||||
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
||||||
});
|
});
|
||||||
|
it('should fail if sheet name is not valid', function() {
|
||||||
|
var names = [
|
||||||
|
"", // cannot be blank
|
||||||
|
"abcdefghijklmnopqrstuvwxyz1234567890", // cannot exceed 31 chars
|
||||||
|
"'sheetjs", "sheetjs'", // cannot start or end with apostrophe
|
||||||
|
"History", // cannot be History
|
||||||
|
"Sheet:JS", "Sheet]JS", "Sheet[JS", "Sheet*JS", // bad characters
|
||||||
|
"Sheet?JS", "Sheet\\JS", "Sheet\/JS"
|
||||||
|
];
|
||||||
|
names.forEach(function(n) { assert.throws(function() {
|
||||||
|
var wb: X.WorkBook = { SheetNames: [n], Sheets: {} };
|
||||||
|
wb.Sheets[n] = X.utils.aoa_to_sheet([["SheetJS"]]);
|
||||||
|
X.write(wb, {type:"binary", bookType:"xlsx"});
|
||||||
|
}); });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2118,9 +2151,17 @@ describe('CSV', function() {
|
|||||||
assert.equal(cell.w, '2/19/14');
|
assert.equal(cell.w, '2/19/14');
|
||||||
});
|
});
|
||||||
it('should honor dateNF override', function() {
|
it('should honor dateNF override', function() {
|
||||||
var opts: X.ParsingOptions = ({type:"binary", dateNF:"YYYY-MM-DD"});
|
var opts: X.ParsingOptions = ({type:"binary", dateNF:"YYYY-MM-DD", cellNF: true});
|
||||||
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
|
||||||
|
assert.equal(cell.z, "YYYY-MM-DD");
|
||||||
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.ok(cell.w == '14-02-19' || cell.w == "2/19/14");
|
||||||
|
opts = ({type:"binary", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||||
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
@ -2132,10 +2173,18 @@ describe('CSV', function() {
|
|||||||
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 1);
|
assert.equal(cell.v.getMonth(), 1);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
opts = {type:"binary", cellDates:true, dateNF:'d/m/yy'};
|
opts.dateNF = 'd/m/yy';
|
||||||
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 2);
|
assert.equal(cell.v.getMonth(), 2);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts = {type:"binary", cellDates:true, dateNF:'m/d/yy', UTC: true};
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 1);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts.dateNF = 'd/m/yy';
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 2);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
});
|
});
|
||||||
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
||||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
||||||
@ -2163,9 +2212,10 @@ describe('CSV', function() {
|
|||||||
var aoa = [
|
var aoa = [
|
||||||
["3a", "3 a", "3 a-1"],
|
["3a", "3 a", "3 a-1"],
|
||||||
["3b", "3 b", "3 b-1"],
|
["3b", "3 b", "3 b-1"],
|
||||||
["3p", "3 P", "3 p-1"],
|
["3p", "3 P", "3 p-1"]
|
||||||
];
|
];
|
||||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
|
||||||
|
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
@ -2173,14 +2223,46 @@ describe('CSV', function() {
|
|||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: false}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
}
|
}
|
||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -2317,18 +2399,31 @@ describe('numbers', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('dbf', function() {
|
describe('dbf', function() {
|
||||||
var wbs: Array<[string, X.WorkBook]> = ([
|
var wbs: Array<[string, string]> = ([
|
||||||
['d11', dir + 'dbf/d11.dbf'],
|
['d11', dir + 'dbf/d11.dbf'],
|
||||||
['vfp3', dir + 'dbf/vfp3.dbf']
|
['vfp3', dir + 'dbf/vfp3.dbf']
|
||||||
]).map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), {type:TYPE})]; });
|
]);
|
||||||
|
var wbsfalse: Array<[string, X.WorkBook]> = ([]);
|
||||||
|
var wbstrue: Array<[string, X.WorkBook]> = ([]);
|
||||||
|
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: false })]; });
|
||||||
|
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: true })]; });
|
||||||
it(wbs[1][0], function() {
|
it(wbs[1][0], function() {
|
||||||
var ws = wbs[1][1].Sheets["Sheet1"];
|
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
|
||||||
([
|
([
|
||||||
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
|
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
|
||||||
["C2", "v", 12.345], ["D2", "v", 1234.1], ["E2", "w", "19170219"],
|
["E2", "v", 6260], ["E2", "w", "19170219"],
|
||||||
/* [F2", "w", "19170219"], */ ["G2", "v", 1231.4], ["H2", "v", 123234],
|
["F2", "v", 6260], ["F2", "w", "19170219"],
|
||||||
["I2", "v", true], ["L2", "v", "SheetJS"]
|
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
|
||||||
] as Array<[string, string, any]>).forEach(function(r) { assert.equal(get_cell(ws, r[0])[r[1]], r[2]); });
|
] as Array<[string, string, any]>).forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
|
||||||
|
});
|
||||||
|
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
|
||||||
|
([
|
||||||
|
["E2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["E2", "w", "19170219"],
|
||||||
|
["F2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["F2", "w", "19170219"],
|
||||||
|
] as Array<[string, string, any]>).forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wstrue, r[0])[r[1]].valueOf(), r[2].valueOf());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
||||||
([ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ] as Array<[number,string]>).forEach(function(r) {
|
([ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ] as Array<[number,string]>).forEach(function(r) {
|
||||||
|
163
test.ts
163
test.ts
@ -1006,7 +1006,7 @@ Deno.test('parse features', async function(t) {
|
|||||||
|
|
||||||
await t.step('sheetRows', async function(t) {
|
await t.step('sheetRows', async function(t) {
|
||||||
await t.step('should use original range if not set', async function(t) {
|
await t.step('should use original range if not set', async function(t) {
|
||||||
var opts = {type:TYPE};
|
var opts: X.ParsingOptions = {type:TYPE};
|
||||||
FSTPaths.map(function(p) { return X.read(fs.readFileSync(p), opts); }).forEach(function(wb) {
|
FSTPaths.map(function(p) { return X.read(fs.readFileSync(p), opts); }).forEach(function(wb) {
|
||||||
assert.equal(wb.Sheets["Text"]["!ref"],"A1:F49");
|
assert.equal(wb.Sheets["Text"]["!ref"],"A1:F49");
|
||||||
});
|
});
|
||||||
@ -1510,6 +1510,22 @@ Deno.test('write features', async function(t) {
|
|||||||
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
||||||
assert.equal(((wb2.Workbook as any).Names as any).length, ((wb3.Workbook as any).Names as any).length);
|
assert.equal(((wb2.Workbook as any).Names as any).length, ((wb3.Workbook as any).Names as any).length);
|
||||||
}); });
|
}); });
|
||||||
|
await t.step('should handle non-string values for "s" cells', async function(t) {([
|
||||||
|
"xlsx", "xlsb", "xls", "biff5", "biff2", "xlml", "numbers", "ods", "fods", "wk3", "csv", "txt", "sylk", "html", "dif", "dbf", "wk1", "rtf", "prn"
|
||||||
|
] as Array<X.BookType>).forEach(function(fmt) {
|
||||||
|
if(fmt == "numbers" && !can_write_numbers) return;
|
||||||
|
var ws = X.utils.aoa_to_sheet([
|
||||||
|
["String", "123"],
|
||||||
|
["Number", 123],
|
||||||
|
["Boolean", true],
|
||||||
|
["Date", new Date()],
|
||||||
|
], { cellDates: true });
|
||||||
|
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
||||||
|
var wb = X.utils.book_new();
|
||||||
|
X.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: false, numbers:XLSX_ZAHL});
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: true, numbers:XLSX_ZAHL});
|
||||||
|
}); });
|
||||||
});
|
});
|
||||||
|
|
||||||
function seq(end: number, start?: number): Array<number> {
|
function seq(end: number, start?: number): Array<number> {
|
||||||
@ -1519,28 +1535,30 @@ function seq(end: number, start?: number): Array<number> {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v: Date, date1904?: boolean): number {
|
function datenum(v: Date, date1904?: boolean): number {
|
||||||
var epoch = v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
|
if(date1904) return res - 1462;
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]] sans "Z"
|
||||||
function parseDate(str: string|Date): Date {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str: string|Date, date1904?: boolean): Date {
|
||||||
if(good_pd) return d;
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
m = str.match(pdre3);
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
var d = new Date(str);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
||||||
@ -1851,6 +1869,21 @@ Deno.test('invalid files', async function(t) {
|
|||||||
wb.SheetNames.push(wb.SheetNames[0]);
|
wb.SheetNames.push(wb.SheetNames[0]);
|
||||||
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
||||||
});
|
});
|
||||||
|
await t.step('should fail if sheet name is not valid', async function(t) {
|
||||||
|
var names = [
|
||||||
|
"", // cannot be blank
|
||||||
|
"abcdefghijklmnopqrstuvwxyz1234567890", // cannot exceed 31 chars
|
||||||
|
"'sheetjs", "sheetjs'", // cannot start or end with apostrophe
|
||||||
|
"History", // cannot be History
|
||||||
|
"Sheet:JS", "Sheet]JS", "Sheet[JS", "Sheet*JS", // bad characters
|
||||||
|
"Sheet?JS", "Sheet\\JS", "Sheet\/JS"
|
||||||
|
];
|
||||||
|
names.forEach(function(n) { assert.throws(function() {
|
||||||
|
var wb: X.WorkBook = { SheetNames: [n], Sheets: {} };
|
||||||
|
wb.Sheets[n] = X.utils.aoa_to_sheet([["SheetJS"]]);
|
||||||
|
X.write(wb, {type:"binary", bookType:"xlsx"});
|
||||||
|
}); });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2118,9 +2151,17 @@ Deno.test('CSV', async function(t) {
|
|||||||
assert.equal(cell.w, '2/19/14');
|
assert.equal(cell.w, '2/19/14');
|
||||||
});
|
});
|
||||||
await t.step('should honor dateNF override', async function(t) {
|
await t.step('should honor dateNF override', async function(t) {
|
||||||
var opts: X.ParsingOptions = ({type:"binary", dateNF:"YYYY-MM-DD"});
|
var opts: X.ParsingOptions = ({type:"binary", dateNF:"YYYY-MM-DD", cellNF: true});
|
||||||
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
|
assert.assert(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
|
||||||
|
assert.equal(cell.z, "YYYY-MM-DD");
|
||||||
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.assert(cell.w == '14-02-19' || cell.w == "2/19/14");
|
||||||
|
opts = ({type:"binary", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
assert.assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
assert.assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||||
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
@ -2132,10 +2173,18 @@ Deno.test('CSV', async function(t) {
|
|||||||
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 1);
|
assert.equal(cell.v.getMonth(), 1);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
opts = {type:"binary", cellDates:true, dateNF:'d/m/yy'};
|
opts.dateNF = 'd/m/yy';
|
||||||
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 2);
|
assert.equal(cell.v.getMonth(), 2);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts = {type:"binary", cellDates:true, dateNF:'m/d/yy', UTC: true};
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 1);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts.dateNF = 'd/m/yy';
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 2);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
});
|
});
|
||||||
await t.step('should interpret values by default', async function(t) { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
await t.step('should interpret values by default', async function(t) { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
||||||
await t.step('should generate strings if raw option is passed', async function(t) { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
await t.step('should generate strings if raw option is passed', async function(t) { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
||||||
@ -2163,9 +2212,10 @@ Deno.test('CSV', async function(t) {
|
|||||||
var aoa = [
|
var aoa = [
|
||||||
["3a", "3 a", "3 a-1"],
|
["3a", "3 a", "3 a-1"],
|
||||||
["3b", "3 b", "3 b-1"],
|
["3b", "3 b", "3 b-1"],
|
||||||
["3p", "3 P", "3 p-1"],
|
["3p", "3 P", "3 p-1"]
|
||||||
];
|
];
|
||||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
|
||||||
|
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
@ -2173,14 +2223,46 @@ Deno.test('CSV', async function(t) {
|
|||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: false}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
}
|
}
|
||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -2317,18 +2399,31 @@ Deno.test('numbers', async function(t) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Deno.test('dbf', async function(t) {
|
Deno.test('dbf', async function(t) {
|
||||||
var wbs: Array<[string, X.WorkBook]> = ([
|
var wbs: Array<[string, string]> = ([
|
||||||
['d11', dir + 'dbf/d11.dbf'],
|
['d11', dir + 'dbf/d11.dbf'],
|
||||||
['vfp3', dir + 'dbf/vfp3.dbf']
|
['vfp3', dir + 'dbf/vfp3.dbf']
|
||||||
]).map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), {type:TYPE})]; });
|
]);
|
||||||
|
var wbsfalse: Array<[string, X.WorkBook]> = ([]);
|
||||||
|
var wbstrue: Array<[string, X.WorkBook]> = ([]);
|
||||||
|
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: false })]; });
|
||||||
|
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: true })]; });
|
||||||
await t.step(wbs[1][0], async function(t) {
|
await t.step(wbs[1][0], async function(t) {
|
||||||
var ws = wbs[1][1].Sheets["Sheet1"];
|
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
|
||||||
([
|
([
|
||||||
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
|
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
|
||||||
["C2", "v", 12.345], ["D2", "v", 1234.1], ["E2", "w", "19170219"],
|
["E2", "v", 6260], ["E2", "w", "19170219"],
|
||||||
/* [F2", "w", "19170219"], */ ["G2", "v", 1231.4], ["H2", "v", 123234],
|
["F2", "v", 6260], ["F2", "w", "19170219"],
|
||||||
["I2", "v", true], ["L2", "v", "SheetJS"]
|
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
|
||||||
] as Array<[string, string, any]>).forEach(function(r) { assert.equal(get_cell(ws, r[0])[r[1]], r[2]); });
|
] as Array<[string, string, any]>).forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
|
||||||
|
});
|
||||||
|
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
|
||||||
|
([
|
||||||
|
["E2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["E2", "w", "19170219"],
|
||||||
|
["F2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["F2", "w", "19170219"],
|
||||||
|
] as Array<[string, string, any]>).forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wstrue, r[0])[r[1]].valueOf(), r[2].valueOf());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
await t.step("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", async function(t) {
|
await t.step("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", async function(t) {
|
||||||
([ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ] as Array<[number,string]>).forEach(function(r) {
|
([ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ] as Array<[number,string]>).forEach(function(r) {
|
||||||
|
183
testbun.mjs
generated
183
testbun.mjs
generated
@ -684,6 +684,7 @@ describe('parse options', function() {
|
|||||||
}); });
|
}); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('input formats', function() {
|
describe('input formats', function() {
|
||||||
if(false) it('should read binary strings', function() { artifax.forEach(function(p) {
|
if(false) it('should read binary strings', function() { artifax.forEach(function(p) {
|
||||||
X.read(fs.readFileSync(p, 'binary'), {type: 'binary'});
|
X.read(fs.readFileSync(p, 'binary'), {type: 'binary'});
|
||||||
@ -691,6 +692,22 @@ describe('input formats', function() {
|
|||||||
if(false) it('should read base64 strings', function() { artifax.forEach(function(p) {
|
if(false) it('should read base64 strings', function() { artifax.forEach(function(p) {
|
||||||
X.read(fs.readFileSync(p, 'base64'), {type: 'base64'});
|
X.read(fs.readFileSync(p, 'base64'), {type: 'base64'});
|
||||||
}); });
|
}); });
|
||||||
|
it('handles base64 within data URI scheme (gh-2762)', function() {
|
||||||
|
var data = 'TmFtZXMNCkhhZmV6DQpTYW0NCg==';
|
||||||
|
|
||||||
|
var wb0 = X.read(data, { type: 'base64' }); // raw base64 string
|
||||||
|
var wb1 = X.read('data:;base64,' + data, { type: 'base64' }); // data URI, no media type
|
||||||
|
var wb2 = X.read('data:text/csv;base64,' + data, { type: 'base64' }); // data URI, CSV type
|
||||||
|
var wb3 = X.read('data:application/vnd.ms-excel;base64,' + data, { type: 'base64' }); // data URI, Excel
|
||||||
|
|
||||||
|
[wb0, wb1, wb2, wb3].forEach(function(wb) {
|
||||||
|
var ws = wb.Sheets.Sheet1;
|
||||||
|
assert.equal(ws["!ref"], "A1:A3");
|
||||||
|
assert.equal(get_cell(ws, "A1").v, "Names");
|
||||||
|
assert.equal(get_cell(ws, "A2").v, "Hafez");
|
||||||
|
assert.equal(get_cell(ws, "A3").v, "Sam");
|
||||||
|
});
|
||||||
|
});
|
||||||
if(false) if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) {
|
if(false) if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) {
|
||||||
X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||||
}); });
|
}); });
|
||||||
@ -1538,6 +1555,22 @@ describe('write features', function() {
|
|||||||
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
||||||
assert.equal(wb2.Workbook.Names.length, wb3.Workbook.Names.length);
|
assert.equal(wb2.Workbook.Names.length, wb3.Workbook.Names.length);
|
||||||
}); });
|
}); });
|
||||||
|
it('should handle non-string values for "s" cells', function() {[
|
||||||
|
"xlsx", "xlsb", "xls", "biff5", "biff2", "xlml", "numbers", "ods", "fods", "wk3", "csv", "txt", "sylk", "html", "dif", "dbf", "wk1", "rtf", "prn"
|
||||||
|
].forEach(function(fmt) {
|
||||||
|
if(fmt == "numbers" && !can_write_numbers) return;
|
||||||
|
var ws = X.utils.aoa_to_sheet([
|
||||||
|
["String", "123"],
|
||||||
|
["Number", 123],
|
||||||
|
["Boolean", true],
|
||||||
|
["Date", new Date()],
|
||||||
|
], { cellDates: true });
|
||||||
|
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
||||||
|
var wb = X.utils.book_new();
|
||||||
|
X.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: false, numbers:XLSX_ZAHL});
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: true, numbers:XLSX_ZAHL});
|
||||||
|
}); });
|
||||||
});
|
});
|
||||||
|
|
||||||
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
||||||
@ -1547,28 +1580,30 @@ function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
||||||
var epoch = v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
|
if(date1904) return res - 1462;
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]] sans "Z"
|
||||||
function parseDate(str/*:string|Date*/)/*:Date*/ {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
|
||||||
if(good_pd) return d;
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
m = str.match(pdre3);
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
var d = new Date(str);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
||||||
@ -1791,7 +1826,7 @@ describe('roundtrip features', function() {
|
|||||||
];
|
];
|
||||||
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
||||||
data.forEach(function(row, i) {
|
data.forEach(function(row, i) {
|
||||||
Object.keys(row).forEach(function(k) { assert.equal(row[k], o[i][k]); });
|
Object.keys(row).forEach(function(k) { assert.equal(row[k].valueOf(), o[i][k].valueOf()); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1878,6 +1913,21 @@ describe('invalid files', function() {
|
|||||||
wb.SheetNames.push(wb.SheetNames[0]);
|
wb.SheetNames.push(wb.SheetNames[0]);
|
||||||
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
||||||
});
|
});
|
||||||
|
it('should fail if sheet name is not valid', function() {
|
||||||
|
var names = [
|
||||||
|
"", // cannot be blank
|
||||||
|
"abcdefghijklmnopqrstuvwxyz1234567890", // cannot exceed 31 chars
|
||||||
|
"'sheetjs", "sheetjs'", // cannot start or end with apostrophe
|
||||||
|
"History", // cannot be History
|
||||||
|
"Sheet:JS", "Sheet]JS", "Sheet[JS", "Sheet*JS", // bad characters
|
||||||
|
"Sheet?JS", "Sheet\\JS", "Sheet\/JS"
|
||||||
|
];
|
||||||
|
names.forEach(function(n) { assert.throws(function() {
|
||||||
|
var wb = { SheetNames: [n], Sheets: {} };
|
||||||
|
wb.Sheets[n] = X.utils.aoa_to_sheet([["SheetJS"]]);
|
||||||
|
X.write(wb, {type:"binary", bookType:"xlsx"});
|
||||||
|
}); });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2149,7 +2199,15 @@ describe('CSV', function() {
|
|||||||
assert.equal(cell.w, '2/19/14');
|
assert.equal(cell.w, '2/19/14');
|
||||||
});
|
});
|
||||||
it('should honor dateNF override', function() {
|
it('should honor dateNF override', function() {
|
||||||
var opts = ({type:"buffer", dateNF:"YYYY-MM-DD"}/*:any*/);
|
var opts = ({type:"buffer", dateNF:"YYYY-MM-DD", cellNF: true}/*:any*/);
|
||||||
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
|
||||||
|
assert.equal(cell.z, "YYYY-MM-DD");
|
||||||
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.ok(cell.w == '14-02-19' || cell.w == "2/19/14");
|
||||||
|
var opts = ({type:"buffer", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
|
||||||
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||||
@ -2163,10 +2221,18 @@ describe('CSV', function() {
|
|||||||
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 1);
|
assert.equal(cell.v.getMonth(), 1);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
opts = {type:"buffer", cellDates:true, dateNF:'d/m/yy'};
|
opts.dateNF = 'd/m/yy';
|
||||||
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 2);
|
assert.equal(cell.v.getMonth(), 2);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts = {type:"buffer", cellDates:true, dateNF:'m/d/yy', UTC: true};
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 1);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts.dateNF = 'd/m/yy';
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 2);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
});
|
});
|
||||||
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"buffer"}), false); });
|
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"buffer"}), false); });
|
||||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
||||||
@ -2190,6 +2256,48 @@ describe('CSV', function() {
|
|||||||
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('should parse date-less meridien time values', function() {
|
||||||
|
var aoa = [
|
||||||
|
["3a", "3 a", "3 a-1"],
|
||||||
|
["3b", "3 b", "3 b-1"],
|
||||||
|
["3p", "3 P", "3 p-1"]
|
||||||
|
];
|
||||||
|
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||||
|
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
/* this particular case is not well-defined */
|
||||||
|
//var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal((24 + Math.round(B1.v * 24)) % 24, Math.round(3 + 24 + new Date(1899,11,31,0,0,0,0).getTimezoneOffset()/60) % 24);
|
||||||
|
//var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal((24 + Math.round(B3.v * 24)) % 24, Math.round(15 + 24 + new Date(1899,11,31,0,0,0,0).getTimezoneOffset()/60) % 24);
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('output', function(){
|
describe('output', function(){
|
||||||
var data, ws;
|
var data, ws;
|
||||||
@ -2338,19 +2446,36 @@ describe('dbf', function() {
|
|||||||
['d11', dir + 'dbf/d11.dbf'],
|
['d11', dir + 'dbf/d11.dbf'],
|
||||||
['vfp3', dir + 'dbf/vfp3.dbf']
|
['vfp3', dir + 'dbf/vfp3.dbf']
|
||||||
]/*:any*/);
|
]/*:any*/);
|
||||||
|
var wbstrue = ([]);
|
||||||
|
var wbsfalse = ([]);
|
||||||
var bef = (function() {
|
var bef = (function() {
|
||||||
wbs = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), {type:TYPE})]; });
|
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, UTC: false })]; });
|
||||||
|
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, UTC: true })]; });
|
||||||
});
|
});
|
||||||
if(typeof before != 'undefined') before(bef);
|
if(typeof before != 'undefined') before(bef);
|
||||||
else it('before', bef);
|
else it('before', bef);
|
||||||
it(wbs[1][0], function() {
|
it(wbs[1][0], function() {
|
||||||
var ws = wbs[1][1].Sheets["Sheet1"];
|
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
|
||||||
|
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
|
||||||
[
|
[
|
||||||
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
|
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
|
||||||
["C2", "v", 12.345], ["D2", "v", 1234.1], ["E2", "w", "19170219"],
|
["E2", "w", "19170219", (new Date(1917,1,19).getTimezoneOffset() > 0 ? "19170218" : "19170219")],
|
||||||
/* [F2", "w", "19170219"], */ ["G2", "v", 1231.4], ["H2", "v", 123234],
|
["F2", "w", "19170219", (new Date(1917,1,19).getTimezoneOffset() > 0 ? "19170218" : "19170219")],
|
||||||
["I2", "v", true], ["L2", "v", "SheetJS"]
|
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
|
||||||
].forEach(function(r) { assert.equal(get_cell(ws, r[0])[r[1]], r[2]); });
|
].forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wstrue, r[0])[r[1]], r[2]);
|
||||||
|
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[3] || r[2]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
||||||
|
[ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ].forEach(function(r) {
|
||||||
|
var book = X.utils.book_new();
|
||||||
|
var sheet = X.utils.aoa_to_sheet([["ASCII", "encoded"], ["Test", r[1]]]);
|
||||||
|
X.utils.book_append_sheet(book, sheet, "sheet1");
|
||||||
|
var data = X.write(book, {type: TYPE, bookType: "dbf", codepage:r[0]});
|
||||||
|
var wb = X.read(data, {type: TYPE});
|
||||||
|
assert.equal(wb.Sheets.Sheet1.B2.v, r[1]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
//import { JSDOM } from 'jsdom';
|
//import { JSDOM } from 'jsdom';
|
||||||
|
163
testnocp.ts
163
testnocp.ts
@ -1005,7 +1005,7 @@ Deno.test('parse features', async function(t) {
|
|||||||
|
|
||||||
await t.step('sheetRows', async function(t) {
|
await t.step('sheetRows', async function(t) {
|
||||||
await t.step('should use original range if not set', async function(t) {
|
await t.step('should use original range if not set', async function(t) {
|
||||||
var opts = {type:TYPE};
|
var opts: X.ParsingOptions = {type:TYPE};
|
||||||
FSTPaths.map(function(p) { return X.read(fs.readFileSync(p), opts); }).forEach(function(wb) {
|
FSTPaths.map(function(p) { return X.read(fs.readFileSync(p), opts); }).forEach(function(wb) {
|
||||||
assert.equal(wb.Sheets["Text"]["!ref"],"A1:F49");
|
assert.equal(wb.Sheets["Text"]["!ref"],"A1:F49");
|
||||||
});
|
});
|
||||||
@ -1509,6 +1509,22 @@ Deno.test('write features', async function(t) {
|
|||||||
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
assert.equal(Name.Ref, "Sheet1!$A$1:$C$3");
|
||||||
assert.equal(((wb2.Workbook as any).Names as any).length, ((wb3.Workbook as any).Names as any).length);
|
assert.equal(((wb2.Workbook as any).Names as any).length, ((wb3.Workbook as any).Names as any).length);
|
||||||
}); });
|
}); });
|
||||||
|
await t.step('should handle non-string values for "s" cells', async function(t) {([
|
||||||
|
"xlsx", "xlsb", "xls", "biff5", "biff2", "xlml", "numbers", "ods", "fods", "wk3", "csv", "txt", "sylk", "html", "dif", "dbf", "wk1", "rtf", "prn"
|
||||||
|
] as Array<X.BookType>).forEach(function(fmt) {
|
||||||
|
if(fmt == "numbers" && !can_write_numbers) return;
|
||||||
|
var ws = X.utils.aoa_to_sheet([
|
||||||
|
["String", "123"],
|
||||||
|
["Number", 123],
|
||||||
|
["Boolean", true],
|
||||||
|
["Date", new Date()],
|
||||||
|
], { cellDates: true });
|
||||||
|
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
||||||
|
var wb = X.utils.book_new();
|
||||||
|
X.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: false, numbers:XLSX_ZAHL});
|
||||||
|
X.write(wb, {type: TYPE, bookType: fmt, bookSST: true, numbers:XLSX_ZAHL});
|
||||||
|
}); });
|
||||||
});
|
});
|
||||||
|
|
||||||
function seq(end: number, start?: number): Array<number> {
|
function seq(end: number, start?: number): Array<number> {
|
||||||
@ -1518,28 +1534,30 @@ function seq(end: number, start?: number): Array<number> {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v: Date, date1904?: boolean): number {
|
function datenum(v: Date, date1904?: boolean): number {
|
||||||
var epoch = v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
|
if(date1904) return res - 1462;
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]] sans "Z"
|
||||||
function parseDate(str: string|Date): Date {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str: string|Date, date1904?: boolean): Date {
|
||||||
if(good_pd) return d;
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
m = str.match(pdre3);
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
var d = new Date(str);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
||||||
@ -1850,6 +1868,21 @@ Deno.test('invalid files', async function(t) {
|
|||||||
wb.SheetNames.push(wb.SheetNames[0]);
|
wb.SheetNames.push(wb.SheetNames[0]);
|
||||||
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
assert.throws(function() { X.write(wb, {type:'binary'}); });
|
||||||
});
|
});
|
||||||
|
await t.step('should fail if sheet name is not valid', async function(t) {
|
||||||
|
var names = [
|
||||||
|
"", // cannot be blank
|
||||||
|
"abcdefghijklmnopqrstuvwxyz1234567890", // cannot exceed 31 chars
|
||||||
|
"'sheetjs", "sheetjs'", // cannot start or end with apostrophe
|
||||||
|
"History", // cannot be History
|
||||||
|
"Sheet:JS", "Sheet]JS", "Sheet[JS", "Sheet*JS", // bad characters
|
||||||
|
"Sheet?JS", "Sheet\\JS", "Sheet\/JS"
|
||||||
|
];
|
||||||
|
names.forEach(function(n) { assert.throws(function() {
|
||||||
|
var wb: X.WorkBook = { SheetNames: [n], Sheets: {} };
|
||||||
|
wb.Sheets[n] = X.utils.aoa_to_sheet([["SheetJS"]]);
|
||||||
|
X.write(wb, {type:"binary", bookType:"xlsx"});
|
||||||
|
}); });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2117,9 +2150,17 @@ Deno.test('CSV', async function(t) {
|
|||||||
assert.equal(cell.w, '2/19/14');
|
assert.equal(cell.w, '2/19/14');
|
||||||
});
|
});
|
||||||
await t.step('should honor dateNF override', async function(t) {
|
await t.step('should honor dateNF override', async function(t) {
|
||||||
var opts: X.ParsingOptions = ({type:"binary", dateNF:"YYYY-MM-DD"});
|
var opts: X.ParsingOptions = ({type:"binary", dateNF:"YYYY-MM-DD", cellNF: true});
|
||||||
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
|
assert.assert(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
|
||||||
|
assert.equal(cell.z, "YYYY-MM-DD");
|
||||||
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.assert(cell.w == '14-02-19' || cell.w == "2/19/14");
|
||||||
|
opts = ({type:"binary", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
assert.assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
assert.assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||||
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
@ -2131,10 +2172,18 @@ Deno.test('CSV', async function(t) {
|
|||||||
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 1);
|
assert.equal(cell.v.getMonth(), 1);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
opts = {type:"binary", cellDates:true, dateNF:'d/m/yy'};
|
opts.dateNF = 'd/m/yy';
|
||||||
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 2);
|
assert.equal(cell.v.getMonth(), 2);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts = {type:"binary", cellDates:true, dateNF:'m/d/yy', UTC: true};
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 1);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts.dateNF = 'd/m/yy';
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 2);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
});
|
});
|
||||||
await t.step('should interpret values by default', async function(t) { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
await t.step('should interpret values by default', async function(t) { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
||||||
await t.step('should generate strings if raw option is passed', async function(t) { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
await t.step('should generate strings if raw option is passed', async function(t) { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
||||||
@ -2162,9 +2211,10 @@ Deno.test('CSV', async function(t) {
|
|||||||
var aoa = [
|
var aoa = [
|
||||||
["3a", "3 a", "3 a-1"],
|
["3a", "3 a", "3 a-1"],
|
||||||
["3b", "3 b", "3 b-1"],
|
["3b", "3 b", "3 b-1"],
|
||||||
["3p", "3 P", "3 p-1"],
|
["3p", "3 P", "3 p-1"]
|
||||||
];
|
];
|
||||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
|
||||||
|
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
@ -2172,14 +2222,46 @@ Deno.test('CSV', async function(t) {
|
|||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: false}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
}
|
}
|
||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -2316,18 +2398,31 @@ Deno.test('numbers', async function(t) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Deno.test('dbf', async function(t) {
|
Deno.test('dbf', async function(t) {
|
||||||
var wbs: Array<[string, X.WorkBook]> = ([
|
var wbs: Array<[string, string]> = ([
|
||||||
['d11', dir + 'dbf/d11.dbf'],
|
['d11', dir + 'dbf/d11.dbf'],
|
||||||
['vfp3', dir + 'dbf/vfp3.dbf']
|
['vfp3', dir + 'dbf/vfp3.dbf']
|
||||||
]).map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), {type:TYPE})]; });
|
]);
|
||||||
|
var wbsfalse: Array<[string, X.WorkBook]> = ([]);
|
||||||
|
var wbstrue: Array<[string, X.WorkBook]> = ([]);
|
||||||
|
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: false })]; });
|
||||||
|
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: true })]; });
|
||||||
await t.step(wbs[1][0], async function(t) {
|
await t.step(wbs[1][0], async function(t) {
|
||||||
var ws = wbs[1][1].Sheets["Sheet1"];
|
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
|
||||||
([
|
([
|
||||||
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
|
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
|
||||||
["C2", "v", 12.345], ["D2", "v", 1234.1], ["E2", "w", "19170219"],
|
["E2", "v", 6260], ["E2", "w", "19170219"],
|
||||||
/* [F2", "w", "19170219"], */ ["G2", "v", 1231.4], ["H2", "v", 123234],
|
["F2", "v", 6260], ["F2", "w", "19170219"],
|
||||||
["I2", "v", true], ["L2", "v", "SheetJS"]
|
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
|
||||||
] as Array<[string, string, any]>).forEach(function(r) { assert.equal(get_cell(ws, r[0])[r[1]], r[2]); });
|
] as Array<[string, string, any]>).forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
|
||||||
|
});
|
||||||
|
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
|
||||||
|
([
|
||||||
|
["E2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["E2", "w", "19170219"],
|
||||||
|
["F2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["F2", "w", "19170219"],
|
||||||
|
] as Array<[string, string, any]>).forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wstrue, r[0])[r[1]].valueOf(), r[2].valueOf());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
if(false) await t.step("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", async function(t) {
|
if(false) await t.step("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", async function(t) {
|
||||||
([ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ] as Array<[number,string]>).forEach(function(r) {
|
([ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ] as Array<[number,string]>).forEach(function(r) {
|
||||||
|
129
tests/core.js
generated
129
tests/core.js
generated
@ -1554,7 +1554,7 @@ describe('write features', function() {
|
|||||||
["String", "123"],
|
["String", "123"],
|
||||||
["Number", 123],
|
["Number", 123],
|
||||||
["Boolean", true],
|
["Boolean", true],
|
||||||
["Date", new Date()],
|
["Date", new Date()]
|
||||||
], { cellDates: true });
|
], { cellDates: true });
|
||||||
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
ws["B2"].t = ws["B3"].t = ws["B4"].t = "s"
|
||||||
var wb = X.utils.book_new();
|
var wb = X.utils.book_new();
|
||||||
@ -1571,28 +1571,30 @@ function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
|
var dnthresh = /*#__PURE__*/Date.UTC(1899, 11, 30, 0, 0, 0); // -2209161600000
|
||||||
|
var dnthresh1 = /*#__PURE__*/Date.UTC(1899, 11, 31, 0, 0, 0); // -2209075200000
|
||||||
|
var dnthresh2 = /*#__PURE__*/Date.UTC(1904, 0, 1, 0, 0, 0); // -2209075200000
|
||||||
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
||||||
var epoch = v.getTime();
|
var epoch = /*#__PURE__*/v.getTime();
|
||||||
if(date1904) epoch -= 1462*24*60*60*1000;
|
var res = (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
||||||
var dnthresh = basedate.getTime() + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
|
if(date1904) return res - 1462;
|
||||||
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
|
return res < 60 ? res - 1 : res;
|
||||||
}
|
}
|
||||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
/* Blame https://bugs.chromium.org/p/v8/issues/detail?id=7863 for the regexide */
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2017-02-19T19:06:09');
|
var pdre1 = /^(\d+):(\d+)(:\d+)?(\.\d+)?$/; // HH:MM[:SS[.UUU]]
|
||||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
var pdre2 = /^(\d+)-(\d+)-(\d+)$/; // YYYY-mm-dd
|
||||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
var pdre3 = /^(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)(:\d+)?(\.\d+)?$/; // YYYY-mm-dd(T or space)HH:MM[:SS[.UUU]] sans "Z"
|
||||||
function parseDate(str/*:string|Date*/)/*:Date*/ {
|
/* parses a date string as a UTC date */
|
||||||
var d = new Date(str);
|
function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
|
||||||
if(good_pd) return d;
|
|
||||||
if(str instanceof Date) return str;
|
if(str instanceof Date) return str;
|
||||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
var m = str.match(pdre1);
|
||||||
var s = d.getFullYear();
|
if(m) return new Date((date1904 ? dnthresh2 : dnthresh1) + ((parseInt(m[1], 10)*60 + parseInt(m[2], 10))*60 + (m[3] ? parseInt(m[3].slice(1), 10) : 0))*1000 + (m[4] ? parseInt((m[4]+"000").slice(1,4), 10) : 0));
|
||||||
if(str.indexOf("" + s) > -1) return d;
|
m = str.match(pdre2);
|
||||||
d.setFullYear(d.getFullYear() + 100); return d;
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||||
}
|
m = str.match(pdre3);
|
||||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
var d = new Date(str);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
|
||||||
@ -1816,7 +1818,7 @@ describe('roundtrip features', function() {
|
|||||||
];
|
];
|
||||||
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
var o = X.utils.sheet_to_json(X.utils.json_to_sheet(data, {cellDates:true}));
|
||||||
data.forEach(function(row, i) {
|
data.forEach(function(row, i) {
|
||||||
Object.keys(row).forEach(function(k) { assert.equal(row[k], o[i][k]); });
|
Object.keys(row).forEach(function(k) { assert.equal(row[k].valueOf(), o[i][k].valueOf()); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2189,7 +2191,15 @@ describe('CSV', function() {
|
|||||||
assert.equal(cell.w, '2/19/14');
|
assert.equal(cell.w, '2/19/14');
|
||||||
});
|
});
|
||||||
it('should honor dateNF override', function() {
|
it('should honor dateNF override', function() {
|
||||||
var opts = ({type:"binary", dateNF:"YYYY-MM-DD"}/*:any*/);
|
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", cellNF: true}/*:any*/);
|
||||||
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
|
||||||
|
assert.equal(cell.z, "YYYY-MM-DD");
|
||||||
|
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||||
|
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.ok(cell.w == '14-02-19' || cell.w == "2/19/14");
|
||||||
|
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
|
||||||
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
|
||||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||||
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||||
@ -2203,10 +2213,18 @@ describe('CSV', function() {
|
|||||||
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 1);
|
assert.equal(cell.v.getMonth(), 1);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
opts = {type:"binary", cellDates:true, dateNF:'d/m/yy'};
|
opts.dateNF = 'd/m/yy';
|
||||||
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
assert.equal(cell.v.getMonth(), 2);
|
assert.equal(cell.v.getMonth(), 2);
|
||||||
assert.equal(cell.w, "2/3/14");
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts = {type:"binary", cellDates:true, dateNF:'m/d/yy', UTC: true};
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 1);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
|
opts.dateNF = 'd/m/yy';
|
||||||
|
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
|
||||||
|
assert.equal(cell.v.getUTCMonth(), 2);
|
||||||
|
assert.equal(cell.w, "2/3/14");
|
||||||
});
|
});
|
||||||
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
|
||||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
|
||||||
@ -2236,7 +2254,8 @@ describe('CSV', function() {
|
|||||||
["3b", "3 b", "3 b-1"],
|
["3b", "3 b", "3 b-1"],
|
||||||
["3p", "3 P", "3 p-1"]
|
["3p", "3 P", "3 p-1"]
|
||||||
];
|
];
|
||||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
|
||||||
|
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
@ -2244,14 +2263,46 @@ describe('CSV', function() {
|
|||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: false}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||||
|
for(var R = 0; R < 3; ++R) {
|
||||||
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
|
}
|
||||||
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getUTCHours(), 3);
|
||||||
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getUTCHours(), 15);
|
||||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||||
for(var R = 0; R < 3; ++R) {
|
for(var R = 0; R < 3; ++R) {
|
||||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||||
}
|
}
|
||||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -2402,19 +2453,31 @@ describe('dbf', function() {
|
|||||||
['d11', dir + 'dbf/d11.dbf'],
|
['d11', dir + 'dbf/d11.dbf'],
|
||||||
['vfp3', dir + 'dbf/vfp3.dbf']
|
['vfp3', dir + 'dbf/vfp3.dbf']
|
||||||
]/*:any*/);
|
]/*:any*/);
|
||||||
|
var wbsfalse = ([]);
|
||||||
|
var wbstrue = ([]);
|
||||||
var bef = (function() {
|
var bef = (function() {
|
||||||
wbs = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), {type:TYPE})]; });
|
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: false })]; });
|
||||||
|
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: true })]; });
|
||||||
});
|
});
|
||||||
if(typeof before != 'undefined') before(bef);
|
if(typeof before != 'undefined') before(bef);
|
||||||
else it('before', bef);
|
else it('before', bef);
|
||||||
it(wbs[1][0], function() {
|
it(wbs[1][0], function() {
|
||||||
var ws = wbs[1][1].Sheets["Sheet1"];
|
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
|
||||||
[
|
[
|
||||||
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
|
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
|
||||||
["C2", "v", 12.345], ["D2", "v", 1234.1], ["E2", "w", "19170219"],
|
["E2", "v", 6260], ["E2", "w", "19170219"],
|
||||||
/* [F2", "w", "19170219"], */ ["G2", "v", 1231.4], ["H2", "v", 123234],
|
["F2", "v", 6260], ["F2", "w", "19170219"],
|
||||||
["I2", "v", true], ["L2", "v", "SheetJS"]
|
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
|
||||||
].forEach(function(r) { assert.equal(get_cell(ws, r[0])[r[1]], r[2]); });
|
].forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
|
||||||
|
});
|
||||||
|
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
|
||||||
|
[
|
||||||
|
["E2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["E2", "w", "19170219"],
|
||||||
|
["F2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["F2", "w", "19170219"]
|
||||||
|
].forEach(function(r) {
|
||||||
|
assert.equal(get_cell(wstrue, r[0])[r[1]].valueOf(), r[2].valueOf());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
|
||||||
[ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ].forEach(function(r) {
|
[ [620, "Ś╫êëτ⌡ś"], [895, "Š╫ěéτ⌡š"] ].forEach(function(r) {
|
||||||
|
59
types/index.d.ts
vendored
59
types/index.d.ts
vendored
@ -139,8 +139,20 @@ export interface DateNFOption {
|
|||||||
dateNF?: NumberFormat;
|
dateNF?: NumberFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UTCOption {
|
||||||
|
/**
|
||||||
|
* For plaintext formats, interpret ambiguous datetimes in UTC
|
||||||
|
* If explicitly set to `false`, dates will be parsed in local time.
|
||||||
|
*
|
||||||
|
* The `true` option is consistent with spreadsheet application export.
|
||||||
|
*
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
UTC?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/** Options for read and readFile */
|
/** Options for read and readFile */
|
||||||
export interface ParsingOptions extends CommonOptions {
|
export interface ParsingOptions extends UTCOption, CommonOptions {
|
||||||
/** Input data encoding */
|
/** Input data encoding */
|
||||||
type?: 'base64' | 'binary' | 'buffer' | 'file' | 'array' | 'string';
|
type?: 'base64' | 'binary' | 'buffer' | 'file' | 'array' | 'string';
|
||||||
|
|
||||||
@ -294,6 +306,12 @@ export interface WritingOptions extends CommonOptions {
|
|||||||
* If this option is omitted, the first worksheet will be exported.
|
* If this option is omitted, the first worksheet will be exported.
|
||||||
*/
|
*/
|
||||||
sheet?: string | number;
|
sheet?: string | number;
|
||||||
|
|
||||||
|
/** Field Separator ("delimiter") for CSV / Text output */
|
||||||
|
FS?: string;
|
||||||
|
|
||||||
|
/** Record Separator ("row separator") for CSV / Text output */
|
||||||
|
RS?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Workbook Object */
|
/** Workbook Object */
|
||||||
@ -803,9 +821,27 @@ export interface Sheet2JSONOpts extends DateNFOption {
|
|||||||
|
|
||||||
/** if true, return raw numbers; if false, return formatted numbers */
|
/** if true, return raw numbers; if false, return formatted numbers */
|
||||||
rawNumbers?: boolean;
|
rawNumbers?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, return dates whose UTC interpretation is correct
|
||||||
|
* By default, return dates whose local interpretation is correct
|
||||||
|
*
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
UTC?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AOA2SheetOpts extends CommonOptions, DateNFOption {
|
export interface UTCDateOption {
|
||||||
|
/**
|
||||||
|
* If true, dates are interpreted using the UTC methods
|
||||||
|
* By default, dates are interpreted in the local timezone
|
||||||
|
*
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
UTC?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AOA2SheetOpts extends CommonOptions, UTCDateOption, DateNFOption {
|
||||||
/**
|
/**
|
||||||
* Create cell objects for stub cells
|
* Create cell objects for stub cells
|
||||||
* @default false
|
* @default false
|
||||||
@ -815,7 +851,7 @@ export interface AOA2SheetOpts extends CommonOptions, DateNFOption {
|
|||||||
|
|
||||||
export interface SheetAOAOpts extends AOA2SheetOpts, OriginOption {}
|
export interface SheetAOAOpts extends AOA2SheetOpts, OriginOption {}
|
||||||
|
|
||||||
export interface JSON2SheetOpts extends CommonOptions, DateNFOption, OriginOption {
|
export interface JSON2SheetOpts extends CommonOptions, UTCDateOption, DateNFOption, OriginOption {
|
||||||
/** Use specified column order */
|
/** Use specified column order */
|
||||||
header?: string[];
|
header?: string[];
|
||||||
|
|
||||||
@ -841,6 +877,14 @@ export interface Table2SheetOpts extends CommonOptions, DateNFOption, OriginOpti
|
|||||||
* @default "Sheet1"
|
* @default "Sheet1"
|
||||||
*/
|
*/
|
||||||
sheet?: string;
|
sheet?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, interpret date strings as if they are UTC.
|
||||||
|
* By default, date strings are interpreted in the local timezone.
|
||||||
|
*
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
UTC?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Table2BookOpts extends Table2SheetOpts {
|
export interface Table2BookOpts extends Table2SheetOpts {
|
||||||
@ -887,15 +931,6 @@ export interface XLSX$Utils {
|
|||||||
/** Generates a list of the formulae (with value fallbacks) */
|
/** Generates a list of the formulae (with value fallbacks) */
|
||||||
sheet_to_formulae(worksheet: WorkSheet): string[];
|
sheet_to_formulae(worksheet: WorkSheet): string[];
|
||||||
|
|
||||||
/** Generates DIF */
|
|
||||||
sheet_to_dif(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string;
|
|
||||||
|
|
||||||
/** Generates SYLK (Symbolic Link) */
|
|
||||||
sheet_to_slk(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string;
|
|
||||||
|
|
||||||
/** Generates ETH */
|
|
||||||
sheet_to_eth(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string;
|
|
||||||
|
|
||||||
/* --- Cell Address Utilities --- */
|
/* --- Cell Address Utilities --- */
|
||||||
|
|
||||||
/** Converts 0-indexed cell address to A1 form */
|
/** Converts 0-indexed cell address to A1 form */
|
||||||
|
@ -21,9 +21,6 @@ interface Tester {
|
|||||||
const jsonvalues: Tester[] = XLSX.utils.sheet_to_json<Tester>(firstworksheet);
|
const jsonvalues: Tester[] = XLSX.utils.sheet_to_json<Tester>(firstworksheet);
|
||||||
const csv: string = XLSX.utils.sheet_to_csv(firstworksheet);
|
const csv: string = XLSX.utils.sheet_to_csv(firstworksheet);
|
||||||
const txt: string = XLSX.utils.sheet_to_txt(firstworksheet);
|
const txt: string = XLSX.utils.sheet_to_txt(firstworksheet);
|
||||||
const dif: string = XLSX.utils.sheet_to_dif(firstworksheet);
|
|
||||||
const slk: string = XLSX.utils.sheet_to_slk(firstworksheet);
|
|
||||||
const eth: string = XLSX.utils.sheet_to_eth(firstworksheet);
|
|
||||||
const formulae: string[] = XLSX.utils.sheet_to_formulae(firstworksheet);
|
const formulae: string[] = XLSX.utils.sheet_to_formulae(firstworksheet);
|
||||||
const aoa: any[][] = XLSX.utils.sheet_to_json<any[]>(firstworksheet, {raw:true, header:1});
|
const aoa: any[][] = XLSX.utils.sheet_to_json<any[]>(firstworksheet, {raw:true, header:1});
|
||||||
|
|
||||||
|
2278
xlsx.flow.js
2278
xlsx.flow.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
506
xlsx.mini.js
506
xlsx.mini.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user