forked from sheetjs/sheetjs
fixed flow typecheck
- update FilterDatabase defined name when writing AutoFilter - XLML stub cells have blank Data block - HTML export honor `id` option - expose `sheet_get_cell`
This commit is contained in:
parent
b0d18ed6db
commit
b7c0b0d914
@ -8,11 +8,14 @@
|
||||
.*/misc/.*
|
||||
.*/perf/.*
|
||||
.*/_book/.*
|
||||
.*/packages/.*
|
||||
|
||||
.*/demo/browser.js
|
||||
.*/shim.js
|
||||
|
||||
.*/xlsx.js
|
||||
.*/xlsx.mini.js
|
||||
.*/xlsx.mini.flow.js
|
||||
.*/xlsxworker.js
|
||||
.*/jszip.js
|
||||
.*/tests/.*
|
||||
|
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@ -1,2 +1,3 @@
|
||||
github: SheetJSDev
|
||||
custom: https://sheetjs.com
|
||||
open_collective: s5s
|
||||
|
2
LICENSE
2
LICENSE
@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (C) 2012-present SheetJS LLC
|
||||
Copyright (C) 2012-present SheetJS LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -261,21 +261,21 @@ switch(true) {
|
||||
break;
|
||||
}
|
||||
|
||||
function dump_props(wb) {
|
||||
function dump_props(wb/*:Workbook*/) {
|
||||
var propaoa = [];
|
||||
if(Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops));
|
||||
else {
|
||||
var Keys, pi;
|
||||
var Keys/*:: :Array<string> = []*/, 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(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]]]);
|
||||
if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ function new_unsafe_buf(len/*:number*/) {
|
||||
}
|
||||
|
||||
var s2a = function s2a(s/*:string*/)/*:any*/ {
|
||||
// $FlowIgnore
|
||||
if(has_buf) return Buffer_from(s, "binary");
|
||||
return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; });
|
||||
};
|
||||
|
@ -64,17 +64,6 @@ function zip_add_file(zip, path, content) {
|
||||
else zip.file(path, content);
|
||||
}
|
||||
|
||||
function zip_read(d, o) {
|
||||
var zip;
|
||||
switch(o.type) {
|
||||
case "base64": zip = new jszip(d, { base64:true }); break;
|
||||
case "binary": case "array": zip = new jszip(d, { base64:false }); break;
|
||||
case "buffer": zip = new jszip(d); break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
return zip;
|
||||
}
|
||||
|
||||
var jszip;
|
||||
/*:: declare var JSZipSync:any; */
|
||||
/*global JSZipSync:true */
|
||||
@ -86,10 +75,29 @@ if(typeof exports !== 'undefined') {
|
||||
}
|
||||
|
||||
function zip_new() {
|
||||
if(!jszip) return CFB.utils.cfb_new();
|
||||
return new jszip();
|
||||
}
|
||||
|
||||
function zip_read(d, o) {
|
||||
var zip;
|
||||
if(jszip) switch(o.type) {
|
||||
case "base64": zip = new jszip(d, { base64:true }); break;
|
||||
case "binary": case "array": zip = new jszip(d, { base64:false }); break;
|
||||
case "buffer": zip = new jszip(d); break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
else switch(o.type) {
|
||||
case "base64": zip = CFB.read(d, { type: "base64" }); break;
|
||||
case "binary": zip = CFB.read(d, { type: "binary" }); break;
|
||||
case "buffer": case "array": zip = CFB.read(d, { type: "buffer" }); break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
return zip;
|
||||
}
|
||||
|
||||
function resolve_path(path/*:string*/, base/*:string*/)/*:string*/ {
|
||||
if(path.charAt(0) == "/") return path.slice(1);
|
||||
var result = base.split('/');
|
||||
if(base.slice(-1) != "/") result.pop(); // folder path
|
||||
var target = path.split('/');
|
||||
|
@ -1,6 +1,7 @@
|
||||
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
|
||||
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
|
||||
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s?[\/\?]?>/g;
|
||||
|
||||
if(!(XML_HEADER.match(tagregex))) tagregex = /<[^>]*>/g;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
|
||||
@ -154,11 +155,9 @@ 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_from(data, 'binary').toString('utf8'); };
|
||||
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
|
||||
|
||||
// $FlowIgnore
|
||||
utf8write = function(data) { return Buffer_from(data, 'utf8').toString("binary"); };
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ function encode_cell_xls(c/*:CellAddress*/, biff/*:number*/)/*:string*/ {
|
||||
if(c.cRel && c.c < 0) { c = dup(c); c.c += (biff > 8) ? 0x4000 : 0x100; }
|
||||
if(c.rRel && c.r < 0) { c = dup(c); c.r += (biff > 8) ? 0x100000 : ((biff > 5) ? 0x10000 : 0x4000); }
|
||||
var s = encode_cell(c);
|
||||
if(c.cRel === 0) s = fix_col(s);
|
||||
if(c.rRel === 0) s = fix_row(s);
|
||||
if(!c.cRel && c.cRel != null) s = fix_col(s);
|
||||
if(!c.rRel && c.rRel != null) s = fix_row(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,7 @@ function write_RfX(r/*:Range*/, o) {
|
||||
var parse_UncheckedRfX = parse_RfX;
|
||||
var write_UncheckedRfX = write_RfX;
|
||||
|
||||
|
||||
/* [MS-XLS] 2.5.342 ; [MS-XLSB] 2.5.171 */
|
||||
/* TODO: error checking, NaN and Infinity values are not valid Xnum */
|
||||
function parse_Xnum(data/*::, length*/) { return data.read_shift(8, 'f'); }
|
||||
@ -204,10 +205,10 @@ function parse_BrtColor(data/*::, length*/) {
|
||||
function write_BrtColor(color, o) {
|
||||
if(!o) o = new_buf(8);
|
||||
if(!color||color.auto) { o.write_shift(4, 0); o.write_shift(4, 0); return o; }
|
||||
if(color.index) {
|
||||
if(color.index != null) {
|
||||
o.write_shift(1, 0x02);
|
||||
o.write_shift(1, color.index);
|
||||
} else if(color.theme) {
|
||||
} else if(color.theme != null) {
|
||||
o.write_shift(1, 0x06);
|
||||
o.write_shift(1, color.theme);
|
||||
} else {
|
||||
@ -218,12 +219,13 @@ function write_BrtColor(color, o) {
|
||||
if(nTS > 0) nTS *= 32767;
|
||||
else if(nTS < 0) nTS *= 32768;
|
||||
o.write_shift(2, nTS);
|
||||
if(!color.rgb) {
|
||||
if(!color.rgb || color.theme != null) {
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(1, 0);
|
||||
o.write_shift(1, 0);
|
||||
} else {
|
||||
var rgb = (color.rgb || 'FFFFFF');
|
||||
if(typeof rgb == 'number') rgb = ("000000" + rgb.toString(16)).slice(-6);
|
||||
o.write_shift(1, parseInt(rgb.slice(0,2),16));
|
||||
o.write_shift(1, parseInt(rgb.slice(2,4),16));
|
||||
o.write_shift(1, parseInt(rgb.slice(4,6),16));
|
||||
@ -237,9 +239,9 @@ function parse_FontFlags(data/*::, length, opts*/) {
|
||||
var d = data.read_shift(1);
|
||||
data.l++;
|
||||
var out = {
|
||||
/* fBold: d & 0x01 */
|
||||
fBold: d & 0x01,
|
||||
fItalic: d & 0x02,
|
||||
/* fUnderline: d & 0x04 */
|
||||
fUnderline: d & 0x04,
|
||||
fStrikeout: d & 0x08,
|
||||
fOutline: d & 0x10,
|
||||
fShadow: d & 0x20,
|
||||
|
@ -185,11 +185,11 @@ var XLSFillPattern = [
|
||||
'gray0625'
|
||||
];
|
||||
|
||||
function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
|
||||
function rgbify(arr/*:Array<number>*/)/*:Array<[number, number, number]>*/ { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
|
||||
|
||||
/* [MS-XLS] 2.5.161 */
|
||||
/* [MS-XLSB] 2.5.75 Icv */
|
||||
var XLSIcv = rgbify([
|
||||
var _XLSIcv = rgbify([
|
||||
/* Color Constants */
|
||||
0x000000,
|
||||
0xFFFFFF,
|
||||
@ -281,4 +281,4 @@ var XLSIcv = rgbify([
|
||||
0x000000, /* 0x50 icvInfoBk ?? */
|
||||
0x000000 /* 0x51 icvInfoText ?? */
|
||||
]);
|
||||
|
||||
var XLSIcv = dup(_XLSIcv);
|
||||
|
@ -26,12 +26,18 @@ var ct2type/*{[string]:string}*/ = ({
|
||||
"application/vnd.ms-excel.pivotTable": "TODO",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO",
|
||||
|
||||
/* Chart Objects */
|
||||
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
|
||||
|
||||
/* Chart Colors */
|
||||
"application/vnd.ms-office.chartcolorstyle+xml": "TODO",
|
||||
|
||||
/* Chart Style */
|
||||
"application/vnd.ms-office.chartstyle+xml": "TODO",
|
||||
|
||||
/* Chart Advanced */
|
||||
"application/vnd.ms-office.chartex+xml": "TODO",
|
||||
|
||||
/* Calculation Chain */
|
||||
"application/vnd.ms-excel.calcChain": "calcchains",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
|
||||
@ -122,7 +128,6 @@ var ct2type/*{[string]:string}*/ = ({
|
||||
|
||||
/* Drawing */
|
||||
"application/vnd.openxmlformats-officedocument.drawing+xml": "drawings",
|
||||
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
|
||||
"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO",
|
||||
"application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO",
|
||||
"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO",
|
||||
@ -231,6 +236,7 @@ var CTYPE_DEFAULTS = [
|
||||
['xml', 'application/xml'],
|
||||
['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'],
|
||||
['vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'],
|
||||
['data', 'application/vnd.openxmlformats-officedocument.model+data'],
|
||||
/* from test files */
|
||||
['bmp', 'image/bmp'],
|
||||
['png', 'image/png'],
|
||||
@ -250,6 +256,8 @@ function write_ct(ct, opts)/*:string*/ {
|
||||
o[o.length] = (XML_HEADER);
|
||||
o[o.length] = (CTYPE_XML_ROOT);
|
||||
o = o.concat(CTYPE_DEFAULTS);
|
||||
|
||||
/* only write first instance */
|
||||
var f1 = function(w) {
|
||||
if(ct[w] && ct[w].length > 0) {
|
||||
v = ct[w][0];
|
||||
@ -259,6 +267,8 @@ function write_ct(ct, opts)/*:string*/ {
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/* book type-specific */
|
||||
var f2 = function(w) {
|
||||
(ct[w]||[]).forEach(function(v) {
|
||||
o[o.length] = (writextag('Override', null, {
|
||||
@ -267,6 +277,8 @@ function write_ct(ct, opts)/*:string*/ {
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
/* standard type */
|
||||
var f3 = function(t) {
|
||||
(ct[t]||[]).forEach(function(v) {
|
||||
o[o.length] = (writextag('Override', null, {
|
||||
@ -275,6 +287,7 @@ function write_ct(ct, opts)/*:string*/ {
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
f1('workbooks');
|
||||
f2('sheets');
|
||||
f2('charts');
|
||||
|
@ -4,6 +4,9 @@ var RELS = ({
|
||||
SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
|
||||
HLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
||||
VML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
|
||||
XPATH: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath",
|
||||
XMISS: "http://schemas.microsoft.com/office/2006/relationships/xlExternalLinkPath/xlPathMissing",
|
||||
XLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
|
||||
VBA: "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
|
||||
}/*:any*/);
|
||||
|
||||
@ -52,14 +55,16 @@ function write_rels(rels)/*:string*/ {
|
||||
return o.join("");
|
||||
}
|
||||
|
||||
function add_rels(rels, rId, f, type, relobj)/*:number*/ {
|
||||
var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
|
||||
function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
|
||||
if(!relobj) relobj = {};
|
||||
if(!rels['!id']) rels['!id'] = {};
|
||||
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
||||
relobj.Id = 'rId' + rId;
|
||||
relobj.Type = type;
|
||||
relobj.Target = f;
|
||||
if(relobj.Type == RELS.HLINK) relobj.TargetMode = "External";
|
||||
if(targetmode) relobj.TargetMode = targetmode;
|
||||
else if(RELS_EXTERN.indexOf(relobj.Type) > -1) relobj.TargetMode = "External";
|
||||
if(rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId);
|
||||
rels['!id'][relobj.Id] = relobj;
|
||||
rels[('/' + relobj.Target).replace("//","/")] = relobj;
|
||||
|
@ -44,12 +44,14 @@ function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) {
|
||||
case "Folhas de cálculo":
|
||||
case "Planilhas":
|
||||
case "Regneark":
|
||||
case "Hojas de cálculo":
|
||||
case "Werkbladen":
|
||||
props.Worksheets = len;
|
||||
props.SheetNames = parts.slice(idx, idx + len);
|
||||
break;
|
||||
|
||||
case "Named Ranges":
|
||||
case "Rangos con nombre":
|
||||
case "名前付き一覧":
|
||||
case "Benannte Bereiche":
|
||||
case "Navngivne områder":
|
||||
|
@ -943,7 +943,9 @@ function parse_ColInfo(blob, length, opts) {
|
||||
var ixfe = blob.read_shift(w);
|
||||
var flags = blob.read_shift(2);
|
||||
if(w == 2) blob.l += 2;
|
||||
return {s:colFirst, e:colLast, w:coldx, ixfe:ixfe, flags:flags};
|
||||
var o = ({s:colFirst, e:colLast, w:coldx, ixfe:ixfe, flags:flags}/*:any*/);
|
||||
if(opts.biff >= 5 || !opts.biff) o.level = (flags >> 8) & 0x7;
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.4.257 */
|
||||
|
@ -259,7 +259,7 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
|
||||
h.write_shift(2, 296 + 32 * hcnt);
|
||||
h.write_shift(2, rlen);
|
||||
for(i=0; i < 4; ++i) h.write_shift(4, 0);
|
||||
h.write_shift(4, 0x00000000 | ((+dbf_reverse_map[current_ansi] || 0x03)<<8));
|
||||
h.write_shift(4, 0x00000000 | ((+dbf_reverse_map[/*::String(*/current_ansi/*::)*/] || 0x03)<<8));
|
||||
|
||||
for(i = 0, j = 0; i < headers.length; ++i) {
|
||||
if(headers[i] == null) continue;
|
||||
@ -316,7 +316,7 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
|
||||
|
||||
var SYLK = (function() {
|
||||
/* TODO: stress test sequences */
|
||||
var sylk_escapes = {
|
||||
var sylk_escapes = ({
|
||||
AA:'À', BA:'Á', CA:'Â', DA:195, HA:'Ä', JA:197,
|
||||
AE:'È', BE:'É', CE:'Ê', HE:'Ë',
|
||||
AI:'Ì', BI:'Í', CI:'Î', HI:'Ï',
|
||||
@ -329,11 +329,13 @@ var SYLK = (function() {
|
||||
Au:'ù', Bu:'ú', Cu:'û', Hu:'ü',
|
||||
KC:'Ç', Kc:'ç', q:'æ', z:'œ', a:'Æ', j:'Œ',
|
||||
DN:209, Dn:241, Hy:255,
|
||||
S:169, c:170, R:174, 0:176, 1:177, 2:178, 3:179, B:180, 5:181,
|
||||
6:182, 7:183, Q:185, k:186, b:208, i:216, l:222, s:240, y:248,
|
||||
S:169, c:170, R:174, B:180,
|
||||
/*::[*/0/*::]*/:176, /*::[*/1/*::]*/:177, /*::[*/2/*::]*/:178,
|
||||
/*::[*/3/*::]*/:179, /*::[*/5/*::]*/:181, /*::[*/6/*::]*/:182,
|
||||
/*::[*/7/*::]*/:183, Q:185, k:186, b:208, i:216, l:222, s:240, y:248,
|
||||
"!":161, '"':162, "#":163, "(":164, "%":165, "'":167, "H ":168,
|
||||
"+":171, ";":187, "<":188, "=":189, ">":190, "?":191, "{":223
|
||||
};
|
||||
}/*:any*/);
|
||||
var sylk_char_regex = new RegExp("\u001BN(" + keys(sylk_escapes).join("|").replace(/\|\|\|/, "|\\||").replace(/([?()+])/g,"\\$1") + "|\\|)", "gm");
|
||||
var sylk_char_fn = function(_, $1){ var o = sylk_escapes[$1]; return typeof o == "number" ? _getansi(o) : o; };
|
||||
var decode_sylk_char = function($$, $1, $2) { var newcc = (($1.charCodeAt(0) - 0x20)<<4) | ($2.charCodeAt(0) - 0x30); return newcc == 59 ? $$ : _getansi(newcc); };
|
||||
|
@ -3,7 +3,7 @@ function parse_borders(t, styles, themes, opts) {
|
||||
styles.Borders = [];
|
||||
var border = {}/*, sub_border = {}*/;
|
||||
var pass = false;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<borders': case '<borders>': case '</borders>': break;
|
||||
@ -11,8 +11,8 @@ function parse_borders(t, styles, themes, opts) {
|
||||
/* 18.8.4 border CT_Border */
|
||||
case '<border': case '<border>': case '<border/>':
|
||||
border = {};
|
||||
if (y.diagonalUp) { border.diagonalUp = y.diagonalUp; }
|
||||
if (y.diagonalDown) { border.diagonalDown = y.diagonalDown; }
|
||||
if(y.diagonalUp) border.diagonalUp = parsexmlbool(y.diagonalUp);
|
||||
if(y.diagonalDown) border.diagonalDown = parsexmlbool(y.diagonalDown);
|
||||
styles.Borders.push(border);
|
||||
break;
|
||||
case '</border>': break;
|
||||
@ -58,7 +58,8 @@ function parse_borders(t, styles, themes, opts) {
|
||||
case '</end>': break;
|
||||
|
||||
/* 18.8.? color CT_Color */
|
||||
case '<color': case '<color>': break;
|
||||
case '<color': case '<color>':
|
||||
break;
|
||||
case '<color/>': case '</color>': break;
|
||||
|
||||
/* 18.2.10 extLst CT_ExtensionList ? */
|
||||
@ -77,7 +78,7 @@ function parse_fills(t, styles, themes, opts) {
|
||||
styles.Fills = [];
|
||||
var fill = {};
|
||||
var pass = false;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<fills': case '<fills>': case '</fills>': break;
|
||||
@ -115,7 +116,7 @@ function parse_fills(t, styles, themes, opts) {
|
||||
if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
|
||||
if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
|
||||
/* Excel uses ARGB strings */
|
||||
if(y.rgb) fill.fgColor.rgb = y.rgb.slice(-6);
|
||||
if(y.rgb != null) fill.fgColor.rgb = y.rgb.slice(-6);
|
||||
break;
|
||||
case '<fgColor/>': case '</fgColor>': break;
|
||||
|
||||
@ -143,7 +144,7 @@ function parse_fonts(t, styles, themes, opts) {
|
||||
styles.Fonts = [];
|
||||
var font = {};
|
||||
var pass = false;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<fonts': case '<fonts>': case '</fonts>': break;
|
||||
@ -243,6 +244,10 @@ function parse_fonts(t, styles, themes, opts) {
|
||||
break;
|
||||
case '<color/>': case '</color>': break;
|
||||
|
||||
/* note: sometimes mc:AlternateContent appears bare */
|
||||
case '<AlternateContent': pass = true; break;
|
||||
case '</AlternateContent>': pass = false; break;
|
||||
|
||||
/* 18.2.10 extLst CT_ExtensionList ? */
|
||||
case '<extLst': case '<extLst>': case '</extLst>': break;
|
||||
case '<ext': pass = true; break;
|
||||
@ -300,7 +305,7 @@ function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
var xf;
|
||||
var pass = false;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x), i = 0;
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
|
||||
@ -326,13 +331,19 @@ function parse_cellXfs(t, styles, opts) {
|
||||
if(y.horizontal) alignment.horizontal = y.horizontal;
|
||||
if(y.textRotation != null) alignment.textRotation = y.textRotation;
|
||||
if(y.indent) alignment.indent = y.indent;
|
||||
if(y.wrapText) alignment.wrapText = y.wrapText;
|
||||
if(y.wrapText) alignment.wrapText = parsexmlbool(y.wrapText);
|
||||
xf.alignment = alignment;
|
||||
break;
|
||||
case '</alignment>': break;
|
||||
|
||||
/* 18.8.33 protection CT_CellProtection */
|
||||
case '<protection': case '</protection>': case '<protection/>': break;
|
||||
case '<protection':
|
||||
break;
|
||||
case '</protection>': case '<protection/>': break;
|
||||
|
||||
/* note: sometimes mc:AlternateContent appears bare */
|
||||
case '<AlternateContent': pass = true; break;
|
||||
case '</AlternateContent>': pass = false; break;
|
||||
|
||||
/* 18.2.10 extLst CT_ExtensionList ? */
|
||||
case '<extLst': case '<extLst>': case '</extLst>': break;
|
||||
@ -348,7 +359,9 @@ function parse_cellXfs(t, styles, opts) {
|
||||
function write_cellXfs(cellXfs)/*:string*/ {
|
||||
var o/*:Array<string>*/ = [];
|
||||
o[o.length] = (writextag('cellXfs',null));
|
||||
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
|
||||
cellXfs.forEach(function(c) {
|
||||
o[o.length] = (writextag('xf', null, c));
|
||||
});
|
||||
o[o.length] = ("</cellXfs>");
|
||||
if(o.length === 2) return "";
|
||||
o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");
|
||||
|
@ -151,7 +151,8 @@ function write_BrtXF(data, ixfeP, o) {
|
||||
o.write_shift(2, 0); /* ixBorder */
|
||||
o.write_shift(1, 0); /* trot */
|
||||
o.write_shift(1, 0); /* indent */
|
||||
o.write_shift(1, 0); /* flags */
|
||||
var flow = 0;
|
||||
o.write_shift(1, flow); /* flags */
|
||||
o.write_shift(1, 0); /* flags */
|
||||
o.write_shift(1, 0); /* xfGrbitAtr */
|
||||
o.write_shift(1, 0);
|
||||
@ -222,8 +223,10 @@ function parse_sty_bin(data, themes, opts) {
|
||||
}
|
||||
break;
|
||||
case 0x0401: /* 'BrtKnownFonts' */ break;
|
||||
case 0x002D: /* 'BrtFill' */ break;
|
||||
case 0x002E: /* 'BrtBorder' */ break;
|
||||
case 0x002D: /* 'BrtFill' */
|
||||
break;
|
||||
case 0x002E: /* 'BrtBorder' */
|
||||
break;
|
||||
case 0x002F: /* 'BrtXF' */
|
||||
if(state[state.length - 1] == "BrtBeginCellXFs") {
|
||||
styles.CellXf.push(val);
|
||||
@ -248,14 +251,14 @@ function parse_sty_bin(data, themes, opts) {
|
||||
case 0x0024: /* 'BrtFRTEnd' */
|
||||
pass = false; break;
|
||||
case 0x0025: /* 'BrtACBegin' */
|
||||
state.push(R_n); break;
|
||||
state.push(R_n); pass = true; break;
|
||||
case 0x0026: /* 'BrtACEnd' */
|
||||
state.pop(); break;
|
||||
state.pop(); pass = false; break;
|
||||
|
||||
default:
|
||||
if((R_n||"").indexOf("Begin") > 0) state.push(R_n);
|
||||
else if((R_n||"").indexOf("End") > 0) state.pop();
|
||||
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||
else if(!pass || (opts.WTF && state[state.length-1] != "BrtACBegin")) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||
}
|
||||
});
|
||||
return styles;
|
||||
@ -319,10 +322,10 @@ function write_CELLSTYLEXFS_bin(ba/*::, data*/) {
|
||||
var cnt = 1;
|
||||
write_record(ba, "BrtBeginCellStyleXFs", write_UInt32LE(cnt));
|
||||
write_record(ba, "BrtXF", write_BrtXF({
|
||||
numFmtId:0,
|
||||
fontId:0,
|
||||
fillId:0,
|
||||
borderId:0
|
||||
numFmtId: 0,
|
||||
fontId: 0,
|
||||
fillId: 0,
|
||||
borderId: 0
|
||||
}, 0xFFFF));
|
||||
/* 1*65430(BrtXF *FRT) */
|
||||
write_record(ba, "BrtEndCellStyleXFs");
|
||||
|
@ -103,6 +103,7 @@ function parse_theme_xml(data/*:string*/, opts) {
|
||||
|
||||
function write_theme(Themes, opts)/*:string*/ {
|
||||
if(opts && opts.themeXLSX) return opts.themeXLSX;
|
||||
if(Themes && typeof Themes.raw == "string") return Themes.raw;
|
||||
var o = [XML_HEADER];
|
||||
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
|
||||
o[o.length] = '<a:themeElements>';
|
||||
|
@ -1,11 +1,11 @@
|
||||
/* 18.14 Supplementary Workbook Data */
|
||||
function parse_xlink_xml(/*::data, name:string, _opts*/) {
|
||||
function parse_xlink_xml(/*::data, rel, name:string, _opts*/) {
|
||||
//var opts = _opts || {};
|
||||
//if(opts.WTF) throw "XLSX External Link";
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.25 External Link */
|
||||
function parse_xlink_bin(data, name/*:string*/, _opts) {
|
||||
function parse_xlink_bin(data, rel, name/*:string*/, _opts) {
|
||||
if(!data) return data;
|
||||
var opts = _opts || {};
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* 20.5 DrawingML - SpreadsheetML Drawing */
|
||||
RELS.IMG = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
||||
RELS.DRAW = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
|
||||
/* 20.5 DrawingML - SpreadsheetML Drawing */
|
||||
|
||||
/* 20.5.2.35 wsDr CT_Drawing */
|
||||
function parse_drawing(data, rels/*:any*/) {
|
||||
if(!data) return "??";
|
||||
/*
|
||||
|
@ -1,24 +1,6 @@
|
||||
RELS.CMNT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
|
||||
|
||||
function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
|
||||
for(var i = 0; i != dirComments.length; ++i) {
|
||||
var canonicalpath=dirComments[i];
|
||||
var comments=parse_cmnt(getzipdata(zip, canonicalpath.replace(/^\//,''), true), canonicalpath, opts);
|
||||
if(!comments || !comments.length) continue;
|
||||
// find the sheets targeted by these comments
|
||||
var sheetNames = keys(sheets);
|
||||
for(var j = 0; j != sheetNames.length; ++j) {
|
||||
var sheetName = sheetNames[j];
|
||||
var rels = sheetRels[sheetName];
|
||||
if(rels) {
|
||||
var rel = rels[canonicalpath];
|
||||
if(rel) insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*/) {
|
||||
function sheet_insert_comments(sheet, comments/*:Array<RawComment>*/) {
|
||||
var dense = Array.isArray(sheet);
|
||||
var cell/*:Cell*/;
|
||||
comments.forEach(function(comment) {
|
||||
@ -28,7 +10,7 @@ function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*
|
||||
cell = sheet[r.r][r.c];
|
||||
} else cell = sheet[comment.ref];
|
||||
if (!cell) {
|
||||
cell = {};
|
||||
cell = ({t:"z"}/*:any*/);
|
||||
if(dense) sheet[r.r][r.c] = cell;
|
||||
else sheet[comment.ref] = cell;
|
||||
var range = safe_decode_range(sheet["!ref"]||"BDWGO1000001:A1");
|
||||
|
@ -39,8 +39,8 @@ function parse_comments_bin(data, opts)/*:Array<RawComment>*/ {
|
||||
c.t = val.t; c.h = val.h; c.r = val.r; break;
|
||||
case 0x027C: /* 'BrtEndComment' */
|
||||
c.author = authors[c.iauthor];
|
||||
delete c.iauthor;
|
||||
if(opts.sheetRows && opts.sheetRows <= c.rfx.r) break;
|
||||
delete (c/*:any*/).iauthor;
|
||||
if(opts.sheetRows && c.rfx && opts.sheetRows <= c.rfx.r) break;
|
||||
if(!c.t) c.t = "";
|
||||
delete c.rfx; out.push(c); break;
|
||||
|
||||
|
@ -1,13 +1,20 @@
|
||||
/* TODO: it will be useful to parse the function str */
|
||||
var rc_to_a1 = (function(){
|
||||
var rcregex = /(^|[^A-Za-z])R(\[?)(-?\d+|)\]?C(\[?)(-?\d+|)\]?/g;
|
||||
var rcregex = /(^|[^A-Za-z_])R(\[?-?\d+\]|[1-9]\d*|)C(\[?-?\d+\]|[1-9]\d*|)(?![A-Za-z0-9_])/g;
|
||||
var rcbase/*:Cell*/ = ({r:0,c:0}/*:any*/);
|
||||
function rcfunc($$,$1,$2,$3,$4,$5) {
|
||||
var R = $3.length>0?parseInt($3,10)|0:0, C = $5.length>0?parseInt($5,10)|0:0;
|
||||
if(C<0 && $4.length === 0) C=0;
|
||||
function rcfunc($$,$1,$2,$3) {
|
||||
var cRel = false, rRel = false;
|
||||
if($4.length > 0 || $5.length == 0) cRel = true; if(cRel) C += rcbase.c; else --C;
|
||||
if($2.length > 0 || $3.length == 0) rRel = true; if(rRel) R += rcbase.r; else --R;
|
||||
|
||||
if($2.length == 0) rRel = true;
|
||||
else if($2.charAt(0) == "[") { rRel = true; $2 = $2.slice(1, -1); }
|
||||
|
||||
if($3.length == 0) cRel = true;
|
||||
else if($3.charAt(0) == "[") { cRel = true; $3 = $3.slice(1, -1); }
|
||||
|
||||
var R = $2.length>0?parseInt($2,10)|0:0, C = $3.length>0?parseInt($3,10)|0:0;
|
||||
|
||||
if(cRel) C += rcbase.c; else --C;
|
||||
if(rRel) R += rcbase.r; else --R;
|
||||
return $1 + (cRel ? "" : "$") + encode_col(C) + (rRel ? "" : "$") + encode_row(R);
|
||||
}
|
||||
return function rc_to_a1(fstr/*:string*/, base/*:Cell*/)/*:string*/ {
|
||||
|
@ -51,6 +51,19 @@ function parse_FormulaValue(blob/*::, length*/) {
|
||||
}
|
||||
return [];
|
||||
}
|
||||
function write_FormulaValue(value) {
|
||||
if(value == null) {
|
||||
// Blank String Value
|
||||
var o = new_buf(8);
|
||||
o.write_shift(1, 0x03);
|
||||
o.write_shift(1, 0);
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(2, 0xFFFF);
|
||||
return o;
|
||||
} else if(typeof value == "number") return write_Xnum(value);
|
||||
return write_Xnum(0);
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.4.127 TODO */
|
||||
function parse_Formula(blob, length, opts) {
|
||||
@ -68,6 +81,27 @@ function parse_Formula(blob, length, opts) {
|
||||
var cbf = parse_XLSCellParsedFormula(blob, end - blob.l, opts);
|
||||
return {cell:cell, val:val[0], formula:cbf, shared: (flags >> 3) & 1, tt:val[1]};
|
||||
}
|
||||
function write_Formula(cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, os/*:number*/) {
|
||||
// Cell
|
||||
var o1 = write_XLSCell(R, C, os);
|
||||
|
||||
// FormulaValue
|
||||
var o2 = write_FormulaValue(cell.v);
|
||||
|
||||
// flags + cache
|
||||
var o3 = new_buf(6);
|
||||
var flags = 0x01 | 0x20;
|
||||
o3.write_shift(2, flags);
|
||||
o3.write_shift(4, 0);
|
||||
|
||||
// CellParsedFormula
|
||||
var bf = new_buf(cell.bf.length);
|
||||
for(var i = 0; i < cell.bf.length; ++i) bf[i] = cell.bf[i];
|
||||
|
||||
var out = bconcat([o1, o2, o3, bf]);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/* XLSB Parsed Formula records have the same shape */
|
||||
function parse_XLSBParsedFormula(data, length, opts) {
|
||||
@ -82,6 +116,10 @@ function parse_XLSBParsedFormula(data, length, opts) {
|
||||
var parse_XLSBArrayParsedFormula = parse_XLSBParsedFormula;
|
||||
/* [MS-XLSB] 2.5.97.4 CellParsedFormula */
|
||||
var parse_XLSBCellParsedFormula = parse_XLSBParsedFormula;
|
||||
/* [MS-XLSB] 2.5.97.8 DVParsedFormula */
|
||||
//var parse_XLSBDVParsedFormula = parse_XLSBParsedFormula;
|
||||
/* [MS-XLSB] 2.5.97.9 FRTParsedFormula */
|
||||
//var parse_XLSBFRTParsedFormula = parse_XLSBParsedFormula2;
|
||||
/* [MS-XLSB] 2.5.97.12 NameParsedFormula */
|
||||
var parse_XLSBNameParsedFormula = parse_XLSBParsedFormula;
|
||||
/* [MS-XLSB] 2.5.97.98 SharedParsedFormula */
|
||||
|
@ -11,9 +11,11 @@ var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g
|
||||
var marginregex= /<(?:\w:)?pageMargins[^>]*\/>/g;
|
||||
var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
|
||||
var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;
|
||||
|
||||
/* 18.3 Worksheets */
|
||||
function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
|
||||
if(!data) return data;
|
||||
if(!rels) rels = {'!id':{}};
|
||||
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
|
||||
|
||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||
@ -32,7 +34,6 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
||||
if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
|
||||
|
||||
/* 18.3.1.35 dimension CT_SheetDimension */
|
||||
// $FlowIgnore
|
||||
var ridx = (data1.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
|
||||
if(ridx > 0) {
|
||||
var ref = data1.slice(ridx,ridx+50).match(dimregex);
|
||||
@ -105,18 +106,18 @@ function parse_ws_xml_sheetpr(sheetPr/*:string*/, s, wb/*:WBWBProps*/, idx/*:num
|
||||
}
|
||||
|
||||
/* 18.3.1.85 sheetProtection CT_SheetProtection */
|
||||
var sheetprot_deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
|
||||
var sheetprot_deftrue = [
|
||||
"formatColumns", "formatRows", "formatCells",
|
||||
"insertColumns", "insertRows", "insertHyperlinks",
|
||||
"deleteColumns", "deleteRows",
|
||||
"sort", "autoFilter", "pivotTables"
|
||||
];
|
||||
function write_ws_xml_protection(sp)/*:string*/ {
|
||||
// algorithmName, hashValue, saltValue, spinCountpassword
|
||||
var o = ({sheet:1}/*:any*/);
|
||||
var deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
|
||||
var deftrue = [
|
||||
"formatColumns", "formatRows", "formatCells",
|
||||
"insertColumns", "insertRows", "insertHyperlinks",
|
||||
"deleteColumns", "deleteRows",
|
||||
"sort", "autoFilter", "pivotTables"
|
||||
];
|
||||
deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
|
||||
deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
|
||||
sheetprot_deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
|
||||
sheetprot_deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
|
||||
/* TODO: algorithm */
|
||||
if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
|
||||
return writextag('sheetProtection', null, o);
|
||||
@ -176,7 +177,6 @@ function parse_ws_xml_cols(columns, cols) {
|
||||
while(colm <= colM) columns[colm++] = dup(coll);
|
||||
}
|
||||
}
|
||||
|
||||
function write_ws_xml_cols(ws, cols)/*:string*/ {
|
||||
var o = ["<cols>"], col;
|
||||
for(var i = 0; i != cols.length; ++i) {
|
||||
@ -193,7 +193,7 @@ function parse_ws_xml_autofilter(data/*:string*/) {
|
||||
}
|
||||
function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
|
||||
var ref = typeof data.ref == "string" ? data.ref : encode_range(data.ref);
|
||||
if(!wb.Workbook) wb.Workbook = {};
|
||||
if(!wb.Workbook) wb.Workbook = ({Sheets:[]}/*:any*/);
|
||||
if(!wb.Workbook.Names) wb.Workbook.Names = [];
|
||||
var names/*: Array<any> */ = wb.Workbook.Names;
|
||||
var range = decode_range(ref);
|
||||
@ -210,21 +210,21 @@ function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
|
||||
|
||||
/* 18.3.1.88 sheetViews CT_SheetViews */
|
||||
/* 18.3.1.87 sheetView CT_SheetView */
|
||||
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/>/;
|
||||
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/;
|
||||
function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
|
||||
(data.match(sviewregex)||[]).forEach(function(r/*:string*/) {
|
||||
if(!wb.Views) wb.Views = [{}];
|
||||
(data.match(sviewregex)||[]).forEach(function(r/*:string*/, i/*:number*/) {
|
||||
var tag = parsexmltag(r);
|
||||
if(parsexmlbool(tag.rightToLeft)) {
|
||||
if(!wb.Views) wb.Views = [{}];
|
||||
if(!wb.Views[0]) wb.Views[0] = {};
|
||||
wb.Views[0].RTL = true;
|
||||
}
|
||||
// $FlowIgnore
|
||||
if(!wb.Views[i]) wb.Views[i] = {};
|
||||
// $FlowIgnore
|
||||
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
});
|
||||
}
|
||||
function write_ws_xml_sheetviews(ws, opts, idx, wb)/*:string*/ {
|
||||
var sview = {workbookViewId:"0"};
|
||||
var sview = ({workbookViewId:"0"}/*:any*/);
|
||||
// $FlowIgnore
|
||||
if( (((wb||{}).Workbook||{}).Views||[])[0] ) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
|
||||
if((((wb||{}).Workbook||{}).Views||[])[0]) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
|
||||
return writextag("sheetViews", writextag("sheetView", null, sview), {});
|
||||
}
|
||||
|
||||
@ -232,12 +232,12 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string
|
||||
if(cell.v === undefined && cell.f === undefined || cell.t === 'z') return "";
|
||||
var vv = "";
|
||||
var oldt = cell.t, oldv = cell.v;
|
||||
switch(cell.t) {
|
||||
if(cell.t !== "z") switch(cell.t) {
|
||||
case 'b': vv = cell.v ? "1" : "0"; break;
|
||||
case 'n': vv = ''+cell.v; break;
|
||||
case 'e': vv = BErr[cell.v]; break;
|
||||
case 'd':
|
||||
if(opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
|
||||
if(opts && opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
|
||||
else {
|
||||
cell = dup(cell);
|
||||
cell.t = 'n';
|
||||
@ -312,6 +312,8 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
||||
|
||||
/* 18.3.1.4 c CT_Cell */
|
||||
cells = x.slice(ri).split(cellregex);
|
||||
for(var rslice = 0; rslice != cells.length; ++rslice) if(cells[rslice].trim().charAt(0) != "<") break;
|
||||
cells = cells.slice(rslice);
|
||||
for(ri = 0; ri != cells.length; ++ri) {
|
||||
x = cells[ri].trim();
|
||||
if(x.length === 0) continue;
|
||||
@ -393,7 +395,10 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
||||
case 'inlineStr':
|
||||
cref = d.match(isregex);
|
||||
p.t = 's';
|
||||
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
|
||||
if(cref != null && (sstr = parse_si(cref[1]))) {
|
||||
p.v = sstr.t;
|
||||
if(opts.cellHTML) p.h = sstr.h;
|
||||
} else p.v = "";
|
||||
break;
|
||||
case 'b': p.v = parsexmlbool(p.v); break;
|
||||
case 'd':
|
||||
@ -407,6 +412,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
||||
}
|
||||
/* formatting */
|
||||
fmtid = fillid = 0;
|
||||
cf = null;
|
||||
if(do_format && tag.s !== undefined) {
|
||||
cf = styles.CellXf[tag.s];
|
||||
if(cf != null) {
|
||||
@ -541,9 +547,9 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
/* dataValidations */
|
||||
|
||||
var relc = -1, rel, rId = -1;
|
||||
if(ws['!links'].length > 0) {
|
||||
if(/*::(*/ws['!links']/*::||[])*/.length > 0) {
|
||||
o[o.length] = "<hyperlinks>";
|
||||
ws['!links'].forEach(function(l) {
|
||||
/*::(*/ws['!links']/*::||[])*/.forEach(function(l) {
|
||||
if(!l[1].Target) return;
|
||||
rel = ({"ref":l[0]}/*:any*/);
|
||||
if(l[1].Target.charAt(0) != "#") {
|
||||
@ -562,7 +568,6 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
if (ws['!margins'] != null) o[o.length] = write_ws_xml_margins(ws['!margins']);
|
||||
/* pageSetup */
|
||||
|
||||
//var hfidx = o.length;
|
||||
o[o.length] = "";
|
||||
|
||||
/* rowBreaks */
|
||||
@ -574,7 +579,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
|
||||
/* smartTags */
|
||||
|
||||
if(ws['!drawing'].length > 0) {
|
||||
if(/*::(*/ws['!drawing']/*::||[])*/.length > 0) {
|
||||
rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW);
|
||||
o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId});
|
||||
}
|
||||
|
@ -315,8 +315,8 @@ function write_BrtColInfo(C/*:number*/, col, o) {
|
||||
var flags = 0;
|
||||
if(col.hidden) flags |= 0x01;
|
||||
if(typeof p.width == 'number') flags |= 0x02;
|
||||
o.write_shift(1, flags); // bit flag
|
||||
o.write_shift(1, 0); // bit flag
|
||||
if(col.level) flags |= (col.level << 8);
|
||||
o.write_shift(2, flags); // bit flag
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -408,6 +408,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
var ref;
|
||||
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
|
||||
|
||||
var state/*:Array<string>*/ = [];
|
||||
var pass = false, end = false;
|
||||
var row, p, cf, R, C, addr, sstr, rr, cell/*:Cell*/;
|
||||
var merges/*:Array<Range>*/ = [];
|
||||
@ -418,7 +419,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
|
||||
var arrayf/*:Array<[Range, string]>*/ = [];
|
||||
var sharedf = {};
|
||||
var supbooks = opts.supbooks || wb.supbooks || ([[]]/*:any*/);
|
||||
var supbooks = opts.supbooks || /*::(*/wb/*:: :any)*/.supbooks || ([[]]/*:any*/);
|
||||
supbooks.sharedf = sharedf;
|
||||
supbooks.arrayf = arrayf;
|
||||
supbooks.SheetNames = wb.SheetNames || wb.Sheets.map(function(x) { return x.name; });
|
||||
@ -543,7 +544,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
case 0x003C: /* 'BrtColInfo' */
|
||||
if(!opts.cellStyles) break;
|
||||
while(val.e >= val.s) {
|
||||
colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01) };
|
||||
colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01), level: val.level };
|
||||
if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
|
||||
process_col(colinfo[val.e+1]);
|
||||
}
|
||||
@ -570,6 +571,13 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
|
||||
case 0x01E5: /* 'BrtWsFmtInfo' */
|
||||
break;
|
||||
|
||||
case 0x0040: /* 'BrtDVal' */
|
||||
case 0x041D: /* 'BrtDVal14' */
|
||||
break;
|
||||
|
||||
case 0x0097: /* 'BrtPane' */
|
||||
break;
|
||||
case 0x00AF: /* 'BrtAFilterDateGroupItem' */
|
||||
case 0x0284: /* 'BrtActiveX' */
|
||||
case 0x0271: /* 'BrtBigName' */
|
||||
@ -590,8 +598,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
case 0x00AE: /* 'BrtCustomFilter' */
|
||||
case 0x049C: /* 'BrtCustomFilter14' */
|
||||
case 0x01F3: /* 'BrtDRef' */
|
||||
case 0x0040: /* 'BrtDVal' */
|
||||
case 0x041D: /* 'BrtDVal14' */
|
||||
case 0x0226: /* 'BrtDrawing' */
|
||||
case 0x00AB: /* 'BrtDynamicFilter' */
|
||||
case 0x00A7: /* 'BrtFilter' */
|
||||
@ -603,7 +609,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
case 0x0295: /* 'BrtListPart' */
|
||||
case 0x027F: /* 'BrtOleObject' */
|
||||
case 0x01DE: /* 'BrtPageSetup' */
|
||||
case 0x0097: /* 'BrtPane' */
|
||||
case 0x0219: /* 'BrtPhoneticInfo' */
|
||||
case 0x01DD: /* 'BrtPrintOptions' */
|
||||
case 0x0218: /* 'BrtRangeProtection' */
|
||||
@ -629,8 +634,10 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
pass = true; break;
|
||||
case 0x0024: /* 'BrtFRTEnd' */
|
||||
pass = false; break;
|
||||
case 0x0025: /* 'BrtACBegin' */ break;
|
||||
case 0x0026: /* 'BrtACEnd' */ break;
|
||||
case 0x0025: /* 'BrtACBegin' */
|
||||
state.push(R_n); pass = true; break;
|
||||
case 0x0026: /* 'BrtACEnd' */
|
||||
state.pop(); pass = false; break;
|
||||
|
||||
default:
|
||||
if((R_n||"").indexOf("Begin") > 0){/* empty */}
|
||||
@ -663,7 +670,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
|
||||
/* TODO: something useful -- this is a stub */
|
||||
function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, ws/*:Worksheet*/) {
|
||||
if(cell.v === undefined) return "";
|
||||
if(cell.v === undefined) return;
|
||||
var vv = "";
|
||||
switch(cell.t) {
|
||||
case 'b': vv = cell.v ? "1" : "0"; break;
|
||||
@ -769,9 +776,26 @@ function write_LEGACYDRAWING(ba, ws/*:Worksheet*/, idx/*:number*/, rels) {
|
||||
}
|
||||
}
|
||||
|
||||
function write_AUTOFILTER(ba, ws) {
|
||||
function write_AUTOFILTER(ba, ws, wb, idx) {
|
||||
if(!ws['!autofilter']) return;
|
||||
write_record(ba, "BrtBeginAFilter", write_UncheckedRfX(safe_decode_range(ws['!autofilter'].ref)));
|
||||
var data = ws['!autofilter'];
|
||||
var ref = typeof data.ref === "string" ? data.ref : encode_range(data.ref);
|
||||
|
||||
/* Update FilterDatabase defined name for the worksheet */
|
||||
if(!wb.Workbook) wb.Workbook = ({Sheets:[]}/*:any*/);
|
||||
if(!wb.Workbook.Names) wb.Workbook.Names = [];
|
||||
var names/*: Array<any> */ = wb.Workbook.Names;
|
||||
var range = decode_range(ref);
|
||||
if(range.s.r == range.e.r) { range.e.r = decode_range(ws["!ref"]).e.r; ref = encode_range(range); }
|
||||
for(var i = 0; i < names.length; ++i) {
|
||||
var name = names[i];
|
||||
if(name.Name != '_xlnm._FilterDatabase') continue;
|
||||
if(name.Sheet != idx) continue;
|
||||
name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref; break;
|
||||
}
|
||||
if(i == names.length) names.push({ Name: '_xlnm._FilterDatabase', Sheet: idx, Ref: "'" + wb.SheetNames[idx] + "'!" + ref });
|
||||
|
||||
write_record(ba, "BrtBeginAFilter", write_UncheckedRfX(safe_decode_range(ref)));
|
||||
/* *FILTERCOLUMN */
|
||||
/* [SORTSTATE] */
|
||||
/* BrtEndAFilter */
|
||||
@ -828,7 +852,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
|
||||
write_SHEETPROTECT(ba, ws);
|
||||
/* *([BrtRangeProtectionIso] BrtRangeProtection) */
|
||||
/* [SCENMAN] */
|
||||
write_AUTOFILTER(ba, ws);
|
||||
write_AUTOFILTER(ba, ws, wb, idx);
|
||||
/* [SORTSTATE] */
|
||||
/* [DCON] */
|
||||
/* [USERSHVIEWS] */
|
||||
|
@ -1,17 +1,24 @@
|
||||
function parse_numCache(data/*:string*/)/*:[Array<number>, string]*/ {
|
||||
var col/*:Array<number>*/ = [];
|
||||
RELS.CHART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
|
||||
RELS.CHARTEX = "http://schemas.microsoft.com/office/2014/relationships/chartEx";
|
||||
|
||||
function parse_Cache(data/*:string*/)/*:[Array<number|string>, string, ?string]*/ {
|
||||
var col/*:Array<number|string>*/ = [];
|
||||
var num = data.match(/^<c:numCache>/);
|
||||
var f;
|
||||
|
||||
/* 21.2.2.150 pt CT_NumVal */
|
||||
(data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg)||[]).forEach(function(pt) {
|
||||
var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
|
||||
if(!q) return;
|
||||
col[+q[1]] = +q[2];
|
||||
col[+q[1]] = num ? +q[2] : q[2];
|
||||
});
|
||||
|
||||
/* 21.2.2.71 formatCode CT_Xstring */
|
||||
var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["","General"])[1]);
|
||||
|
||||
return [col, nf];
|
||||
(data.match(/<c:f>(.*?)<\/c:f>/mg)||[]).forEach(function(F) { f = F.replace(/<.*?>/g,""); });
|
||||
|
||||
return [col, nf, f];
|
||||
}
|
||||
|
||||
/* 21.2 DrawingML - Charts */
|
||||
@ -25,7 +32,7 @@ function parse_chart(data/*:?string*/, name/*:string*/, opts, rels, wb, csheet)
|
||||
|
||||
/* 21.2.2.120 numCache CT_NumData */
|
||||
(data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm)||[]).forEach(function(nc) {
|
||||
var cache = parse_numCache(nc);
|
||||
var cache = parse_Cache(nc);
|
||||
refguess.s.r = refguess.s.c = 0;
|
||||
refguess.e.c = C;
|
||||
col = encode_col(C);
|
||||
|