forked from sheetjs/sheetjs
cell comments
- `sheet_to_json` handle arrays (h/t AaronWoodrow) - XLS parse comment visibility (h/t Godrules500) - chrome manifest v3 writeFile support - raw v8 (no TextEncoder/TextDecoder) optimization - handle empty shared formula body (h/t florian)
This commit is contained in:
parent
d3a480750b
commit
6e260c9185
@ -45,6 +45,26 @@ function Base64_encode_pass(input) {
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function Base64_encode_arr(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
for (var i = 0; i < input.length; ) {
|
||||
c1 = input[i++];
|
||||
e1 = c1 >> 2;
|
||||
c2 = input[i++];
|
||||
e2 = (c1 & 3) << 4 | c2 >> 4;
|
||||
c3 = input[i++];
|
||||
e3 = (c2 & 15) << 2 | c3 >> 6;
|
||||
e4 = c3 & 63;
|
||||
if (isNaN(c2)) {
|
||||
e3 = e4 = 64;
|
||||
} else if (isNaN(c3)) {
|
||||
e4 = 64;
|
||||
}
|
||||
o += Base64_map.charAt(e1) + Base64_map.charAt(e2) + Base64_map.charAt(e3) + Base64_map.charAt(e4);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function Base64_decode(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
|
@ -35,7 +35,7 @@ function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
|
||||
/*:: declare var chrome: any; */
|
||||
if(typeof chrome === 'object' && typeof (chrome.downloads||{}).download == "function") {
|
||||
if(URL.revokeObjectURL && typeof setTimeout !== 'undefined') setTimeout(function() { URL.revokeObjectURL(url); }, 60000);
|
||||
return chrome.downloads.download({ url: url, filename: fname, saveAs: true});
|
||||
return chrome.downloads.download({ url: url, filename: fname, saveAs: true });
|
||||
}
|
||||
var a = document.createElement("a");
|
||||
if(a.download != null) {
|
||||
@ -45,6 +45,10 @@ function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
|
||||
if(URL.revokeObjectURL && typeof setTimeout !== 'undefined') setTimeout(function() { URL.revokeObjectURL(url); }, 60000);
|
||||
return url;
|
||||
}
|
||||
} else if(typeof URL !== 'undefined' && !URL.createObjectURL && typeof chrome === 'object') {
|
||||
/* manifest v3 extensions -- no URL.createObjectURL */
|
||||
var b64 = "data:application/octet-stream;base64," + Base64_encode_arr(new Uint8Array(blobify(data)));
|
||||
return chrome.downloads.download({ url: b64, filename: fname, saveAs: true });
|
||||
}
|
||||
}
|
||||
// $FlowIgnore
|
||||
|
@ -129,8 +129,18 @@ function cc2str(arr/*:Array<number>*/, debomit)/*:string*/ {
|
||||
return new TextDecoder("latin1").decode(arr).replace(/[€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ]/g, function(c) { return rev[c] || c; });
|
||||
} catch(e) {}
|
||||
|
||||
var o = [];
|
||||
for(var i = 0; i != arr.length; ++i) o.push(String.fromCharCode(arr[i]));
|
||||
var o = [], i = 0;
|
||||
// this cascade is for the browsers and runtimes of antiquity (and for modern runtimes that lack TextEncoder)
|
||||
try {
|
||||
for(i = 0; i < arr.length - 65536; i+=65536) o.push(String.fromCharCode.apply(0, arr.slice(i, i + 65536)));
|
||||
o.push(String.fromCharCode.apply(0, arr.slice(i)));
|
||||
} catch(e) { try {
|
||||
for(; i < arr.length - 16384; i+=16384) o.push(String.fromCharCode.apply(0, arr.slice(i, i + 16384)));
|
||||
o.push(String.fromCharCode.apply(0, arr.slice(i)));
|
||||
} catch(e) {
|
||||
for(; i != arr.length; ++i) o.push(String.fromCharCode(arr[i]));
|
||||
}
|
||||
}
|
||||
return o.join("");
|
||||
}
|
||||
|
||||
|
@ -752,21 +752,34 @@ function parse_MTRSettings(blob) {
|
||||
return [fMTREnabled, fUserSetThreadCount, cUserThreadCount];
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.186 TODO: BIFF5 */
|
||||
/* [MS-XLS] 2.5.186 */
|
||||
function parse_NoteSh(blob, length, opts) {
|
||||
if(opts.biff < 8) return;
|
||||
var row = blob.read_shift(2), col = blob.read_shift(2);
|
||||
var flags = blob.read_shift(2), idObj = blob.read_shift(2);
|
||||
var stAuthor = parse_XLUnicodeString2(blob, 0, opts);
|
||||
if(opts.biff < 8) blob.read_shift(1);
|
||||
return [{r:row,c:col}, stAuthor, idObj, flags];
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.4.179 */
|
||||
function parse_Note(blob, length, opts) {
|
||||
if(opts && (opts.biff < 8)) {
|
||||
var row = blob.read_shift(2), col = blob.read_shift(2);
|
||||
if(row == 0xFFFF || row == -1) return; // TODO: test continuation
|
||||
var cch = blob.read_shift(2);
|
||||
var cmnt = blob.read_shift(Math.min(cch,2048), 'cpstr');
|
||||
return [{r:row, c:col}, cmnt];
|
||||
}
|
||||
/* TODO: Support revisions */
|
||||
return parse_NoteSh(blob, length, opts);
|
||||
}
|
||||
function write_NOTE_BIFF2(text/*:string*/, R/*:number*/, C/*:number*/, len/*?:number*/) {
|
||||
var o = new_buf(6 + (len || text.length));
|
||||
o.write_shift(2, R);
|
||||
o.write_shift(2, C);
|
||||
o.write_shift(2, len || text.length);
|
||||
o.write_shift(text.length, text, "sbcs");
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.4.168 */
|
||||
function parse_MergeCells(blob, length)/*:Array<Range>*/ {
|
||||
|
@ -405,6 +405,8 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
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); };
|
||||
sylk_escapes["|"] = 254;
|
||||
/* TODO: evert the escape map */
|
||||
var encode_sylk_str = function($$) { return $$.replace(/\n/g, "\x1b :").replace(/\r/g, "\x1b ="); };
|
||||
/* https://oss.sheetjs.com/notes/sylk/ for more details */
|
||||
function sylk_to_aoa(d/*:RawData*/, opts)/*:[AOA, Worksheet]*/ {
|
||||
switch(opts.type) {
|
||||
@ -457,8 +459,9 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
// case 'NU': // ??
|
||||
case 'C': /* cell */
|
||||
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1, formula = "", cell_t = "z";
|
||||
var cmnt = "";
|
||||
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
|
||||
case 'A': break; // TODO: comment
|
||||
case 'A': cmnt = record[rj].slice(1); break; // TODO: comment
|
||||
case 'X': C = parseInt(record[rj].slice(1), 10)-1; C_seen_X = true; break;
|
||||
case 'Y':
|
||||
R = parseInt(record[rj].slice(1), 10)-1; if(!C_seen_X) C = 0;
|
||||
@ -509,6 +512,10 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
if(!arr[R][C]) arr[R][C] = { t: 'n', f: formula };
|
||||
else arr[R][C].f = formula;
|
||||
}
|
||||
if(cmnt) {
|
||||
if(!arr[R][C]) arr[R][C] = { t: 'z' };
|
||||
arr[R][C].c = [{a:"SheetJSYLK", t: cmnt}];
|
||||
}
|
||||
break;
|
||||
case 'F': /* Format */
|
||||
var F_seen = 0;
|
||||
@ -584,6 +591,13 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
return o;
|
||||
}
|
||||
|
||||
function write_ws_cmnt_sylk(cmnt/*:Comment*/, R/*:number*/, C/*:number*/)/*:string*/ {
|
||||
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";A";
|
||||
/* TODO: max length? */
|
||||
o += encode_sylk_str(cmnt.map(function(c) { return c.t; }).join(""));
|
||||
return o;
|
||||
}
|
||||
|
||||
function write_ws_cols_sylk(out, cols) {
|
||||
cols.forEach(function(col, i) {
|
||||
var rec = "F;W" + (i+1) + " " + (i+1) + " ";
|
||||
@ -622,6 +636,17 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
|
||||
preamble.push("B;Y" + (r.e.r - r.s.r + 1) + ";X" + (r.e.c - r.s.c + 1) + ";D" + [r.s.c,r.s.r,r.e.c,r.e.r].join(" "));
|
||||
preamble.push("O;L;D;B" + (d1904 ? ";V4" : "") + ";K47;G100 0.001");
|
||||
/* Excel has been inconsistent in comment placement, */
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
if(dense && !ws["!data"][R]) continue;
|
||||
var p = [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) {
|
||||
cell = dense ? ws["!data"][R][C] : ws[encode_col(C) + encode_row(R)];
|
||||
if(!cell || !cell.c) continue;
|
||||
p.push(write_ws_cmnt_sylk(cell.c, R, C)); // TODO: pass date1904 info
|
||||
}
|
||||
o.push(p.join(RS));
|
||||
}
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
if(dense && !ws["!data"][R]) continue;
|
||||
var p = [];
|
||||
|
@ -1,5 +1,42 @@
|
||||
/* L.5.5.2 SpreadsheetML Comments + VML Schema */
|
||||
function write_vml(rId/*:number*/, comments) {
|
||||
var shapevmlregex = /<(?:\w+:)?shape(?:[^\w][^>]*)?>([\s\S]*?)<\/(?:\w+:)?shape>/g;
|
||||
function parse_vml(data/*:string*/, sheet, comments) {
|
||||
var cidx = 0;
|
||||
(data.match(shapevmlregex)||[]).forEach(function(m) {
|
||||
var type = "";
|
||||
var hidden = true;
|
||||
var R = -1, C = -1;
|
||||
m.replace(tagregex, function(x/*:string*/, idx/*:number*/) {
|
||||
var y = parsexmltag(x);
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<ClientData': if(y.ObjectType) type = y.ObjectType; break;
|
||||
|
||||
case '<Visible': case '<Visible/>': hidden = false; break;
|
||||
|
||||
case '<Row': case '<Row>': aidx = idx + x.length; break;
|
||||
case '</Row>': R = +m.slice(aidx, idx).trim(); break;
|
||||
|
||||
case '<Column': case '<Column>': aidx = idx + x.length; break;
|
||||
case '</Column>': C = +m.slice(aidx, idx).trim(); break;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
switch(type) {
|
||||
case 'Note':
|
||||
var cell = ws_get_cell_stub(sheet, ((R>=0 && C>=0) ? encode_cell({r:R,c:C}) : comments[cidx].ref));
|
||||
if(cell.c) {
|
||||
cell.c.hidden = hidden;
|
||||
}
|
||||
++cidx;
|
||||
break;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* comment boxes */
|
||||
function write_vml(rId/*:number*/, comments, ws) {
|
||||
var csize = [21600, 21600];
|
||||
/* L.5.2.1.2 Path Attribute */
|
||||
var bbox = ["m0,0l0",csize[1],csize[0],csize[1],csize[0],"0xe"].join(",");
|
||||
@ -21,7 +58,7 @@ function write_vml(rId/*:number*/, comments) {
|
||||
return o.join("");
|
||||
}
|
||||
|
||||
function write_vml_comment(x, _shapeid)/*:string*/ {
|
||||
function write_vml_comment(x, _shapeid, ws)/*:string*/ {
|
||||
var c = decode_cell(x[0]);
|
||||
var fillopts = /*::(*/{'color2':"#BEFF82", 'type':"gradient"}/*:: :any)*/;
|
||||
if(fillopts.type == "gradient") fillopts.angle = "-180";
|
||||
|
@ -64,6 +64,7 @@ function write_comments_xml(data/*::, opts*/) {
|
||||
o.push('</text></comment>');
|
||||
});
|
||||
} else {
|
||||
if(d[1][0] && d[1][0].T && d[1][0].ID) lastauthor = iauthor.indexOf("tc=" + d[1][0].ID);
|
||||
/* based on Threaded Comments -> Comments projection */
|
||||
o.push('<comment ref="' + d[0] + '" authorId="' + lastauthor + '"><text>');
|
||||
var t = "Comment:\n " + (ts[0]) + "\n";
|
||||
|
@ -74,6 +74,10 @@ function write_comments_bin(data/*::, opts*/) {
|
||||
if(iauthor.indexOf(c.a) > -1) return;
|
||||
iauthor.push(c.a.slice(0,54));
|
||||
write_record(ba, 0x0278 /* BrtCommentAuthor */, write_BrtCommentAuthor(c.a));
|
||||
if(c.T && c.ID && iauthor.indexOf("tc=" + c.ID) == -1) {
|
||||
iauthor.push("tc=" + c.ID);
|
||||
write_record(ba, 0x0278 /* BrtCommentAuthor */, write_BrtCommentAuthor("tc=" + c.ID));
|
||||
}
|
||||
});
|
||||
});
|
||||
write_record(ba, 0x0277 /* BrtEndCommentAuthors */);
|
||||
@ -81,7 +85,11 @@ function write_comments_bin(data/*::, opts*/) {
|
||||
write_record(ba, 0x0279 /* BrtBeginCommentList */);
|
||||
data.forEach(function(comment) {
|
||||
comment[1].forEach(function(c) {
|
||||
c.iauthor = iauthor.indexOf(c.a);
|
||||
var _ia = -1;
|
||||
if(c.ID) _ia = iauthor.indexOf("tc=" + c.ID);
|
||||
if(_ia == -1 && comment[1][0].T && comment[1][0].ID) _ia = iauthor.indexOf("tc=" + comment[1][0].ID);
|
||||
if(_ia == -1) _ia = iauthor.indexOf(c.a);
|
||||
c.iauthor = _ia;
|
||||
var range = {s:decode_cell(comment[0]),e:decode_cell(comment[0])};
|
||||
write_record(ba, 0x027B /* BrtBeginComment */, write_BrtBeginComment([range, c]));
|
||||
if(c.t && c.t.length > 0) write_record(ba, 0x027D /* BrtCommentText */, write_BrtCommentText(c));
|
||||
|
@ -75,6 +75,9 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
||||
var margins = data2.match(marginregex);
|
||||
if(margins) s['!margins'] = parse_ws_xml_margins(parsexmltag(margins[0]));
|
||||
|
||||
/* legacyDrawing */
|
||||
if((m = data2.match(/legacyDrawing r:id="(.*?)"/))) s['!legrel'] = m[1];
|
||||
|
||||
if(opts && opts.nodim) refguess.s.c = refguess.s.r = 0;
|
||||
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
|
||||
if(opts.sheetRows > 0 && s["!ref"]) {
|
||||
@ -91,6 +94,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
||||
}
|
||||
if(columns.length > 0) s["!cols"] = columns;
|
||||
if(merges.length > 0) s["!merges"] = merges;
|
||||
if(rels['!id'][s['!legrel']]) s['!legdrawel'] = rels['!id'][s['!legrel']];
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -395,19 +399,27 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
||||
|
||||
if((cref=d.match(match_v))!= null && /*::cref != null && */cref[1] !== '') p.v=unescapexml(cref[1]);
|
||||
if(opts.cellFormula) {
|
||||
if((cref=d.match(match_f))!= null && /*::cref != null && */cref[1] !== '') {
|
||||
/* TODO: match against XLSXFutureFunctions */
|
||||
p.f=unescapexml(utf8read(cref[1]), true);
|
||||
if(!opts.xlfn) p.f = _xlfn(p.f);
|
||||
if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="array"') > -1) {
|
||||
p.F = (d.match(refregex)||[])[1];
|
||||
if(p.F.indexOf(":") > -1) arrayf.push([safe_decode_range(p.F), p.F]);
|
||||
} else if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="shared"') > -1) {
|
||||
// TODO: parse formula
|
||||
ftag = parsexmltag(cref[0]);
|
||||
var ___f = unescapexml(utf8read(cref[1]));
|
||||
if(!opts.xlfn) ___f = _xlfn(___f);
|
||||
sharedf[parseInt(ftag.si, 10)] = [ftag, ___f, tag.r];
|
||||
if((cref=d.match(match_f))!= null /*:: && cref != null*/) {
|
||||
if(cref[1] == "") {
|
||||
if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="shared"') > -1) {
|
||||
// TODO: parse formula
|
||||
ftag = parsexmltag(cref[0]);
|
||||
if(sharedf[ftag.si]) p.f = shift_formula_xlsx(sharedf[ftag.si][1], sharedf[ftag.si][2]/*[0].ref*/, tag.r);
|
||||
}
|
||||
} else {
|
||||
/* TODO: match against XLSXFutureFunctions */
|
||||
p.f=unescapexml(utf8read(cref[1]), true);
|
||||
if(!opts.xlfn) p.f = _xlfn(p.f);
|
||||
if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="array"') > -1) {
|
||||
p.F = (d.match(refregex)||[])[1];
|
||||
if(p.F.indexOf(":") > -1) arrayf.push([safe_decode_range(p.F), p.F]);
|
||||
} else if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="shared"') > -1) {
|
||||
// TODO: parse formula
|
||||
ftag = parsexmltag(cref[0]);
|
||||
var ___f = unescapexml(utf8read(cref[1]));
|
||||
if(!opts.xlfn) ___f = _xlfn(___f);
|
||||
sharedf[parseInt(ftag.si, 10)] = [ftag, ___f, tag.r];
|
||||
}
|
||||
}
|
||||
} else if((cref=d.match(/<f[^>]*\/>/))) {
|
||||
ftag = parsexmltag(cref[0]);
|
||||
|
@ -686,6 +686,10 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0227: /* 'BrtLegacyDrawing' */
|
||||
if(val) s["!legrel"] = val;
|
||||
break;
|
||||
|
||||
case 0x00A1: /* 'BrtBeginAFilter' */
|
||||
s['!autofilter'] = { ref:encode_range(val) };
|
||||
break;
|
||||
@ -742,7 +746,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
case 0x0499: /* 'BrtFilter14' */
|
||||
case 0x00A9: /* 'BrtIconFilter' */
|
||||
case 0x049D: /* 'BrtIconFilter14' */
|
||||
case 0x0227: /* 'BrtLegacyDrawing' */
|
||||
case 0x0228: /* 'BrtLegacyDrawingHF' */
|
||||
case 0x0295: /* 'BrtListPart' */
|
||||
case 0x027F: /* 'BrtOleObject' */
|
||||
@ -801,6 +804,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
||||
if(merges.length > 0) s["!merges"] = merges;
|
||||
if(colinfo.length > 0) s["!cols"] = colinfo;
|
||||
if(rowinfo.length > 0) s["!rows"] = rowinfo;
|
||||
if(rels['!id'][s['!legrel']]) s['!legdrawel'] = rels['!id'][s['!legrel']];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -443,6 +443,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
||||
} else {
|
||||
state.push([Rn[3], false]);
|
||||
tmp = xlml_parsexmltag(Rn[0]);
|
||||
if(!parsexmlbool(tmp["ShowAlways"]||"0")) comments.hidden = true;
|
||||
comment = ({a:tmp.Author}/*:any*/);
|
||||
}
|
||||
break;
|
||||
@ -534,6 +535,9 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
||||
/*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */
|
||||
Workbook.WBProps.date1904 = true;
|
||||
break;
|
||||
case 'hidehorizontalscrollbar' /*case 'HideHorizontalScrollBar'*/: break;
|
||||
case 'hideverticalscrollbar' /*case 'HideVerticalScrollBar'*/: break;
|
||||
case 'hideworkbooktabs' /*case 'HideWorkbookTabs'*/: break;
|
||||
case 'windowheight' /*case 'WindowHeight'*/: break;
|
||||
case 'windowwidth' /*case 'WindowWidth'*/: break;
|
||||
case 'windowtopx' /*case 'WindowTopX'*/: break;
|
||||
@ -1102,11 +1106,15 @@ function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workb
|
||||
return writextag("WorksheetOptions", o.join(""), {xmlns:XLMLNS.x});
|
||||
}
|
||||
function write_ws_xlml_comment(comments/*:Array<any>*/)/*:string*/ {
|
||||
/* TODO: test multiple comments */
|
||||
return comments.map(function(c) {
|
||||
// TODO: formatted text
|
||||
var t = xlml_unfixstr(c.t||"");
|
||||
var d =writextag("ss:Data", t, {"xmlns":"http://www.w3.org/TR/REC-html40"});
|
||||
return writextag("Comment", d, {"ss:Author":c.a});
|
||||
var p = {};
|
||||
if(c.a) p["ss:Author"] = c.a;
|
||||
if(!comments.hidden) p["ss:ShowAlways"] = "1";
|
||||
return writextag("Comment", d, p);
|
||||
}).join("");
|
||||
}
|
||||
function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb, addr)/*:string*/{
|
||||
|
@ -520,9 +520,8 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
}
|
||||
} break;
|
||||
case 0x001c /* Note */: {
|
||||
if(opts.biff <= 5 && opts.biff >= 2) break; /* TODO: BIFF5 */
|
||||
/* TODO: comment continuation (row == -1 / 0xFFFF) */
|
||||
cc = options.dense ? (out["!data"][val[0].r]||[])[val[0].c] : out[encode_cell(val[0])];
|
||||
var noteobj = objects[val[2]];
|
||||
if(!cc) {
|
||||
if(options.dense) {
|
||||
if(!out["!data"][val[0].r]) out["!data"][val[0].r] = [];
|
||||
@ -536,7 +535,12 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
range.s.c = Math.min(range.s.c, val[0].c);
|
||||
}
|
||||
if(!cc.c) cc.c = [];
|
||||
cmnt = {a:val[1],t:noteobj.TxO.t};
|
||||
if(opts.biff <= 5 && opts.biff >= 2) cmnt = {a:"SheetJ5", t:val[1]};
|
||||
else {
|
||||
var noteobj = objects[val[2]];
|
||||
cmnt = {a:val[1],t:noteobj.TxO.t};
|
||||
if(val[3] != null && !(val[3] & 0x02)) cc.c.hidden = true;
|
||||
}
|
||||
cc.c.push(cmnt);
|
||||
} break;
|
||||
case 0x087d /* XFExt */: update_xfext(XFs[val.ixfe], val.ext); break;
|
||||
|
@ -482,7 +482,7 @@ var XLSBRecordEnum = {
|
||||
/*::[*/0x0224/*::]*/: { /* n:"BrtFileSharing" */ },
|
||||
/*::[*/0x0225/*::]*/: { /* n:"BrtOleSize" */ },
|
||||
/*::[*/0x0226/*::]*/: { /* n:"BrtDrawing", */ f:parse_RelID },
|
||||
/*::[*/0x0227/*::]*/: { /* n:"BrtLegacyDrawing" */ },
|
||||
/*::[*/0x0227/*::]*/: { /* n:"BrtLegacyDrawing", */ f:parse_XLNullableWideString },
|
||||
/*::[*/0x0228/*::]*/: { /* n:"BrtLegacyDrawingHF" */ },
|
||||
/*::[*/0x0229/*::]*/: { /* n:"BrtWebOpt" */ },
|
||||
/*::[*/0x022A/*::]*/: { /* n:"BrtBeginWebPubItems", */ T:1 },
|
||||
@ -1233,30 +1233,30 @@ var XLSRecordEnum = {
|
||||
/*::[*/0x0021/*::]*/: { /* n:"Array", */ f:parse_Array },
|
||||
/*::[*/0x0024/*::]*/: { /* n:"COLWIDTH", */ },
|
||||
/*::[*/0x0025/*::]*/: { /* n:"DefaultRowHeight", */ f:parse_DefaultRowHeight },
|
||||
// 0x2c ??
|
||||
// 0x2d ??
|
||||
// 0x2e ??
|
||||
// 0x30 FONTCOUNT: number of fonts
|
||||
// 0x002c ??
|
||||
// 0x002d ??
|
||||
// 0x002e ??
|
||||
// 0x0030 FONTCOUNT: number of fonts
|
||||
/*::[*/0x0032/*::]*/: { /* n:"BIFF2FONTXTRA", */ f:parse_BIFF2FONTXTRA },
|
||||
// 0x35: INFOOPTS
|
||||
// 0x36: TABLE (BIFF2 only)
|
||||
// 0x37: TABLE2 (BIFF2 only)
|
||||
// 0x38: WNDESK
|
||||
// 0x39 ??
|
||||
// 0x3a: BEGINPREF
|
||||
// 0x3b: ENDPREF
|
||||
// 0x0035: INFOOPTS
|
||||
// 0x0036: TABLE (BIFF2 only)
|
||||
// 0x0037: TABLE2 (BIFF2 only)
|
||||
// 0x0038: WNDESK
|
||||
// 0x0039 ??
|
||||
// 0x003a: BEGINPREF
|
||||
// 0x003b: ENDPREF
|
||||
/*::[*/0x003e/*::]*/: { /* n:"BIFF2WINDOW2", */ },
|
||||
// 0x3f ??
|
||||
// 0x46: SHOWSCROLL
|
||||
// 0x47: SHOWFORMULA
|
||||
// 0x48: STATUSBAR
|
||||
// 0x49: SHORTMENUS
|
||||
// 0x4A:
|
||||
// 0x4B:
|
||||
// 0x4C:
|
||||
// 0x4E:
|
||||
// 0x4F:
|
||||
// 0x58: TOOLBAR (BIFF3)
|
||||
// 0x003f ??
|
||||
// 0x0046: SHOWSCROLL
|
||||
// 0x0047: SHOWFORMULA
|
||||
// 0x0048: STATUSBAR
|
||||
// 0x0049: SHORTMENUS
|
||||
// 0x004A:
|
||||
// 0x004B:
|
||||
// 0x004C:
|
||||
// 0x004E:
|
||||
// 0x004F:
|
||||
// 0x0058: TOOLBAR (BIFF3)
|
||||
|
||||
/* - - - */
|
||||
/*::[*/0x0034/*::]*/: { /* n:"DDEObjName", */ },
|
||||
|
@ -56,6 +56,17 @@ function write_BIFF2LABEL(r/*:number*/, c/*:number*/, val) {
|
||||
return out.l < out.length ? out.slice(0, out.l) : out;
|
||||
}
|
||||
|
||||
function write_comments_biff2(ba/*:BufArray*/, comments/*:Array<[Comment[], number, number]>*/) {
|
||||
comments.forEach(function(data) {
|
||||
var text = data[0].map(function(cc) { return cc.t; }).join("");
|
||||
// TODO: should '\n' be translated to '\r' to correct for Excel 5.0 bug when exporting to BIFF2/3 ?
|
||||
if(text.length <= 2048) return write_biff_rec(ba, 0x001C, write_NOTE_BIFF2(text, data[1], data[2]));
|
||||
write_biff_rec(ba, 0x001C, write_NOTE_BIFF2(text.slice(0, 2048), data[1], data[2], text.length));
|
||||
for(var i = 2048; i < text.length; i += 2048)
|
||||
write_biff_rec(ba, 0x001C, write_NOTE_BIFF2(text.slice(i, Math.min(i+2048, text.length)), -1, -1, Math.min(2048, text.length - i)));
|
||||
});
|
||||
}
|
||||
|
||||
function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*//*::, opts*/) {
|
||||
if(cell.v != null) switch(cell.t) {
|
||||
case 'd': case 'n':
|
||||
@ -86,7 +97,7 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||
}
|
||||
var row = [];
|
||||
var row = [], comments = [];
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
if(dense) row = ws["!data"][R] || [];
|
||||
@ -96,8 +107,13 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff2_cell(ba, cell, R, C, opts);
|
||||
if(cell.c) comments.push([cell.c, R, C]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ... 0x12 0x19 0x13 (Password) */
|
||||
write_comments_biff2(ba, comments);
|
||||
/* 0x3d (Window1) ... */
|
||||
}
|
||||
|
||||
/* Based on test files */
|
||||
@ -115,6 +131,257 @@ function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
return ba.end();
|
||||
}
|
||||
|
||||
var b8oid = 1, b8ocnts/*:Array<[number, number, number]>*/ = [];
|
||||
function write_MsoDrawingGroup() {
|
||||
var buf = new_buf(82 + 8 * b8ocnts.length);
|
||||
/* [MS-ODRAW] 2.2.12 OfficeArtDggContainer */
|
||||
buf.write_shift(2, 0x0F);
|
||||
buf.write_shift(2, 0xF000);
|
||||
buf.write_shift(4, 74 + 8 * b8ocnts.length);
|
||||
/* 2.2.48 OfficeArtFDGGBlock */
|
||||
{
|
||||
buf.write_shift(2, 0);
|
||||
buf.write_shift(2, 0xF006);
|
||||
buf.write_shift(4, 16 + 8 * b8ocnts.length);
|
||||
/* 2.2.47 OfficeArtFDGG */
|
||||
{
|
||||
buf.write_shift(4, b8oid);
|
||||
buf.write_shift(4, b8ocnts.length+1);
|
||||
buf.write_shift(4, b8ocnts.reduce(function(acc,x) { return acc+x[1]; }, 0));
|
||||
buf.write_shift(4, b8ocnts.length);
|
||||
}
|
||||
/* 2.2.46 OfficeArtIDCL + */
|
||||
b8ocnts.forEach(function(b8) {
|
||||
buf.write_shift(4, b8[0]);
|
||||
buf.write_shift(4, b8[2]);
|
||||
});
|
||||
}
|
||||
/* 2.2.9 OfficeArtFOPT */
|
||||
{
|
||||
buf.write_shift(2, 0x33); // 0x03 | (3 << 4)
|
||||
buf.write_shift(2, 0xF00B);
|
||||
buf.write_shift(4, 0x12); // 3 * 6
|
||||
/* 2.3.21.15 Text Boolean Properties */
|
||||
buf.write_shift(2, 0xBF); buf.write_shift(4, 0x00080008);
|
||||
/* 2.3.7.2 fillColor */
|
||||
buf.write_shift(2, 0x0181); buf.write_shift(4, 0x08000041);
|
||||
/* 2.3.8.1 lineColor */
|
||||
buf.write_shift(2, 0x01C0); buf.write_shift(4, 0x08000040);
|
||||
}
|
||||
/* 2.2.45 OfficeArtSplitMenuColorContainer */
|
||||
{
|
||||
buf.write_shift(2, 0x40);
|
||||
buf.write_shift(2, 0xF11E);
|
||||
buf.write_shift(4, 16);
|
||||
buf.write_shift(4, 0x0800000D);
|
||||
buf.write_shift(4, 0x0800000C);
|
||||
buf.write_shift(4, 0x08000017);
|
||||
buf.write_shift(4, 0x100000F7);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
function write_comments_biff8(ba/*:BufArray*/, comments/*:Array<[Comment[], number, number]>*/) {
|
||||
var notes/*:Array<RawData>*/ = [], sz = 0, pl = buf_array(), baseid = b8oid;
|
||||
var _oasc;
|
||||
comments.forEach(function(c, ci) {
|
||||
var author = "";
|
||||
var text = c[0].map(function(t) { if(t.a && !author) author = t.a; return t.t }).join("");
|
||||
++b8oid;
|
||||
|
||||
/* 2.2.14 OfficeArtSpContainer */
|
||||
{
|
||||
var oasc = new_buf(0x96);
|
||||
oasc.write_shift(2, 0x0F);
|
||||
oasc.write_shift(2, 0xF004);
|
||||
oasc.write_shift(4, 0x96);
|
||||
/* 2.2.40 OfficeArtFSP */
|
||||
{
|
||||
oasc.write_shift(2, 0xca2); // 0x02 | (0xca << 4)
|
||||
oasc.write_shift(2, 0xF00A);
|
||||
oasc.write_shift(4, 8);
|
||||
oasc.write_shift(4, b8oid);
|
||||
oasc.write_shift(4, 0xA00);
|
||||
}
|
||||
/* 2.2.9 OfficeArtFOPT */
|
||||
{
|
||||
oasc.write_shift(2, 0xE3); // 0x03 | (14 << 4)
|
||||
oasc.write_shift(2, 0xF00B);
|
||||
oasc.write_shift(4, 0x54); // 14 * 6
|
||||
/* 2.3.21.1 ITxid */
|
||||
oasc.write_shift(2, 0x80); oasc.write_shift(4, 0);
|
||||
/* 2.3.21.12 txdir */
|
||||
oasc.write_shift(2, 0x8B); oasc.write_shift(4, 0x02);
|
||||
/* 2.3.21.15 Text Boolean Properties */
|
||||
oasc.write_shift(2, 0xBF); oasc.write_shift(4, 0x00080008);
|
||||
/* 2.3.6.30 cxk */
|
||||
oasc.write_shift(2, 0x0158); oasc.l += 4;
|
||||
/* 2.3.7.2 fillColor */
|
||||
oasc.write_shift(2, 0x0181); oasc.write_shift(4, 0x08000050);
|
||||
/* 2.3.7.4 fillBackColor */
|
||||
oasc.write_shift(2, 0x0183); oasc.write_shift(4, 0x08000050);
|
||||
/* 2.3.7.6 fillCrMod */
|
||||
oasc.write_shift(2, 0x0185); oasc.write_shift(4, 0x100000F4);
|
||||
/* 2.3.7.43 Fill Style Boolean Properties */
|
||||
oasc.write_shift(2, 0x01BF); oasc.write_shift(4, 0x00100010);
|
||||
/* 2.3.8.1 lineColor */
|
||||
oasc.write_shift(2, 0x01C0); oasc.write_shift(4, 0x08000051);
|
||||
/* 2.3.8.4 lineCrMod */
|
||||
oasc.write_shift(2, 0x01C3); oasc.write_shift(4, 0x100000F4);
|
||||
/* 2.3.13.2 shadowColor */
|
||||
oasc.write_shift(2, 0x0201); oasc.write_shift(4, 0x08000051);
|
||||
/* 2.3.13.4 shadowCrMod */
|
||||
oasc.write_shift(2, 0x0203); oasc.write_shift(4, 0x100000F4);
|
||||
/* 2.3.13.23 Shadow Style Boolean Properties */
|
||||
oasc.write_shift(2, 0x023F); oasc.write_shift(4, 0x00030001);
|
||||
/* 2.3.4.44 Group Shape Boolean Properties */
|
||||
oasc.write_shift(2, 0x03BF); oasc.write_shift(4, 0x00020000 | (c[0].hidden ? 2 : 0));
|
||||
}
|
||||
/* [MS-XLS] 2.5.193 OfficeArtClientAnchorSheet */
|
||||
{
|
||||
oasc.l += 2;
|
||||
oasc.write_shift(2, 0xF010);
|
||||
oasc.write_shift(4, 0x12);
|
||||
oasc.write_shift(2, 0x3); // do not move or size with cells
|
||||
oasc.write_shift(2, c[2] + 2); oasc.l += 2;
|
||||
oasc.write_shift(2, c[1] + 1); oasc.l += 2;
|
||||
oasc.write_shift(2, c[2] + 4); oasc.l += 2;
|
||||
oasc.write_shift(2, c[1] + 5); oasc.l += 2;
|
||||
}
|
||||
/* [MS-XLS] 2.5.194 OfficeArtClientData */
|
||||
{
|
||||
oasc.l += 2;
|
||||
oasc.write_shift(2, 0xF011);
|
||||
oasc.l += 4;
|
||||
}
|
||||
oasc.l = 0x96;
|
||||
if(ci == 0) /* write_biff_rec(pl, 0x003C, oasc); */ _oasc = oasc;
|
||||
else write_biff_rec(pl, 0x00EC, oasc);
|
||||
}
|
||||
sz += 0x96;
|
||||
|
||||
/* [MS-XLS] 2.4.181 Obj */
|
||||
{
|
||||
var obj = new_buf(52); // 22 + 26 + 4
|
||||
/* [MS-XLS] 2.5.143 FtCmo */
|
||||
obj.write_shift(2, 0x15);
|
||||
obj.write_shift(2, 0x12);
|
||||
obj.write_shift(2, 0x19);
|
||||
obj.write_shift(2, b8oid);
|
||||
obj.write_shift(2, 0);
|
||||
obj.l = 22;
|
||||
/* [MS-XLS] 2.5.149 FtNts */
|
||||
obj.write_shift(2, 0x0D);
|
||||
obj.write_shift(2, 0x16);
|
||||
obj.write_shift(4, 0x62726272);
|
||||
obj.write_shift(4, 0x95374305);
|
||||
obj.write_shift(4, 0x80301328);
|
||||
obj.write_shift(4, 0x69696904 + b8oid*256);
|
||||
obj.write_shift(2,0);
|
||||
obj.write_shift(4,0);
|
||||
// reserved
|
||||
obj.l += 4;
|
||||
write_biff_rec(pl, 0x005D, obj);
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.195 OfficeArtClientTextbox */
|
||||
{
|
||||
var oact = new_buf(8);
|
||||
oact.l += 2;
|
||||
oact.write_shift(2, 0xF00D);
|
||||
oact.l += 4;
|
||||
write_biff_rec(pl, 0x00EC, oact);
|
||||
}
|
||||
sz += 8;
|
||||
|
||||
/* [MS-XLS] 2.4.329 TxO */
|
||||
{
|
||||
var txo = new_buf(18);
|
||||
txo.write_shift(2, 0x12);
|
||||
txo.l += 8;
|
||||
txo.write_shift(2, text.length);
|
||||
txo.write_shift(2, 0x10);
|
||||
txo.l += 4;
|
||||
write_biff_rec(pl, 0x01b6, txo);
|
||||
/* text continue record TODO: switch to wide strings */
|
||||
{
|
||||
var cont = new_buf(1 + text.length);
|
||||
cont.write_shift(1, 0);
|
||||
cont.write_shift(text.length, text, "sbcs");
|
||||
write_biff_rec(pl, 0x003C, cont);
|
||||
}
|
||||
/* formatting continue records */
|
||||
{
|
||||
var conf = new_buf(0x10);
|
||||
conf.l += 8;
|
||||
conf.write_shift(2, text.length);
|
||||
conf.l += 6;
|
||||
write_biff_rec(pl, 0x003C, conf);
|
||||
}
|
||||
}
|
||||
|
||||
/* 2.4.179 Note */
|
||||
{
|
||||
var notesh = new_buf(12 + author.length);
|
||||
notesh.write_shift(2, c[1]);
|
||||
notesh.write_shift(2, c[2]);
|
||||
notesh.write_shift(2, 0 | (c[0].hidden ? 0 : 2));
|
||||
notesh.write_shift(2, b8oid);
|
||||
notesh.write_shift(2, author.length);
|
||||
notesh.write_shift(1, 0);
|
||||
notesh.write_shift(author.length, author, "sbcs");
|
||||
notesh.l ++;
|
||||
notes.push(notesh);
|
||||
}
|
||||
});
|
||||
/* [MS-ODRAW] 2.2.13 OfficeArtDgContainer */
|
||||
{
|
||||
var hdr = new_buf(80);
|
||||
hdr.write_shift(2, 0x0F)
|
||||
hdr.write_shift(2, 0xF002);
|
||||
hdr.write_shift(4, sz + hdr.length - 8);
|
||||
/* [MS-ODRAW] 2.2.49 OfficeArtFDG */
|
||||
{
|
||||
hdr.write_shift(2, 0x10);
|
||||
hdr.write_shift(2, 0xF008);
|
||||
hdr.write_shift(4, 0x08);
|
||||
hdr.write_shift(4, comments.length + 1);
|
||||
hdr.write_shift(4, b8oid);
|
||||
}
|
||||
/* [MS-ODRAW] 2.2.16 OfficeArtSpgrContainer */
|
||||
{
|
||||
hdr.write_shift(2, 0x0f);
|
||||
hdr.write_shift(2, 0xF003);
|
||||
hdr.write_shift(4, sz + 0x30);
|
||||
/* [MS-ODRAW] 2.2.14 OfficeArtSpContainer */
|
||||
{
|
||||
hdr.write_shift(2, 0x0f);
|
||||
hdr.write_shift(2, 0xF004);
|
||||
hdr.write_shift(4, 0x28);
|
||||
/* [MS-ODRAW] 2.2.38 OfficeArtFSPGR */
|
||||
{
|
||||
hdr.write_shift(2, 0x01);
|
||||
hdr.write_shift(2, 0xF009);
|
||||
hdr.write_shift(4, 0x10);
|
||||
hdr.l += 16;
|
||||
}
|
||||
/* [MS-ODRAW] 2.2.40 OfficeArtFSP */
|
||||
{
|
||||
hdr.write_shift(2, 0x02);
|
||||
hdr.write_shift(2, 0xF00A);
|
||||
hdr.write_shift(4, 0x08);
|
||||
hdr.write_shift(4, baseid);
|
||||
hdr.write_shift(4, 0x05);
|
||||
}
|
||||
}
|
||||
}
|
||||
write_biff_rec(ba, 0x00EC, /* hdr */ bconcat([hdr, _oasc]));
|
||||
}
|
||||
ba.push(pl.end());
|
||||
notes.forEach(function(n) { write_biff_rec(ba, 0x001C, n); });
|
||||
b8ocnts.push([baseid, comments.length + 1, b8oid]);
|
||||
++b8oid;
|
||||
}
|
||||
|
||||
function write_FONTS_biff8(ba, data, opts) {
|
||||
write_biff_rec(ba, 0x0031 /* Font */, write_Font({
|
||||
sz:12,
|
||||
@ -260,12 +527,12 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
/* write cell */
|
||||
write_ws_biff8_cell(ba, cell, R, C, opts);
|
||||
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
|
||||
if(b8 && cell.c) comments.push([ref, cell.c]);
|
||||
if(cell.c) comments.push([cell.c, R, C]);
|
||||
}
|
||||
}
|
||||
var cname/*:string*/ = _sheet.CodeName || _sheet.name || s;
|
||||
/* ... */
|
||||
// if(b8) comments.forEach(function(comment) { write_biff_rec(ba, 0x001c /* Note */, write_NoteSh(comment)); });
|
||||
if(b8) write_comments_biff8(ba, comments); else write_comments_biff2(ba, comments);
|
||||
/* ... */
|
||||
if(b8) write_biff_rec(ba, 0x023e /* Window2 */, write_Window2((_WB.Views||[])[0]));
|
||||
/* ... */
|
||||
@ -335,8 +602,10 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
|
||||
var C = buf_array();
|
||||
/* METADATA [MTRSettings] [ForceFullCalculation] */
|
||||
if(b8) write_biff_rec(C, 0x008C /* Country */, write_Country());
|
||||
/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */
|
||||
/* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture */
|
||||
|
||||
/* BIFF8: MsoDrawingGroup [*Continue] */
|
||||
if(b8 && b8ocnts.length) write_biff_rec(C, 0x00EB /* MsoDrawingGroup */, write_MsoDrawingGroup());
|
||||
/* BIFF8: [SST *Continue] ExtSST */
|
||||
if(b8 && opts.Strings) write_biff_continue(C, 0x00FC /* SST */, write_SST(opts.Strings, opts));
|
||||
|
||||
@ -379,6 +648,7 @@ function write_biff8_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
o.ssf = wb.SSF;
|
||||
}
|
||||
|
||||
b8oid = 1; b8ocnts = [];
|
||||
o.Strings = /*::((*/[]/*:: :any):SST)*/; o.Strings.Count = 0; o.Strings.Unique = 0;
|
||||
fix_write_opts(o);
|
||||
|
||||
|
@ -248,8 +248,8 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
||||
var ws = ({}/*:any*/); if(opts.dense) ws["!data"] = [];
|
||||
var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
|
||||
var ctag = ({value:""}/*:any*/);
|
||||
var textp = "", textpidx = 0, textptag/*:: = {}*/;
|
||||
var textR = [];
|
||||
var textp = "", textpidx = 0, textptag/*:: = {}*/, oldtextp = "", oldtextpidx = 0;
|
||||
var textR = [], oldtextR = [];
|
||||
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
|
||||
var row_ol = 0;
|
||||
var number_format_map = _nfm || {}, styles = {};
|
||||
@ -334,7 +334,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
||||
C+= colpeat-1;
|
||||
} else if(Rn[1]!=='/') {
|
||||
++C;
|
||||
textp = ""; textpidx = 0; textR = [];
|
||||
textp = oldtextp = ""; textpidx = oldtextpidx = 0; textR = []; oldtextR = [];
|
||||
colpeat = 1;
|
||||
var rptR = rowpeat ? R + rowpeat - 1 : R;
|
||||
if(C > range.e.c) range.e.c = C;
|
||||
@ -443,10 +443,17 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
||||
if(textR.length) /*::(*/comment/*:: :any)*/.R = textR;
|
||||
comment.a = creator;
|
||||
comments.push(comment);
|
||||
textp = oldtextp; textpidx = oldtextpidx; textR = oldtextR;
|
||||
}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
|
||||
state.push([Rn[3], false]);
|
||||
var annotag = parsexmltag(Rn[0], true);
|
||||
/* office:display TODO: check if there is a global override */
|
||||
if(!(annotag["display"] && parsexmlbool(annotag["display"]))) comments.hidden = true;
|
||||
oldtextp = textp; oldtextpidx = textpidx; oldtextR = textR;
|
||||
textp = ""; textpidx = 0; textR = [];
|
||||
}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') {state.push([Rn[3], false]);}
|
||||
creator = ""; creatoridx = 0;
|
||||
textp = ""; textpidx = 0; textR = [];
|
||||
break;
|
||||
|
||||
case 'creator': // 4.3.2.7 <dc:creator>
|
||||
|
@ -204,7 +204,6 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
||||
};
|
||||
|
||||
var null_cell_xml = ' <table:table-cell />\n';
|
||||
var covered_cell_xml = ' <table:covered-table-cell/>\n';
|
||||
var write_ws = function(ws, wb/*:Workbook*/, i/*:number*/, opts, nfs)/*:string*/ {
|
||||
/* Section 9 Tables */
|
||||
var o/*:Array<string>*/ = [];
|
||||
@ -236,7 +235,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
||||
ct['table:number-rows-spanned'] = (marr[mi].e.r - marr[mi].s.r + 1);
|
||||
break;
|
||||
}
|
||||
if(skip) { o.push(covered_cell_xml); continue; }
|
||||
if(skip) { o.push(' <table:covered-table-cell/>\n'); continue; }
|
||||
var ref = encode_cell({r:R, c:C}), cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
|
||||
if(cell && cell.f) {
|
||||
ct['table:formula'] = escapexml(csf_to_ods_formula(cell.f));
|
||||
@ -270,8 +269,8 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
||||
ct['office:date-value'] = (parseDate(cell.v).toISOString());
|
||||
ct['table:style-name'] = "ce1";
|
||||
break;
|
||||
//case 'e':
|
||||
default: o.push(null_cell_xml); continue;
|
||||
//case 'e': // TODO: translate to ODS errors
|
||||
default: o.push(null_cell_xml); continue; // TODO: empty cell with comments
|
||||
}
|
||||
var text_p = write_text_p(textp);
|
||||
if(cell.l && cell.l.Target) {
|
||||
@ -282,7 +281,17 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
||||
text_p = writextag('text:a', text_p, {'xlink:href': _tgt.replace(/&/g, "&")});
|
||||
}
|
||||
if(nfs[cell.z]) ct["table:style-name"] = "ce" + nfs[cell.z].slice(1);
|
||||
o.push(' ' + writextag('table:table-cell', writextag('text:p', text_p, {}), ct) + '\n');
|
||||
var payload = writextag('text:p', text_p, {});
|
||||
if(cell.c) {
|
||||
var acreator = "", apayload = "", aprops = {};
|
||||
for(var ci = 0; ci < cell.c.length; ++ci) {
|
||||
if(!acreator && cell.c[ci].a) acreator = cell.c[ci].a;
|
||||
apayload += "<text:p>" + write_text_p(cell.c[ci].t) + "</text:p>";
|
||||
}
|
||||
if(!cell.c.hidden) aprops["office:display"] = true;
|
||||
payload = writextag('office:annotation', apayload, aprops) + payload;
|
||||
}
|
||||
o.push(' ' + writextag('table:table-cell', payload, ct) + '\n');
|
||||
}
|
||||
o.push(' </table:table-row>\n');
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ function compress_iwa_file(buf) {
|
||||
return u8concat(out);
|
||||
}
|
||||
var numbers_lut_new = function() {
|
||||
return { sst: [], rsst: [], ofmt: [], nfmt: [], fmla: [], ferr: [] };
|
||||
return { sst: [], rsst: [], ofmt: [], nfmt: [], fmla: [], ferr: [], cmnt: [] };
|
||||
};
|
||||
function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
|
||||
var _a, _b, _c, _d;
|
||||
@ -684,7 +684,8 @@ function parse_new_storage(buf, lut) {
|
||||
var t = buf[1];
|
||||
switch (t) {
|
||||
case 0:
|
||||
return void 0;
|
||||
ret = { t: "z" };
|
||||
break;
|
||||
case 2:
|
||||
ret = { t: "n", v: d128 };
|
||||
break;
|
||||
@ -726,6 +727,12 @@ function parse_new_storage(buf, lut) {
|
||||
zidx = dv.getUint32(doff, true);
|
||||
doff += 4;
|
||||
}
|
||||
if (fields & 524288) {
|
||||
var cmntidx = dv.getUint32(doff, true);
|
||||
doff += 4;
|
||||
if (lut.cmnt[cmntidx])
|
||||
ret.c = iwa_to_s5s_comment(lut.cmnt[cmntidx]);
|
||||
}
|
||||
if (zidx > -1)
|
||||
numbers_format_cell(ret, t | 5 << 8, fields >> 13, lut.ofmt[zidx], lut.nfmt[zidx]);
|
||||
if (t == 7)
|
||||
@ -927,6 +934,12 @@ function parse_TST_TableDataList(M, root) {
|
||||
case 3:
|
||||
data[key] = parse_shallow(le[5][0].data);
|
||||
break;
|
||||
case 10:
|
||||
{
|
||||
var cs = M[parse_TSP_Reference(le[10][0].data)][0];
|
||||
data[key] = parse_TSD_CommentStorageArchive(M, cs.data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw type;
|
||||
}
|
||||
@ -992,8 +1005,38 @@ function parse_TST_Tile(M, root) {
|
||||
}, [])
|
||||
};
|
||||
}
|
||||
function parse_TSD_CommentStorageArchive(M, data) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
||||
var out = { t: "", a: "" };
|
||||
var csp = parse_shallow(data);
|
||||
if ((_b = (_a = csp == null ? void 0 : csp[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.data)
|
||||
out.t = u8str((_d = (_c = csp == null ? void 0 : csp[1]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) || "";
|
||||
if ((_f = (_e = csp == null ? void 0 : csp[3]) == null ? void 0 : _e[0]) == null ? void 0 : _f.data) {
|
||||
var as = M[parse_TSP_Reference((_h = (_g = csp == null ? void 0 : csp[3]) == null ? void 0 : _g[0]) == null ? void 0 : _h.data)][0];
|
||||
var asp = parse_shallow(as.data);
|
||||
if ((_j = (_i = asp[1]) == null ? void 0 : _i[0]) == null ? void 0 : _j.data)
|
||||
out.a = u8str(asp[1][0].data);
|
||||
}
|
||||
if (csp == null ? void 0 : csp[4]) {
|
||||
out.replies = [];
|
||||
csp[4].forEach(function(pi) {
|
||||
var cs = M[parse_TSP_Reference(pi.data)][0];
|
||||
out.replies.push(parse_TSD_CommentStorageArchive(M, cs.data));
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function iwa_to_s5s_comment(iwa) {
|
||||
var out = [];
|
||||
out.push({ t: iwa.t || "", a: iwa.a, T: iwa.replies && iwa.replies.length > 0 });
|
||||
if (iwa.replies)
|
||||
iwa.replies.forEach(function(reply) {
|
||||
out.push({ t: reply.t || "", a: reply.a, T: true });
|
||||
});
|
||||
return out;
|
||||
}
|
||||
function parse_TST_TableModelArchive(M, root, ws) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
||||
var pb = parse_shallow(root.data);
|
||||
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
|
||||
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
|
||||
@ -1016,7 +1059,9 @@ function parse_TST_TableModelArchive(M, root, ws) {
|
||||
lut.ferr = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[12][0].data)][0]);
|
||||
if ((_e = store[17]) == null ? void 0 : _e[0])
|
||||
lut.rsst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]);
|
||||
if ((_f = store[22]) == null ? void 0 : _f[0])
|
||||
if ((_f = store[19]) == null ? void 0 : _f[0])
|
||||
lut.cmnt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[19][0].data)][0]);
|
||||
if ((_g = store[22]) == null ? void 0 : _g[0])
|
||||
lut.nfmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[22][0].data)][0]);
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
var _R = 0;
|
||||
@ -1043,12 +1088,12 @@ function parse_TST_TableModelArchive(M, root, ws) {
|
||||
});
|
||||
_R += _tile.nrows;
|
||||
});
|
||||
if ((_g = store[13]) == null ? void 0 : _g[0]) {
|
||||
if ((_h = store[13]) == null ? void 0 : _h[0]) {
|
||||
var ref = M[parse_TSP_Reference(store[13][0].data)][0];
|
||||
var mtype = varint_to_i32(ref.meta[1][0].data);
|
||||
if (mtype != 6144)
|
||||
throw new Error("Expected merge type 6144, found ".concat(mtype));
|
||||
ws["!merges"] = (_h = parse_shallow(ref.data)) == null ? void 0 : _h[1].map(function(pi) {
|
||||
ws["!merges"] = (_i = parse_shallow(ref.data)) == null ? void 0 : _i[1].map(function(pi) {
|
||||
var merge = parse_shallow(pi.data);
|
||||
var origin = u8_to_dataview(parse_shallow(merge[1][0].data)[1][0].data), size = u8_to_dataview(parse_shallow(merge[2][0].data)[1][0].data);
|
||||
return {
|
||||
|
@ -13,6 +13,13 @@ function safe_parse_wbrels(wbrels, sheets) {
|
||||
return !wbrels || wbrels.length === 0 ? null : wbrels;
|
||||
}
|
||||
|
||||
function parse_sheet_legacy_drawing(sheet, type, zip, path, idx, opts, wb, comments) {
|
||||
if(!sheet || !sheet['!legdrawel']) return;
|
||||
var dfile = resolve_path(sheet['!legdrawel'].Target, path);
|
||||
var draw = getzipstr(zip, dfile, true);
|
||||
if(draw) parse_vml(utf8read(draw), sheet, comments||[]);
|
||||
}
|
||||
|
||||
function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/*:number*/, sheetRels, sheets, stype/*:string*/, opts, wb, themes, styles) {
|
||||
try {
|
||||
sheetRels[sheet]=parse_rels(getzipstr(zip, relsPath, true), path);
|
||||
@ -51,6 +58,7 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
|
||||
}
|
||||
});
|
||||
if(tcomments && tcomments.length) sheet_insert_comments(_ws, tcomments, true, opts.people || []);
|
||||
parse_sheet_legacy_drawing(_ws, stype, zip, path, idx, opts, wb, comments);
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,9 @@ function write_zip_xlsb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
add_rels(opts.rels, 4, f, RELS.CUST_PROPS);
|
||||
}
|
||||
|
||||
var people = ["SheetJ5"];
|
||||
opts.tcid = 0;
|
||||
|
||||
for(rId=1;rId <= wb.SheetNames.length; ++rId) {
|
||||
var wsrels = {'!id':{}};
|
||||
var ws = wb.Sheets[wb.SheetNames[rId-1]];
|
||||
@ -70,6 +73,17 @@ function write_zip_xlsb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
var need_vml = false;
|
||||
var cf = "";
|
||||
if(comments && comments.length > 0) {
|
||||
var needtc = false;
|
||||
comments.forEach(function(carr) {
|
||||
carr[1].forEach(function(c) { if(c.T == true) needtc = true; });
|
||||
});
|
||||
if(needtc) {
|
||||
cf = "xl/threadedComments/threadedComment" + rId + ".xml";
|
||||
zip_add_file(zip, cf, write_tcmnt_xml(comments, people, opts));
|
||||
ct.threadedcomments.push(cf);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + ".xml", RELS.TCMNT);
|
||||
}
|
||||
|
||||
cf = "xl/comments" + rId + "." + wbext;
|
||||
zip_add_file(zip, cf, write_comments_bin(comments, opts));
|
||||
ct.comments.push(cf);
|
||||
@ -125,6 +139,13 @@ function write_zip_xlsb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
ct.metadata.push(f);
|
||||
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||
|
||||
if(people.length > 1) {
|
||||
f = "xl/persons/person.xml";
|
||||
zip_add_file(zip, f, write_people_xml(people, opts));
|
||||
ct.people.push(f);
|
||||
add_rels(opts.wbrels, -1, "persons/person.xml", RELS.PEOPLE);
|
||||
}
|
||||
|
||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||
|
@ -15,7 +15,7 @@ function make_json_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Ar
|
||||
}
|
||||
if(!dense || sheet["!data"][R]) for (var C = r.s.c; C <= r.e.c; ++C) {
|
||||
var val = dense ? (sheet["!data"][R]||[])[C] : sheet[cols[C] + rr];
|
||||
if(val === undefined || val.t === undefined) {
|
||||
if(val == null || val.t === undefined) {
|
||||
if(defval === undefined) continue;
|
||||
if(hdr[C] != null) { row[hdr[C]] = defval; }
|
||||
continue;
|
||||
|
@ -45,6 +45,26 @@ function Base64_encode_pass(input) {
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function Base64_encode_arr(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
for (var i = 0; i < input.length; ) {
|
||||
c1 = input[i++];
|
||||
e1 = c1 >> 2;
|
||||
c2 = input[i++];
|
||||
e2 = (c1 & 3) << 4 | c2 >> 4;
|
||||
c3 = input[i++];
|
||||
e3 = (c2 & 15) << 2 | c3 >> 6;
|
||||
e4 = c3 & 63;
|
||||
if (isNaN(c2)) {
|
||||
e3 = e4 = 64;
|
||||
} else if (isNaN(c3)) {
|
||||
e4 = 64;
|
||||
}
|
||||
o += Base64_map.charAt(e1) + Base64_map.charAt(e2) + Base64_map.charAt(e3) + Base64_map.charAt(e4);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function Base64_decode(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
|
@ -37,6 +37,25 @@ function Base64_encode_pass(input: string): string {
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function Base64_encode_arr(input: Uint8Array|number[]): string {
|
||||
var o = "";
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
c1 = input[i++];
|
||||
e1 = (c1 >> 2);
|
||||
|
||||
c2 = input[i++];
|
||||
e2 = ((c1 & 3) << 4) | (c2 >> 4);
|
||||
|
||||
c3 = input[i++];
|
||||
e3 = ((c2 & 15) << 2) | (c3 >> 6);
|
||||
e4 = (c3 & 63);
|
||||
if (isNaN(c2)) { e3 = e4 = 64; }
|
||||
else if (isNaN(c3)) { e4 = 64; }
|
||||
o += Base64_map.charAt(e1) + Base64_map.charAt(e2) + Base64_map.charAt(e3) + Base64_map.charAt(e4);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function Base64_decode(input: string): string {
|
||||
var o = "";
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
|
@ -450,7 +450,7 @@ function compress_iwa_file(buf) {
|
||||
return u8concat(out);
|
||||
}
|
||||
var numbers_lut_new = function() {
|
||||
return { sst: [], rsst: [], ofmt: [], nfmt: [], fmla: [], ferr: [] };
|
||||
return { sst: [], rsst: [], ofmt: [], nfmt: [], fmla: [], ferr: [], cmnt: [] };
|
||||
};
|
||||
function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
|
||||
var _a, _b, _c, _d;
|
||||
@ -684,7 +684,8 @@ function parse_new_storage(buf, lut) {
|
||||
var t = buf[1];
|
||||
switch (t) {
|
||||
case 0:
|
||||
return void 0;
|
||||
ret = { t: "z" };
|
||||
break;
|
||||
case 2:
|
||||
ret = { t: "n", v: d128 };
|
||||
break;
|
||||
@ -726,6 +727,12 @@ function parse_new_storage(buf, lut) {
|
||||
zidx = dv.getUint32(doff, true);
|
||||
doff += 4;
|
||||
}
|
||||
if (fields & 524288) {
|
||||
var cmntidx = dv.getUint32(doff, true);
|
||||
doff += 4;
|
||||
if (lut.cmnt[cmntidx])
|
||||
ret.c = iwa_to_s5s_comment(lut.cmnt[cmntidx]);
|
||||
}
|
||||
if (zidx > -1)
|
||||
numbers_format_cell(ret, t | 5 << 8, fields >> 13, lut.ofmt[zidx], lut.nfmt[zidx]);
|
||||
if (t == 7)
|
||||
@ -927,6 +934,12 @@ function parse_TST_TableDataList(M, root) {
|
||||
case 3:
|
||||
data[key] = parse_shallow(le[5][0].data);
|
||||
break;
|
||||
case 10:
|
||||
{
|
||||
var cs = M[parse_TSP_Reference(le[10][0].data)][0];
|
||||
data[key] = parse_TSD_CommentStorageArchive(M, cs.data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw type;
|
||||
}
|
||||
@ -992,8 +1005,38 @@ function parse_TST_Tile(M, root) {
|
||||
}, [])
|
||||
};
|
||||
}
|
||||
function parse_TSD_CommentStorageArchive(M, data) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
||||
var out = { t: "", a: "" };
|
||||
var csp = parse_shallow(data);
|
||||
if ((_b = (_a = csp == null ? void 0 : csp[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.data)
|
||||
out.t = u8str((_d = (_c = csp == null ? void 0 : csp[1]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) || "";
|
||||
if ((_f = (_e = csp == null ? void 0 : csp[3]) == null ? void 0 : _e[0]) == null ? void 0 : _f.data) {
|
||||
var as = M[parse_TSP_Reference((_h = (_g = csp == null ? void 0 : csp[3]) == null ? void 0 : _g[0]) == null ? void 0 : _h.data)][0];
|
||||
var asp = parse_shallow(as.data);
|
||||
if ((_j = (_i = asp[1]) == null ? void 0 : _i[0]) == null ? void 0 : _j.data)
|
||||
out.a = u8str(asp[1][0].data);
|
||||
}
|
||||
if (csp == null ? void 0 : csp[4]) {
|
||||
out.replies = [];
|
||||
csp[4].forEach(function(pi) {
|
||||
var cs = M[parse_TSP_Reference(pi.data)][0];
|
||||
out.replies.push(parse_TSD_CommentStorageArchive(M, cs.data));
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function iwa_to_s5s_comment(iwa) {
|
||||
var out = [];
|
||||
out.push({ t: iwa.t || "", a: iwa.a, T: iwa.replies && iwa.replies.length > 0 });
|
||||
if (iwa.replies)
|
||||
iwa.replies.forEach(function(reply) {
|
||||
out.push({ t: reply.t || "", a: reply.a, T: true });
|
||||
});
|
||||
return out;
|
||||
}
|
||||
function parse_TST_TableModelArchive(M, root, ws) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
||||
var pb = parse_shallow(root.data);
|
||||
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
|
||||
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
|
||||
@ -1016,7 +1059,9 @@ function parse_TST_TableModelArchive(M, root, ws) {
|
||||
lut.ferr = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[12][0].data)][0]);
|
||||
if ((_e = store[17]) == null ? void 0 : _e[0])
|
||||
lut.rsst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]);
|
||||
if ((_f = store[22]) == null ? void 0 : _f[0])
|
||||
if ((_f = store[19]) == null ? void 0 : _f[0])
|
||||
lut.cmnt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[19][0].data)][0]);
|
||||
if ((_g = store[22]) == null ? void 0 : _g[0])
|
||||
lut.nfmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[22][0].data)][0]);
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
var _R = 0;
|
||||
@ -1043,12 +1088,12 @@ function parse_TST_TableModelArchive(M, root, ws) {
|
||||
});
|
||||
_R += _tile.nrows;
|
||||
});
|
||||
if ((_g = store[13]) == null ? void 0 : _g[0]) {
|
||||
if ((_h = store[13]) == null ? void 0 : _h[0]) {
|
||||
var ref = M[parse_TSP_Reference(store[13][0].data)][0];
|
||||
var mtype = varint_to_i32(ref.meta[1][0].data);
|
||||
if (mtype != 6144)
|
||||
throw new Error("Expected merge type 6144, found ".concat(mtype));
|
||||
ws["!merges"] = (_h = parse_shallow(ref.data)) == null ? void 0 : _h[1].map(function(pi) {
|
||||
ws["!merges"] = (_i = parse_shallow(ref.data)) == null ? void 0 : _i[1].map(function(pi) {
|
||||
var merge = parse_shallow(pi.data);
|
||||
var origin = u8_to_dataview(parse_shallow(merge[1][0].data)[1][0].data), size = u8_to_dataview(parse_shallow(merge[2][0].data)[1][0].data);
|
||||
return {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
/* these are type imports and do not show up in the generated JS */
|
||||
import { CFB$Container, CFB$Entry } from 'cfb';
|
||||
import { WorkBook, WorkSheet, Range, CellObject, ParsingOptions, WritingOptions, DenseWorkSheet } from '../';
|
||||
import { WorkBook, WorkSheet, Range, CellObject, ParsingOptions, WritingOptions, DenseWorkSheet, Comments } from '../';
|
||||
import type { utils } from "../";
|
||||
|
||||
declare var encode_col: typeof utils.encode_col;
|
||||
@ -389,6 +389,14 @@ interface RichText {
|
||||
l?: string;
|
||||
}
|
||||
|
||||
/** IWA tree-style comment */
|
||||
interface IWAComment {
|
||||
/** text */
|
||||
t?: string;
|
||||
/** author */
|
||||
a?: string;
|
||||
replies?: IWAComment[];
|
||||
}
|
||||
/** .TST.DataStore */
|
||||
interface DataLUT {
|
||||
/** shared string table */
|
||||
@ -403,8 +411,10 @@ interface DataLUT {
|
||||
fmla: ProtoMessage[];
|
||||
/** formula errors */
|
||||
ferr: ProtoMessage[];
|
||||
/** comment table */
|
||||
cmnt: IWAComment[];
|
||||
}
|
||||
var numbers_lut_new = (): DataLUT => ({ sst: [], rsst: [], ofmt: [], nfmt: [], fmla: [], ferr: [] });
|
||||
var numbers_lut_new = (): DataLUT => ({ sst: [], rsst: [], ofmt: [], nfmt: [], fmla: [], ferr: [], cmnt: [] });
|
||||
|
||||
function numbers_format_cell(cell: CellObject, t: number, flags: number, ofmt: ProtoMessage, nfmt: ProtoMessage): void {
|
||||
var ctype = t & 0xFF, ver = t >> 8;
|
||||
@ -552,7 +562,7 @@ function parse_new_storage(buf: Uint8Array, lut: DataLUT): CellObject | void {
|
||||
var ret: CellObject;
|
||||
var t = buf[1];
|
||||
switch(t) {
|
||||
case 0: return void 0; // return { t: "z" }; // blank?
|
||||
case 0: ret = { t: "z" }; break;
|
||||
case 2: ret = { t: "n", v: d128 }; break; // number
|
||||
case 3: ret = { t: "s", v: lut.sst[sidx] }; break; // string
|
||||
case 5: ret = { t: "d", v: dt }; break; // date-time
|
||||
@ -578,6 +588,10 @@ function parse_new_storage(buf: Uint8Array, lut: DataLUT): CellObject | void {
|
||||
if(fields & 0x07E000) { if(zidx == -1) zidx = dv.getUint32(doff, true); doff += 4; }
|
||||
|
||||
// 0x080000 comment
|
||||
if(fields & 0x080000) {
|
||||
var cmntidx = dv.getUint32(doff, true); doff += 4;
|
||||
if(lut.cmnt[cmntidx]) ret.c = iwa_to_s5s_comment(lut.cmnt[cmntidx]);
|
||||
}
|
||||
// 0x100000 warning
|
||||
|
||||
if(zidx > -1) numbers_format_cell(ret, t | (5<<8), fields >> 13, lut.ofmt[zidx], lut.nfmt[zidx] );
|
||||
@ -736,6 +750,11 @@ function parse_TST_TableDataList(M: MessageSpace, root: IWAMessage): any[] {
|
||||
} break;
|
||||
case 2: data[key] = parse_shallow(le[6][0].data); break;
|
||||
case 3: data[key] = parse_shallow(le[5][0].data); break;
|
||||
case 10: {
|
||||
// .TSD.CommentStorageArchive
|
||||
var cs = M[parse_TSP_Reference(le[10][0].data)][0];
|
||||
data[key] = parse_TSD_CommentStorageArchive(M, cs.data);
|
||||
} break;
|
||||
default: throw type;
|
||||
}
|
||||
});
|
||||
@ -804,6 +823,37 @@ function parse_TST_Tile(M: MessageSpace, root: IWAMessage): TileInfo {
|
||||
};
|
||||
}
|
||||
|
||||
/** Parse .TSD.CommentStorageArchive (3056) */
|
||||
function parse_TSD_CommentStorageArchive(M: MessageSpace, data: Uint8Array): IWAComment {
|
||||
var out: IWAComment = { t: "", a: ""};
|
||||
var csp = parse_shallow(data);
|
||||
if(csp?.[1]?.[0]?.data) out.t = u8str(csp?.[1]?.[0]?.data) || "";
|
||||
if(csp?.[3]?.[0]?.data) {
|
||||
/* .TSK.AnnotationAuthorArchive (212) */
|
||||
var as = M[parse_TSP_Reference(csp?.[3]?.[0]?.data)][0];
|
||||
var asp = parse_shallow(as.data);
|
||||
if(asp[1]?.[0]?.data) out.a = u8str(asp[1][0].data)
|
||||
}
|
||||
if(csp?.[4]) {
|
||||
out.replies = [];
|
||||
csp[4].forEach(pi => {
|
||||
var cs = M[parse_TSP_Reference(pi.data)][0];
|
||||
out.replies!.push(parse_TSD_CommentStorageArchive(M, cs.data));
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
/** Create SheetJS threaded comment structure from IWA comment */
|
||||
function iwa_to_s5s_comment(iwa: IWAComment): Comments {
|
||||
var out: Comments = [];
|
||||
out.push({t: iwa.t||"", a: iwa.a, T: iwa.replies && (iwa.replies.length > 0) });
|
||||
/* TODO: do apps support a tree of replies? */
|
||||
if(iwa.replies) iwa.replies.forEach(reply => {
|
||||
out.push({t: reply.t ||"", a: reply.a, T:true });
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Parse .TST.TableModelArchive (6001) */
|
||||
function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: WorkSheet) {
|
||||
var pb = parse_shallow(root.data);
|
||||
@ -822,6 +872,7 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
|
||||
if(store[11]?.[0]) lut.ofmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[11][0].data)][0]);
|
||||
if(store[12]?.[0]) lut.ferr = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[12][0].data)][0]);
|
||||
if(store[17]?.[0]) lut.rsst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]);
|
||||
if(store[19]?.[0]) lut.cmnt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[19][0].data)][0]);
|
||||
if(store[22]?.[0]) lut.nfmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[22][0].data)][0]);
|
||||
|
||||
// .TST.TileStorage
|
||||
|
Loading…
Reference in New Issue
Block a user