version bump 0.12.12: ecosystem deprecations

- node 10 `Buffer` deprecation workaround (with dependency update)
- Angular 6 global deprecation workaround (fixes #1088 h/t @cristhiank)
- BIFF8 write standard and custom properties
- TH elements in HTML string (fixes #1090 h/t @GigiSan)
- planmaker export quirks
This commit is contained in:
SheetJS 2018-05-05 02:34:37 -04:00
parent eb5fc87be4
commit c0b4895881
41 changed files with 1658 additions and 530 deletions

2
.gitignore vendored
View File

@ -10,6 +10,8 @@ tmp
*.[cC][sS][vV]
*.[dD][iIbB][fF]
*.[pP][rR][nN]
*.[pP][mM][dD]*
*.[pP][dD][fF]
*.[sS][lL][kK]
*.socialcalc
*.[xX][lL][sSwWcCaAtTmM]

View File

@ -12,6 +12,8 @@ tmp
*.[cC][sS][vV]
*.[dD][iIbB][fF]
*.[pP][rR][nN]
*.[pP][mM][dD]*
*.[pP][dD][fF]
*.[sS][lL][kK]
*.socialcalc
*.[xX][lL][sSwWcCaAtTmM]

View File

@ -43,6 +43,7 @@ program
.option('-t, --txt', 'emit TXT to <sheetname> or <file>.txt (UTF-8 TSV)')
.option('-r, --rtf', 'emit RTF to <sheetname> or <file>.txt (Table RTF)')
.option('-z, --dump', 'dump internal representation as JSON')
.option('--props', 'dump workbook properties as CSV')
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
@ -163,6 +164,10 @@ if(program.dump) {
console.log(JSON.stringify(wb));
process.exit(0);
}
if(program.props) {
dump_props(wb);
process.exit(0);
}
/* full workbook formats */
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
@ -255,3 +260,24 @@ switch(true) {
} else doit(function(ws) { return X.utils.sheet_to_csv(ws,{FS:program.fieldSep, RS:program.rowSep}); });
break;
}
function dump_props(wb) {
var propaoa = [];
if(Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops));
else {
var Keys, pi;
if(wb.Props) {
Keys = Object.keys(wb.Props);
for(pi = 0; pi < Keys.length; ++pi) {
if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[Keys[pi]]]);
}
}
if(wb.Custprops) {
Keys = Object.keys(wb.Custprops);
for(pi = 0; pi < Keys.length; ++pi) {
if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[Keys[pi]]]);
}
}
}
console.log(X.utils.sheet_to_csv(X.utils.aoa_to_sheet(propaoa)));
}

View File

@ -1 +1 @@
XLSX.version = '0.12.11';
XLSX.version = '0.12.12';

View File

@ -1,8 +1,11 @@
var current_codepage = 1200, current_ansi = 1252;
/*:: declare var cptable:any; */
/*global cptable:true */
/*global cptable:true, window */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js');
if(typeof cptable === 'undefined') {
if(typeof global !== 'undefined') global.cptable = require('./dist/cpexcel.js');
else if(typeof window !== 'undefined') window.cptable = require('./dist/cpexcel.js');
}
}
var VALID_ANSI = [ 874, 932, 936, 949, 950 ];

View File

@ -1,16 +1,22 @@
var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
function new_raw_buf(len/*:number*/) {
/* jshint -W056 */
// $FlowIgnore
return new (has_buf ? Buffer : Array)(len);
return has_buf ? Buffer.alloc(len) : new Array(len);
/* jshint +W056 */
}
function s2a(s/*:string*/)/*:any*/ {
if(has_buf) return new Buffer(s, "binary");
var s2a = function s2a(s/*:string*/)/*:any*/ {
if(has_buf) return Buffer.from(s, "binary");
return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; });
}
};
function s2ab(s/*:string*/)/*:any*/ {
if(typeof ArrayBuffer === 'undefined') return s2a(s);

View File

@ -38,7 +38,7 @@ type CFBFiles = {[n:string]:CFBEntry};
/* [MS-CFB] v20171201 */
var CFB = (function _CFB(){
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
exports.version = '1.0.6';
exports.version = '1.0.7';
/* [MS-CFB] 2.6.4 */
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
var L = l.split("/"), R = r.split("/");

View File

@ -135,7 +135,7 @@ var utf8write/*:StringConv*/ = function(orig/*:string*/)/*:string*/ {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {
j = 1;
if((c=data.charCodeAt(i)) < 128) w = c;
@ -153,10 +153,10 @@ if(has_buf) {
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); };
}
// matches <foo>...</foo> extracts content

View File

@ -51,15 +51,15 @@ var DocSummaryPIDDSI = {
/*::[*/0x08/*::]*/: { n: 'NoteCount', t: VT_I4 },
/*::[*/0x09/*::]*/: { n: 'HiddenCount', t: VT_I4 },
/*::[*/0x0a/*::]*/: { n: 'MultimediaClipCount', t: VT_I4 },
/*::[*/0x0b/*::]*/: { n: 'Scale', t: VT_BOOL },
/*::[*/0x0c/*::]*/: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT },
/*::[*/0x0d/*::]*/: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR },
/*::[*/0x0b/*::]*/: { n: 'ScaleCrop', t: VT_BOOL },
/*::[*/0x0c/*::]*/: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT },
/*::[*/0x0d/*::]*/: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR },
/*::[*/0x0e/*::]*/: { n: 'Manager', t: VT_STRING },
/*::[*/0x0f/*::]*/: { n: 'Company', t: VT_STRING },
/*::[*/0x10/*::]*/: { n: 'LinksDirty', t: VT_BOOL },
/*::[*/0x10/*::]*/: { n: 'LinksUpToDate', t: VT_BOOL },
/*::[*/0x11/*::]*/: { n: 'CharacterCount', t: VT_I4 },
/*::[*/0x13/*::]*/: { n: 'SharedDoc', t: VT_BOOL },
/*::[*/0x16/*::]*/: { n: 'HLinksChanged', t: VT_BOOL },
/*::[*/0x16/*::]*/: { n: 'HyperlinksChanged', t: VT_BOOL },
/*::[*/0x17/*::]*/: { n: 'AppVersion', t: VT_I4, p: 'version' },
/*::[*/0x18/*::]*/: { n: 'DigSig', t: VT_BLOB },
/*::[*/0x1A/*::]*/: { n: 'ContentType', t: VT_STRING },
@ -88,8 +88,8 @@ var SummaryPIDSI = {
/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 },
/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 },
/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF },
/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_STRING },
/*::[*/0x13/*::]*/: { n: 'DocumentSecurity', t: VT_I4 },
/*::[*/0x12/*::]*/: { n: 'Application', t: VT_STRING },
/*::[*/0x13/*::]*/: { n: 'DocSecurity', t: VT_I4 },
/*::[*/0xFF/*::]*/: {}
};
@ -105,6 +105,9 @@ var SpecialProperties = {
DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y];
})();
var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n");
var SummaryRE = evert_key(SummaryPIDSI, "n");
/* [MS-XLS] 2.4.63 Country/Region codes */
var CountryEnum = {
/*::[*/0x0001/*::]*/: "US", // United States

View File

@ -17,6 +17,56 @@ var EXT_PROPS/*:Array<Array<string> >*/ = [
XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
var PseudoPropsPairs = [
"Worksheets", "SheetNames",
"NamedRanges", "DefinedNames",
"Chartsheets", "ChartNames"
];
function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) {
var v = [];
if(typeof HP == "string") v = parseVector(HP, opts);
else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; }));
var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP;
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
props.NamedRanges = len;
props.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
props.Chartsheets = len;
props.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
function parse_ext_props(data, p, opts) {
var q = {}; if(!p) p = {};
data = utf8read(data);
@ -32,48 +82,7 @@ function parse_ext_props(data, p, opts) {
}
});
if(q.HeadingPairs && q.TitlesOfParts) {
var v = parseVector(q.HeadingPairs, opts);
var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; });
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
p.Worksheets = len;
p.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
p.NamedRanges = len;
p.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
p.Chartsheets = len;
p.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts);
return p;
}

View File

@ -5,6 +5,15 @@ function parse_FILETIME(blob) {
var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4);
return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,"");
}
function write_FILETIME(time/*:string|Date*/) {
var date = (typeof time == "string") ? new Date(Date.parse(time)) : time;
var t = date.getTime() / 1000 + 11644473600;
var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32);
l *= 1e7; h *= 1e7;
var w = (l / Math.pow(2,32)) | 0;
if(w > 0) { l = l % Math.pow(2,32); h += w; }
var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o;
}
/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
function parse_lpstr(blob, type, pad/*:?number*/) {
@ -74,6 +83,7 @@ function parse_dictionary(blob,CodePage) {
var pid = blob.read_shift(4);
var len = blob.read_shift(4);
dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!');
if(CodePage === 0x4B0 && (len % 2)) blob.l += 2;
}
if(blob.l & 3) blob.l = (blob.l>>2+1)<<2;
return dict;
@ -121,6 +131,25 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
}
}
function write_TypedPropertyValue(type/*:number*/, value) {
var o = new_buf(4), p = new_buf(4);
o.write_shift(4, type == 0x50 ? 0x1F : type);
switch(type) {
case 0x03 /*VT_I4*/: p.write_shift(-4, value); break;
case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break;
case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break;
case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break;
case 0x1F /*VT_LPWSTR*/:
case 0x50 /*VT_STRING*/:
p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
p.write_shift(4, value.length + 1);
p.write_shift(0, value, "dbcs");
while(p.l != p.length) p.write_shift(1, 0);
break;
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value);
}
return bconcat([o, p]);
}
/* [MS-OLEPS] 2.20 PropertySet */
function parse_PropertySet(blob, PIDSI) {
@ -151,7 +180,7 @@ function parse_PropertySet(blob, PIDSI) {
if(PIDSI) {
var piddsi = PIDSI[Props[i][0]];
PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF);
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
case 0: PropH[piddsi.n] = 1252;
/* falls through */
@ -196,8 +225,8 @@ function parse_PropertySet(blob, PIDSI) {
/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
switch(blob[blob.l]) {
case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;
@ -212,6 +241,79 @@ function parse_PropertySet(blob, PIDSI) {
blob.l = start_addr + size; /* step ahead to skip padding */
return PropH;
}
var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs);
function guess_property_type(val/*:any*/)/*:number*/ {
switch(typeof val) {
case "boolean": return 0x0B;
case "number": return ((val|0)==val) ? 0x03 : 0x05;
case "string": return 0x1F;
case "object": if(val instanceof Date) return 0x40; break;
}
return -1;
}
function write_PropertySet(entries, RE, PIDSI) {
var hdr = new_buf(8), piao = [], prop = [];
var sz = 8, i = 0;
var pr = new_buf(8), pio = new_buf(8);
pr.write_shift(4, 0x0002);
pr.write_shift(4, 0x04B0);
pio.write_shift(4, 0x0001);
prop.push(pr); piao.push(pio);
sz += 8 + pr.length;
if(!RE) {
pio = new_buf(8);
pio.write_shift(4, 0);
piao.unshift(pio);
var bufs = [new_buf(4)];
bufs[0].write_shift(4, entries.length);
for(i = 0; i < entries.length; ++i) {
var value = entries[i][0];
pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
pr.write_shift(4, i+2);
pr.write_shift(4, value.length + 1);
pr.write_shift(0, value, "dbcs");
while(pr.l != pr.length) pr.write_shift(1, 0);
bufs.push(pr);
}
pr = bconcat(bufs);
prop.unshift(pr);
sz += 8 + pr.length;
}
for(i = 0; i < entries.length; ++i) {
if(RE && !RE[entries[i][0]]) continue;
if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue;
if(entries[i][1] == null) continue;
var val = entries[i][1], idx = 0;
if(RE) {
idx = +RE[entries[i][0]];
var pinfo = PIDSI[idx];
if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0);
pr = write_TypedPropertyValue(pinfo.t, val);
} else {
var T = guess_property_type(val);
if(T == -1) { T = 0x1F; val = String(val); }
pr = write_TypedPropertyValue(T, val);
}
prop.push(pr);
pio = new_buf(8);
pio.write_shift(4, !RE ? 2+i : idx);
piao.push(pio);
sz += 8 + pr.length;
}
var w = 8 * (prop.length + 1);
for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; }
hdr.write_shift(4, sz);
hdr.write_shift(4, prop.length);
return bconcat([hdr].concat(piao).concat(prop));
}
/* [MS-OLEPS] 2.21 PropertySetStream */
function parse_PropertySetStream(file, PIDSI, clsid) {
@ -248,7 +350,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) {
rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
return rval;
}
function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2/*:?any*/, clsid2/*:?any*/) {
var hdr = new_buf(entries2 ? 68 : 48);
var bufs = [hdr];
hdr.write_shift(2, 0xFFFE);
hdr.write_shift(2, 0x0000); /* TODO: type 1 props */
hdr.write_shift(4, 0x32363237);
hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex");
hdr.write_shift(4, (entries2 ? 2 : 1));
hdr.write_shift(16, clsid, "hex");
hdr.write_shift(4, (entries2 ? 68 : 48));
var ps0 = write_PropertySet(entries, RE, PIDSI);
bufs.push(ps0);
if(entries2) {
var ps1 = write_PropertySet(entries2, null, null);
hdr.write_shift(16, clsid2, "hex");
hdr.write_shift(4, 68 + ps0.length);
bufs.push(ps1);
}
return bconcat(bufs);
}
function parsenoop2(blob, length) { blob.read_shift(length); return null; }
function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; }

