forked from sheetjs/sheetjs
version bump 0.10.2: date processing corner cases
- all formats follow cellDates / dateNF (fixes #653 h/t @mmancosu) - IE6-8 Date corrections - XLML Date force UTC - updated SSF to 0.9.3 (fixes #372 h/t @HuFlungDu) - removed CFB export
This commit is contained in:
parent
3fde651a8c
commit
3ff724e349
@ -5,9 +5,10 @@ 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.
|
||||
|
||||
|
||||
## 0.10.2 (2017-05-??)
|
||||
## 0.10.2 (2017-05-16)
|
||||
|
||||
* CSV generates numeric dates by default (aligning with XLSX cellDates behavior)
|
||||
* Dates are converted to numbers by default (set `cellDates:true` to emit Dates)
|
||||
* Module does not export CFB
|
||||
|
||||
## 0.9.10 (2017-04-08)
|
||||
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.10.1';
|
||||
XLSX.version = '0.10.2';
|
||||
|
@ -75,12 +75,19 @@ function parse_isodur(s) {
|
||||
}
|
||||
|
||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
||||
function parseDate(str/*:string|Date*/)/*:Date*/ {
|
||||
if(good_pd) return new Date(str);
|
||||
var d = new Date(str);
|
||||
if(good_pd) return d;
|
||||
if(str instanceof Date) return str;
|
||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
||||
var s = d.getFullYear();
|
||||
if(str.indexOf("" + s) > -1) return d;
|
||||
d.setFullYear(d.getFullYear() + 100); return d;
|
||||
}
|
||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0)));
|
||||
}
|
||||
|
||||
function cc2str(arr/*:Array<number>*/)/*:string*/ {
|
||||
|
@ -237,6 +237,8 @@ var SYLK = (function() {
|
||||
else if(+val === +val) {
|
||||
val = +val;
|
||||
if(next_cell_format !== null && SSF.is_date(next_cell_format)) val = numdate(val);
|
||||
} else if(!isNaN(fuzzydate(val).getDate())) {
|
||||
val = parseDate(val);
|
||||
}
|
||||
arr[R][C] = val;
|
||||
next_cell_format = null;
|
||||
@ -254,7 +256,7 @@ var SYLK = (function() {
|
||||
case 'Y':
|
||||
R = parseInt(record[rj].substr(1))-1; /*C = 0;*/
|
||||
for(j = arr.length; j <= R; ++j) arr[j] = [];
|
||||
++F_seen; break;
|
||||
break;
|
||||
case 'M': Mval = parseInt(record[rj].substr(1)) / 20; break;
|
||||
case 'F': break; /* ??? */
|
||||
case 'P':
|
||||
@ -281,7 +283,7 @@ var SYLK = (function() {
|
||||
break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(F_seen < 2) next_cell_format = null; break;
|
||||
if(F_seen < 1) next_cell_format = null; break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
}
|
||||
@ -480,6 +482,7 @@ var PRN = (function() {
|
||||
else if(data === 'FALSE') arr[R][C] = false;
|
||||
else if(data === ""){/* empty */}
|
||||
else if(+data == +data) arr[R][C] = +data;
|
||||
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
|
||||
else arr[R][C] = data;
|
||||
}
|
||||
|
||||
|
@ -51,11 +51,15 @@ var WK_ = (function() {
|
||||
case 0x0E: /* NUMBER */
|
||||
case 0x10: /* FORMULA */
|
||||
case 0x33: /* STRING */
|
||||
/* TODO: actual translation of the format code */
|
||||
if(RT == 0x0E && (val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
|
||||
val[1].z = o.dateNF || SSF._table[14];
|
||||
if(o.cellDates) { val[1].t = 'd'; val[1].v = numdate(val[1].v); }
|
||||
}
|
||||
if(o.dense) {
|
||||
if(!s[val[0].r]) s[val[0].r] = [];
|
||||
s[val[0].r][val[0].c] = val[1];
|
||||
} else s[encode_cell(val[0])] = val[1];
|
||||
/* TODO: FORMAT */
|
||||
break;
|
||||
} else switch(RT) {
|
||||
case 0x16: /* LABEL16 */
|
||||
@ -224,7 +228,7 @@ var WK_ = (function() {
|
||||
var WK1Enum = {
|
||||
/*::[*/0x0000/*::]*/: { n:"BOF", f:parseuint16 },
|
||||
/*::[*/0x0001/*::]*/: { n:"EOF", f:parsenoop },
|
||||
/*::[*/0x0002/*::]*/: { n: "CALCMODE", f:parsenoop },
|
||||
/*::[*/0x0002/*::]*/: { n:"CALCMODE", f:parsenoop },
|
||||
/*::[*/0x0003/*::]*/: { n:"CALCORDER", f:parsenoop },
|
||||
/*::[*/0x0004/*::]*/: { n:"SPLIT", f:parsenoop },
|
||||
/*::[*/0x0005/*::]*/: { n:"SYNC", f:parsenoop },
|
||||
|
@ -112,6 +112,7 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
|
||||
cell.v = xml.indexOf("<") > -1 ? unescapexml(ss) : cell.r;
|
||||
break;
|
||||
case 'DateTime':
|
||||
if(xml.slice(-1) != "Z") xml += "Z";
|
||||
cell.v = (parseDate(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
|
||||
if(cell.v !== cell.v) cell.v = unescapexml(xml);
|
||||
else if(cell.v<60) cell.v = cell.v -1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* TODO: in browser attach to DOM; in node use an html parser */
|
||||
/* note: browser DOM element cannot see mso- style attrs, must parse */
|
||||
var HTML_ = (function() {
|
||||
function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
|
||||
var opts = _opts || {};
|
||||
@ -112,7 +112,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText;
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent;
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -120,8 +120,15 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
/* TODO: figure out how to extract nonstandard mso- style */
|
||||
CS = +elt.getAttribute("colspan") || 1;
|
||||
if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
var o = {t:'s', v:v};
|
||||
if(v != null && v.length && !isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
var o/*:Cell*/ = {t:'s', v:v};
|
||||
if(v != null && v.length) {
|
||||
if(!isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
else if(!isNaN(fuzzydate(v).getDate())) {
|
||||
o = ({t:'d', v:parseDate(v)}/*:any*/);
|
||||
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
|
||||
o.z = opts.dateNF || SSF._table[14];
|
||||
}
|
||||
}
|
||||
if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; }
|
||||
else ws[encode_cell({c:C, r:R})] = o;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
|
@ -169,6 +169,7 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
|
||||
function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
var o = opts || {};
|
||||
var ws = ({}/*:any*/);
|
||||
var cell/*:Cell*/;
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:js.length}}/*:any*/);
|
||||
var hdr = o.header || [], C = 0;
|
||||
|
||||
@ -177,11 +178,17 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
|
||||
var v = js[R][k];
|
||||
var t = 'z';
|
||||
var z = "";
|
||||
if(typeof v == 'number') t = 'n';
|
||||
else if(typeof v == 'boolean') t = 'b';
|
||||
else if(typeof v == 'string') t = 's';
|
||||
else if(v instanceof Date) t = 'd';
|
||||
ws[encode_cell({c:C,r:R+1})] = {t:t, v:v};
|
||||
else if(v instanceof Date) {
|
||||
t = 'd';
|
||||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v}/*:any*/);
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
}
|
||||
range.e.c = hdr.length - 1;
|
||||
|
@ -11,5 +11,4 @@ XLSX.writeFile = writeFileSync;
|
||||
XLSX.writeFileSync = writeFileSync;
|
||||
XLSX.writeFileAsync = writeFileAsync;
|
||||
XLSX.utils = utils;
|
||||
XLSX.CFB = CFB;
|
||||
XLSX.SSF = SSF;
|
||||
|
4
dist/jszip.js
vendored
4
dist/jszip.js
vendored
@ -9,7 +9,7 @@ Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/js
|
||||
JSZip uses the library pako released under the MIT license :
|
||||
https://github.com/nodeca/pako/blob/master/LICENSE
|
||||
*/
|
||||
!function(e){
|
||||
(function(e){
|
||||
if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();
|
||||
else if("function"==typeof define&&define.amd){JSZip=e();define([],e);}
|
||||
else{
|
||||
@ -8985,4 +8985,4 @@ function ZStream() {
|
||||
module.exports = ZStream;
|
||||
},{}]},{},[9])
|
||||
(9)
|
||||
});
|
||||
}));
|
||||
|
34
dist/xlsx.core.min.js
vendored
34
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
34
dist/xlsx.full.min.js
vendored
34
dist/xlsx.full.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
vendored
2
dist/xlsx.full.min.map
vendored
File diff suppressed because one or more lines are too long
204
dist/xlsx.js
vendored
204
dist/xlsx.js
vendored
@ -1,16 +1,16 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint -W041 */
|
||||
/*jshint funcscope:true, eqnull:true */
|
||||
/*jshint funcscope:true, eqnull:true, loopfunc:true */
|
||||
/*exported XLSX */
|
||||
/*global exports, module, require:false, process:false, Buffer:false */
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.10.1';
|
||||
XLSX.version = '0.10.2';
|
||||
var current_codepage = 1200;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js');
|
||||
if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js');
|
||||
}
|
||||
function reset_cp() { set_cp(1200); }
|
||||
var set_cp = function(cp) { current_codepage = cp; };
|
||||
@ -1431,12 +1431,19 @@ function parse_isodur(s) {
|
||||
}
|
||||
|
||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
||||
function parseDate(str) {
|
||||
if(good_pd) return new Date(str);
|
||||
var d = new Date(str);
|
||||
if(good_pd) return d;
|
||||
if(str instanceof Date) return str;
|
||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
||||
var s = d.getFullYear();
|
||||
if(str.indexOf("" + s) > -1) return d;
|
||||
d.setFullYear(d.getFullYear() + 100); return d;
|
||||
}
|
||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0)));
|
||||
}
|
||||
|
||||
function cc2str(arr) {
|
||||
@ -1662,8 +1669,7 @@ if(has_buf) {
|
||||
if(ww !== 0) { out[k++] = ww&255; out[k++] = ww>>>8; ww = 0; }
|
||||
out[k++] = w%256; out[k++] = w>>>8;
|
||||
}
|
||||
out.length = k;
|
||||
return out.toString('ucs2');
|
||||
return out.slice(0,k).toString('ucs2');
|
||||
};
|
||||
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
|
||||
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
|
||||
@ -5313,12 +5319,14 @@ var SYLK = (function() {
|
||||
else if(+val === +val) {
|
||||
val = +val;
|
||||
if(next_cell_format !== null && SSF.is_date(next_cell_format)) val = numdate(val);
|
||||
} else if(!isNaN(fuzzydate(val).getDate())) {
|
||||
val = parseDate(val);
|
||||
}
|
||||
arr[R][C] = val;
|
||||
next_cell_format = null;
|
||||
break;
|
||||
case 'E':
|
||||
formula = rc_to_a1(record[rj].substr(1), {r:R,c:C});
|
||||
var formula = rc_to_a1(record[rj].substr(1), {r:R,c:C});
|
||||
arr[R][C] = [arr[R][C], formula];
|
||||
break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
@ -5330,7 +5338,7 @@ var SYLK = (function() {
|
||||
case 'Y':
|
||||
R = parseInt(record[rj].substr(1))-1; /*C = 0;*/
|
||||
for(j = arr.length; j <= R; ++j) arr[j] = [];
|
||||
++F_seen; break;
|
||||
break;
|
||||
case 'M': Mval = parseInt(record[rj].substr(1)) / 20; break;
|
||||
case 'F': break; /* ??? */
|
||||
case 'P':
|
||||
@ -5357,19 +5365,18 @@ var SYLK = (function() {
|
||||
break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(F_seen < 2) next_cell_format = null; break;
|
||||
if(F_seen < 1) next_cell_format = null; break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
}
|
||||
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
|
||||
if(colinfo.length > 0) sht['!cols'] = colinfo;
|
||||
arr[arr.length] = sht;
|
||||
return arr;
|
||||
return [arr, sht];
|
||||
}
|
||||
|
||||
function sylk_to_sheet(str, opts) {
|
||||
var aoa = sylk_to_aoa(str, opts);
|
||||
var ws = aoa.pop();
|
||||
var aoasht = sylk_to_aoa(str, opts);
|
||||
var aoa = aoasht[0], ws = aoasht[1];
|
||||
var o = aoa_to_sheet(aoa, opts);
|
||||
keys(ws).forEach(function(k) { o[k] = ws[k]; });
|
||||
return o;
|
||||
@ -5557,6 +5564,7 @@ var PRN = (function() {
|
||||
else if(data === 'FALSE') arr[R][C] = false;
|
||||
else if(data === ""){/* empty */}
|
||||
else if(+data == +data) arr[R][C] = +data;
|
||||
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
|
||||
else arr[R][C] = data;
|
||||
}
|
||||
|
||||
@ -5604,8 +5612,12 @@ var PRN = (function() {
|
||||
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
||||
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
||||
else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; }
|
||||
else if(!isNaN(fuzzydate(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); }
|
||||
else {
|
||||
else if(!isNaN(fuzzydate(s).getDate())) {
|
||||
cell.z = o.dateNF || SSF._table[14];
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s); }
|
||||
else { cell.t = 'n'; cell.v = datenum(parseDate(s)); }
|
||||
cell.w = SSF.format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
|
||||
} else {
|
||||
cell.t = 's';
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
cell.v = s;
|
||||
@ -5742,11 +5754,15 @@ var WK_ = (function() {
|
||||
case 0x0E: /* NUMBER */
|
||||
case 0x10: /* FORMULA */
|
||||
case 0x33: /* STRING */
|
||||
/* TODO: actual translation of the format code */
|
||||
if(RT == 0x0E && (val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
|
||||
val[1].z = o.dateNF || SSF._table[14];
|
||||
if(o.cellDates) { val[1].t = 'd'; val[1].v = numdate(val[1].v); }
|
||||
}
|
||||
if(o.dense) {
|
||||
if(!s[val[0].r]) s[val[0].r] = [];
|
||||
s[val[0].r][val[0].c] = val[1];
|
||||
} else s[encode_cell(val[0])] = val[1];
|
||||
/* TODO: FORMAT */
|
||||
break;
|
||||
} else switch(RT) {
|
||||
case 0x16: /* LABEL16 */
|
||||
@ -5915,7 +5931,7 @@ var WK_ = (function() {
|
||||
var WK1Enum = {
|
||||
0x0000: { n:"BOF", f:parseuint16 },
|
||||
0x0001: { n:"EOF", f:parsenoop },
|
||||
0x0002: { n: "CALCMODE", f:parsenoop },
|
||||
0x0002: { n:"CALCMODE", f:parsenoop },
|
||||
0x0003: { n:"CALCORDER", f:parsenoop },
|
||||
0x0004: { n:"SPLIT", f:parsenoop },
|
||||
0x0005: { n:"SYNC", f:parsenoop },
|
||||
@ -6308,6 +6324,7 @@ function parse_CRYPTOVersion(blob, length) {
|
||||
var o = {};
|
||||
o.Major = blob.read_shift(2);
|
||||
o.Minor = blob.read_shift(2);
|
||||
if(length >= 4) blob.l += length - 4;
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -7192,7 +7209,7 @@ var XLSBFillPTNames = [
|
||||
"gray125",
|
||||
"gray0625"
|
||||
];
|
||||
var rev_XLSBFillPTNames = evert(XLSBFillPTNames);
|
||||
var rev_XLSBFillPTNames = (evert(XLSBFillPTNames));
|
||||
/* TODO: gradient fill representation */
|
||||
function write_BrtFill(fill, o) {
|
||||
if(!o) o = new_buf(4*3 + 8*7 + 16*1);
|
||||
@ -7352,13 +7369,13 @@ function write_FMTS_bin(ba, NF) {
|
||||
if(!NF) return;
|
||||
var cnt = 0;
|
||||
[[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) {
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt;
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt;
|
||||
});
|
||||
|
||||
if(cnt == 0) return;
|
||||
write_record(ba, "BrtBeginFmts", write_UInt32LE(cnt));
|
||||
[[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) {
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i]));
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i]));
|
||||
});
|
||||
write_record(ba, "BrtEndFmts");
|
||||
}
|
||||
@ -8965,15 +8982,15 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
||||
|
||||
|
||||
case 'PtgRef': /* 2.5.198.84 */
|
||||
type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts);
|
||||
type = f[1][0]; c = shift_cell_xls((f[1][1]), _range, opts);
|
||||
stack.push(encode_cell_xls(c));
|
||||
break;
|
||||
case 'PtgRefN': /* 2.5.198.88 */
|
||||
type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1];
|
||||
type = f[1][0]; c = cell ? shift_cell_xls((f[1][1]), cell, opts) : (f[1][1]);
|
||||
stack.push(encode_cell_xls(c));
|
||||
break;
|
||||
case 'PtgRef3d': /* 2.5.198.85 */
|
||||
type = f[1][0]; ixti = f[1][1]; c = shift_cell_xls(f[1][2], _range, opts);
|
||||
type = f[1][0]; ixti = f[1][1]; c = shift_cell_xls((f[1][2]), _range, opts);
|
||||
sname = supbooks.SheetNames[ixti];
|
||||
var w = sname; /* IE9 fails on defined names */
|
||||
stack.push(sname + "!" + encode_cell_xls(c));
|
||||
@ -9024,7 +9041,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
||||
|
||||
case 'PtgName': /* 2.5.97.60 TODO: revisions */
|
||||
/* f[1] = type, 0, nameindex */
|
||||
nameidx = f[1][2];
|
||||
nameidx = (f[1][2]);
|
||||
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
||||
var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx);
|
||||
if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name];
|
||||
@ -9033,7 +9050,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
||||
|
||||
case 'PtgNameX': /* 2.5.97.61 TODO: revisions */
|
||||
/* f[1] = type, ixti, nameindex */
|
||||
var bookidx = (f[1][1]); nameidx = f[1][2]; var externbook;
|
||||
var bookidx = (f[1][1]); nameidx = (f[1][2]); var externbook;
|
||||
/* TODO: Properly handle missing values */
|
||||
//console.log(bookidx, supbooks);
|
||||
if(opts.biff <= 5) {
|
||||
@ -10592,7 +10609,7 @@ function parse_ws_xml(data, opts, rels, wb, themes, styles) {
|
||||
var refguess = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} });
|
||||
|
||||
var data1 = "", data2 = "";
|
||||
var mtch=data.match(sheetdataregex);
|
||||
var mtch =data.match(sheetdataregex);
|
||||
if(mtch) {
|
||||
data1 = data.substr(0, mtch.index);
|
||||
data2 = data.substr(mtch.index + mtch[0].length);
|
||||
@ -11063,7 +11080,6 @@ function write_ws_xml(idx, opts, wb, rels) {
|
||||
|
||||
if(ws['!drawing'].length > 0) {
|
||||
rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW);
|
||||
ws['!drawing'].rid = rId;
|
||||
o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId});
|
||||
}
|
||||
else delete ws['!drawing'];
|
||||
@ -11464,7 +11480,7 @@ function write_BrtSheetProtection(sp, o) {
|
||||
["pivotTables", true], // fPivotTables
|
||||
["selectUnlockedCells", false] // fSelUnlockedCells
|
||||
].forEach(function(n) {
|
||||
if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0);
|
||||
if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0);
|
||||
else o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1);
|
||||
});
|
||||
return o;
|
||||
@ -11476,7 +11492,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) {
|
||||
var opts = _opts || {};
|
||||
if(!rels) rels = {'!id':{}};
|
||||
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
|
||||
var s = opts.dense ? [] : {};
|
||||
var s = (opts.dense ? [] : {});
|
||||
|
||||
var ref;
|
||||
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
|
||||
@ -11598,7 +11614,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) {
|
||||
case 0x01AA: /* 'BrtArrFmla' */
|
||||
if(!opts.cellFormula) break;
|
||||
array_formulae.push(val);
|
||||
cell = (opts.dense ? s[R][C] : s[encode_col(C) + rr]);
|
||||
cell = ((opts.dense ? s[R][C] : s[encode_col(C) + rr]));
|
||||
cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts);
|
||||
cell.F = encode_range(val[0]);
|
||||
break;
|
||||
@ -12445,7 +12461,7 @@ function parse_wb_bin(data, opts) {
|
||||
opts.biff = 12;
|
||||
|
||||
var Names = [];
|
||||
var supbooks = [];
|
||||
var supbooks = ([]);
|
||||
supbooks.SheetNames = [];
|
||||
|
||||
recordhopper(data, function hopper_wb(val, R_n, RT) {
|
||||
@ -12815,6 +12831,7 @@ function parse_xlml_data(xml, ss, data, cell, base, styles, csty, row, arrayf, o
|
||||
cell.v = xml.indexOf("<") > -1 ? unescapexml(ss) : cell.r;
|
||||
break;
|
||||
case 'DateTime':
|
||||
if(xml.slice(-1) != "Z") xml += "Z";
|
||||
cell.v = (parseDate(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
|
||||
if(cell.v !== cell.v) cell.v = unescapexml(xml);
|
||||
else if(cell.v<60) cell.v = cell.v -1;
|
||||
@ -13026,12 +13043,12 @@ for(var cma = c; cma <= cc; ++cma) {
|
||||
case 'NamedRange':
|
||||
if(!Workbook.Names) Workbook.Names = [];
|
||||
var _NamedRange = parsexmltag(Rn[0]);
|
||||
var _DefinedName = {
|
||||
var _DefinedName = ({
|
||||
Name: _NamedRange.Name,
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1))
|
||||
};
|
||||
});
|
||||
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
|
||||
Workbook.Names.push(_DefinedName);
|
||||
Workbook.Names.push(_DefinedName);
|
||||
break;
|
||||
|
||||
case 'NamedCell': break;
|
||||
@ -13835,8 +13852,9 @@ function slurp(R, blob, length, opts) {
|
||||
function safe_format_xf(p, opts, date1904) {
|
||||
if(p.t === 'z') return;
|
||||
if(!p.XF) return;
|
||||
var fmtid = 0;
|
||||
try {
|
||||
var fmtid = p.z || p.XF.ifmt || 0;
|
||||
fmtid = p.z || p.XF.ifmt || 0;
|
||||
if(opts.cellNF) p.z = SSF._table[fmtid];
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
if(!opts || opts.cellText !== false) try {
|
||||
@ -13864,7 +13882,7 @@ function parse_workbook(blob, options) {
|
||||
var wb = ({opts:{}});
|
||||
var Sheets = {};
|
||||
if(DENSE != null && options.dense == null) options.dense = DENSE;
|
||||
var out = (options.dense ? [] : {});
|
||||
var out = ((options.dense ? [] : {}));
|
||||
var Directory = {};
|
||||
var found_sheet = false;
|
||||
var range = ({});
|
||||
@ -13880,7 +13898,7 @@ function parse_workbook(blob, options) {
|
||||
var cell_valid = true;
|
||||
var XFs = []; /* XF records */
|
||||
var palette = [];
|
||||
var Workbook = { Sheets:[] }, wsprops = {};
|
||||
var Workbook = ({ Sheets:[] }), wsprops = {};
|
||||
var get_rgb = function getrgb(icv) {
|
||||
if(icv < 8) return XLSIcv[icv];
|
||||
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
||||
@ -14043,10 +14061,10 @@ function parse_workbook(blob, options) {
|
||||
break;
|
||||
case 'Index': break; // TODO
|
||||
case 'Lbl':
|
||||
last_lbl = {
|
||||
last_lbl = ({
|
||||
Name: val.Name,
|
||||
Ref: stringify_formula(val.rgce,range,null,supbooks,opts)
|
||||
};
|
||||
});
|
||||
if(val.itab > 0) last_lbl.Sheet = val.itab - 1;
|
||||
supbooks.names.push(last_lbl);
|
||||
if(!supbooks[0]) supbooks[0] = [];
|
||||
@ -14061,7 +14079,7 @@ function parse_workbook(blob, options) {
|
||||
case 'NameCmt':
|
||||
/* TODO: search for correct name */
|
||||
if(opts.biff < 8) break;
|
||||
last_lbl.Comment = val[1];
|
||||
if(last_lbl != null) last_lbl.Comment = val[1];
|
||||
break;
|
||||
|
||||
case 'Protect': out["!protect"] = val; break; /* for sheet or book */
|
||||
@ -14087,7 +14105,7 @@ function parse_workbook(blob, options) {
|
||||
Workbook.Sheets.push(wsprops);
|
||||
}
|
||||
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
|
||||
out = options.dense ? [] : {};
|
||||
out = ((options.dense ? [] : {}));
|
||||
} break;
|
||||
case 'BOF': {
|
||||
if(opts.biff !== 8){/* empty */}
|
||||
@ -14100,7 +14118,7 @@ function parse_workbook(blob, options) {
|
||||
else if(val.BIFFVer === 0x0007) opts.biff = 2;
|
||||
if(file_depth++) break;
|
||||
cell_valid = true;
|
||||
out = (options.dense ? [] : {});
|
||||
out = ((options.dense ? [] : {}));
|
||||
|
||||
if(opts.biff < 5) {
|
||||
if(cur_sheet === "") cur_sheet = "Sheet1";
|
||||
@ -14123,19 +14141,19 @@ function parse_workbook(blob, options) {
|
||||
|
||||
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
||||
if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c;
|
||||
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'};
|
||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'});
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
} break;
|
||||
case 'BoolErr': {
|
||||
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t};
|
||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t});
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
} break;
|
||||
case 'RK': {
|
||||
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'};
|
||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'});
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
@ -14143,7 +14161,7 @@ function parse_workbook(blob, options) {
|
||||
case 'MulRk': {
|
||||
for(var j = val.c; j <= val.C; ++j) {
|
||||
var ixfe = val.rkrec[j-val.c][0];
|
||||
temp_val= {ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'};
|
||||
temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'});
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:j, r:val.r}, temp_val, options);
|
||||
@ -14151,7 +14169,7 @@ function parse_workbook(blob, options) {
|
||||
} break;
|
||||
case 'Formula': {
|
||||
if(val.val == 'String') { last_formula = val; break; }
|
||||
temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt});
|
||||
temp_val = make_cell(val.val, val.cell.ixfe, val.tt);
|
||||
temp_val.XF = XFs[temp_val.ixfe];
|
||||
if(options.cellFormula) {
|
||||
var _f = val.formula;
|
||||
@ -14170,7 +14188,7 @@ function parse_workbook(blob, options) {
|
||||
case 'String': {
|
||||
if(last_formula) { /* technically always true */
|
||||
last_formula.val = val;
|
||||
temp_val = ({v:val, ixfe:last_formula.cell.ixfe, t:'s'});
|
||||
temp_val = make_cell(val, last_formula.cell.ixfe, 's');
|
||||
temp_val.XF = XFs[temp_val.ixfe];
|
||||
if(options.cellFormula) {
|
||||
temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
|
||||
@ -14211,7 +14229,7 @@ function parse_workbook(blob, options) {
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
break;
|
||||
case 'Blank': if(options.sheetStubs) {
|
||||
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'};
|
||||
temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'});
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
@ -14219,7 +14237,7 @@ function parse_workbook(blob, options) {
|
||||
case 'MulBlank': if(options.sheetStubs) {
|
||||
for(var _j = val.c; _j <= val.C; ++_j) {
|
||||
var _ixfe = val.ixfe[_j-val.c];
|
||||
temp_val= {ixfe:_ixfe, XF:XFs[_ixfe], t:'z'};
|
||||
temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'});
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:_j, r:val.r}, temp_val, options);
|
||||
@ -14310,12 +14328,7 @@ function parse_workbook(blob, options) {
|
||||
case 'TopMargin':
|
||||
case 'BottomMargin':
|
||||
if(!out['!margins']) default_margins(out['!margins'] = {});
|
||||
switch(Rn) {
|
||||
case 'LeftMargin': out['!margins'].left = val; break;
|
||||
case 'RightMargin': out['!margins'].right = val; break;
|
||||
case 'TopMargin': out['!margins'].top = val; break;
|
||||
case 'BottomMargin': out['!margins'].bottom = val; break;
|
||||
}
|
||||
out['!margins'][Rn.slice(0,-6).toLowerCase()] = val;
|
||||
break;
|
||||
|
||||
case 'Setup': // TODO
|
||||
@ -15978,7 +15991,7 @@ function write_biff_buf(wb, opts) {
|
||||
// TODO
|
||||
return ba.end();
|
||||
}
|
||||
/* TODO: in browser attach to DOM; in node use an html parser */
|
||||
/* note: browser DOM element cannot see mso- style attrs, must parse */
|
||||
var HTML_ = (function() {
|
||||
function html_to_sheet(str, _opts) {
|
||||
var opts = _opts || {};
|
||||
@ -16034,6 +16047,7 @@ var HTML_ = (function() {
|
||||
function make_html_row(ws, r, R, o) {
|
||||
var M = (ws['!merges'] ||[]);
|
||||
var oo = [];
|
||||
var nullcell = "<td" + (o.editable ? ' contenteditable="true"' : "" ) + "></td>";
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) {
|
||||
var RS = 0, CS = 0;
|
||||
for(var j = 0; j < M.length; ++j) {
|
||||
@ -16045,28 +16059,36 @@ var HTML_ = (function() {
|
||||
if(RS < 0) continue;
|
||||
var coord = encode_cell({r:R,c:C});
|
||||
var cell = o.dense ? (ws[R]||[])[C] : ws[coord];
|
||||
if(!cell || cell.v == null) { oo.push("<td></td>"); continue; }
|
||||
if(!cell || cell.v == null) { oo.push(nullcell); continue; }
|
||||
/* TODO: html entities */
|
||||
var w = cell.h || escapexml(cell.w || (format_cell(cell), cell.w) || "");
|
||||
var sp = {};
|
||||
if(RS > 1) sp.rowspan = RS;
|
||||
if(CS > 1) sp.colspan = CS;
|
||||
if(o.editable) sp.contenteditable = "true";
|
||||
oo.push(writextag('td', w, sp));
|
||||
}
|
||||
return "<tr>" + oo.join("") + "</tr>";
|
||||
}
|
||||
var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>";
|
||||
var _END = "</table></body></html>";
|
||||
function sheet_to_html(ws, opts) {
|
||||
var o = [];
|
||||
var o = opts || {};
|
||||
var out = [];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) o.push(make_html_row(ws, r, R, o));
|
||||
return "<html><body><table>" + o.join("") + "</table></body></html>";
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
var header = o.header != null ? o.header : _BEGIN;
|
||||
var footer = o.footer != null ? o.footer : _END;
|
||||
return header + out.join("") + footer ;
|
||||
}
|
||||
|
||||
return {
|
||||
to_workbook: html_to_book,
|
||||
to_sheet: html_to_sheet,
|
||||
_row: make_html_row,
|
||||
BEGIN: _BEGIN,
|
||||
END: _END,
|
||||
from_sheet: sheet_to_html
|
||||
};
|
||||
})();
|
||||
@ -16083,7 +16105,7 @@ function parse_dom_table(table, _opts) {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText;
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent;
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -16092,7 +16114,14 @@ function parse_dom_table(table, _opts) {
|
||||
CS = +elt.getAttribute("colspan") || 1;
|
||||
if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
var o = {t:'s', v:v};
|
||||
if(v != null && v.length && !isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
if(v != null && v.length) {
|
||||
if(!isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
else if(!isNaN(fuzzydate(v).getDate())) {
|
||||
o = ({t:'d', v:parseDate(v)});
|
||||
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
|
||||
o.z = opts.dateNF || SSF._table[14];
|
||||
}
|
||||
}
|
||||
if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; }
|
||||
else ws[encode_cell({c:C, r:R})] = o;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
@ -16998,8 +17027,7 @@ function parse_xlsxcfb(cfb, opts) {
|
||||
data = cfb.find(f);
|
||||
if(!data) throw new Error("ECMA-376 Encrypted file missing " + f);
|
||||
var dsm = parse_DataSpaceMap(data.content);
|
||||
if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 ||
|
||||
dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage")
|
||||
if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage")
|
||||
throw new Error("ECMA-376 Encrypted file bad " + f);
|
||||
|
||||
f = 'StrongEncryptionDataSpace';
|
||||
@ -17509,6 +17537,7 @@ function sheet_to_formulae(sheet) {
|
||||
function json_to_sheet(js, opts) {
|
||||
var o = opts || {};
|
||||
var ws = ({});
|
||||
var cell;
|
||||
var range = ({s: {c:0, r:0}, e: {c:0, r:js.length}});
|
||||
var hdr = o.header || [], C = 0;
|
||||
|
||||
@ -17517,11 +17546,17 @@ function json_to_sheet(js, opts) {
|
||||
if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
|
||||
var v = js[R][k];
|
||||
var t = 'z';
|
||||
var z = "";
|
||||
if(typeof v == 'number') t = 'n';
|
||||
else if(typeof v == 'boolean') t = 'b';
|
||||
else if(typeof v == 'string') t = 's';
|
||||
else if(v instanceof Date) t = 'd';
|
||||
ws[encode_cell({c:C,r:R+1})] = {t:t, v:v};
|
||||
else if(v instanceof Date) {
|
||||
t = 'd';
|
||||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v});
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
}
|
||||
range.e.c = hdr.length - 1;
|
||||
@ -17551,13 +17586,14 @@ var utils = {
|
||||
table_to_book: table_to_book,
|
||||
sheet_to_csv: sheet_to_csv,
|
||||
sheet_to_json: sheet_to_json,
|
||||
sheet_to_html: HTML_.from_sheet,
|
||||
sheet_to_formulae: sheet_to_formulae,
|
||||
sheet_to_row_object_array: sheet_to_json
|
||||
};
|
||||
|
||||
(function(utils) {
|
||||
utils.consts = utils.consts || {};
|
||||
function add_consts(R) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); }
|
||||
function add_consts(R/*Array<any>*/) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); }
|
||||
|
||||
function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); }
|
||||
|
||||
@ -17568,7 +17604,7 @@ function ws_get_cell_stub(ws, R, C) {
|
||||
/* cell address object */
|
||||
if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R));
|
||||
/* R and C are 0-based indices */
|
||||
return ws_get_cell_stub(ws, encode_cell({r:R,c:C}));
|
||||
return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0}));
|
||||
}
|
||||
|
||||
/* find sheet index for given name / validate index */
|
||||
@ -17590,7 +17626,8 @@ utils.book_new = function() {
|
||||
|
||||
/* add a worksheet to the end of a given workbook */
|
||||
utils.book_append_sheet = function(wb, ws, name) {
|
||||
if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf("Sheet" + i) == -1) break;
|
||||
if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break;
|
||||
if(!name) throw new Error("Too many worksheets");
|
||||
check_ws_name(name);
|
||||
if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!");
|
||||
|
||||
@ -17604,12 +17641,14 @@ utils.book_set_sheet_visibility = function(wb, sh, vis) {
|
||||
get_default(wb.Workbook,"Sheets",[]);
|
||||
|
||||
var idx = wb_sheet_idx(wb, sh);
|
||||
// $FlowIgnore
|
||||
get_default(wb.Workbook.Sheets,idx, {});
|
||||
|
||||
switch(vis) {
|
||||
case 0: case 1: case 2: break;
|
||||
default: throw new Error("Bad sheet visibility setting " + vis);
|
||||
}
|
||||
// $FlowIgnore
|
||||
wb.Workbook.Sheets[idx].Hidden = vis;
|
||||
};
|
||||
add_consts([
|
||||
@ -17629,7 +17668,7 @@ utils.cell_set_hyperlink = function(cell, target, tooltip) {
|
||||
if(!target) {
|
||||
delete cell.l;
|
||||
} else {
|
||||
cell.l = { Target: target };
|
||||
cell.l = ({ Target: target });
|
||||
if(tooltip) cell.l.Tooltip = tooltip;
|
||||
}
|
||||
return cell;
|
||||
@ -17678,32 +17717,30 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
if(R > r.e.r) return stream.push(null);
|
||||
while(R <= r.e.r) {
|
||||
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
|
||||
if(row == null) { ++R; continue; }
|
||||
if(o.strip) row = row.replace(endregex,"");
|
||||
stream.push(row + RS);
|
||||
++R;
|
||||
break;
|
||||
if(row != null) {
|
||||
if(o.strip) row = row.replace(endregex,"");
|
||||
stream.push(row + RS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
return stream;
|
||||
};
|
||||
|
||||
var HTML_BEGIN = "<html><body><table>";
|
||||
var HTML_END = "</table></body></html>";
|
||||
|
||||
var write_html_stream = function(sheet, opts) {
|
||||
var stream = Readable();
|
||||
|
||||
var o = [];
|
||||
var o = opts == null ? {} : opts;
|
||||
var r = decode_range(sheet['!ref']), cell;
|
||||
o.dense = Array.isArray(sheet);
|
||||
stream.push(HTML_BEGIN);
|
||||
stream.push(HTML_.BEGIN);
|
||||
|
||||
var R = r.s.r;
|
||||
var end = false;
|
||||
stream._read = function() {
|
||||
if(R > r.e.r) {
|
||||
if(!end) { end = true; stream.push(HTML_END); }
|
||||
if(!end) { end = true; stream.push(HTML_.END); }
|
||||
return stream.push(null);
|
||||
}
|
||||
while(R <= r.e.r) {
|
||||
@ -17734,7 +17771,6 @@ XLSX.writeFile = writeFileSync;
|
||||
XLSX.writeFileSync = writeFileSync;
|
||||
XLSX.writeFileAsync = writeFileAsync;
|
||||
XLSX.utils = utils;
|
||||
XLSX.CFB = CFB;
|
||||
XLSX.SSF = SSF;
|
||||
})(typeof exports !== 'undefined' ? exports : XLSX);
|
||||
/*exported XLS */
|
||||
|
28
dist/xlsx.min.js
vendored
28
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
@ -30,8 +30,10 @@ merge_cells .xls .xlsb .xlsx .xls.xml
|
||||
named_ranges_2011 .xls .xlsb .xlsx .xls.xml
|
||||
# yes-formula
|
||||
# no-csv (macro serialization in xml)
|
||||
# no-formula (rounding issue in IE8)
|
||||
#number_format .xls .xlsb .xlsm .xls.xml .xlsb.xml .xlsm.xml
|
||||
number_format .xls .xlsb .xlsm .xls.xml
|
||||
# yes-formula
|
||||
# yes-csv
|
||||
number_format_entities .xls .xlsb .xlsx .xml
|
||||
pivot_table_named_range .xls .xlsb .xlsx .xml
|
||||
@ -43,4 +45,5 @@ sushi .xls .xlsb .xlsx .xml
|
||||
text_and_numbers .xls .xlsb .xlsx .xml
|
||||
#time_stress_test_1 .xls .xlsb .xlsx .xml
|
||||
#xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
|
||||
# no-formula (rounding issue in IE8)
|
||||
xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.10.1",
|
||||
"version": "0.10.2",
|
||||
"author": "sheetjs",
|
||||
"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS (ODS/FODS/UOS) spreadsheet parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "office", "spreadsheet" ],
|
||||
"description": "Excel (XLSB/XLSX/XLS/XML) ODS and other spreadsheet format (CSV/DIF/DBF/SYLK) parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "csv", "dbf", "dif", "sylk", "office", "spreadsheet" ],
|
||||
"bin": {
|
||||
"xlsx": "./bin/xlsx.njs"
|
||||
},
|
||||
@ -18,7 +18,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"exit-on-epipe":"~1.0.0",
|
||||
"ssf":"~0.9.2",
|
||||
"ssf":"~0.9.3",
|
||||
"codepage":"~1.8.0",
|
||||
"cfb":"~0.11.1",
|
||||
"crc-32":"~1.0.2",
|
||||
|
9
test.js
9
test.js
@ -1431,7 +1431,7 @@ describe('roundtrip features', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should preserve js objects', function() {
|
||||
it('should preserve JS objects', function() {
|
||||
var data = [
|
||||
{a:1},
|
||||
{b:2,c:3},
|
||||
@ -1439,7 +1439,7 @@ describe('roundtrip features', function() {
|
||||
{a:true, c:false},
|
||||
{c:new Date("2017-02-19T14:30Z")}
|
||||
];
|
||||
var wb = X.utils.json_to_sheet(data);
|
||||
var wb = X.utils.json_to_sheet(data, {cellDates:true});
|
||||
var out = X.utils.sheet_to_json(wb, {raw:true});
|
||||
data.forEach(function(row, i) {
|
||||
Object.keys(row).forEach(function(k) { assert.equal(row[k], out[i][k]); });
|
||||
@ -1679,7 +1679,8 @@ describe('csv', function() {
|
||||
it('should honor dateNF override', function() {
|
||||
var opts = {type:"binary", dateNF:"YYYY-MM-DD"};
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '2014-02-19');
|
||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||
assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '14-02-19');
|
||||
@ -1868,7 +1869,7 @@ var mfopts = opts;
|
||||
var mft = fs.readFileSync('multiformat.lst','utf-8').split("\n").map(function(x) { return x.trim(); });
|
||||
var csv = true, formulae = false;
|
||||
mft.forEach(function(x) {
|
||||
if(x[0]!="#") describe('MFT ' + x, function() {
|
||||
if(x.charAt(0)!="#") describe('MFT ' + x, function() {
|
||||
var fil = {}, f = [], r = x.split(/\s+/);
|
||||
if(r.length < 3) return;
|
||||
it('should parse all', function() {
|
||||
|
@ -637,6 +637,23 @@ describe('output formats', function() {
|
||||
});
|
||||
});
|
||||
|
||||
function eqarr(a,b) {
|
||||
assert.equal(a.length, b.length);
|
||||
a.forEach(function(x, i) { assert.equal(x, b[i]); });
|
||||
}
|
||||
|
||||
describe('API', function() {
|
||||
it('book_append_sheet', function() {
|
||||
var wb = X.utils.book_new();
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]), "A");
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]), "B");
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
|
||||
eqarr(wb.SheetNames, ["A","Sheet1","Sheet2","B","Sheet3"]);
|
||||
});
|
||||
});
|
||||
|
||||
function coreprop(wb) {
|
||||
assert.equal(wb.Props.Title, 'Example with properties');
|
||||
assert.equal(wb.Props.Subject, 'Test it before you code it');
|
||||
@ -1408,15 +1425,15 @@ describe('roundtrip features', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should preserve js objects', function() {
|
||||
it('should preserve JS objects', function() {
|
||||
var data = [
|
||||
{a:1},
|
||||
{b:2,c:3},
|
||||
{b:"a",d:"b"},
|
||||
{a:true, c:false},
|
||||
{c:new Date("2017-02-19T14:30Z")}
|
||||
{c:parseDate("2017-02-19T14:30:00.000Z")}
|
||||
];
|
||||
var wb = X.utils.json_to_sheet(data);
|
||||
var wb = X.utils.json_to_sheet(data, {cellDates:true});
|
||||
var out = X.utils.sheet_to_json(wb, {raw:true});
|
||||
data.forEach(function(row, i) {
|
||||
Object.keys(row).forEach(function(k) { assert.equal(row[k], out[i][k]); });
|
||||
@ -1485,14 +1502,22 @@ function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
|
||||
return (epoch + 2209161600000) / (24 * 60 * 60 * 1000);
|
||||
}
|
||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
||||
function parseDate(str/*:string|Date*/)/*:Date*/ {
|
||||
if(good_pd) return new Date(str);
|
||||
var d = new Date(str);
|
||||
if(good_pd) return d;
|
||||
if(str instanceof Date) return str;
|
||||
var n = str.match(/\d+/g);
|
||||
return new Date(Date.UTC(+n[0], n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
||||
var s = d.getFullYear();
|
||||
if(str.indexOf("" + s) > -1) return d;
|
||||
d.setFullYear(d.getFullYear() + 100); return d;
|
||||
}
|
||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
||||
}
|
||||
|
||||
|
||||
describe('json output', function() {
|
||||
function seeker(json, keys, val) {
|
||||
for(var i = 0; i != json.length; ++i) {
|
||||
@ -1664,7 +1689,8 @@ describe('csv', function() {
|
||||
it('should honor dateNF override', function() {
|
||||
var opts = {type:"binary", dateNF:"YYYY-MM-DD"};
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '2014-02-19');
|
||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||
assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '14-02-19');
|
||||
@ -1677,7 +1703,7 @@ describe('csv', function() {
|
||||
data = [
|
||||
[1,2,3,null],
|
||||
[true, false, null, "sheetjs"],
|
||||
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
|
||||
["foo", "bar", parseDate("2014-02-19T14:30:00.000Z"), "0.3"],
|
||||
[null, null, null],
|
||||
["baz", undefined, "qux"]
|
||||
];
|
||||
@ -1817,10 +1843,6 @@ describe('corner cases', function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
it.skip('CFB', function() {
|
||||
var cfb = X.CFB.read(paths.swcxls, {type:"file"});
|
||||
var xls = X.parse_xlscfb(cfb);
|
||||
});
|
||||
it('codepage', function() {
|
||||
X.read(fs.readFileSync(dir + "biff5/number_format_greek.xls"), {type:"binary"});
|
||||
});
|
||||
|
File diff suppressed because one or more lines are too long
56
xlsx.flow.js
56
xlsx.flow.js
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.10.1';
|
||||
XLSX.version = '0.10.2';
|
||||
var current_codepage = 1200;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
@ -1481,12 +1481,19 @@ function parse_isodur(s) {
|
||||
}
|
||||
|
||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
||||
function parseDate(str/*:string|Date*/)/*:Date*/ {
|
||||
if(good_pd) return new Date(str);
|
||||
var d = new Date(str);
|
||||
if(good_pd) return d;
|
||||
if(str instanceof Date) return str;
|
||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
||||
var s = d.getFullYear();
|
||||
if(str.indexOf("" + s) > -1) return d;
|
||||
d.setFullYear(d.getFullYear() + 100); return d;
|
||||
}
|
||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0)));
|
||||
}
|
||||
|
||||
function cc2str(arr/*:Array<number>*/)/*:string*/ {
|
||||
@ -5373,6 +5380,8 @@ var SYLK = (function() {
|
||||
else if(+val === +val) {
|
||||
val = +val;
|
||||
if(next_cell_format !== null && SSF.is_date(next_cell_format)) val = numdate(val);
|
||||
} else if(!isNaN(fuzzydate(val).getDate())) {
|
||||
val = parseDate(val);
|
||||
}
|
||||
arr[R][C] = val;
|
||||
next_cell_format = null;
|
||||
@ -5390,7 +5399,7 @@ var SYLK = (function() {
|
||||
case 'Y':
|
||||
R = parseInt(record[rj].substr(1))-1; /*C = 0;*/
|
||||
for(j = arr.length; j <= R; ++j) arr[j] = [];
|
||||
++F_seen; break;
|
||||
break;
|
||||
case 'M': Mval = parseInt(record[rj].substr(1)) / 20; break;
|
||||
case 'F': break; /* ??? */
|
||||
case 'P':
|
||||
@ -5417,7 +5426,7 @@ var SYLK = (function() {
|
||||
break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(F_seen < 2) next_cell_format = null; break;
|
||||
if(F_seen < 1) next_cell_format = null; break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
}
|
||||
@ -5616,6 +5625,7 @@ var PRN = (function() {
|
||||
else if(data === 'FALSE') arr[R][C] = false;
|
||||
else if(data === ""){/* empty */}
|
||||
else if(+data == +data) arr[R][C] = +data;
|
||||
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
|
||||
else arr[R][C] = data;
|
||||
}
|
||||
|
||||
@ -5805,11 +5815,15 @@ var WK_ = (function() {
|
||||
case 0x0E: /* NUMBER */
|
||||
case 0x10: /* FORMULA */
|
||||
case 0x33: /* STRING */
|
||||
/* TODO: actual translation of the format code */
|
||||
if(RT == 0x0E && (val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
|
||||
val[1].z = o.dateNF || SSF._table[14];
|
||||
if(o.cellDates) { val[1].t = 'd'; val[1].v = numdate(val[1].v); }
|
||||
}
|
||||
if(o.dense) {
|
||||
if(!s[val[0].r]) s[val[0].r] = [];
|
||||
s[val[0].r][val[0].c] = val[1];
|
||||
} else s[encode_cell(val[0])] = val[1];
|
||||
/* TODO: FORMAT */
|
||||
break;
|
||||
} else switch(RT) {
|
||||
case 0x16: /* LABEL16 */
|
||||
@ -5978,7 +5992,7 @@ var WK_ = (function() {
|
||||
var WK1Enum = {
|
||||
/*::[*/0x0000/*::]*/: { n:"BOF", f:parseuint16 },
|
||||
/*::[*/0x0001/*::]*/: { n:"EOF", f:parsenoop },
|
||||
/*::[*/0x0002/*::]*/: { n: "CALCMODE", f:parsenoop },
|
||||
/*::[*/0x0002/*::]*/: { n:"CALCMODE", f:parsenoop },
|
||||
/*::[*/0x0003/*::]*/: { n:"CALCORDER", f:parsenoop },
|
||||
/*::[*/0x0004/*::]*/: { n:"SPLIT", f:parsenoop },
|
||||
/*::[*/0x0005/*::]*/: { n:"SYNC", f:parsenoop },
|
||||
@ -12885,6 +12899,7 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
|
||||
cell.v = xml.indexOf("<") > -1 ? unescapexml(ss) : cell.r;
|
||||
break;
|
||||
case 'DateTime':
|
||||
if(xml.slice(-1) != "Z") xml += "Z";
|
||||
cell.v = (parseDate(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
|
||||
if(cell.v !== cell.v) cell.v = unescapexml(xml);
|
||||
else if(cell.v<60) cell.v = cell.v -1;
|
||||
@ -16046,7 +16061,7 @@ function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
// TODO
|
||||
return ba.end();
|
||||
}
|
||||
/* TODO: in browser attach to DOM; in node use an html parser */
|
||||
/* note: browser DOM element cannot see mso- style attrs, must parse */
|
||||
var HTML_ = (function() {
|
||||
function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
|
||||
var opts = _opts || {};
|
||||
@ -16160,7 +16175,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText;
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent;
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -16168,8 +16183,15 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
/* TODO: figure out how to extract nonstandard mso- style */
|
||||
CS = +elt.getAttribute("colspan") || 1;
|
||||
if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
var o = {t:'s', v:v};
|
||||
if(v != null && v.length && !isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
var o/*:Cell*/ = {t:'s', v:v};
|
||||
if(v != null && v.length) {
|
||||
if(!isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
else if(!isNaN(fuzzydate(v).getDate())) {
|
||||
o = ({t:'d', v:parseDate(v)}/*:any*/);
|
||||
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
|
||||
o.z = opts.dateNF || SSF._table[14];
|
||||
}
|
||||
}
|
||||
if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; }
|
||||
else ws[encode_cell({c:C, r:R})] = o;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
@ -17589,6 +17611,7 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
|
||||
function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
var o = opts || {};
|
||||
var ws = ({}/*:any*/);
|
||||
var cell/*:Cell*/;
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:js.length}}/*:any*/);
|
||||
var hdr = o.header || [], C = 0;
|
||||
|
||||
@ -17597,11 +17620,17 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
|
||||
var v = js[R][k];
|
||||
var t = 'z';
|
||||
var z = "";
|
||||
if(typeof v == 'number') t = 'n';
|
||||
else if(typeof v == 'boolean') t = 'b';
|
||||
else if(typeof v == 'string') t = 's';
|
||||
else if(v instanceof Date) t = 'd';
|
||||
ws[encode_cell({c:C,r:R+1})] = {t:t, v:v};
|
||||
else if(v instanceof Date) {
|
||||
t = 'd';
|
||||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v}/*:any*/);
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
}
|
||||
range.e.c = hdr.length - 1;
|
||||
@ -17816,7 +17845,6 @@ XLSX.writeFile = writeFileSync;
|
||||
XLSX.writeFileSync = writeFileSync;
|
||||
XLSX.writeFileAsync = writeFileAsync;
|
||||
XLSX.utils = utils;
|
||||
XLSX.CFB = CFB;
|
||||
XLSX.SSF = SSF;
|
||||
})(typeof exports !== 'undefined' ? exports : XLSX);
|
||||
/*exported XLS */
|
||||
|
54
xlsx.js
54
xlsx.js
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.10.1';
|
||||
XLSX.version = '0.10.2';
|
||||
var current_codepage = 1200;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -1431,12 +1431,19 @@ function parse_isodur(s) {
|
||||
}
|
||||
|
||||
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
|
||||
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
|
||||
var good_pd = good_pd_date.getFullYear() == 2017;
|
||||
function parseDate(str) {
|
||||
if(good_pd) return new Date(str);
|
||||
var d = new Date(str);
|
||||
if(good_pd) return d;
|
||||
if(str instanceof Date) return str;
|
||||
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
|
||||
var s = d.getFullYear();
|
||||
if(str.indexOf("" + s) > -1) return d;
|
||||
d.setFullYear(d.getFullYear() + 100); return d;
|
||||
}
|
||||
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
|
||||
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0)));
|
||||
}
|
||||
|
||||
function cc2str(arr) {
|
||||
@ -5312,6 +5319,8 @@ var SYLK = (function() {
|
||||
else if(+val === +val) {
|
||||
val = +val;
|
||||
if(next_cell_format !== null && SSF.is_date(next_cell_format)) val = numdate(val);
|
||||
} else if(!isNaN(fuzzydate(val).getDate())) {
|
||||
val = parseDate(val);
|
||||
}
|
||||
arr[R][C] = val;
|
||||
next_cell_format = null;
|
||||
@ -5329,7 +5338,7 @@ var SYLK = (function() {
|
||||
case 'Y':
|
||||
R = parseInt(record[rj].substr(1))-1; /*C = 0;*/
|
||||
for(j = arr.length; j <= R; ++j) arr[j] = [];
|
||||
++F_seen; break;
|
||||
break;
|
||||
case 'M': Mval = parseInt(record[rj].substr(1)) / 20; break;
|
||||
case 'F': break; /* ??? */
|
||||
case 'P':
|
||||
@ -5356,7 +5365,7 @@ var SYLK = (function() {
|
||||
break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(F_seen < 2) next_cell_format = null; break;
|
||||
if(F_seen < 1) next_cell_format = null; break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
}
|
||||
@ -5555,6 +5564,7 @@ var PRN = (function() {
|
||||
else if(data === 'FALSE') arr[R][C] = false;
|
||||
else if(data === ""){/* empty */}
|
||||
else if(+data == +data) arr[R][C] = +data;
|
||||
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
|
||||
else arr[R][C] = data;
|
||||
}
|
||||
|
||||
@ -5744,11 +5754,15 @@ var WK_ = (function() {
|
||||
case 0x0E: /* NUMBER */
|
||||
case 0x10: /* FORMULA */
|
||||
case 0x33: /* STRING */
|
||||
/* TODO: actual translation of the format code */
|
||||
if(RT == 0x0E && (val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
|
||||
val[1].z = o.dateNF || SSF._table[14];
|
||||
if(o.cellDates) { val[1].t = 'd'; val[1].v = numdate(val[1].v); }
|
||||
}
|
||||
if(o.dense) {
|
||||
if(!s[val[0].r]) s[val[0].r] = [];
|
||||
s[val[0].r][val[0].c] = val[1];
|
||||
} else s[encode_cell(val[0])] = val[1];
|
||||
/* TODO: FORMAT */
|
||||
break;
|
||||
} else switch(RT) {
|
||||
case 0x16: /* LABEL16 */
|
||||
@ -5917,7 +5931,7 @@ var WK_ = (function() {
|
||||
var WK1Enum = {
|
||||
0x0000: { n:"BOF", f:parseuint16 },
|
||||
0x0001: { n:"EOF", f:parsenoop },
|
||||
0x0002: { n: "CALCMODE", f:parsenoop },
|
||||
0x0002: { n:"CALCMODE", f:parsenoop },
|
||||
0x0003: { n:"CALCORDER", f:parsenoop },
|
||||
0x0004: { n:"SPLIT", f:parsenoop },
|
||||
0x0005: { n:"SYNC", f:parsenoop },
|
||||
@ -12817,6 +12831,7 @@ function parse_xlml_data(xml, ss, data, cell, base, styles, csty, row, arrayf, o
|
||||
cell.v = xml.indexOf("<") > -1 ? unescapexml(ss) : cell.r;
|
||||
break;
|
||||
case 'DateTime':
|
||||
if(xml.slice(-1) != "Z") xml += "Z";
|
||||
cell.v = (parseDate(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
|
||||
if(cell.v !== cell.v) cell.v = unescapexml(xml);
|
||||
else if(cell.v<60) cell.v = cell.v -1;
|
||||
@ -15976,7 +15991,7 @@ function write_biff_buf(wb, opts) {
|
||||
// TODO
|
||||
return ba.end();
|
||||
}
|
||||
/* TODO: in browser attach to DOM; in node use an html parser */
|
||||
/* note: browser DOM element cannot see mso- style attrs, must parse */
|
||||
var HTML_ = (function() {
|
||||
function html_to_sheet(str, _opts) {
|
||||
var opts = _opts || {};
|
||||
@ -16090,7 +16105,7 @@ function parse_dom_table(table, _opts) {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText;
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent;
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -16099,7 +16114,14 @@ function parse_dom_table(table, _opts) {
|
||||
CS = +elt.getAttribute("colspan") || 1;
|
||||
if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
var o = {t:'s', v:v};
|
||||
if(v != null && v.length && !isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
if(v != null && v.length) {
|
||||
if(!isNaN(Number(v))) o = {t:'n', v:Number(v)};
|
||||
else if(!isNaN(fuzzydate(v).getDate())) {
|
||||
o = ({t:'d', v:parseDate(v)});
|
||||
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
|
||||
o.z = opts.dateNF || SSF._table[14];
|
||||
}
|
||||
}
|
||||
if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; }
|
||||
else ws[encode_cell({c:C, r:R})] = o;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
@ -17515,6 +17537,7 @@ function sheet_to_formulae(sheet) {
|
||||
function json_to_sheet(js, opts) {
|
||||
var o = opts || {};
|
||||
var ws = ({});
|
||||
var cell;
|
||||
var range = ({s: {c:0, r:0}, e: {c:0, r:js.length}});
|
||||
var hdr = o.header || [], C = 0;
|
||||
|
||||
@ -17523,11 +17546,17 @@ function json_to_sheet(js, opts) {
|
||||
if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
|
||||
var v = js[R][k];
|
||||
var t = 'z';
|
||||
var z = "";
|
||||
if(typeof v == 'number') t = 'n';
|
||||
else if(typeof v == 'boolean') t = 'b';
|
||||
else if(typeof v == 'string') t = 's';
|
||||
else if(v instanceof Date) t = 'd';
|
||||
ws[encode_cell({c:C,r:R+1})] = {t:t, v:v};
|
||||
else if(v instanceof Date) {
|
||||
t = 'd';
|
||||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v});
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
}
|
||||
range.e.c = hdr.length - 1;
|
||||
@ -17742,7 +17771,6 @@ XLSX.writeFile = writeFileSync;
|
||||
XLSX.writeFileSync = writeFileSync;
|
||||
XLSX.writeFileAsync = writeFileAsync;
|
||||
XLSX.utils = utils;
|
||||
XLSX.CFB = CFB;
|
||||
XLSX.SSF = SSF;
|
||||
})(typeof exports !== 'undefined' ? exports : XLSX);
|
||||
/*exported XLS */
|
||||
|
Loading…
Reference in New Issue
Block a user