forked from sheetjs/sheetjs
updating to 0.5.4
This commit is contained in:
parent
36ba3bfbb2
commit
358b221295
294
xlsx.js
294
xlsx.js
@ -9,7 +9,7 @@ var _strrev = function(x) { return String(x).split("").reverse().join("");};
|
||||
function fill(c,l) { return new Array(l+1).join(c); }
|
||||
function pad(v,d,c){var t=String(v);return t.length>=d?t:(fill(c||0,d-t.length)+t);}
|
||||
function rpad(v,d,c){var t=String(v);return t.length>=d?t:(t+fill(c||0,d-t.length));}
|
||||
SSF.version = '0.5.4';
|
||||
SSF.version = '0.5.7';
|
||||
/* Options */
|
||||
var opts_fmt = {};
|
||||
function fixopts(o){for(var y in opts_fmt) if(o[y]===undefined) o[y]=opts_fmt[y];}
|
||||
@ -150,23 +150,20 @@ var write_date = function(type, fmt, val) {
|
||||
switch(type) {
|
||||
case 'y': switch(fmt) { /* year */
|
||||
case 'y': case 'yy': return pad(val.y % 100,2);
|
||||
case 'yyy': case 'yyyy': return pad(val.y % 10000,4);
|
||||
default: throw 'bad year format: ' + fmt;
|
||||
default: return pad(val.y % 10000,4);
|
||||
}
|
||||
case 'm': switch(fmt) { /* month */
|
||||
case 'm': return val.m;
|
||||
case 'mm': return pad(val.m,2);
|
||||
case 'mmm': return months[val.m-1][1];
|
||||
case 'mmmm': return months[val.m-1][2];
|
||||
case 'mmmmm': return months[val.m-1][0];
|
||||
default: throw 'bad month format: ' + fmt;
|
||||
default: return months[val.m-1][2];
|
||||
}
|
||||
case 'd': switch(fmt) { /* day */
|
||||
case 'd': return val.d;
|
||||
case 'dd': return pad(val.d,2);
|
||||
case 'ddd': return days[val.q][0];
|
||||
case 'dddd': return days[val.q][1];
|
||||
default: throw 'bad day format: ' + fmt;
|
||||
default: return days[val.q][1];
|
||||
}
|
||||
case 'h': switch(fmt) { /* 12-hour */
|
||||
case 'h': return 1+(val.H+11)%12;
|
||||
@ -199,7 +196,6 @@ var write_date = function(type, fmt, val) {
|
||||
} return fmt.length === 3 ? o : pad(o, 2);
|
||||
/* TODO: handle the ECMA spec format ee -> yy */
|
||||
case 'e': { return val.y; } break;
|
||||
default: throw 'bad format type ' + type + ' in ' + fmt;
|
||||
}
|
||||
};
|
||||
/*jshint +W086 */
|
||||
@ -215,14 +211,20 @@ var write_num = function(type, fmt, val) {
|
||||
if(mul !== 0) return write_num(type, fmt, val * Math.pow(10,2*mul)) + fill("%",mul);
|
||||
if(fmt.indexOf("E") > -1) {
|
||||
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
|
||||
if(fmt == '##0.0E+0') {
|
||||
var period = fmt.length - 5;
|
||||
if(fmt.match(/^#+0.0E\+0$/)) {
|
||||
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
|
||||
var ee = (Number(val.toExponential(0).substr(2+(val<0))))%period;
|
||||
if(ee < 0) ee += period;
|
||||
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
|
||||
if(!o.match(/[Ee]/)) {
|
||||
var fakee = (Number(val.toExponential(0).substr(2+(val<0))));
|
||||
if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
|
||||
else throw "missing E |" + o;
|
||||
else o += "E+" + (fakee - ee);
|
||||
while(o.substr(0,2) === "0.") {
|
||||
o = o[0] + o.substr(2,period) + "." + o.substr(2+period);
|
||||
o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");
|
||||
}
|
||||
o = o.replace(/\+-/,"-");
|
||||
}
|
||||
o = o.replace(/^([+-]?)([0-9]*)\.([0-9]*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
|
||||
} else o = val.toExponential(idx);
|
||||
@ -237,6 +239,7 @@ var write_num = function(type, fmt, val) {
|
||||
var myn = (rnd - base*den), myd = den;
|
||||
return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad(myn,r[1].length," ") + r[2] + "/" + r[3] + pad(myd,r[4].length));
|
||||
}
|
||||
if(fmt.match(/^#+0+$/)) fmt = fmt.replace(/#/g,"");
|
||||
if(fmt.match(/^00+$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length);
|
||||
if(fmt.match(/^[#?]+$/)) return String(Math.round(val)).replace(/^0$/,"");
|
||||
if((r = fmt.match(/^#*0+\.(0+)/))) {
|
||||
@ -326,7 +329,8 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
out.push(q); lst = c; break;
|
||||
case '[': /* TODO: Fix this -- ignore all conditionals and formatting */
|
||||
o = c;
|
||||
while(fmt[i++] !== ']') o += fmt[i];
|
||||
while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
|
||||
if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.match(/\[[HhMmSs]*\]/)) {
|
||||
if(!dt) dt = parse_date_code(v, opts);
|
||||
if(!dt) return "";
|
||||
@ -347,7 +351,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
out.push({t:'D', v:o}); break;
|
||||
case ' ': out.push({t:c,v:c}); ++i; break;
|
||||
default:
|
||||
if(",$-+/():!^&'~{}<>=".indexOf(c) === -1)
|
||||
if(",$-+/():!^&'~{}<>=€".indexOf(c) === -1)
|
||||
throw 'unrecognized character ' + fmt[i] + ' in ' + fmt;
|
||||
out.push({t:'t', v:c}); ++i; break;
|
||||
}
|
||||
@ -365,21 +369,20 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
/* replace fields */
|
||||
for(i=0; i < out.length; ++i) {
|
||||
switch(out[i].t) {
|
||||
case 't': case 'T': case ' ': break;
|
||||
case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'A': case 'e': case 'Z':
|
||||
case 't': case 'T': case ' ': case 'D': break;
|
||||
case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'Z':
|
||||
out[i].v = write_date(out[i].t, out[i].v, dt);
|
||||
out[i].t = 't'; break;
|
||||
case 'n': case '(': case '?':
|
||||
var jj = i+1;
|
||||
while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
|
||||
while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || '$€'.indexOf(out[jj].v) > -1 || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
|
||||
out[i].v += out[jj].v;
|
||||
delete out[jj]; ++jj;
|
||||
}
|
||||
out[i].v = write_num(out[i].t, out[i].v, v);
|
||||
out[i].v = write_num(out[i].t, out[i].v, (flen >1 && v < 0 && i>0 && out[i-1].v == "-" ? -v:v));
|
||||
out[i].t = 't';
|
||||
i = jj-1; break;
|
||||
case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break;
|
||||
default: console.error(out); throw "unrecognized type " + out[i].t;
|
||||
}
|
||||
}
|
||||
return out.map(function(x){return x.v;}).join("");
|
||||
@ -389,6 +392,7 @@ function choose_fmt(fmt, v, o) {
|
||||
if(typeof fmt === 'number') fmt = ((o&&o.table) ? o.table : table_fmt)[fmt];
|
||||
if(typeof fmt === "string") fmt = split_fmt(fmt);
|
||||
var l = fmt.length;
|
||||
if(l<4 && fmt[l-1].indexOf("@")>-1) --l;
|
||||
switch(fmt.length) {
|
||||
case 1: fmt = fmt[0].indexOf("@")>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
|
||||
case 2: fmt = fmt[1].indexOf("@")>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
|
||||
@ -420,7 +424,7 @@ SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.loa
|
||||
make_ssf(SSF);
|
||||
var XLSX = {};
|
||||
(function(XLSX){
|
||||
XLSX.version = '0.5.2';
|
||||
XLSX.version = '0.5.4';
|
||||
var current_codepage, current_cptable, cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('codepage');
|
||||
@ -560,40 +564,9 @@ function readIEEE754(buf, idx, isLE, nl, ml) {
|
||||
return (s ? -1 : 1) * m * Math.pow(2, e - ml);
|
||||
}
|
||||
|
||||
function s2a(s) {
|
||||
if(typeof Buffer !== 'undefined') return new Buffer(s, "binary");
|
||||
var w = s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
|
||||
return w;
|
||||
}
|
||||
|
||||
var __toBuffer;
|
||||
if(typeof Buffer !== "undefined") {
|
||||
Buffer.prototype.hexlify= function() { return this.toString('hex'); };
|
||||
Buffer.prototype.utf16le= function(s,e){return this.toString('utf16le',s,e).replace(/\u0000/,'').replace(/[\u0001-\u0006]/,'!');};
|
||||
Buffer.prototype.utf8 = function(s,e) { return this.toString('utf8',s,e); };
|
||||
Buffer.prototype.lpstr = function(i) { var len = this.readUInt32LE(i); return len > 0 ? this.utf8(i+4,i+4+len-1) : "";};
|
||||
Buffer.prototype.lpwstr = function(i) { var len = 2*this.readUInt32LE(i); return this.utf8(i+4,i+4+len-1);};
|
||||
if(typeof cptable !== "undefined") Buffer.prototype.lpstr = function(i) {
|
||||
var len = this.readUInt32LE(i);
|
||||
if(len === 0) return "";
|
||||
if(typeof current_cptable === "undefined") return this.utf8(i+4,i+4+len-1);
|
||||
var t = Array(this.slice(i+4,i+4+len-1));
|
||||
//1console.log("start", this.l, len, t);
|
||||
var c, j = i+4, o = "", cc;
|
||||
for(;j!=i+4+len;++j) {
|
||||
c = this.readUInt8(j);
|
||||
cc = current_cptable.dec[c];
|
||||
if(typeof cc === 'undefined') {
|
||||
c = c*256 + this.readUInt8(++j);
|
||||
cc = current_cptable.dec[c];
|
||||
}
|
||||
if(typeof cc === 'undefined') throw "Unrecognized character " + c.toString(16);
|
||||
if(c === 0) break;
|
||||
o += cc;
|
||||
//1console.log(cc, cc.charCodeAt(0), o, this.l);
|
||||
}
|
||||
return o;
|
||||
};
|
||||
__toBuffer = function(bufs) { return Buffer.concat(bufs[0]); };
|
||||
} else {
|
||||
__toBuffer = function(bufs) {
|
||||
@ -610,16 +583,6 @@ var __readUInt32LE = function(b, idx) { return b.readUInt32LE ? b.readUInt32LE(i
|
||||
var __readInt32LE = function(b, idx) { if(b.readInt32LE) return b.readInt32LE(idx); var u = __readUInt32LE(b,idx); if(!(u & 0x80000000)) return u; return (0xffffffff - u + 1) * -1; };
|
||||
var __readDoubleLE = function(b, idx) { return b.readDoubleLE ? b.readDoubleLE(idx) : readIEEE754(b, idx||0);};
|
||||
|
||||
var __hexlify = function(b) { return b.map(function(x){return (x<16?"0":"") + x.toString(16);}).join(""); };
|
||||
|
||||
var __utf16le = function(b,s,e) { if(b.utf16le) return b.utf16le(s,e); var str = ""; for(var i=s; i<e; i+=2) str += String.fromCharCode(__readUInt16LE(b,i)); return str.replace(/\u0000/,'').replace(/[\u0001-\u0006]/,'!'); };
|
||||
|
||||
var __utf8 = function(b,s,e) { if(b.utf8) return b.utf8(s,e); var str = ""; for(var i=s; i<e; i++) str += String.fromCharCode(__readUInt8(b,i)); return str; };
|
||||
|
||||
var __lpstr = function(b,i) { if(b.lpstr) return b.lpstr(i); var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __lpwstr = function(b,i) { if(b.lpwstr) return b.lpwstr(i); var len = 2*__readUInt32LE(b,i); return __utf8(b, i+4,i+4+len-1);};
|
||||
|
||||
function bconcat(bufs) { return (typeof Buffer !== 'undefined') ? Buffer.concat(bufs) : [].concat.apply([], bufs); }
|
||||
|
||||
function ReadShift(size, t) {
|
||||
var o, w, vv, i, loc; t = t || 'u';
|
||||
@ -632,46 +595,19 @@ function ReadShift(size, t) {
|
||||
/* falls through */
|
||||
case 16: o = this.toString('hex', this.l,this.l+size); break;
|
||||
|
||||
case 'utf8': size = t; o = __utf8(this, this.l, this.l + size); break;
|
||||
case 'utf16le': size=2*t; o = __utf16le(this, this.l, this.l + size); break;
|
||||
|
||||
/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
|
||||
case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break;
|
||||
|
||||
case 'lpwstr': o = __lpwstr(this, this.l); size = 5 + o.length; if(o[o.length-1] == '\u0000') size += 2; break;
|
||||
|
||||
/* sbcs and dbcs support continue records in the SST way TODO codepages */
|
||||
/* TODO: DBCS http://msdn.microsoft.com/en-us/library/cc194788.aspx */
|
||||
case 'dbcs': size = 2*t; o = ""; loc = this.l;
|
||||
for(i = 0; i != t; ++i) {
|
||||
if(this.lens && this.lens.indexOf(loc) !== -1) {
|
||||
w = __readUInt8(this, loc);
|
||||
this.l = loc + 1;
|
||||
vv = ReadShift.call(this, w ? 'dbcs' : 'sbcs', t-i);
|
||||
return o + vv;
|
||||
}
|
||||
o += _getchar(__readUInt16LE(this, loc));
|
||||
loc+=2;
|
||||
} break;
|
||||
|
||||
case 'sbcs': size = t; o = ""; loc = this.l;
|
||||
for(i = 0; i != t; ++i) {
|
||||
if(this.lens && this.lens.indexOf(loc) !== -1) {
|
||||
w = __readUInt8(this, loc);
|
||||
this.l = loc + 1;
|
||||
vv = ReadShift.call(this, w ? 'dbcs' : 'sbcs', t-i);
|
||||
return o + vv;
|
||||
}
|
||||
o += _getchar(__readUInt8(this, loc));
|
||||
loc+=1;
|
||||
} break;
|
||||
|
||||
case 'cstr': size = 0; o = "";
|
||||
while((w=__readUInt8(this, this.l + size++))!==0) o+= _getchar(w);
|
||||
break;
|
||||
case 'wstr': size = 0; o = "";
|
||||
while((w=__readUInt16LE(this,this.l +size))!==0){o+= _getchar(w);size+=2;}
|
||||
size+=2; break;
|
||||
}
|
||||
this.l+=size; return o;
|
||||
}
|
||||
@ -692,18 +628,26 @@ var recordhopper = function(data, cb) {
|
||||
var RT = data.read_shift(1);
|
||||
if(RT & 0x80) RT = (RT & 0x7F) + ((data.read_shift(1) & 0x7F)<<7);
|
||||
var R = RecordEnum[RT] || RecordEnum[0xFFFF];
|
||||
length = tmpbyte = data.read_shift(1);
|
||||
tmpbyte = data.read_shift(1);
|
||||
length = tmpbyte & 0x7F;
|
||||
for(cntbyte = 1; cntbyte <4 && (tmpbyte & 0x80); ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F)<<(7*cntbyte);
|
||||
var d = R.f(data, length);
|
||||
if(cb(d, R, RT)) return;
|
||||
}
|
||||
};
|
||||
|
||||
/* [MS-XLSB] 2.5.143 */
|
||||
var parse_StrRun = function(data, length) {
|
||||
return { ich: data.read_shift(2), ifnt: data.read_shift(2) };
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.121 */
|
||||
var parse_RichStr = function(data, length) {
|
||||
var start = data.l;
|
||||
var flags = data.read_shift(1);
|
||||
var fRichStr = flags & 1, fExtStr = flags & 2;
|
||||
var str = parse_XLWideString(data);
|
||||
var rgsStrRun = [];
|
||||
var z = {
|
||||
t: str,
|
||||
r:"<t>" + escapexml(str) + "</t>",
|
||||
@ -712,6 +656,7 @@ var parse_RichStr = function(data, length) {
|
||||
if(fRichStr) {
|
||||
/* TODO: formatted string */
|
||||
var dwSizeStrRun = data.read_shift(4);
|
||||
for(var i = 0; i != dwSizeStrRun; ++i) rgsStrRun.push(parse_StrRun(data));
|
||||
}
|
||||
if(fExtStr) {
|
||||
/* TODO: phonetic string */
|
||||
@ -891,7 +836,8 @@ var parse_rs = (function() {
|
||||
})();
|
||||
|
||||
/* 18.4.8 si CT_Rst */
|
||||
var parse_si = function(x) {
|
||||
var parse_si = function(x, opts) {
|
||||
var html = opts ? opts.cellHTML : true;
|
||||
var z = {};
|
||||
if(!x) return null;
|
||||
var y;
|
||||
@ -899,14 +845,14 @@ var parse_si = function(x) {
|
||||
if(x[1] === 't') {
|
||||
z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/t>/)[0]));
|
||||
z.r = x;
|
||||
z.h = z.t;
|
||||
if(html) z.h = z.t;
|
||||
}
|
||||
/* 18.4.4 r CT_RElt (Rich Text Run) */
|
||||
else if((y = x.match(/<r>/))) {
|
||||
z.r = x;
|
||||
/* TODO: properly parse (note: no other valid child can have body text) */
|
||||
z.t = utf8read(unescapexml(x.replace(/<[^>]*>/gm,"")));
|
||||
z.h = parse_rs(x);
|
||||
if(html) z.h = parse_rs(x);
|
||||
}
|
||||
/* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
|
||||
/* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */
|
||||
@ -914,12 +860,12 @@ var parse_si = function(x) {
|
||||
};
|
||||
|
||||
/* 18.4 Shared String Table */
|
||||
var parse_sst_xml = function(data) {
|
||||
var parse_sst_xml = function(data, opts) {
|
||||
var s = [];
|
||||
/* 18.4.9 sst CT_Sst */
|
||||
var sst = data.match(new RegExp("<sst([^>]*)>([\\s\\S]*)<\/sst>","m"));
|
||||
if(isval(sst)) {
|
||||
s = sst[2].replace(/<(?:si|sstItem)>/g,"").split(/<\/(?:si|sstItem)>/).map(parse_si).filter(function(x) { return x; });
|
||||
s = sst[2].replace(/<(?:si|sstItem)>/g,"").split(/<\/(?:si|sstItem)>/).map(function(x) { return parse_si(x, opts); }).filter(function(x) { return x; });
|
||||
sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
|
||||
}
|
||||
return s;
|
||||
@ -943,10 +889,6 @@ var parse_sst_bin = function(data) {
|
||||
});
|
||||
return s;
|
||||
};
|
||||
|
||||
var parse_sst = function(data, name) {
|
||||
return name.substr(-4)===".bin" ? parse_sst_bin(data) : parse_sst_xml(data);
|
||||
};
|
||||
var styles = {}; // shared styles
|
||||
|
||||
/* 18.8.31 numFmts CT_NumFmts */
|
||||
@ -994,7 +936,7 @@ function parseCXfs(t) {
|
||||
}
|
||||
|
||||
/* 18.8 Styles CT_Stylesheet*/
|
||||
function parse_styles(data) {
|
||||
function parse_sty_xml(data) {
|
||||
/* 18.8.39 styleSheet CT_Stylesheet */
|
||||
var t;
|
||||
|
||||
@ -1032,7 +974,7 @@ function parse_BrtXF(data, length) {
|
||||
function parse_sty_bin(data) {
|
||||
styles.NumberFmt = [];
|
||||
for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
|
||||
|
||||
|
||||
styles.CellXf = [];
|
||||
var state = "";
|
||||
var pass = false;
|
||||
@ -1230,10 +1172,8 @@ function parseRels(data, currentFilePath) {
|
||||
|
||||
|
||||
/* 18.7.3 CT_Comment */
|
||||
function parseComments(data) {
|
||||
if(data.match(/<comments *\/>/)) {
|
||||
throw new Error('Not a valid comments xml');
|
||||
}
|
||||
function parse_comments_xml(data, opts) {
|
||||
if(data.match(/<comments *\/>/)) return [];
|
||||
var authors = [];
|
||||
var commentList = [];
|
||||
data.match(/<authors>([^\u2603]*)<\/authors>/m)[1].split('</author>').forEach(function(x) {
|
||||
@ -1249,26 +1189,24 @@ function parseComments(data) {
|
||||
var rt = parse_si(textMatch[1]);
|
||||
comment.r = rt.r;
|
||||
comment.t = rt.t;
|
||||
comment.h = rt.h;
|
||||
if(opts.cellHTML) comment.h = rt.h;
|
||||
commentList.push(comment);
|
||||
});
|
||||
return commentList;
|
||||
}
|
||||
|
||||
function parseCommentsAddToSheets(zip, dirComments, sheets, sheetRels) {
|
||||
function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
|
||||
for(var i = 0; i != dirComments.length; ++i) {
|
||||
var canonicalpath=dirComments[i];
|
||||
var comments=parseComments(getdata(getzipfile(zip, canonicalpath.replace(/^\//,''))));
|
||||
var comments=parse_comments_xml(getdata(getzipfile(zip, canonicalpath.replace(/^\//,''))), opts);
|
||||
// find the sheets targeted by these comments
|
||||
var sheetNames = Object.keys(sheets);
|
||||
for(var j = 0; j != sheetNames.length; ++j) {
|
||||
var sheetName = sheetNames[j];
|
||||
var rels = sheetRels[sheetName];
|
||||
if (rels) {
|
||||
if(rels) {
|
||||
var rel = rels[canonicalpath];
|
||||
if (rel) {
|
||||
insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
|
||||
}
|
||||
if(rel) insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1290,10 +1228,10 @@ function insertCommentsIntoSheet(sheetName, sheet, comments) {
|
||||
if (encoded !== sheet["!ref"]) sheet["!ref"] = encoded;
|
||||
}
|
||||
|
||||
if (!cell.c) {
|
||||
cell.c = [];
|
||||
}
|
||||
cell.c.push({a: comment.author, t: comment.t, r: comment.r, h: comment.h});
|
||||
if (!cell.c) cell.c = [];
|
||||
var o = {a: comment.author, t: comment.t, r: comment.r};
|
||||
if(comment.h) o.h = comment.h;
|
||||
cell.c.push(o);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1301,7 +1239,7 @@ var strs = {}; // shared strings
|
||||
var _ssfopts = {}; // spreadsheet formatting options
|
||||
|
||||
/* 18.3 Worksheets */
|
||||
function parse_worksheet(data) {
|
||||
function parse_ws_xml(data, opts) {
|
||||
if(!data) return data;
|
||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||
var s = {};
|
||||
@ -1332,23 +1270,26 @@ function parse_worksheet(data) {
|
||||
var cref_cell = decode_cell(cref[1]);
|
||||
idx = cref_cell.c;
|
||||
}
|
||||
if(refguess.s.c > idx) refguess.s.c = idx;
|
||||
if(refguess.e.c < idx) refguess.e.c = idx;
|
||||
var cell = parsexmltag((c.match(/<c[^>]*>/)||[c])[0]); delete cell[0];
|
||||
var d = c.substr(c.indexOf('>')+1);
|
||||
var p = {};
|
||||
q.forEach(function(f){var x=d.match(matchtag(f));if(x)p[f]=unescapexml(x[1]);});
|
||||
|
||||
/* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */
|
||||
if(cell.t === undefined && p.v === undefined) { p.t = "str"; p.v = undefined; }
|
||||
if(cell.t === undefined && p.v === undefined) {
|
||||
if(!opts.sheetStubs) return;
|
||||
p.t = "str"; p.v = undefined;
|
||||
}
|
||||
else p.t = (cell.t ? cell.t : "n"); // default is "n" in schema
|
||||
if(refguess.s.c > idx) refguess.s.c = idx;
|
||||
if(refguess.e.c < idx) refguess.e.c = idx;
|
||||
switch(p.t) {
|
||||
case 'n': p.v = parseFloat(p.v); break;
|
||||
case 's': {
|
||||
sidx = parseInt(p.v, 10);
|
||||
p.v = strs[sidx].t;
|
||||
p.r = strs[sidx].r;
|
||||
p.h = strs[sidx].h;
|
||||
if(opts.cellHTML) p.h = strs[sidx].h;
|
||||
} break;
|
||||
case 'str': if(p.v) p.v = utf8read(p.v); break;
|
||||
case 'inlineStr':
|
||||
@ -1373,7 +1314,10 @@ function parse_worksheet(data) {
|
||||
var cf = styles.CellXf[cell.s];
|
||||
if(cf && cf.numFmtId) fmtid = cf.numFmtId;
|
||||
}
|
||||
try { p.w = SSF.format(fmtid,p.v,_ssfopts); } catch(e) { }
|
||||
try {
|
||||
p.w = SSF.format(fmtid,p.v,_ssfopts);
|
||||
if(opts.cellNF) p.z = SSF._table[fmtid];
|
||||
} catch(e) { }
|
||||
s[cell.r] = p;
|
||||
});
|
||||
});
|
||||
@ -1443,6 +1387,14 @@ var parse_BrtCellSt = function(data, length) {
|
||||
return [cell, value, 'str'];
|
||||
};
|
||||
|
||||
/* [MS-XLSB] 2.4.647 BrtFmlaBool */
|
||||
var parse_BrtFmlaBool = function(data, length) {
|
||||
var cell = parse_Cell(data);
|
||||
var value = data.read_shift(1);
|
||||
data.l += length-9;
|
||||
return [cell, value, 'b' /*, formula */];
|
||||
};
|
||||
|
||||
/* [MS-XLSB] 2.4.648 BrtFmlaError */
|
||||
var parse_BrtFmlaError = function(data, length) {
|
||||
var cell = parse_Cell(data);
|
||||
@ -1459,31 +1411,35 @@ var parse_BrtFmlaNum = function(data, length) {
|
||||
return [cell, value, 'n' /*, formula */];
|
||||
};
|
||||
|
||||
/* [MS-XLSB] 2.4.650 BrtFmlaString */
|
||||
var parse_BrtFmlaString = function(data, length) {
|
||||
var start = data.l;
|
||||
var cell = parse_Cell(data);
|
||||
var value = parse_XLWideString(data);
|
||||
data.l = start + length;
|
||||
return [cell, value, 'str' /*, formula */];
|
||||
};
|
||||
|
||||
var parse_BrtCellBlank = parsenoop;
|
||||
var parse_BrtFmlaBool = parsenoop;
|
||||
var parse_BrtFmlaString = parsenoop;
|
||||
|
||||
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
||||
var parse_ws_bin = function(data) {
|
||||
var parse_ws_bin = function(data, opts) {
|
||||
if(!data) return data;
|
||||
var s = {};
|
||||
|
||||
var ref;
|
||||
|
||||
var pass = false;
|
||||
var row, p;
|
||||
var row, p, cf;
|
||||
recordhopper(data, function(val, R) {
|
||||
switch(R.n) {
|
||||
case 'BrtWsDim': ref = val; break;
|
||||
case 'BrtRowHdr': row = val; break;
|
||||
|
||||
case 'BrtRowHdr':
|
||||
row = val;
|
||||
break; // TODO
|
||||
|
||||
case 'BrtFmlaError': break; // TODO
|
||||
case 'BrtFmlaString': break; // TODO
|
||||
case 'BrtFmlaBool': break; // TODO
|
||||
case 'BrtFmlaBool':
|
||||
case 'BrtFmlaError':
|
||||
case 'BrtFmlaNum':
|
||||
case 'BrtFmlaString':
|
||||
case 'BrtCellBool':
|
||||
case 'BrtCellError':
|
||||
case 'BrtCellIsst':
|
||||
@ -1495,11 +1451,12 @@ var parse_ws_bin = function(data) {
|
||||
case 's': p.v = strs[val[1]].t; p.r = strs[val[1]].r; break;
|
||||
case 'b': p.v = val[1] ? true : false; break;
|
||||
case 'e': p.raw = val[1]; p.v = BErr[p.raw]; break;
|
||||
case 'str': if(p.v) p.v = utf8read(p.v); break;
|
||||
case 'str': p.v = utf8read(val[1]); break;
|
||||
}
|
||||
if(val[3]) p.f = val[3];
|
||||
if(styles.CellXf[val[0].iStyleRef]) try {
|
||||
p.w = SSF.format(styles.CellXf[val[0].iStyleRef].ifmt,p.v,_ssfopts);
|
||||
if(val[3] && opts.cellFormula) p.f = val[3];
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) try {
|
||||
p.w = SSF.format(cf.ifmt,p.v,_ssfopts);
|
||||
if(opts.cellNF) p.z = SSF._table[cf.ifmt];
|
||||
} catch(e) { }
|
||||
s[encode_cell({c:val[0].c,r:row.r})] = p;
|
||||
break; // TODO
|
||||
@ -1624,7 +1581,7 @@ var XMLNS_WB = [
|
||||
];
|
||||
|
||||
/* 18.2 Workbook */
|
||||
function parse_workbook(data) {
|
||||
function parse_wb_xml(data) {
|
||||
var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
|
||||
var pass = false;
|
||||
data.match(/<[^>]*>/g).forEach(function(x) {
|
||||
@ -1793,16 +1750,20 @@ var parse_wb_bin = function(data) {
|
||||
|
||||
return wb;
|
||||
};
|
||||
function parse_wb(data, name) {
|
||||
return name.substr(-4)===".bin" ? parse_wb_bin(data) : parse_workbook(data);
|
||||
function parse_wb(data, name, opts) {
|
||||
return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name) {
|
||||
return name.substr(-4)===".bin" ? parse_ws_bin(data) : parse_worksheet(data);
|
||||
function parse_ws(data, name, opts) {
|
||||
return name.substr(-4)===".bin" ? parse_ws_bin(data, opts) : parse_ws_xml(data, opts);
|
||||
}
|
||||
|
||||
function parse_sty(data, name) {
|
||||
return name.substr(-4)===".bin" ? parse_sty_bin(data) : parse_styles(data);
|
||||
function parse_sty(data, name, opts) {
|
||||
return name.substr(-4)===".bin" ? parse_sty_bin(data, opts) : parse_sty_xml(data, opts);
|
||||
}
|
||||
|
||||
function parse_sst(data, name, opts) {
|
||||
return name.substr(-4)===".bin" ? parse_sst_bin(data, opts) : parse_sst_xml(data, opts);
|
||||
}
|
||||
/* [MS-XLSB] 2.3 Record Enumeration */
|
||||
var RecordEnum = {
|
||||
@ -2624,7 +2585,21 @@ var RecordEnum = {
|
||||
0xFFFF: { n:"", f:parsenoop }
|
||||
};
|
||||
|
||||
function parseZip(zip) {
|
||||
function fixopts(opts) {
|
||||
var defaults = [
|
||||
['cellNF', false], /* emit cell number format string as .z */
|
||||
['cellHTML', true], /* emit html string as .h */
|
||||
['cellFormula', true], /* emit formulae as .h */
|
||||
|
||||
['sheetStubs', false], /* emit empty cells */
|
||||
|
||||
['WTF', false] /* WTF mode (do not use) */
|
||||
];
|
||||
defaults.forEach(function(d) { if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1]; });
|
||||
}
|
||||
function parseZip(zip, opts) {
|
||||
opts = opts || {};
|
||||
fixopts(opts);
|
||||
reset_cp();
|
||||
var entries = Object.keys(zip.files);
|
||||
var keys = entries.filter(function(x){return x.substr(-1) != '/';}).sort();
|
||||
@ -2637,7 +2612,7 @@ function parseZip(zip) {
|
||||
xlsb = true;
|
||||
}
|
||||
strs = {};
|
||||
if(dir.sst) strs=parse_sst(getdata(getzipfile(zip, dir.sst.replace(/^\//,''))), dir.sst);
|
||||
if(dir.sst) strs=parse_sst(getdata(getzipfile(zip, dir.sst.replace(/^\//,''))), dir.sst, opts);
|
||||
|
||||
styles = {};
|
||||
if(dir.style) styles = parse_sty(getdata(getzipfile(zip, dir.style.replace(/^\//,''))),dir.style);
|
||||
@ -2666,7 +2641,7 @@ function parseZip(zip) {
|
||||
try { /* TODO: remove these guards */
|
||||
path = 'xl/worksheets/sheet' + (i+1) + (xlsb?'.bin':'.xml');
|
||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||
sheets[props.SheetNames[i]]=parse_ws(getdata(getzipfile(zip, path)),path);
|
||||
sheets[props.SheetNames[i]]=parse_ws(getdata(getzipfile(zip, path)),path,opts);
|
||||
sheetRels[props.SheetNames[i]]=parseRels(getdata(getzipfile(zip, relsPath)), path);
|
||||
} catch(e) {}
|
||||
}
|
||||
@ -2676,13 +2651,13 @@ function parseZip(zip) {
|
||||
//var path = dir.sheets[i].replace(/^\//,'');
|
||||
path = 'xl/worksheets/sheet' + (i+1) + (xlsb?'.bin':'.xml');
|
||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||
sheets[props.SheetNames[i]]=parse_ws(getdata(getzipfile(zip, path)),path);
|
||||
sheets[props.SheetNames[i]]=parse_ws(getdata(getzipfile(zip, path)),path,opts);
|
||||
sheetRels[props.SheetNames[i]]=parseRels(getdata(getzipfile(zip, relsPath)), path);
|
||||
} catch(e) {/*console.error(e);*/}
|
||||
}
|
||||
}
|
||||
|
||||
if(dir.comments) parseCommentsAddToSheets(zip, dir.comments, sheets, sheetRels);
|
||||
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
|
||||
|
||||
return {
|
||||
Directory: dir,
|
||||
@ -2708,7 +2683,7 @@ function readSync(data, options) {
|
||||
case "base64": zip = new jszip(d, { base64:true }); break;
|
||||
case "binary": zip = new jszip(d, { base64:false }); break;
|
||||
}
|
||||
return parseZip(zip);
|
||||
return parseZip(zip, o);
|
||||
}
|
||||
|
||||
function readFileSync(data, options) {
|
||||
@ -2737,7 +2712,7 @@ function decode_range(range) { var x =range.split(":").map(decode_cell); return
|
||||
function encode_range(range) { return encode_cell(range.s) + ":" + encode_cell(range.e); }
|
||||
|
||||
function sheet_to_row_object_array(sheet, opts){
|
||||
var val, row, r, hdr = {}, isempty, R, C, v;
|
||||
var val, row, r, hdr = {}, isempty, R, C;
|
||||
var out = [];
|
||||
opts = opts || {};
|
||||
if(!sheet || !sheet["!ref"]) return out;
|
||||
@ -2779,12 +2754,10 @@ function sheet_to_row_object_array(sheet, opts){
|
||||
function sheet_to_csv(sheet, opts) {
|
||||
var stringify = function stringify(val) {
|
||||
if(!val.t) return "";
|
||||
if(typeof val.w !== 'undefined') return '"' + val.w.replace(/"/,'""') + '"';
|
||||
if(typeof val.w !== 'undefined') return val.w;
|
||||
switch(val.t){
|
||||
case 'n': return String(val.v);
|
||||
case 's': case 'str':
|
||||
if(typeof val.v === 'undefined') return "";
|
||||
return '"' + val.v.replace(/"/,'""') + '"';
|
||||
case 's': case 'str': return typeof val.v !== 'undefined' ? val.v : "";
|
||||
case 'b': return val.v ? "TRUE" : "FALSE";
|
||||
case 'e': return val.v; /* throw out value in case of error */
|
||||
default: throw 'unrecognized type ' + val.t;
|
||||
@ -2794,15 +2767,18 @@ function sheet_to_csv(sheet, opts) {
|
||||
opts = opts || {};
|
||||
if(!sheet || !sheet["!ref"]) return out;
|
||||
var r = XLSX.utils.decode_range(sheet["!ref"]);
|
||||
var fs = opts.FS||",", rs = opts.RS||"\n";
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
var row = [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) {
|
||||
var val = sheet[XLSX.utils.encode_cell({c:C,r:R})];
|
||||
if(!val) { row.push(""); continue; }
|
||||
txt = stringify(val);
|
||||
row.push(String(txt).replace(/\\r\\n/g,"\n").replace(/\\t/g,"\t").replace(/\\\\/g,"\\").replace("\\\"","\"\""));
|
||||
txt = String(stringify(val));
|
||||
if(txt.indexOf(fs)!==-1 || txt.indexOf(rs)!==-1 || txt.indexOf('"')!==-1)
|
||||
txt = "\"" + txt.replace(/"/g, '""') + "\"";
|
||||
row.push(txt);
|
||||
}
|
||||
out += row.join(opts.FS||",") + (opts.RS||"\n");
|
||||
out += row.join(fs) + (rs);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -2843,10 +2819,4 @@ if(typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
||||
exports.readFile = XLSX.readFile;
|
||||
exports.utils = XLSX.utils;
|
||||
exports.version = XLSX.version;
|
||||
exports.main = function(args) {
|
||||
var zip = XLSX.read(args[0], {type:'file'});
|
||||
console.log(zip.Sheets);
|
||||
};
|
||||
if(typeof module !== 'undefined' && require.main === module)
|
||||
exports.main(process.argv.slice(2));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user