View File

@ -330,6 +330,7 @@ var SYLK = (function() {
formats.push(rstr.slice(3).replace(/;;/g, ";"));
break;
case 'C':
var C_seen_K = false;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; break;
case 'Y':
@ -347,15 +348,16 @@ var SYLK = (function() {
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
arr[R][C] = val;
next_cell_format = null;
C_seen_K = true;
break;
case 'E':
var formula = rc_to_a1(record[rj].slice(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);
} break;
}
if(C_seen_K) { arr[R][C] = val; next_cell_format = null; }
break;
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
@ -366,6 +368,7 @@ var SYLK = (function() {
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
break;

View File

@ -2,6 +2,7 @@
function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -60,7 +61,13 @@ function parse_borders(t, styles, themes, opts) {
case '<color': case '<color>': break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders');
}
}
});
}
@ -69,6 +76,7 @@ function parse_borders(t, styles, themes, opts) {
function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -119,7 +127,13 @@ function parse_fills(t, styles, themes, opts) {
case '<color': case '<color/>': break;
case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills');
}
}
});
}
@ -128,6 +142,7 @@ function parse_fills(t, styles, themes, opts) {
function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -228,7 +243,13 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
}
}
});
}
@ -278,6 +299,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "
function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(y[0]) {
@ -313,9 +335,12 @@ function parse_cellXfs(t, styles, opts) {
case '<protection': case '</protection>': case '<protection/>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
}
}
});
}

View File

@ -284,6 +284,7 @@ function parse_SerAr(blob, biff/*:number*/) {
case 0x04: /* SerBool -- boolean */
val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE';
if(biff != 12) blob.l += 7; break;
case 0x25: /* appears to be an alias */
case 0x10: /* SerErr -- error */
val[1] = BErr[blob[blob.l]];
blob.l += ((biff == 12) ? 4 : 8); break;
@ -293,7 +294,7 @@ function parse_SerAr(blob, biff/*:number*/) {
val[1] = parse_Xnum(blob, 8); break;
case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */
val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break;
default: throw "Bad SerAr: " + val[0]; /* Unreachable */
default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */
}
return val;
}

View File

@ -842,21 +842,51 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
return wb;
}
/* TODO: WTF */
function parse_props(cfb/*:CFBContainer*/, props, o) {
/* TODO: split props*/
var PSCLSID = {
SI: "e0859ff2f94f6810ab9108002b27b3d9",
DSI: "02d5cdd59c2e1b10939708002b2cf9ae",
UDI: "05d5cdd59c2e1b10939708002b2cf9ae"
};
function parse_xls_props(cfb/*:CFBContainer*/, props, o) {
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
if(DSI && DSI.size > 0) try {
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae");
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
for(var d in DocSummary) props[d] = DocSummary[d];
} catch(e) {if(o.WTF) throw e;/* empty */}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = CFB.find(cfb, '!SummaryInformation');
if(SI && SI.size > 0) try {
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9");
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
} catch(e) {if(o.WTF) throw e;/* empty */}
if(props.HeadingPairs && props.TitlesOfParts) {
load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);
delete props.HeadingPairs; delete props.TitlesOfParts;
}
}
function write_xls_props(wb/*:Workbook*/, cfb/*:CFBContainer*/) {
var DSEntries = [], SEntries = [], CEntries = [];
var i = 0, Keys;
if(wb.Props) {
Keys = keys(wb.Props);
for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]);
}
if(wb.Custprops) {
Keys = keys(wb.Custprops);
for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]);
}
var CEntries2 = [];
for(i = 0; i < CEntries.length; ++i) {
if(XLSPSSkip.indexOf(CEntries[i][0]) > -1) continue;
if(CEntries[i][1] == null) continue;
CEntries2.push(CEntries[i]);
}
if(SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI));
if(DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI));
}
function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ {
@ -896,7 +926,7 @@ else/*:: if(cfb instanceof CFBContainer) */ {
}
var props = {};
if(cfb.FullPaths) parse_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options);
if(cfb.FullPaths) parse_xls_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options);
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
if(options.bookFiles) WorkbookP.cfb = cfb;
@ -919,6 +949,7 @@ function write_xlscfb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:CFBContainer*/ {
default: throw new Error("invalid type " + o.bookType + " for XLS CFB");
}
CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb);
// TODO: SI, DSI, CO
if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"}));
return cfb;

View File

@ -120,7 +120,7 @@ function write_FEAT(ba, ws) {
o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0);
o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0);
o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0);
write_Ref8U(safe_decode_range(ws['!ref']), o);
write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o);
o.write_shift(4, 4);
write_biff_rec(ba, "Feat", o);
}

View File

@ -16,11 +16,11 @@ var HTML_ = (function() {
var row = rows[i].trim();
var hd = row.slice(0,3).toLowerCase();
if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; }
if(hd != "<td") continue;
var cells = row.split(/<\/td>/i);
if(hd != "<td" && hd != "<th") continue;
var cells = row.split(/<\/t[dh]>/i);
for(j = 0; j < cells.length; ++j) {
var cell = cells[j].trim();
if(cell.slice(0,3).toLowerCase() != "<td") continue;
if(!cell.match(/<t[dh]/i)) continue;
var m = cell, cc = 0;
/* TODO: parse styles etc */
while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1);
@ -155,7 +155,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
C += CS;
}
}
ws['!merges'] = merges;
if(merges.length) ws['!merges'] = merges;
ws['!ref'] = encode_range(range);
if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range));
return ws;

View File

@ -70,7 +70,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var styles = ({}/*:any*/);
if(!opts.bookSheets && !opts.bookProps) {
strs = [];
if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts);
if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; }
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);

View File

@ -38,7 +38,7 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
if(has_buf) return new Buffer(o, 'utf8');
if(has_buf) return Buffer.from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
}
@ -52,7 +52,7 @@ function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
if(has_buf) return new Buffer(out, 'binary');
if(has_buf) return Buffer.from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
}

41
dist/cpexcel.js generated vendored
View File

@ -1,6 +1,6 @@
/* cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
/*jshint -W100 */
var cptable = {version:"1.12.0"};
var cptable = {version:"1.13.0"};
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖÜ¢Ł¥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[737] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
@ -1018,9 +1018,14 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
var has_buf = (typeof Buffer !== 'undefined');
if(has_buf) {
var mdl = 1024, mdb = new Buffer(mdl);
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); };
var mdl = 1024, mdb = Buffer.allocUnsafe(mdl);
var make_EE = function make_EE(E){
var EE = new Buffer(65536);
var EE = Buffer.allocUnsafe(65536);
for(var i = 0; i < 65536;++i) EE[i] = 0;
var keys = Object.keys(E), len = keys.length;
for(var ee = 0, e = keys[ee]; ee < len; ++ee) {
@ -1035,10 +1040,10 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
var len = data.length;
var out, i=0, j=0, D=0, w=0;
if(typeof data === 'string') {
out = new Buffer(len);
out = Buffer.allocUnsafe(len);
for(i = 0; i < len; ++i) out[i] = EE[data.charCodeAt(i)];
} else if(Buffer.isBuffer(data)) {
out = new Buffer(2*len);
out = Buffer.allocUnsafe(2*len);
j = 0;
for(i = 0; i < len; ++i) {
D = data[i];
@ -1053,7 +1058,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
}
out = out.slice(0,j);
} else {
out = new Buffer(len);
out = Buffer.allocUnsafe(len);
for(i = 0; i < len; ++i) out[i] = EE[data[i].charCodeAt(0)];
}
if(!ofmt || ofmt === 'buf') return out;
@ -1063,7 +1068,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
};
var sbcs_decode = function make_sbcs_decode(cp) {
var D = cpt[cp].dec;
var DD = new Buffer(131072), d=0, c="";
var DD = Buffer.allocUnsafe(131072), d=0, c="";
for(d=0;d<D.length;++d) {
if(!(c=D[d])) continue;
var w = c.charCodeAt(0);
@ -1071,7 +1076,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
}
return function sbcs_d(data) {
var len = data.length, i=0, j=0;
if(2 * len > mdl) { mdl = 2 * len; mdb = new Buffer(mdl); }
if(2 * len > mdl) { mdl = 2 * len; mdb = Buffer.allocUnsafe(mdl); }
if(Buffer.isBuffer(data)) {
for(i = 0; i < len; i++) {
j = 2*data[i];
@ -1093,7 +1098,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
};
var dbcs_encode = function make_dbcs_encode(cp) {
var E = cpt[cp].enc;
var EE = new Buffer(131072);
var EE = Buffer.allocUnsafe(131072);
for(var i = 0; i < 131072; ++i) EE[i] = 0;
var keys = Object.keys(E);
for(var ee = 0, e = keys[ee]; ee < keys.length; ++ee) {
@ -1102,7 +1107,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
EE[2*f] = E[e] & 255; EE[2*f+1] = E[e]>>8;
}
return function dbcs_e(data, ofmt) {
var len = data.length, out = new Buffer(2*len), i=0, j=0, jj=0, k=0, D=0;
var len = data.length, out = Buffer.allocUnsafe(2*len), i=0, j=0, jj=0, k=0, D=0;
if(typeof data === 'string') {
for(i = k = 0; i < len; ++i) {
j = data.charCodeAt(i)*2;
@ -1136,7 +1141,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
};
var dbcs_decode = function make_dbcs_decode(cp) {
var D = cpt[cp].dec;
var DD = new Buffer(131072), d=0, c, w=0, j=0, i=0;
var DD = Buffer.allocUnsafe(131072), d=0, c, w=0, j=0, i=0;
for(i = 0; i < 65536; ++i) { DD[2*i] = 0xFF; DD[2*i+1] = 0xFD;}
for(d = 0; d < D.length; ++d) {
if(!(c=D[d])) continue;
@ -1145,7 +1150,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
DD[j] = w&255; DD[j+1] = w>>8;
}
return function dbcs_d(data) {
var len = data.length, out = new Buffer(2*len), i=0, j=0, k=0;
var len = data.length, out = Buffer.allocUnsafe(2*len), i=0, j=0, k=0;
if(Buffer.isBuffer(data)) {
for(i = 0; i < len; i++) {
j = 2*data[i];
@ -1171,7 +1176,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
magic_decode[65001] = function utf8_d(data) {
if(typeof data === "string") return utf8_d(data.split("").map(cca));
var len = data.length, w = 0, ww = 0;
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
if(4 * len > mdl) { mdl = 4 * len; mdb = Buffer.allocUnsafe(mdl); }
var i = 0;
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
for(var j = 1, k = 0, D = 0; i < len; i+=j) {
@ -1196,7 +1201,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
}
var len = data.length, w = 0, ww = 0, j = 0;
var direct = typeof data === "string";
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
if(4 * len > mdl) { mdl = 4 * len; mdb = Buffer.allocUnsafe(mdl); }
for(var i = 0; i < len; ++i) {
w = direct ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) mdb[j++] = w;
@ -1275,7 +1280,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
if(cpecache[cp]) { last_enc = cpecache[last_cp=cp]; return last_enc(data, ofmt); }
if(has_buf && Buffer.isBuffer(data)) data = data.toString('utf8');
var len = data.length;
var out = has_buf ? new Buffer(4*len) : [], w=0, i=0, j = 0, ww=0;
var out = has_buf ? Buffer.allocUnsafe(4*len) : [], w=0, i=0, j = 0, ww=0;
var C = cpt[cp], E, M = "";
var isstr = typeof data === 'string';
if(C && (E=C.enc)) for(i = 0; i < len; ++i, ++j) {
@ -1287,7 +1292,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
}
else if((M=magic[cp])) switch(M) {
case "utf8":
if(has_buf && isstr) { out = new Buffer(data, M); j = out.length; break; }
if(has_buf && isstr) { out = Buffer.from(data, M); j = out.length; break; }
for(i = 0; i < len; ++i, ++j) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) out[j] = w;
@ -1309,7 +1314,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
}
break;
case "ascii":
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
if(has_buf && typeof data === "string") { out = Buffer.from(data, M); j = out.length; break; }
for(i = 0; i < len; ++i, ++j) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) out[j] = w;
@ -1317,7 +1322,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE
}
break;
case "utf16le":
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
if(has_buf && typeof data === "string") { out = Buffer.from(data, M); j = out.length; break; }
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
out[j++] = w&255;

8
dist/jszip.js generated vendored
View File

@ -600,8 +600,14 @@ module.exports = function(data, options) {
},{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){
(function (Buffer){
'use strict';
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
module.exports = function(data, encoding){
return new Buffer(data, encoding);
return typeof data == 'number' ? Buffer.alloc(data) : Buffer.from(data, encoding);
};
module.exports.test = function(b){
return Buffer.isBuffer(b);

30
dist/xlsx.core.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.core.min.map generated vendored

File diff suppressed because one or more lines are too long

385
dist/xlsx.extendscript.js generated vendored
View File

@ -752,8 +752,14 @@ module.exports = function(data, options) {
},{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){
(function (Buffer){
'use strict';
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
module.exports = function(data, encoding){
return new Buffer(data, encoding);
return typeof data == 'number' ? Buffer.alloc(data) : Buffer.from(data, encoding);
};
module.exports.test = function(b){
return Buffer.isBuffer(b);
@ -9147,11 +9153,14 @@ module.exports = ZStream;
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.12.11';
XLSX.version = '0.12.12';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true */
/*global cptable:true, window */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') global.cptable = undefined;
if(typeof cptable === 'undefined') {
if(typeof global !== 'undefined') global.cptable = undefined;
else if(typeof window !== 'undefined') window.cptable = undefined;
}
}
var VALID_ANSI = [ 874, 932, 936, 949, 950 ];
@ -9267,17 +9276,23 @@ var Base64 = (function make_b64(){
})();
var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
function new_raw_buf(len) {
/* jshint -W056 */
// $FlowIgnore
return new (has_buf ? Buffer : Array)(len);
return has_buf ? Buffer.alloc(len) : new Array(len);
/* jshint +W056 */
}
function s2a(s) {
if(has_buf) return new Buffer(s, "binary");
var s2a = function s2a(s) {
if(has_buf) return Buffer.from(s, "binary");
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
}
};
function s2ab(s) {
if(typeof ArrayBuffer === 'undefined') return s2a(s);
@ -10267,7 +10282,7 @@ var DO_NOT_EXPORT_CFB = true;
/* [MS-CFB] v20171201 */
var CFB = (function _CFB(){
var exports = {};
exports.version = '1.0.6';
exports.version = '1.0.7';
/* [MS-CFB] 2.6.4 */
function namecmp(l, r) {
var L = l.split("/"), R = r.split("/");
@ -11390,7 +11405,7 @@ var utf8write = function(orig) {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {
j = 1;
if((c=data.charCodeAt(i)) < 128) w = c;
@ -11408,10 +11423,10 @@ if(has_buf) {
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); };
}
// matches <foo>...</foo> extracts content
@ -12350,15 +12365,15 @@ var DocSummaryPIDDSI = {
0x08: { n: 'NoteCount', t: VT_I4 },
0x09: { n: 'HiddenCount', t: VT_I4 },
0x0a: { n: 'MultimediaClipCount', t: VT_I4 },
0x0b: { n: 'Scale', t: VT_BOOL },
0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT },
0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR },
0x0b: { n: 'ScaleCrop', t: VT_BOOL },
0x0c: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT },
0x0d: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR },
0x0e: { n: 'Manager', t: VT_STRING },
0x0f: { n: 'Company', t: VT_STRING },
0x10: { n: 'LinksDirty', t: VT_BOOL },
0x10: { n: 'LinksUpToDate', t: VT_BOOL },
0x11: { n: 'CharacterCount', t: VT_I4 },
0x13: { n: 'SharedDoc', t: VT_BOOL },
0x16: { n: 'HLinksChanged', t: VT_BOOL },
0x16: { n: 'HyperlinksChanged', t: VT_BOOL },
0x17: { n: 'AppVersion', t: VT_I4, p: 'version' },
0x18: { n: 'DigSig', t: VT_BLOB },
0x1A: { n: 'ContentType', t: VT_STRING },
@ -12387,8 +12402,8 @@ var SummaryPIDSI = {
0x0F: { n: 'WordCount', t: VT_I4 },
0x10: { n: 'CharCount', t: VT_I4 },
0x11: { n: 'Thumbnail', t: VT_CF },
0x12: { n: 'ApplicationName', t: VT_STRING },
0x13: { n: 'DocumentSecurity', t: VT_I4 },
0x12: { n: 'Application', t: VT_STRING },
0x13: { n: 'DocSecurity', t: VT_I4 },
0xFF: {}
};
@ -12404,6 +12419,9 @@ var SpecialProperties = {
DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y];
})();
var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n");
var SummaryRE = evert_key(SummaryPIDSI, "n");
/* [MS-XLS] 2.4.63 Country/Region codes */
var CountryEnum = {
0x0001: "US", // United States
@ -13100,6 +13118,56 @@ var EXT_PROPS = [
XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
var PseudoPropsPairs = [
"Worksheets", "SheetNames",
"NamedRanges", "DefinedNames",
"Chartsheets", "ChartNames"
];
function load_props_pairs(HP, TOP, props, opts) {
var v = [];
if(typeof HP == "string") v = parseVector(HP, opts);
else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; }));
var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP;
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
props.NamedRanges = len;
props.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
props.Chartsheets = len;
props.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
function parse_ext_props(data, p, opts) {
var q = {}; if(!p) p = {};
data = utf8read(data);
@ -13115,48 +13183,7 @@ function parse_ext_props(data, p, opts) {
}
});
if(q.HeadingPairs && q.TitlesOfParts) {
var v = parseVector(q.HeadingPairs, opts);
var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; });
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
p.Worksheets = len;
p.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
p.NamedRanges = len;
p.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
p.Chartsheets = len;
p.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts);
return p;
}
@ -13353,6 +13380,15 @@ function parse_FILETIME(blob) {
var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4);
return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,"");
}
function write_FILETIME(time) {
var date = (typeof time == "string") ? new Date(Date.parse(time)) : time;
var t = date.getTime() / 1000 + 11644473600;
var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32);
l *= 1e7; h *= 1e7;
var w = (l / Math.pow(2,32)) | 0;
if(w > 0) { l = l % Math.pow(2,32); h += w; }
var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o;
}
/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
function parse_lpstr(blob, type, pad) {
@ -13422,6 +13458,7 @@ function parse_dictionary(blob,CodePage) {
var pid = blob.read_shift(4);
var len = blob.read_shift(4);
dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!');
if(CodePage === 0x4B0 && (len % 2)) blob.l += 2;
}
if(blob.l & 3) blob.l = (blob.l>>2+1)<<2;
return dict;
@ -13469,6 +13506,25 @@ function parse_TypedPropertyValue(blob, type, _opts) {
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
}
}
function write_TypedPropertyValue(type, value) {
var o = new_buf(4), p = new_buf(4);
o.write_shift(4, type == 0x50 ? 0x1F : type);
switch(type) {
case 0x03 /*VT_I4*/: p.write_shift(-4, value); break;
case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break;
case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break;
case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break;
case 0x1F /*VT_LPWSTR*/:
case 0x50 /*VT_STRING*/:
p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
p.write_shift(4, value.length + 1);
p.write_shift(0, value, "dbcs");
while(p.l != p.length) p.write_shift(1, 0);
break;
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value);
}
return bconcat([o, p]);
}
/* [MS-OLEPS] 2.20 PropertySet */
function parse_PropertySet(blob, PIDSI) {
@ -13499,7 +13555,7 @@ function parse_PropertySet(blob, PIDSI) {
if(PIDSI) {
var piddsi = PIDSI[Props[i][0]];
PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF);
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
case 0: PropH[piddsi.n] = 1252;
/* falls through */
@ -13544,8 +13600,8 @@ function parse_PropertySet(blob, PIDSI) {
/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
switch(blob[blob.l]) {
case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;
@ -13560,6 +13616,79 @@ function parse_PropertySet(blob, PIDSI) {
blob.l = start_addr + size; /* step ahead to skip padding */
return PropH;
}
var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs);
function guess_property_type(val) {
switch(typeof val) {
case "boolean": return 0x0B;
case "number": return ((val|0)==val) ? 0x03 : 0x05;
case "string": return 0x1F;
case "object": if(val instanceof Date) return 0x40; break;
}
return -1;
}
function write_PropertySet(entries, RE, PIDSI) {
var hdr = new_buf(8), piao = [], prop = [];
var sz = 8, i = 0;
var pr = new_buf(8), pio = new_buf(8);
pr.write_shift(4, 0x0002);
pr.write_shift(4, 0x04B0);
pio.write_shift(4, 0x0001);
prop.push(pr); piao.push(pio);
sz += 8 + pr.length;
if(!RE) {
pio = new_buf(8);
pio.write_shift(4, 0);
piao.unshift(pio);
var bufs = [new_buf(4)];
bufs[0].write_shift(4, entries.length);
for(i = 0; i < entries.length; ++i) {
var value = entries[i][0];
pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
pr.write_shift(4, i+2);
pr.write_shift(4, value.length + 1);
pr.write_shift(0, value, "dbcs");
while(pr.l != pr.length) pr.write_shift(1, 0);
bufs.push(pr);
}
pr = bconcat(bufs);
prop.unshift(pr);
sz += 8 + pr.length;
}
for(i = 0; i < entries.length; ++i) {
if(RE && !RE[entries[i][0]]) continue;
if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue;
if(entries[i][1] == null) continue;
var val = entries[i][1], idx = 0;
if(RE) {
idx = +RE[entries[i][0]];
var pinfo = PIDSI[idx];
if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0);
pr = write_TypedPropertyValue(pinfo.t, val);
} else {
var T = guess_property_type(val);
if(T == -1) { T = 0x1F; val = String(val); }
pr = write_TypedPropertyValue(T, val);
}
prop.push(pr);
pio = new_buf(8);
pio.write_shift(4, !RE ? 2+i : idx);
piao.push(pio);
sz += 8 + pr.length;
}
var w = 8 * (prop.length + 1);
for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; }
hdr.write_shift(4, sz);
hdr.write_shift(4, prop.length);
return bconcat([hdr].concat(piao).concat(prop));
}
/* [MS-OLEPS] 2.21 PropertySetStream */
function parse_PropertySetStream(file, PIDSI, clsid) {
@ -13596,7 +13725,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) {
rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
return rval;
}
function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2, clsid2) {
var hdr = new_buf(entries2 ? 68 : 48);
var bufs = [hdr];
hdr.write_shift(2, 0xFFFE);
hdr.write_shift(2, 0x0000); /* TODO: type 1 props */
hdr.write_shift(4, 0x32363237);
hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex");
hdr.write_shift(4, (entries2 ? 2 : 1));
hdr.write_shift(16, clsid, "hex");
hdr.write_shift(4, (entries2 ? 68 : 48));
var ps0 = write_PropertySet(entries, RE, PIDSI);
bufs.push(ps0);
if(entries2) {
var ps1 = write_PropertySet(entries2, null, null);
hdr.write_shift(16, clsid2, "hex");
hdr.write_shift(4, 68 + ps0.length);
bufs.push(ps1);
}
return bconcat(bufs);
}
function parsenoop2(blob, length) { blob.read_shift(length); return null; }
function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; }
@ -15211,6 +15360,7 @@ var SYLK = (function() {
formats.push(rstr.slice(3).replace(/;;/g, ";"));
break;
case 'C':
var C_seen_K = false;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; break;
case 'Y':
@ -15228,15 +15378,16 @@ var SYLK = (function() {
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
arr[R][C] = val;
next_cell_format = null;
C_seen_K = true;
break;
case 'E':
var formula = rc_to_a1(record[rj].slice(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);
} break;
}
if(C_seen_K) { arr[R][C] = val; next_cell_format = null; }
break;
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
@ -15247,6 +15398,7 @@ var SYLK = (function() {
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
break;
@ -16844,6 +16996,7 @@ var XLMLPatternTypeMap = {
function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -16902,7 +17055,13 @@ function parse_borders(t, styles, themes, opts) {
case '<color': case '<color>': break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders');
}
}
});
}
@ -16911,6 +17070,7 @@ function parse_borders(t, styles, themes, opts) {
function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -16961,7 +17121,13 @@ function parse_fills(t, styles, themes, opts) {
case '<color': case '<color/>': break;
case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills');
}
}
});
}
@ -16970,6 +17136,7 @@ function parse_fills(t, styles, themes, opts) {
function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -17070,7 +17237,13 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
}
}
});
}
@ -17120,6 +17293,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "
function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(y[0]) {
@ -17155,9 +17329,12 @@ function parse_cellXfs(t, styles, opts) {
case '<protection': case '</protection>': case '<protection/>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
}
}
});
}
@ -18728,6 +18905,7 @@ function parse_SerAr(blob, biff) {
case 0x04: /* SerBool -- boolean */
val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE';
if(biff != 12) blob.l += 7; break;
case 0x25: /* appears to be an alias */
case 0x10: /* SerErr -- error */
val[1] = BErr[blob[blob.l]];
blob.l += ((biff == 12) ? 4 : 8); break;
@ -18737,7 +18915,7 @@ function parse_SerAr(blob, biff) {
val[1] = parse_Xnum(blob, 8); break;
case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */
val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break;
default: throw "Bad SerAr: " + val[0]; /* Unreachable */
default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */
}
return val;
}
@ -25307,21 +25485,51 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook";
return wb;
}
/* TODO: WTF */
function parse_props(cfb, props, o) {
/* TODO: split props*/
var PSCLSID = {
SI: "e0859ff2f94f6810ab9108002b27b3d9",
DSI: "02d5cdd59c2e1b10939708002b2cf9ae",
UDI: "05d5cdd59c2e1b10939708002b2cf9ae"
};
function parse_xls_props(cfb, props, o) {
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
if(DSI && DSI.size > 0) try {
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae");
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
for(var d in DocSummary) props[d] = DocSummary[d];
} catch(e) {if(o.WTF) throw e;/* empty */}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = CFB.find(cfb, '!SummaryInformation');
if(SI && SI.size > 0) try {
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9");
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
} catch(e) {if(o.WTF) throw e;/* empty */}
if(props.HeadingPairs && props.TitlesOfParts) {
load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);
delete props.HeadingPairs; delete props.TitlesOfParts;
}
}
function write_xls_props(wb, cfb) {
var DSEntries = [], SEntries = [], CEntries = [];
var i = 0, Keys;
if(wb.Props) {
Keys = keys(wb.Props);
for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]);
}
if(wb.Custprops) {
Keys = keys(wb.Custprops);
for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]);
}
var CEntries2 = [];
for(i = 0; i < CEntries.length; ++i) {
if(XLSPSSkip.indexOf(CEntries[i][0]) > -1) continue;
if(CEntries[i][1] == null) continue;
CEntries2.push(CEntries[i]);
}
if(SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI));
if(DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI));
}
function parse_xlscfb(cfb, options) {
@ -25361,7 +25569,7 @@ else {
}
var props = {};
if(cfb.FullPaths) parse_props(cfb, props, options);
if(cfb.FullPaths) parse_xls_props(cfb, props, options);
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
if(options.bookFiles) WorkbookP.cfb = cfb;
@ -25384,6 +25592,7 @@ function write_xlscfb(wb, opts) {
default: throw new Error("invalid type " + o.bookType + " for XLS CFB");
}
CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb);
// TODO: SI, DSI, CO
if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"}));
return cfb;
@ -26772,7 +26981,7 @@ function write_FEAT(ba, ws) {
o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0);
o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0);
o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0);
write_Ref8U(safe_decode_range(ws['!ref']), o);
write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o);
o.write_shift(4, 4);
write_biff_rec(ba, "Feat", o);
}
@ -26995,11 +27204,11 @@ var HTML_ = (function() {
var row = rows[i].trim();
var hd = row.slice(0,3).toLowerCase();
if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; }
if(hd != "<td") continue;
var cells = row.split(/<\/td>/i);
if(hd != "<td" && hd != "<th") continue;
var cells = row.split(/<\/t[dh]>/i);
for(j = 0; j < cells.length; ++j) {
var cell = cells[j].trim();
if(cell.slice(0,3).toLowerCase() != "<td") continue;
if(!cell.match(/<t[dh]/i)) continue;
var m = cell, cc = 0;
/* TODO: parse styles etc */
while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1);
@ -27134,7 +27343,7 @@ function parse_dom_table(table, _opts) {
C += CS;
}
}
ws['!merges'] = merges;
if(merges.length) ws['!merges'] = merges;
ws['!ref'] = encode_range(range);
if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range));
return ws;
@ -28062,7 +28271,7 @@ function parse_zip(zip, opts) {
var styles = ({});
if(!opts.bookSheets && !opts.bookProps) {
strs = [];
if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts);
if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; }
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
@ -28488,7 +28697,7 @@ function write_string_type(out, opts, bom) {
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
if(has_buf) return new Buffer(o, 'utf8');
if(has_buf) return Buffer.from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
}
@ -28502,7 +28711,7 @@ function write_stxt_type(out, opts) {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
if(has_buf) return new Buffer(out, 'binary');
if(has_buf) return Buffer.from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
}

42
dist/xlsx.full.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.full.min.map generated vendored

File diff suppressed because one or more lines are too long

377
dist/xlsx.js generated vendored
View File

@ -4,11 +4,14 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.12.11';
XLSX.version = '0.12.12';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true */
/*global cptable:true, window */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') global.cptable = undefined;
if(typeof cptable === 'undefined') {
if(typeof global !== 'undefined') global.cptable = undefined;
else if(typeof window !== 'undefined') window.cptable = undefined;
}
}
var VALID_ANSI = [ 874, 932, 936, 949, 950 ];
@ -124,17 +127,23 @@ var Base64 = (function make_b64(){
})();
var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
function new_raw_buf(len) {
/* jshint -W056 */
// $FlowIgnore
return new (has_buf ? Buffer : Array)(len);
return has_buf ? Buffer.alloc(len) : new Array(len);
/* jshint +W056 */
}
function s2a(s) {
if(has_buf) return new Buffer(s, "binary");
var s2a = function s2a(s) {
if(has_buf) return Buffer.from(s, "binary");
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
}
};
function s2ab(s) {
if(typeof ArrayBuffer === 'undefined') return s2a(s);
@ -1124,7 +1133,7 @@ var DO_NOT_EXPORT_CFB = true;
/* [MS-CFB] v20171201 */
var CFB = (function _CFB(){
var exports = {};
exports.version = '1.0.6';
exports.version = '1.0.7';
/* [MS-CFB] 2.6.4 */
function namecmp(l, r) {
var L = l.split("/"), R = r.split("/");
@ -2247,7 +2256,7 @@ var utf8write = function(orig) {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {
j = 1;
if((c=data.charCodeAt(i)) < 128) w = c;
@ -2265,10 +2274,10 @@ if(has_buf) {
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); };
}
// matches <foo>...</foo> extracts content
@ -3207,15 +3216,15 @@ var DocSummaryPIDDSI = {
0x08: { n: 'NoteCount', t: VT_I4 },
0x09: { n: 'HiddenCount', t: VT_I4 },
0x0a: { n: 'MultimediaClipCount', t: VT_I4 },
0x0b: { n: 'Scale', t: VT_BOOL },
0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT },
0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR },
0x0b: { n: 'ScaleCrop', t: VT_BOOL },
0x0c: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT },
0x0d: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR },
0x0e: { n: 'Manager', t: VT_STRING },
0x0f: { n: 'Company', t: VT_STRING },
0x10: { n: 'LinksDirty', t: VT_BOOL },
0x10: { n: 'LinksUpToDate', t: VT_BOOL },
0x11: { n: 'CharacterCount', t: VT_I4 },
0x13: { n: 'SharedDoc', t: VT_BOOL },
0x16: { n: 'HLinksChanged', t: VT_BOOL },
0x16: { n: 'HyperlinksChanged', t: VT_BOOL },
0x17: { n: 'AppVersion', t: VT_I4, p: 'version' },
0x18: { n: 'DigSig', t: VT_BLOB },
0x1A: { n: 'ContentType', t: VT_STRING },
@ -3244,8 +3253,8 @@ var SummaryPIDSI = {
0x0F: { n: 'WordCount', t: VT_I4 },
0x10: { n: 'CharCount', t: VT_I4 },
0x11: { n: 'Thumbnail', t: VT_CF },
0x12: { n: 'ApplicationName', t: VT_STRING },
0x13: { n: 'DocumentSecurity', t: VT_I4 },
0x12: { n: 'Application', t: VT_STRING },
0x13: { n: 'DocSecurity', t: VT_I4 },
0xFF: {}
};
@ -3261,6 +3270,9 @@ var SpecialProperties = {
DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y];
})();
var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n");
var SummaryRE = evert_key(SummaryPIDSI, "n");
/* [MS-XLS] 2.4.63 Country/Region codes */
var CountryEnum = {
0x0001: "US", // United States
@ -3957,6 +3969,56 @@ var EXT_PROPS = [
XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
var PseudoPropsPairs = [
"Worksheets", "SheetNames",
"NamedRanges", "DefinedNames",
"Chartsheets", "ChartNames"
];
function load_props_pairs(HP, TOP, props, opts) {
var v = [];
if(typeof HP == "string") v = parseVector(HP, opts);
else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; }));
var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP;
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
props.NamedRanges = len;
props.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
props.Chartsheets = len;
props.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
function parse_ext_props(data, p, opts) {
var q = {}; if(!p) p = {};
data = utf8read(data);
@ -3972,48 +4034,7 @@ function parse_ext_props(data, p, opts) {
}
});
if(q.HeadingPairs && q.TitlesOfParts) {
var v = parseVector(q.HeadingPairs, opts);
var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; });
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
p.Worksheets = len;
p.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
p.NamedRanges = len;
p.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
p.Chartsheets = len;
p.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts);
return p;
}
@ -4210,6 +4231,15 @@ function parse_FILETIME(blob) {
var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4);
return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,"");
}
function write_FILETIME(time) {
var date = (typeof time == "string") ? new Date(Date.parse(time)) : time;
var t = date.getTime() / 1000 + 11644473600;
var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32);
l *= 1e7; h *= 1e7;
var w = (l / Math.pow(2,32)) | 0;
if(w > 0) { l = l % Math.pow(2,32); h += w; }
var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o;
}
/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
function parse_lpstr(blob, type, pad) {
@ -4279,6 +4309,7 @@ function parse_dictionary(blob,CodePage) {
var pid = blob.read_shift(4);
var len = blob.read_shift(4);
dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!');
if(CodePage === 0x4B0 && (len % 2)) blob.l += 2;
}
if(blob.l & 3) blob.l = (blob.l>>2+1)<<2;
return dict;
@ -4326,6 +4357,25 @@ function parse_TypedPropertyValue(blob, type, _opts) {
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
}
}
function write_TypedPropertyValue(type, value) {
var o = new_buf(4), p = new_buf(4);
o.write_shift(4, type == 0x50 ? 0x1F : type);
switch(type) {
case 0x03 /*VT_I4*/: p.write_shift(-4, value); break;
case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break;
case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break;
case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break;
case 0x1F /*VT_LPWSTR*/:
case 0x50 /*VT_STRING*/:
p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
p.write_shift(4, value.length + 1);
p.write_shift(0, value, "dbcs");
while(p.l != p.length) p.write_shift(1, 0);
break;
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value);
}
return bconcat([o, p]);
}
/* [MS-OLEPS] 2.20 PropertySet */
function parse_PropertySet(blob, PIDSI) {
@ -4356,7 +4406,7 @@ function parse_PropertySet(blob, PIDSI) {
if(PIDSI) {
var piddsi = PIDSI[Props[i][0]];
PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF);
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
case 0: PropH[piddsi.n] = 1252;
/* falls through */
@ -4401,8 +4451,8 @@ function parse_PropertySet(blob, PIDSI) {
/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
switch(blob[blob.l]) {
case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;
@ -4417,6 +4467,79 @@ function parse_PropertySet(blob, PIDSI) {
blob.l = start_addr + size; /* step ahead to skip padding */
return PropH;
}
var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs);
function guess_property_type(val) {
switch(typeof val) {
case "boolean": return 0x0B;
case "number": return ((val|0)==val) ? 0x03 : 0x05;
case "string": return 0x1F;
case "object": if(val instanceof Date) return 0x40; break;
}
return -1;
}
function write_PropertySet(entries, RE, PIDSI) {
var hdr = new_buf(8), piao = [], prop = [];
var sz = 8, i = 0;
var pr = new_buf(8), pio = new_buf(8);
pr.write_shift(4, 0x0002);
pr.write_shift(4, 0x04B0);
pio.write_shift(4, 0x0001);
prop.push(pr); piao.push(pio);
sz += 8 + pr.length;
if(!RE) {
pio = new_buf(8);
pio.write_shift(4, 0);
piao.unshift(pio);
var bufs = [new_buf(4)];
bufs[0].write_shift(4, entries.length);
for(i = 0; i < entries.length; ++i) {
var value = entries[i][0];
pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
pr.write_shift(4, i+2);
pr.write_shift(4, value.length + 1);
pr.write_shift(0, value, "dbcs");
while(pr.l != pr.length) pr.write_shift(1, 0);
bufs.push(pr);
}
pr = bconcat(bufs);
prop.unshift(pr);
sz += 8 + pr.length;
}
for(i = 0; i < entries.length; ++i) {
if(RE && !RE[entries[i][0]]) continue;
if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue;
if(entries[i][1] == null) continue;
var val = entries[i][1], idx = 0;
if(RE) {
idx = +RE[entries[i][0]];
var pinfo = PIDSI[idx];
if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0);
pr = write_TypedPropertyValue(pinfo.t, val);
} else {
var T = guess_property_type(val);
if(T == -1) { T = 0x1F; val = String(val); }
pr = write_TypedPropertyValue(T, val);
}
prop.push(pr);
pio = new_buf(8);
pio.write_shift(4, !RE ? 2+i : idx);
piao.push(pio);
sz += 8 + pr.length;
}
var w = 8 * (prop.length + 1);
for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; }
hdr.write_shift(4, sz);
hdr.write_shift(4, prop.length);
return bconcat([hdr].concat(piao).concat(prop));
}
/* [MS-OLEPS] 2.21 PropertySetStream */
function parse_PropertySetStream(file, PIDSI, clsid) {
@ -4453,7 +4576,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) {
rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
return rval;
}
function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2, clsid2) {
var hdr = new_buf(entries2 ? 68 : 48);
var bufs = [hdr];
hdr.write_shift(2, 0xFFFE);
hdr.write_shift(2, 0x0000); /* TODO: type 1 props */
hdr.write_shift(4, 0x32363237);
hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex");
hdr.write_shift(4, (entries2 ? 2 : 1));
hdr.write_shift(16, clsid, "hex");
hdr.write_shift(4, (entries2 ? 68 : 48));
var ps0 = write_PropertySet(entries, RE, PIDSI);
bufs.push(ps0);
if(entries2) {
var ps1 = write_PropertySet(entries2, null, null);
hdr.write_shift(16, clsid2, "hex");
hdr.write_shift(4, 68 + ps0.length);
bufs.push(ps1);
}
return bconcat(bufs);
}
function parsenoop2(blob, length) { blob.read_shift(length); return null; }
function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; }
@ -6068,6 +6211,7 @@ var SYLK = (function() {
formats.push(rstr.slice(3).replace(/;;/g, ";"));
break;
case 'C':
var C_seen_K = false;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; break;
case 'Y':
@ -6085,15 +6229,16 @@ var SYLK = (function() {
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
arr[R][C] = val;
next_cell_format = null;
C_seen_K = true;
break;
case 'E':
var formula = rc_to_a1(record[rj].slice(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);
} break;
}
if(C_seen_K) { arr[R][C] = val; next_cell_format = null; }
break;
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
@ -6104,6 +6249,7 @@ var SYLK = (function() {
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
break;
@ -7701,6 +7847,7 @@ var XLMLPatternTypeMap = {
function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -7759,7 +7906,13 @@ function parse_borders(t, styles, themes, opts) {
case '<color': case '<color>': break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders');
}
}
});
}
@ -7768,6 +7921,7 @@ function parse_borders(t, styles, themes, opts) {
function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -7818,7 +7972,13 @@ function parse_fills(t, styles, themes, opts) {
case '<color': case '<color/>': break;
case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills');
}
}
});
}
@ -7827,6 +7987,7 @@ function parse_fills(t, styles, themes, opts) {
function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -7927,7 +8088,13 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
}
}
});
}
@ -7977,6 +8144,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "
function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(y[0]) {
@ -8012,9 +8180,12 @@ function parse_cellXfs(t, styles, opts) {
case '<protection': case '</protection>': case '<protection/>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
}
}
});
}
@ -9585,6 +9756,7 @@ function parse_SerAr(blob, biff) {
case 0x04: /* SerBool -- boolean */
val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE';
if(biff != 12) blob.l += 7; break;
case 0x25: /* appears to be an alias */
case 0x10: /* SerErr -- error */
val[1] = BErr[blob[blob.l]];
blob.l += ((biff == 12) ? 4 : 8); break;
@ -9594,7 +9766,7 @@ function parse_SerAr(blob, biff) {
val[1] = parse_Xnum(blob, 8); break;
case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */
val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break;
default: throw "Bad SerAr: " + val[0]; /* Unreachable */
default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */
}
return val;
}
@ -16164,21 +16336,51 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook";
return wb;
}
/* TODO: WTF */
function parse_props(cfb, props, o) {
/* TODO: split props*/
var PSCLSID = {
SI: "e0859ff2f94f6810ab9108002b27b3d9",
DSI: "02d5cdd59c2e1b10939708002b2cf9ae",
UDI: "05d5cdd59c2e1b10939708002b2cf9ae"
};
function parse_xls_props(cfb, props, o) {
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
if(DSI && DSI.size > 0) try {
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae");
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
for(var d in DocSummary) props[d] = DocSummary[d];
} catch(e) {if(o.WTF) throw e;/* empty */}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = CFB.find(cfb, '!SummaryInformation');
if(SI && SI.size > 0) try {
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9");
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
} catch(e) {if(o.WTF) throw e;/* empty */}
if(props.HeadingPairs && props.TitlesOfParts) {
load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);
delete props.HeadingPairs; delete props.TitlesOfParts;
}
}
function write_xls_props(wb, cfb) {
var DSEntries = [], SEntries = [], CEntries = [];
var i = 0, Keys;
if(wb.Props) {
Keys = keys(wb.Props);
for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]);
}
if(wb.Custprops) {
Keys = keys(wb.Custprops);
for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]);
}
var CEntries2 = [];
for(i = 0; i < CEntries.length; ++i) {
if(XLSPSSkip.indexOf(CEntries[i][0]) > -1) continue;
if(CEntries[i][1] == null) continue;
CEntries2.push(CEntries[i]);
}
if(SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI));
if(DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI));
}
function parse_xlscfb(cfb, options) {
@ -16218,7 +16420,7 @@ else {
}
var props = {};
if(cfb.FullPaths) parse_props(cfb, props, options);
if(cfb.FullPaths) parse_xls_props(cfb, props, options);
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
if(options.bookFiles) WorkbookP.cfb = cfb;
@ -16241,6 +16443,7 @@ function write_xlscfb(wb, opts) {
default: throw new Error("invalid type " + o.bookType + " for XLS CFB");
}
CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb);
// TODO: SI, DSI, CO
if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"}));
return cfb;
@ -17629,7 +17832,7 @@ function write_FEAT(ba, ws) {
o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0);
o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0);
o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0);
write_Ref8U(safe_decode_range(ws['!ref']), o);
write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o);
o.write_shift(4, 4);
write_biff_rec(ba, "Feat", o);
}
@ -17852,11 +18055,11 @@ var HTML_ = (function() {
var row = rows[i].trim();
var hd = row.slice(0,3).toLowerCase();
if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; }
if(hd != "<td") continue;
var cells = row.split(/<\/td>/i);
if(hd != "<td" && hd != "<th") continue;
var cells = row.split(/<\/t[dh]>/i);
for(j = 0; j < cells.length; ++j) {
var cell = cells[j].trim();
if(cell.slice(0,3).toLowerCase() != "<td") continue;
if(!cell.match(/<t[dh]/i)) continue;
var m = cell, cc = 0;
/* TODO: parse styles etc */
while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1);
@ -17991,7 +18194,7 @@ function parse_dom_table(table, _opts) {
C += CS;
}
}
ws['!merges'] = merges;
if(merges.length) ws['!merges'] = merges;
ws['!ref'] = encode_range(range);
if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range));
return ws;
@ -18919,7 +19122,7 @@ function parse_zip(zip, opts) {
var styles = ({});
if(!opts.bookSheets && !opts.bookProps) {
strs = [];
if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts);
if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; }
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
@ -19345,7 +19548,7 @@ function write_string_type(out, opts, bom) {
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
if(has_buf) return new Buffer(o, 'utf8');
if(has_buf) return Buffer.from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
}
@ -19359,7 +19562,7 @@ function write_stxt_type(out, opts) {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
if(has_buf) return new Buffer(out, 'binary');
if(has_buf) return Buffer.from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
}

26
dist/xlsx.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.min.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -600,8 +600,14 @@ module.exports = function(data, options) {
},{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){
(function (Buffer){
'use strict';
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
module.exports = function(data, encoding){
return new Buffer(data, encoding);
return typeof data == 'number' ? Buffer.alloc(data) : Buffer.from(data, encoding);
};
module.exports.test = function(b){
return Buffer.isBuffer(b);

View File

@ -1,6 +1,6 @@
{
"name": "xlsx",
"version": "0.12.11",
"version": "0.12.12",
"author": "sheetjs",
"description": "SheetJS Spreadsheet data parser and writer",
"keywords": [
@ -31,9 +31,9 @@
},
"dependencies": {
"adler-32": "~1.2.0",
"cfb": "~1.0.6",
"codepage": "~1.12.1",
"commander": "~2.14.1",
"cfb": "~1.0.7",
"codepage": "~1.13.0",
"commander": "~2.15.1",
"crc-32": "~1.2.0",
"exit-on-epipe": "~1.0.1",
"ssf": "~0.10.2"

21
test.js
View File

@ -1347,6 +1347,14 @@ describe('write features', function() {
wb.Sheets.Sheet1['!ref'] = "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r+1, c:0});
assert.throws(function() { X.write(wb, wopts); });
}); }); });
it('single worksheet formats', function() {
var wb = X.utils.book_new();
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2],[3,4]]), "Sheet1");
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[5,6],[7,8]]), "Sheet2");
assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet1"}), "1,2\n3,4\n");
assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet2"}), "5,6\n7,8\n");
assert.throws(function() { X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet3"}); });
});
});
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
@ -1386,6 +1394,7 @@ describe('roundtrip features', function() {
if(typeof before != 'undefined') before(bef);
else it('before', bef);
describe('should preserve core properties', function() { [
['xls', paths.cpxls],
['xlml', paths.cpxml],
['xlsx', paths.cpxlsx],
['xlsb', paths.cpxlsb]
@ -1399,6 +1408,7 @@ describe('roundtrip features', function() {
}); });
describe('should preserve custom properties', function() { [
['xls', paths.cpxls],
['xlml', paths.cpxml],
['xlsx', paths.cpxlsx],
['xlsb', paths.cpxlsb]
@ -2065,6 +2075,17 @@ describe('HTML', function() {
});
if(domtest) it('DOM', function() { chk(X.utils.table_to_sheet(get_dom_element(html))); });
});
describe('TH/THEAD/TBODY/TFOOT elements', function() {
var html = "<table><thead><tr><th>A</th><th>B</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></tbody><tfoot><tr><th>4</th><th>6</th></tr></tfoot></table>";
it('HTML string', function() {
var ws = X.read(html, {type:'string'}).Sheets.Sheet1;
assert.equal(X.utils.sheet_to_csv(ws), "A,B\n1,2\n3,4\n4,6\n");
});
if(domtest) it('DOM', function() {
var ws = X.utils.table_to_sheet(get_dom_element(html));
assert.equal(X.utils.sheet_to_csv(ws), "A,B\n1,2\n3,4\n4,6\n");
});
});
});
describe('js -> file -> js', function() {

21
tests/core.js generated
View File

@ -1347,6 +1347,14 @@ describe('write features', function() {
wb.Sheets.Sheet1['!ref'] = "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r+1, c:0});
assert.throws(function() { X.write(wb, wopts); });
}); }); });
it('single worksheet formats', function() {
var wb = X.utils.book_new();
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2],[3,4]]), "Sheet1");
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[5,6],[7,8]]), "Sheet2");
assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet1"}), "1,2\n3,4\n");
assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet2"}), "5,6\n7,8\n");
assert.throws(function() { X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet3"}); });
});
});
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
@ -1386,6 +1394,7 @@ describe('roundtrip features', function() {
if(typeof before != 'undefined') before(bef);
else it('before', bef);
describe('should preserve core properties', function() { [
['xls', paths.cpxls],
['xlml', paths.cpxml],
['xlsx', paths.cpxlsx],
['xlsb', paths.cpxlsb]
@ -1399,6 +1408,7 @@ describe('roundtrip features', function() {
}); });
describe('should preserve custom properties', function() { [
['xls', paths.cpxls],
['xlml', paths.cpxml],
['xlsx', paths.cpxlsx],
['xlsb', paths.cpxlsb]
@ -2065,6 +2075,17 @@ describe('HTML', function() {
});
if(domtest) it('DOM', function() { chk(X.utils.table_to_sheet(get_dom_element(html))); });
});
describe('TH/THEAD/TBODY/TFOOT elements', function() {
var html = "<table><thead><tr><th>A</th><th>B</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></tbody><tfoot><tr><th>4</th><th>6</th></tr></tfoot></table>";
it('HTML string', function() {
var ws = X.read(html, {type:'string'}).Sheets.Sheet1;
assert.equal(X.utils.sheet_to_csv(ws), "A,B\n1,2\n3,4\n4,6\n");
});
if(domtest) it('DOM', function() {
var ws = X.utils.table_to_sheet(get_dom_element(html));
assert.equal(X.utils.sheet_to_csv(ws), "A,B\n1,2\n3,4\n4,6\n");
});
});
});
describe('js -> file -> js', function() {

View File

@ -41,6 +41,8 @@ program
.option('-E, --eth', 'emit ETH to <sheetname> or <file>.eth (Ethercalc)')
.option('-t, --txt', 'emit TXT to <sheetname> or <file>.txt (UTF-8 TSV)')
.option('-r, --rtf', 'emit RTF to <sheetname> or <file>.txt (Table RTF)')
.option('-z, --dump', 'dump internal representation as JSON')
.option('--props', 'dump workbook properties as CSV')
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
@ -96,7 +98,8 @@ if(!fs.existsSync(filename)) {
process.exit(2);
}
let opts: X.ParsingOptions = {}, wb: X.WorkBook;
const opts: X.ParsingOptions = {};
let wb: X.WorkBook;
if(program.listSheets) opts.bookSheets = true;
if(program.sheetRows) opts.sheetRows = program.sheetRows;
if(program.password) opts.password = program.password;
@ -118,7 +121,7 @@ if(seen) {
} else if(program.formulae) opts.cellFormula = true;
else opts.cellFormula = false;
let wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
const wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
if(program.compress) wopts.compression = true;
if(program.all) {
@ -153,6 +156,14 @@ if(program.listSheets) {
console.log((wb.SheetNames||[]).join("\n"));
process.exit(0);
}
if(program.dump) {
console.log(JSON.stringify(wb));
process.exit(0);
}
if(program.props) {
dump_props(wb);
process.exit(0);
}
/* full workbook formats */
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
@ -214,7 +225,7 @@ else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true}))
else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true, header:1}));
else {
strm = true;
let stream: NodeJS.ReadableStream = X.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep});
const stream: NodeJS.ReadableStream = X.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep});
if(program.output) stream.pipe(fs.createWriteStream(program.output));
else stream.pipe(process.stdout);
}
@ -225,3 +236,9 @@ if(!strm) {
}
/*:: } */
/*:: } */
function dump_props(wb: X.WorkBook) {
let propaoa: any[][] = [];
propaoa = (<any>Object).entries({...wb.Props, ...wb.Custprops});
console.log(X.utils.sheet_to_csv(X.utils.aoa_to_sheet(propaoa)));
}

View File

@ -5,7 +5,7 @@ const version: string = XLSX.version;
const SSF = XLSX.SSF;
let read_opts: XLSX.ParsingOptions = {
const read_opts: XLSX.ParsingOptions = {
type: "buffer",
raw: false,
cellFormula: false,
@ -26,7 +26,7 @@ let read_opts: XLSX.ParsingOptions = {
WTF: false
};
let write_opts: XLSX.WritingOptions = {
const write_opts: XLSX.WritingOptions = {
type: "buffer",
cellDates: false,
bookSST: false,

8
types/index.d.ts vendored
View File

@ -234,12 +234,12 @@ export interface WorkBook {
/** Ordered list of the sheet names in the workbook */
SheetNames: string[];
/**
* an object storing the standard properties. wb.Custprops stores custom properties.
* Since the XLS standard properties deviate from the XLSX standard, XLS parsing stores core properties in both places.
*/
/** Standard workbook Properties */
Props?: FullProperties;
/** Custom workbook Properties */
Custprops?: object;
Workbook?: WBProps;
vbaraw?: any;

View File

@ -6,6 +6,7 @@
"only-arrow-functions": false,
"no-consecutive-blank-lines": false,
"prefer-conditional-expression": false,
"one-variable-per-declaration": false
"one-variable-per-declaration": false,
"prefer-template": false
}
}

View File

@ -2,7 +2,7 @@
/* vim: set ts=2 ft=javascript: */
/* original data */
let data: any[][] = [
const data: any[][] = [
[1, 2, 3],
[true, false, null, "sheetjs"],
["foo bar", "baz", new Date("2014-02-19T14:30Z"), "0.3"],
@ -13,7 +13,7 @@ let data: any[][] = [
const ws_name = "SheetJS";
let wscols: XLSX.ColInfo[] = [
const wscols: XLSX.ColInfo[] = [
{wch: 6}, // "characters"
{wpx: 50}, // "pixels"
,
@ -21,7 +21,7 @@ let wscols: XLSX.ColInfo[] = [
];
/* At 96 PPI, 1 pt = 1 px */
let wsrows: XLSX.RowInfo[] = [
const wsrows: XLSX.RowInfo[] = [
{hpt: 12}, // "points"
{hpx: 16}, // "pixels"
,
@ -47,7 +47,7 @@ let wb: XLSX.WorkBook = { SheetNames: <string[]>[], Sheets: {} };
wb = XLSX.utils.book_new();
/* convert an array of arrays in JS to a CSF spreadsheet */
let ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(data, {cellDates:true});
const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(data, {cellDates:true});
/* TEST: add worksheet to workbook */
wb.SheetNames.push(ws_name);
@ -177,7 +177,7 @@ const filenames: Array<[string]|[string, XLSX.WritingOptions]> = [
filenames.forEach((r) => {
/* write file */
XLSX.writeFile(wb, r[0], r[1]);
XLSX.writeFile(wb, r[0], <XLSX.WritingOptions>r[1]);
/* test by reading back files */
XLSX.readFile(r[0]);
});

View File

@ -58,10 +58,10 @@ const wb_5: XLSX.WorkBook = XLSX.read(XLSX.write(newwb, {type: "array", bookType
const wb_6: XLSX.WorkBook = XLSX.read(XLSX.write(newwb, {type: "string", bookType: "xlsx" }), {type: "string"});
function get_header_row(sheet: XLSX.WorkSheet) {
let headers: string[] = [];
const headers: string[] = [];
const range = XLSX.utils.decode_range(sheet['!ref']);
let C: number = 0, R: number = range.s.r;
for(C = range.s.c; C <= range.e.c; ++C) {
const R: number = range.s.r;
for(let C = range.s.c; C <= range.e.c; ++C) {
const cell: XLSX.CellObject = sheet[XLSX.utils.encode_cell({c:C, r:R})];
let hdr = "UNKNOWN " + C;
if(cell && cell.t) hdr = XLSX.utils.format_cell(cell);

View File

@ -4,12 +4,15 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.12.11';
XLSX.version = '0.12.12';
var current_codepage = 1200, current_ansi = 1252;
/*:: declare var cptable:any; */
/*global cptable:true */
/*global cptable:true, window */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js');
if(typeof cptable === 'undefined') {
if(typeof global !== 'undefined') global.cptable = require('./dist/cpexcel.js');
else if(typeof window !== 'undefined') window.cptable = require('./dist/cpexcel.js');
}
}
var VALID_ANSI = [ 874, 932, 936, 949, 950 ];
@ -125,17 +128,23 @@ var Base64 = (function make_b64(){
})();
var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
function new_raw_buf(len/*:number*/) {
/* jshint -W056 */
// $FlowIgnore
return new (has_buf ? Buffer : Array)(len);
return has_buf ? Buffer.alloc(len) : new Array(len);
/* jshint +W056 */
}
function s2a(s/*:string*/)/*:any*/ {
if(has_buf) return new Buffer(s, "binary");
var s2a = function s2a(s/*:string*/)/*:any*/ {
if(has_buf) return Buffer.from(s, "binary");
return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; });
}
};
function s2ab(s/*:string*/)/*:any*/ {
if(typeof ArrayBuffer === 'undefined') return s2a(s);
@ -1188,7 +1197,7 @@ type CFBFiles = {[n:string]:CFBEntry};
/* [MS-CFB] v20171201 */
var CFB = (function _CFB(){
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
exports.version = '1.0.6';
exports.version = '1.0.7';
/* [MS-CFB] 2.6.4 */
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
var L = l.split("/"), R = r.split("/");
@ -2325,7 +2334,7 @@ var utf8write/*:StringConv*/ = function(orig/*:string*/)/*:string*/ {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {
j = 1;
if((c=data.charCodeAt(i)) < 128) w = c;
@ -2343,10 +2352,10 @@ if(has_buf) {
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); };
}
// matches <foo>...</foo> extracts content
@ -3296,15 +3305,15 @@ var DocSummaryPIDDSI = {
/*::[*/0x08/*::]*/: { n: 'NoteCount', t: VT_I4 },
/*::[*/0x09/*::]*/: { n: 'HiddenCount', t: VT_I4 },
/*::[*/0x0a/*::]*/: { n: 'MultimediaClipCount', t: VT_I4 },
/*::[*/0x0b/*::]*/: { n: 'Scale', t: VT_BOOL },
/*::[*/0x0c/*::]*/: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT },
/*::[*/0x0d/*::]*/: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR },
/*::[*/0x0b/*::]*/: { n: 'ScaleCrop', t: VT_BOOL },
/*::[*/0x0c/*::]*/: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT },
/*::[*/0x0d/*::]*/: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR },
/*::[*/0x0e/*::]*/: { n: 'Manager', t: VT_STRING },
/*::[*/0x0f/*::]*/: { n: 'Company', t: VT_STRING },
/*::[*/0x10/*::]*/: { n: 'LinksDirty', t: VT_BOOL },
/*::[*/0x10/*::]*/: { n: 'LinksUpToDate', t: VT_BOOL },
/*::[*/0x11/*::]*/: { n: 'CharacterCount', t: VT_I4 },
/*::[*/0x13/*::]*/: { n: 'SharedDoc', t: VT_BOOL },
/*::[*/0x16/*::]*/: { n: 'HLinksChanged', t: VT_BOOL },
/*::[*/0x16/*::]*/: { n: 'HyperlinksChanged', t: VT_BOOL },
/*::[*/0x17/*::]*/: { n: 'AppVersion', t: VT_I4, p: 'version' },
/*::[*/0x18/*::]*/: { n: 'DigSig', t: VT_BLOB },
/*::[*/0x1A/*::]*/: { n: 'ContentType', t: VT_STRING },
@ -3333,8 +3342,8 @@ var SummaryPIDSI = {
/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 },
/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 },
/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF },
/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_STRING },
/*::[*/0x13/*::]*/: { n: 'DocumentSecurity', t: VT_I4 },
/*::[*/0x12/*::]*/: { n: 'Application', t: VT_STRING },
/*::[*/0x13/*::]*/: { n: 'DocSecurity', t: VT_I4 },
/*::[*/0xFF/*::]*/: {}
};
@ -3350,6 +3359,9 @@ var SpecialProperties = {
DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y];
})();
var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n");
var SummaryRE = evert_key(SummaryPIDSI, "n");
/* [MS-XLS] 2.4.63 Country/Region codes */
var CountryEnum = {
/*::[*/0x0001/*::]*/: "US", // United States
@ -4046,6 +4058,56 @@ var EXT_PROPS/*:Array<Array<string> >*/ = [
XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
var PseudoPropsPairs = [
"Worksheets", "SheetNames",
"NamedRanges", "DefinedNames",
"Chartsheets", "ChartNames"
];
function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) {
var v = [];
if(typeof HP == "string") v = parseVector(HP, opts);
else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; }));
var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP;
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
props.NamedRanges = len;
props.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
props.Chartsheets = len;
props.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
function parse_ext_props(data, p, opts) {
var q = {}; if(!p) p = {};
data = utf8read(data);
@ -4061,48 +4123,7 @@ function parse_ext_props(data, p, opts) {
}
});
if(q.HeadingPairs && q.TitlesOfParts) {
var v = parseVector(q.HeadingPairs, opts);
var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; });
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
p.Worksheets = len;
p.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
p.NamedRanges = len;
p.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
p.Chartsheets = len;
p.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts);
return p;
}
@ -4301,6 +4322,15 @@ function parse_FILETIME(blob) {
var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4);
return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,"");
}
function write_FILETIME(time/*:string|Date*/) {
var date = (typeof time == "string") ? new Date(Date.parse(time)) : time;
var t = date.getTime() / 1000 + 11644473600;
var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32);
l *= 1e7; h *= 1e7;
var w = (l / Math.pow(2,32)) | 0;
if(w > 0) { l = l % Math.pow(2,32); h += w; }
var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o;
}
/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
function parse_lpstr(blob, type, pad/*:?number*/) {
@ -4370,6 +4400,7 @@ function parse_dictionary(blob,CodePage) {
var pid = blob.read_shift(4);
var len = blob.read_shift(4);
dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!');
if(CodePage === 0x4B0 && (len % 2)) blob.l += 2;
}
if(blob.l & 3) blob.l = (blob.l>>2+1)<<2;
return dict;
@ -4417,6 +4448,25 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
}
}
function write_TypedPropertyValue(type/*:number*/, value) {
var o = new_buf(4), p = new_buf(4);
o.write_shift(4, type == 0x50 ? 0x1F : type);
switch(type) {
case 0x03 /*VT_I4*/: p.write_shift(-4, value); break;
case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break;
case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break;
case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break;
case 0x1F /*VT_LPWSTR*/:
case 0x50 /*VT_STRING*/:
p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
p.write_shift(4, value.length + 1);
p.write_shift(0, value, "dbcs");
while(p.l != p.length) p.write_shift(1, 0);
break;
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value);
}
return bconcat([o, p]);
}
/* [MS-OLEPS] 2.20 PropertySet */
function parse_PropertySet(blob, PIDSI) {
@ -4447,7 +4497,7 @@ function parse_PropertySet(blob, PIDSI) {
if(PIDSI) {
var piddsi = PIDSI[Props[i][0]];
PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF);
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
case 0: PropH[piddsi.n] = 1252;
/* falls through */
@ -4492,8 +4542,8 @@ function parse_PropertySet(blob, PIDSI) {
/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
switch(blob[blob.l]) {
case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;
@ -4508,6 +4558,79 @@ function parse_PropertySet(blob, PIDSI) {
blob.l = start_addr + size; /* step ahead to skip padding */
return PropH;
}
var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs);
function guess_property_type(val/*:any*/)/*:number*/ {
switch(typeof val) {
case "boolean": return 0x0B;
case "number": return ((val|0)==val) ? 0x03 : 0x05;
case "string": return 0x1F;
case "object": if(val instanceof Date) return 0x40; break;
}
return -1;
}
function write_PropertySet(entries, RE, PIDSI) {
var hdr = new_buf(8), piao = [], prop = [];
var sz = 8, i = 0;
var pr = new_buf(8), pio = new_buf(8);
pr.write_shift(4, 0x0002);
pr.write_shift(4, 0x04B0);
pio.write_shift(4, 0x0001);
prop.push(pr); piao.push(pio);
sz += 8 + pr.length;
if(!RE) {
pio = new_buf(8);
pio.write_shift(4, 0);
piao.unshift(pio);
var bufs = [new_buf(4)];
bufs[0].write_shift(4, entries.length);
for(i = 0; i < entries.length; ++i) {
var value = entries[i][0];
pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
pr.write_shift(4, i+2);
pr.write_shift(4, value.length + 1);
pr.write_shift(0, value, "dbcs");
while(pr.l != pr.length) pr.write_shift(1, 0);
bufs.push(pr);
}
pr = bconcat(bufs);
prop.unshift(pr);
sz += 8 + pr.length;
}
for(i = 0; i < entries.length; ++i) {
if(RE && !RE[entries[i][0]]) continue;
if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue;
if(entries[i][1] == null) continue;
var val = entries[i][1], idx = 0;
if(RE) {
idx = +RE[entries[i][0]];
var pinfo = PIDSI[idx];
if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0);
pr = write_TypedPropertyValue(pinfo.t, val);
} else {
var T = guess_property_type(val);
if(T == -1) { T = 0x1F; val = String(val); }
pr = write_TypedPropertyValue(T, val);
}
prop.push(pr);
pio = new_buf(8);
pio.write_shift(4, !RE ? 2+i : idx);
piao.push(pio);
sz += 8 + pr.length;
}
var w = 8 * (prop.length + 1);
for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; }
hdr.write_shift(4, sz);
hdr.write_shift(4, prop.length);
return bconcat([hdr].concat(piao).concat(prop));
}
/* [MS-OLEPS] 2.21 PropertySetStream */
function parse_PropertySetStream(file, PIDSI, clsid) {
@ -4544,7 +4667,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) {
rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
return rval;
}
function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2/*:?any*/, clsid2/*:?any*/) {
var hdr = new_buf(entries2 ? 68 : 48);
var bufs = [hdr];
hdr.write_shift(2, 0xFFFE);
hdr.write_shift(2, 0x0000); /* TODO: type 1 props */
hdr.write_shift(4, 0x32363237);
hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex");
hdr.write_shift(4, (entries2 ? 2 : 1));
hdr.write_shift(16, clsid, "hex");
hdr.write_shift(4, (entries2 ? 68 : 48));
var ps0 = write_PropertySet(entries, RE, PIDSI);
bufs.push(ps0);
if(entries2) {
var ps1 = write_PropertySet(entries2, null, null);
hdr.write_shift(16, clsid2, "hex");
hdr.write_shift(4, 68 + ps0.length);
bufs.push(ps1);
}
return bconcat(bufs);
}
function parsenoop2(blob, length) { blob.read_shift(length); return null; }
function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; }
@ -6160,6 +6303,7 @@ var SYLK = (function() {
formats.push(rstr.slice(3).replace(/;;/g, ";"));
break;
case 'C':
var C_seen_K = false;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; break;
case 'Y':
@ -6177,15 +6321,16 @@ var SYLK = (function() {
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
arr[R][C] = val;
next_cell_format = null;
C_seen_K = true;
break;
case 'E':
var formula = rc_to_a1(record[rj].slice(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);
} break;
}
if(C_seen_K) { arr[R][C] = val; next_cell_format = null; }
break;
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
@ -6196,6 +6341,7 @@ var SYLK = (function() {
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
break;
@ -7794,6 +7940,7 @@ var XLMLPatternTypeMap = {
function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -7852,7 +7999,13 @@ function parse_borders(t, styles, themes, opts) {
case '<color': case '<color>': break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders');
}
}
});
}
@ -7861,6 +8014,7 @@ function parse_borders(t, styles, themes, opts) {
function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -7911,7 +8065,13 @@ function parse_fills(t, styles, themes, opts) {
case '<color': case '<color/>': break;
case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills');
}
}
});
}
@ -7920,6 +8080,7 @@ function parse_fills(t, styles, themes, opts) {
function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -8020,7 +8181,13 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
}
}
});
}
@ -8070,6 +8237,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "
function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(y[0]) {
@ -8105,9 +8273,12 @@ function parse_cellXfs(t, styles, opts) {
case '<protection': case '</protection>': case '<protection/>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
}
}
});
}
@ -9680,6 +9851,7 @@ function parse_SerAr(blob, biff/*:number*/) {
case 0x04: /* SerBool -- boolean */
val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE';
if(biff != 12) blob.l += 7; break;
case 0x25: /* appears to be an alias */
case 0x10: /* SerErr -- error */
val[1] = BErr[blob[blob.l]];
blob.l += ((biff == 12) ? 4 : 8); break;
@ -9689,7 +9861,7 @@ function parse_SerAr(blob, biff/*:number*/) {
val[1] = parse_Xnum(blob, 8); break;
case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */
val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break;
default: throw "Bad SerAr: " + val[0]; /* Unreachable */
default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */
}
return val;
}
@ -16274,21 +16446,51 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
return wb;
}
/* TODO: WTF */
function parse_props(cfb/*:CFBContainer*/, props, o) {
/* TODO: split props*/
var PSCLSID = {
SI: "e0859ff2f94f6810ab9108002b27b3d9",
DSI: "02d5cdd59c2e1b10939708002b2cf9ae",
UDI: "05d5cdd59c2e1b10939708002b2cf9ae"
};
function parse_xls_props(cfb/*:CFBContainer*/, props, o) {
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
if(DSI && DSI.size > 0) try {
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae");
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
for(var d in DocSummary) props[d] = DocSummary[d];
} catch(e) {if(o.WTF) throw e;/* empty */}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = CFB.find(cfb, '!SummaryInformation');
if(SI && SI.size > 0) try {
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9");
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
} catch(e) {if(o.WTF) throw e;/* empty */}
if(props.HeadingPairs && props.TitlesOfParts) {
load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);
delete props.HeadingPairs; delete props.TitlesOfParts;
}
}
function write_xls_props(wb/*:Workbook*/, cfb/*:CFBContainer*/) {
var DSEntries = [], SEntries = [], CEntries = [];
var i = 0, Keys;
if(wb.Props) {
Keys = keys(wb.Props);
for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]);
}
if(wb.Custprops) {
Keys = keys(wb.Custprops);
for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]);
}
var CEntries2 = [];
for(i = 0; i < CEntries.length; ++i) {
if(XLSPSSkip.indexOf(CEntries[i][0]) > -1) continue;
if(CEntries[i][1] == null) continue;
CEntries2.push(CEntries[i]);
}
if(SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI));
if(DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI));
}
function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ {
@ -16328,7 +16530,7 @@ else/*:: if(cfb instanceof CFBContainer) */ {
}
var props = {};
if(cfb.FullPaths) parse_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options);
if(cfb.FullPaths) parse_xls_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options);
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
if(options.bookFiles) WorkbookP.cfb = cfb;
@ -16351,6 +16553,7 @@ function write_xlscfb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:CFBContainer*/ {
default: throw new Error("invalid type " + o.bookType + " for XLS CFB");
}
CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb);
// TODO: SI, DSI, CO
if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"}));
return cfb;
@ -17740,7 +17943,7 @@ function write_FEAT(ba, ws) {
o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0);
o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0);
o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0);
write_Ref8U(safe_decode_range(ws['!ref']), o);
write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o);
o.write_shift(4, 4);
write_biff_rec(ba, "Feat", o);
}
@ -17963,11 +18166,11 @@ var HTML_ = (function() {
var row = rows[i].trim();
var hd = row.slice(0,3).toLowerCase();
if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; }
if(hd != "<td") continue;
var cells = row.split(/<\/td>/i);
if(hd != "<td" && hd != "<th") continue;
var cells = row.split(/<\/t[dh]>/i);
for(j = 0; j < cells.length; ++j) {
var cell = cells[j].trim();
if(cell.slice(0,3).toLowerCase() != "<td") continue;
if(!cell.match(/<t[dh]/i)) continue;
var m = cell, cc = 0;
/* TODO: parse styles etc */
while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1);
@ -18102,7 +18305,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
C += CS;
}
}
ws['!merges'] = merges;
if(merges.length) ws['!merges'] = merges;
ws['!ref'] = encode_range(range);
if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range));
return ws;
@ -19031,7 +19234,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var styles = ({}/*:any*/);
if(!opts.bookSheets && !opts.bookProps) {
strs = [];
if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts);
if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; }
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
@ -19462,7 +19665,7 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
if(has_buf) return new Buffer(o, 'utf8');
if(has_buf) return Buffer.from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
}
@ -19476,7 +19679,7 @@ function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
if(has_buf) return new Buffer(out, 'binary');
if(has_buf) return Buffer.from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
}

377
xlsx.js generated
View File

@ -4,11 +4,14 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.12.11';
XLSX.version = '0.12.12';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true */
/*global cptable:true, window */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js');
if(typeof cptable === 'undefined') {
if(typeof global !== 'undefined') global.cptable = require('./dist/cpexcel.js');
else if(typeof window !== 'undefined') window.cptable = require('./dist/cpexcel.js');
}
}
var VALID_ANSI = [ 874, 932, 936, 949, 950 ];
@ -124,17 +127,23 @@ var Base64 = (function make_b64(){
})();
var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);
if(typeof Buffer !== 'undefined') {
// $FlowIgnore
if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); };
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
}
function new_raw_buf(len) {
/* jshint -W056 */
// $FlowIgnore
return new (has_buf ? Buffer : Array)(len);
return has_buf ? Buffer.alloc(len) : new Array(len);
/* jshint +W056 */
}
function s2a(s) {
if(has_buf) return new Buffer(s, "binary");
var s2a = function s2a(s) {
if(has_buf) return Buffer.from(s, "binary");
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
}
};
function s2ab(s) {
if(typeof ArrayBuffer === 'undefined') return s2a(s);
@ -1124,7 +1133,7 @@ var DO_NOT_EXPORT_CFB = true;
/* [MS-CFB] v20171201 */
var CFB = (function _CFB(){
var exports = {};
exports.version = '1.0.6';
exports.version = '1.0.7';
/* [MS-CFB] 2.6.4 */
function namecmp(l, r) {
var L = l.split("/"), R = r.split("/");
@ -2247,7 +2256,7 @@ var utf8write = function(orig) {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {
j = 1;
if((c=data.charCodeAt(i)) < 128) w = c;
@ -2265,10 +2274,10 @@ if(has_buf) {
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
// $FlowIgnore
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); };
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); };
}
// matches <foo>...</foo> extracts content
@ -3207,15 +3216,15 @@ var DocSummaryPIDDSI = {
0x08: { n: 'NoteCount', t: VT_I4 },
0x09: { n: 'HiddenCount', t: VT_I4 },
0x0a: { n: 'MultimediaClipCount', t: VT_I4 },
0x0b: { n: 'Scale', t: VT_BOOL },
0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT },
0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR },
0x0b: { n: 'ScaleCrop', t: VT_BOOL },
0x0c: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT },
0x0d: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR },
0x0e: { n: 'Manager', t: VT_STRING },
0x0f: { n: 'Company', t: VT_STRING },
0x10: { n: 'LinksDirty', t: VT_BOOL },
0x10: { n: 'LinksUpToDate', t: VT_BOOL },
0x11: { n: 'CharacterCount', t: VT_I4 },
0x13: { n: 'SharedDoc', t: VT_BOOL },
0x16: { n: 'HLinksChanged', t: VT_BOOL },
0x16: { n: 'HyperlinksChanged', t: VT_BOOL },
0x17: { n: 'AppVersion', t: VT_I4, p: 'version' },
0x18: { n: 'DigSig', t: VT_BLOB },
0x1A: { n: 'ContentType', t: VT_STRING },
@ -3244,8 +3253,8 @@ var SummaryPIDSI = {
0x0F: { n: 'WordCount', t: VT_I4 },
0x10: { n: 'CharCount', t: VT_I4 },
0x11: { n: 'Thumbnail', t: VT_CF },
0x12: { n: 'ApplicationName', t: VT_STRING },
0x13: { n: 'DocumentSecurity', t: VT_I4 },
0x12: { n: 'Application', t: VT_STRING },
0x13: { n: 'DocSecurity', t: VT_I4 },
0xFF: {}
};
@ -3261,6 +3270,9 @@ var SpecialProperties = {
DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y];
})();
var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n");
var SummaryRE = evert_key(SummaryPIDSI, "n");
/* [MS-XLS] 2.4.63 Country/Region codes */
var CountryEnum = {
0x0001: "US", // United States
@ -3957,6 +3969,56 @@ var EXT_PROPS = [
XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
var PseudoPropsPairs = [
"Worksheets", "SheetNames",
"NamedRanges", "DefinedNames",
"Chartsheets", "ChartNames"
];
function load_props_pairs(HP, TOP, props, opts) {
var v = [];
if(typeof HP == "string") v = parseVector(HP, opts);
else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; }));
var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP;
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
props.Worksheets = len;
props.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
props.NamedRanges = len;
props.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
props.Chartsheets = len;
props.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
function parse_ext_props(data, p, opts) {
var q = {}; if(!p) p = {};
data = utf8read(data);
@ -3972,48 +4034,7 @@ function parse_ext_props(data, p, opts) {
}
});
if(q.HeadingPairs && q.TitlesOfParts) {
var v = parseVector(q.HeadingPairs, opts);
var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; });
var idx = 0, len = 0;
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
case "工作表":
case "Листы":
case "أوراق العمل":
case "ワークシート":
case "גליונות עבודה":
case "Arbeitsblätter":
case "Çalışma Sayfaları":
case "Feuilles de calcul":
case "Fogli di lavoro":
case "Folhas de cálculo":
case "Planilhas":
case "Regneark":
case "Werkbladen":
p.Worksheets = len;
p.SheetNames = parts.slice(idx, idx + len);
break;
case "Named Ranges":
case "名前付き一覧":
case "Benannte Bereiche":
case "Navngivne områder":
p.NamedRanges = len;
p.DefinedNames = parts.slice(idx, idx + len);
break;
case "Charts":
case "Diagramme":
p.Chartsheets = len;
p.ChartNames = parts.slice(idx, idx + len);
break;
}
idx += len;
}
}
if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts);
return p;
}
@ -4210,6 +4231,15 @@ function parse_FILETIME(blob) {
var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4);
return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,"");
}
function write_FILETIME(time) {
var date = (typeof time == "string") ? new Date(Date.parse(time)) : time;
var t = date.getTime() / 1000 + 11644473600;
var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32);
l *= 1e7; h *= 1e7;
var w = (l / Math.pow(2,32)) | 0;
if(w > 0) { l = l % Math.pow(2,32); h += w; }
var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o;
}
/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
function parse_lpstr(blob, type, pad) {
@ -4279,6 +4309,7 @@ function parse_dictionary(blob,CodePage) {
var pid = blob.read_shift(4);
var len = blob.read_shift(4);
dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!');
if(CodePage === 0x4B0 && (len % 2)) blob.l += 2;
}
if(blob.l & 3) blob.l = (blob.l>>2+1)<<2;
return dict;
@ -4326,6 +4357,25 @@ function parse_TypedPropertyValue(blob, type, _opts) {
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
}
}
function write_TypedPropertyValue(type, value) {
var o = new_buf(4), p = new_buf(4);
o.write_shift(4, type == 0x50 ? 0x1F : type);
switch(type) {
case 0x03 /*VT_I4*/: p.write_shift(-4, value); break;
case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break;
case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break;
case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break;
case 0x1F /*VT_LPWSTR*/:
case 0x50 /*VT_STRING*/:
p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
p.write_shift(4, value.length + 1);
p.write_shift(0, value, "dbcs");
while(p.l != p.length) p.write_shift(1, 0);
break;
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value);
}
return bconcat([o, p]);
}
/* [MS-OLEPS] 2.20 PropertySet */
function parse_PropertySet(blob, PIDSI) {
@ -4356,7 +4406,7 @@ function parse_PropertySet(blob, PIDSI) {
if(PIDSI) {
var piddsi = PIDSI[Props[i][0]];
PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF);
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
case 0: PropH[piddsi.n] = 1252;
/* falls through */
@ -4401,8 +4451,8 @@ function parse_PropertySet(blob, PIDSI) {
/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
switch(blob[blob.l]) {
case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;
@ -4417,6 +4467,79 @@ function parse_PropertySet(blob, PIDSI) {
blob.l = start_addr + size; /* step ahead to skip padding */
return PropH;
}
var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs);
function guess_property_type(val) {
switch(typeof val) {
case "boolean": return 0x0B;
case "number": return ((val|0)==val) ? 0x03 : 0x05;
case "string": return 0x1F;
case "object": if(val instanceof Date) return 0x40; break;
}
return -1;
}
function write_PropertySet(entries, RE, PIDSI) {
var hdr = new_buf(8), piao = [], prop = [];
var sz = 8, i = 0;
var pr = new_buf(8), pio = new_buf(8);
pr.write_shift(4, 0x0002);
pr.write_shift(4, 0x04B0);
pio.write_shift(4, 0x0001);
prop.push(pr); piao.push(pio);
sz += 8 + pr.length;
if(!RE) {
pio = new_buf(8);
pio.write_shift(4, 0);
piao.unshift(pio);
var bufs = [new_buf(4)];
bufs[0].write_shift(4, entries.length);
for(i = 0; i < entries.length; ++i) {
var value = entries[i][0];
pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
pr.write_shift(4, i+2);
pr.write_shift(4, value.length + 1);
pr.write_shift(0, value, "dbcs");
while(pr.l != pr.length) pr.write_shift(1, 0);
bufs.push(pr);
}
pr = bconcat(bufs);
prop.unshift(pr);
sz += 8 + pr.length;
}
for(i = 0; i < entries.length; ++i) {
if(RE && !RE[entries[i][0]]) continue;
if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue;
if(entries[i][1] == null) continue;
var val = entries[i][1], idx = 0;
if(RE) {
idx = +RE[entries[i][0]];
var pinfo = PIDSI[idx];
if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0);
pr = write_TypedPropertyValue(pinfo.t, val);
} else {
var T = guess_property_type(val);
if(T == -1) { T = 0x1F; val = String(val); }
pr = write_TypedPropertyValue(T, val);
}
prop.push(pr);
pio = new_buf(8);
pio.write_shift(4, !RE ? 2+i : idx);
piao.push(pio);
sz += 8 + pr.length;
}
var w = 8 * (prop.length + 1);
for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; }
hdr.write_shift(4, sz);
hdr.write_shift(4, prop.length);
return bconcat([hdr].concat(piao).concat(prop));
}
/* [MS-OLEPS] 2.21 PropertySetStream */
function parse_PropertySetStream(file, PIDSI, clsid) {
@ -4453,7 +4576,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) {
rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
return rval;
}
function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2, clsid2) {
var hdr = new_buf(entries2 ? 68 : 48);
var bufs = [hdr];
hdr.write_shift(2, 0xFFFE);
hdr.write_shift(2, 0x0000); /* TODO: type 1 props */
hdr.write_shift(4, 0x32363237);
hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex");
hdr.write_shift(4, (entries2 ? 2 : 1));
hdr.write_shift(16, clsid, "hex");
hdr.write_shift(4, (entries2 ? 68 : 48));
var ps0 = write_PropertySet(entries, RE, PIDSI);
bufs.push(ps0);
if(entries2) {
var ps1 = write_PropertySet(entries2, null, null);
hdr.write_shift(16, clsid2, "hex");
hdr.write_shift(4, 68 + ps0.length);
bufs.push(ps1);
}
return bconcat(bufs);
}
function parsenoop2(blob, length) { blob.read_shift(length); return null; }
function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; }
@ -6068,6 +6211,7 @@ var SYLK = (function() {
formats.push(rstr.slice(3).replace(/;;/g, ";"));
break;
case 'C':
var C_seen_K = false;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; break;
case 'Y':
@ -6085,15 +6229,16 @@ var SYLK = (function() {
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
arr[R][C] = val;
next_cell_format = null;
C_seen_K = true;
break;
case 'E':
var formula = rc_to_a1(record[rj].slice(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);
} break;
}
if(C_seen_K) { arr[R][C] = val; next_cell_format = null; }
break;
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
@ -6104,6 +6249,7 @@ var SYLK = (function() {
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
break;
@ -7701,6 +7847,7 @@ var XLMLPatternTypeMap = {
function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {}/*, sub_border = {}*/;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -7759,7 +7906,13 @@ function parse_borders(t, styles, themes, opts) {
case '<color': case '<color>': break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders');
}
}
});
}
@ -7768,6 +7921,7 @@ function parse_borders(t, styles, themes, opts) {
function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -7818,7 +7972,13 @@ function parse_fills(t, styles, themes, opts) {
case '<color': case '<color/>': break;
case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills');
}
}
});
}
@ -7827,6 +7987,7 @@ function parse_fills(t, styles, themes, opts) {
function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x);
switch (y[0]) {
@ -7927,7 +8088,13 @@ function parse_fonts(t, styles, themes, opts) {
break;
case '<color/>': case '</color>': break;
default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts');
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
}
}
});
}
@ -7977,6 +8144,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "
function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
t[0].match(tagregex).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(y[0]) {
@ -8012,9 +8180,12 @@ function parse_cellXfs(t, styles, opts) {
case '<protection': case '</protection>': case '<protection/>': break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '</extLst>': break;
case '<ext': break;
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
case '<extLst': case '<extLst>': case '</extLst>': break;
case '<ext': pass = true; break;
case '</ext>': pass = false; break;
default: if(opts && opts.WTF) {
if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
}
}
});
}
@ -9585,6 +9756,7 @@ function parse_SerAr(blob, biff) {
case 0x04: /* SerBool -- boolean */
val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE';
if(biff != 12) blob.l += 7; break;
case 0x25: /* appears to be an alias */
case 0x10: /* SerErr -- error */
val[1] = BErr[blob[blob.l]];
blob.l += ((biff == 12) ? 4 : 8); break;
@ -9594,7 +9766,7 @@ function parse_SerAr(blob, biff) {
val[1] = parse_Xnum(blob, 8); break;
case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */
val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break;
default: throw "Bad SerAr: " + val[0]; /* Unreachable */
default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */
}
return val;
}
@ -16164,21 +16336,51 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook";
return wb;
}
/* TODO: WTF */
function parse_props(cfb, props, o) {
/* TODO: split props*/
var PSCLSID = {
SI: "e0859ff2f94f6810ab9108002b27b3d9",
DSI: "02d5cdd59c2e1b10939708002b2cf9ae",
UDI: "05d5cdd59c2e1b10939708002b2cf9ae"
};
function parse_xls_props(cfb, props, o) {
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
if(DSI && DSI.size > 0) try {
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae");
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
for(var d in DocSummary) props[d] = DocSummary[d];
} catch(e) {if(o.WTF) throw e;/* empty */}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = CFB.find(cfb, '!SummaryInformation');
if(SI && SI.size > 0) try {
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9");
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
} catch(e) {if(o.WTF) throw e;/* empty */}
if(props.HeadingPairs && props.TitlesOfParts) {
load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);
delete props.HeadingPairs; delete props.TitlesOfParts;
}
}
function write_xls_props(wb, cfb) {
var DSEntries = [], SEntries = [], CEntries = [];
var i = 0, Keys;
if(wb.Props) {
Keys = keys(wb.Props);
for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]);
}
if(wb.Custprops) {
Keys = keys(wb.Custprops);
for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]);
}
var CEntries2 = [];
for(i = 0; i < CEntries.length; ++i) {
if(XLSPSSkip.indexOf(CEntries[i][0]) > -1) continue;
if(CEntries[i][1] == null) continue;
CEntries2.push(CEntries[i]);
}
if(SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI));
if(DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI));
}
function parse_xlscfb(cfb, options) {
@ -16218,7 +16420,7 @@ else {
}
var props = {};
if(cfb.FullPaths) parse_props(cfb, props, options);
if(cfb.FullPaths) parse_xls_props(cfb, props, options);
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
if(options.bookFiles) WorkbookP.cfb = cfb;
@ -16241,6 +16443,7 @@ function write_xlscfb(wb, opts) {
default: throw new Error("invalid type " + o.bookType + " for XLS CFB");
}
CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb);
// TODO: SI, DSI, CO
if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"}));
return cfb;
@ -17629,7 +17832,7 @@ function write_FEAT(ba, ws) {
o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0);
o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0);
o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0);
write_Ref8U(safe_decode_range(ws['!ref']), o);
write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o);
o.write_shift(4, 4);
write_biff_rec(ba, "Feat", o);
}
@ -17852,11 +18055,11 @@ var HTML_ = (function() {
var row = rows[i].trim();
var hd = row.slice(0,3).toLowerCase();
if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; }
if(hd != "<td") continue;
var cells = row.split(/<\/td>/i);
if(hd != "<td" && hd != "<th") continue;
var cells = row.split(/<\/t[dh]>/i);
for(j = 0; j < cells.length; ++j) {
var cell = cells[j].trim();
if(cell.slice(0,3).toLowerCase() != "<td") continue;
if(!cell.match(/<t[dh]/i)) continue;
var m = cell, cc = 0;
/* TODO: parse styles etc */
while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1);
@ -17991,7 +18194,7 @@ function parse_dom_table(table, _opts) {
C += CS;
}
}
ws['!merges'] = merges;
if(merges.length) ws['!merges'] = merges;
ws['!ref'] = encode_range(range);
if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range));
return ws;
@ -18919,7 +19122,7 @@ function parse_zip(zip, opts) {
var styles = ({});
if(!opts.bookSheets && !opts.bookProps) {
strs = [];
if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts);
if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; }
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
@ -19345,7 +19548,7 @@ function write_string_type(out, opts, bom) {
case "string": return out;
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
if(has_buf) return new Buffer(o, 'utf8');
if(has_buf) return Buffer.from(o, 'utf8');
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
}
@ -19359,7 +19562,7 @@ function write_stxt_type(out, opts) {
case "string": return out; /* override in sheet_to_txt */
case "file": return write_dl(opts.file, out, 'binary');
case "buffer": {
if(has_buf) return new Buffer(out, 'binary');
if(has_buf) return Buffer.from(out, 'binary');
else return out.split("").map(function(c) { return c.charCodeAt(0); });
}
}