1
forked from sheetjs/sheetjs

updating to 0.11.14

This commit is contained in:
SheetJS 2017-12-14 21:01:07 -05:00
parent 2bfa757670
commit 6e99424766
5 changed files with 266 additions and 111 deletions

@ -129,6 +129,13 @@ var paths = {
hlxlsx: dir + 'hyperlink_stress_test_2011.xlsx', hlxlsx: dir + 'hyperlink_stress_test_2011.xlsx',
hlxlsb: dir + 'hyperlink_stress_test_2011.xlsb', hlxlsb: dir + 'hyperlink_stress_test_2011.xlsb',
ilxls: dir + 'internal_link.xls',
ilxls5: dir + 'internal_link.biff5',
ilxml: dir + 'internal_link.xml',
ilxlsx: dir + 'internal_link.xlsx',
ilxlsb: dir + 'internal_link.xlsb',
ilods: dir + 'internal_link.ods',
lonxls: dir + 'LONumbers.xls', lonxls: dir + 'LONumbers.xls',
lonxlsx: dir + 'LONumbers.xlsx', lonxlsx: dir + 'LONumbers.xlsx',
@ -183,6 +190,7 @@ var NFPaths = pathit("nf", ["xlsx", "xlsb", "xls", "xml"]);
var DTPaths = pathit("dt", ["xlsx", "xlsb", "xls", "xml"]); var DTPaths = pathit("dt", ["xlsx", "xlsb", "xls", "xml"]);
var NFPaths = pathit("nf", ["xlsx", "xlsb", "xls", "xml"]); var NFPaths = pathit("nf", ["xlsx", "xlsb", "xls", "xml"]);
var HLPaths = pathit("hl", ["xlsx", "xlsb", "xls", "xml"]); var HLPaths = pathit("hl", ["xlsx", "xlsb", "xls", "xml"]);
var ILPaths = pathit("il", ["xlsx", "xlsb", "xls", "xml", "ods", "xls5"]);
var OLPaths = pathit("ol", ["xlsx", "xlsb", "xls", "ods", "xls5"]); var OLPaths = pathit("ol", ["xlsx", "xlsb", "xls", "ods", "xls5"]);
var PMPaths = pathit("pm", ["xlsx", "xlsb", "xls", "xml", "xls5"]); var PMPaths = pathit("pm", ["xlsx", "xlsb", "xls", "xml", "xls5"]);
var SVPaths = pathit("sv", ["xlsx", "xlsb", "xls", "xml", "xls5"]); var SVPaths = pathit("sv", ["xlsx", "xlsb", "xls", "xml", "xls5"]);
@ -714,20 +722,28 @@ function diffsty(ws, r1,r2) {
}); });
} }
function hlink(ws) { function hlink1(ws) {[
[ ["A1", "http://www.sheetjs.com"],
["A1", "http://www.sheetjs.com"], ["A2", "http://oss.sheetjs.com"],
["A2", "http://oss.sheetjs.com"], ["A3", "http://oss.sheetjs.com#foo"],
["A3", "http://oss.sheetjs.com#foo"], ["A4", "mailto:dev@sheetjs.com"],
["A4", "mailto:dev@sheetjs.com"], ["A5", "mailto:dev@sheetjs.com?subject=hyperlink"],
["A5", "mailto:dev@sheetjs.com?subject=hyperlink"], ["A6", "../../sheetjs/Documents/Test.xlsx"],
["A6", "../../sheetjs/Documents/Test.xlsx"], ["A7", "http://sheetjs.com", "foo bar baz"]
["A7", "http://sheetjs.com", "foo bar baz"] ].forEach(function(r) {
].forEach(function(r) { assert.equal(get_cell(ws, r[0]).l.Target, r[1]);
assert.equal(get_cell(ws, r[0]).l.Target, r[1]); if(r[2]) assert.equal(get_cell(ws, r[0]).l.Tooltip, r[2]);
assert.equal(get_cell(ws, r[0]).l.Tooltip, r[2]); }); }
});
} function hlink2(ws) { [
["A1", "#Sheet2!A1"],
["A2", "#WBScope"],
["A3", "#Sheet1!WSScope1", "#Sheet1!C7:E8"],
["A5", "#Sheet1!A5"]
].forEach(function(r) {
if(r[2] && get_cell(ws, r[0]).l.Target == r[2]) return;
assert.equal(get_cell(ws, r[0]).l.Target, r[1]);
}); }
function check_margin(margins, exp) { function check_margin(margins, exp) {
["left", "right", "top", "bottom", "header", "footer"].forEach(function(m,i) { ["left", "right", "top", "bottom", "header", "footer"].forEach(function(m,i) {
@ -977,16 +993,20 @@ describe('parse features', function() {
}); });
describe('should find hyperlinks', function() { describe('should find hyperlinks', function() {
var wbs; var wb1, wb2;
var bef = (function() { var bef = (function() {
X = require(modp); X = require(modp);
wbs = HLPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE}); }); wb1 = HLPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE}); });
wb2 = ILPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE}); });
}); });
if(typeof before != 'undefined') before(bef); if(typeof before != 'undefined') before(bef);
else it('before', bef); else it('before', bef);
['XLSX', 'XLSB', 'XLS', 'XML'].forEach(function(x, i) { ['xlsx', 'xlsb', 'xls', 'xml'].forEach(function(x, i) {
it(x, function() { hlink(wbs[i].Sheets.Sheet1); }); it(x + " external", function() { hlink1(wb1[i].Sheets.Sheet1); });
});
['xlsx', 'xlsb', 'xls', 'xml', 'ods'].forEach(function(x, i) {
it(x + " internal", function() { hlink2(wb2[i].Sheets.Sheet1); });
}); });
}); });
@ -1351,13 +1371,19 @@ describe('roundtrip features', function() {
}); }); }); }); }); });
describe('should preserve hyperlink', function() { [ describe('should preserve hyperlink', function() { [
['xlml', paths.hlxml], ['xlml', paths.hlxml, true],
['xlsx', paths.hlxlsx], ['xls', paths.hlxls, true],
['xlsb', paths.hlxlsb] ['xlsx', paths.hlxlsx, true],
].forEach(function(w) { it(w[0], function() { ['xlsb', paths.hlxlsb, true],
var wb = X.read(fs.readFileSync(w[1]), {type:TYPE}); ['xlml', paths.ilxml, false],
hlink(wb.Sheets.Sheet1); ['xls', paths.ilxls, false],
wb = X.read(X.write(wb, {bookType:w[0], type:TYPE}), {type:TYPE}); ['xlsx', paths.ilxlsx, false],
['xlsb', paths.ilxlsb, false],
['ods', paths.ilods, false]
].forEach(function(w) { it(w[0]+" "+(w[2]?"ex":"in")+ "ternal", function() {
var wb = X.read(fs.readFileSync(w[1]), {type:TYPE, WTF:opts.WTF});
var hlink = (w[2] ? hlink1 : hlink2); hlink(wb.Sheets.Sheet1);
wb = X.read(X.write(wb, {bookType:w[0], type:TYPE, WTF:opts.WTF}), {type:TYPE, WTF:opts.WTF});
hlink(wb.Sheets.Sheet1); hlink(wb.Sheets.Sheet1);
}); }); }); }); }); });
@ -1881,6 +1907,20 @@ describe('HTML', function() {
assert.equal(get_cell(ws, "A1").v, "A&B"); assert.equal(get_cell(ws, "A1").v, "A&B");
assert.equal(get_cell(ws, "B1").v, "A·B"); assert.equal(get_cell(ws, "B1").v, "A·B");
}); });
describe('type override', function() {
function chk(ws) {
assert.equal(get_cell(ws, "A1").t, "s");
assert.equal(get_cell(ws, "A1").v, "1234567890");
assert.equal(get_cell(ws, "B1").t, "n");
assert.equal(get_cell(ws, "B1").v, 1234567890);
}
var html = "<table><tr><td t=\"s\">1234567890</td><td>1234567890</td></tr></table>";
it('HTML string', function() {
var ws = X.read(html, {type:'string'}).Sheets.Sheet1; chk(ws);
chk(X.read(X.utils.sheet_to_html(ws), {type:'string'}).Sheets.Sheet1);
});
if(domtest) it('DOM', function() { chk(X.utils.table_to_sheet(get_dom_element(html))); });
});
}); });
describe('js -> file -> js', function() { describe('js -> file -> js', function() {

File diff suppressed because one or more lines are too long

30
xlsx.core.min.js vendored

File diff suppressed because one or more lines are too long

26
xlsx.full.min.js vendored

File diff suppressed because one or more lines are too long

225
xlsx.js

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false */ /*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {}; var XLSX = {};
(function make_xlsx(XLSX){ (function make_xlsx(XLSX){
XLSX.version = '0.11.13'; XLSX.version = '0.11.14';
var current_codepage = 1200; var current_codepage = 1200;
/*global cptable:true */ /*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') { if(typeof module !== "undefined" && typeof require !== 'undefined') {
@ -4428,30 +4428,64 @@ function parse_HyperlinkMoniker(blob, length) {
/* [MS-OSHARED] 2.3.7.9 HyperlinkString */ /* [MS-OSHARED] 2.3.7.9 HyperlinkString */
function parse_HyperlinkString(blob, length) { function parse_HyperlinkString(blob, length) {
var len = blob.read_shift(4); var len = blob.read_shift(4);
var o = blob.read_shift(len, 'utf16le').replace(chr0, ""); var o = len > 0 ? blob.read_shift(len, 'utf16le').replace(chr0, "") : "";
return o; return o;
} }
/* [MS-OSHARED] 2.3.7.1 Hyperlink Object TODO: unify params with XLSX */ /* [MS-OSHARED] 2.3.7.1 Hyperlink Object */
function parse_Hyperlink(blob, length) { function parse_Hyperlink(blob, length) {
var end = blob.l + length; var end = blob.l + length;
var sVer = blob.read_shift(4); var sVer = blob.read_shift(4);
if(sVer !== 2) throw new Error("Unrecognized streamVersion: " + sVer); if(sVer !== 2) throw new Error("Unrecognized streamVersion: " + sVer);
var flags = blob.read_shift(2); var flags = blob.read_shift(2);
blob.l += 2; blob.l += 2;
var displayName, targetFrameName, moniker, oleMoniker, location, guid, fileTime; var displayName, targetFrameName, moniker, oleMoniker, Location="", guid, fileTime;
if(flags & 0x0010) displayName = parse_HyperlinkString(blob, end - blob.l); if(flags & 0x0010) displayName = parse_HyperlinkString(blob, end - blob.l);
if(flags & 0x0080) targetFrameName = parse_HyperlinkString(blob, end - blob.l); if(flags & 0x0080) targetFrameName = parse_HyperlinkString(blob, end - blob.l);
if((flags & 0x0101) === 0x0101) moniker = parse_HyperlinkString(blob, end - blob.l); if((flags & 0x0101) === 0x0101) moniker = parse_HyperlinkString(blob, end - blob.l);
if((flags & 0x0101) === 0x0001) oleMoniker = parse_HyperlinkMoniker(blob, end - blob.l); if((flags & 0x0101) === 0x0001) oleMoniker = parse_HyperlinkMoniker(blob, end - blob.l);
if(flags & 0x0008) location = parse_HyperlinkString(blob, end - blob.l); if(flags & 0x0008) Location = parse_HyperlinkString(blob, end - blob.l);
if(flags & 0x0020) guid = blob.read_shift(16); if(flags & 0x0020) guid = blob.read_shift(16);
if(flags & 0x0040) fileTime = parse_FILETIME(blob/*, 8*/); if(flags & 0x0040) fileTime = parse_FILETIME(blob/*, 8*/);
blob.l = end; blob.l = end;
var target = (targetFrameName||moniker||oleMoniker); var target = targetFrameName||moniker||oleMoniker||"";
if(location) target+="#"+location; if(target && Location) target+="#"+Location;
if(!target) target = "#" + Location;
return {Target: target}; return {Target: target};
} }
function write_Hyperlink(hl) {
var out = new_buf(512), i = 0;
var Target = hl.Target;
var F = Target.indexOf("#") > -1 ? 0x1f : 0x17;
switch(Target.charAt(0)) { case "#": F=0x1c; break; case ".": F&=~2; break; }
out.write_shift(4,2); out.write_shift(4, F);
var data = [8,6815827,6619237,4849780,83]; for(i = 0; i < data.length; ++i) out.write_shift(4, data[i]);
if(F == 0x1C) {
Target = Target.slice(1);
out.write_shift(4, Target.length + 1);
for(i = 0; i < Target.length; ++i) out.write_shift(2, Target.charCodeAt(i));
out.write_shift(2, 0);
} else if(F & 0x02) {
data = "e0 c9 ea 79 f9 ba ce 11 8c 82 00 aa 00 4b a9 0b".split(" ");
for(i = 0; i < data.length; ++i) out.write_shift(1, parseInt(data[i], 16));
out.write_shift(4, 2*(Target.length + 1));
for(i = 0; i < Target.length; ++i) out.write_shift(2, Target.charCodeAt(i));
out.write_shift(2, 0);
} else {
data = "03 03 00 00 00 00 00 00 c0 00 00 00 00 00 00 46".split(" ");
for(i = 0; i < data.length; ++i) out.write_shift(1, parseInt(data[i], 16));
var P = 0;
while(Target.slice(P*3,P*3+3)=="../"||Target.slice(P*3,P*3+3)=="..\\") ++P;
out.write_shift(2, P);
out.write_shift(4, Target.length + 1);
for(i = 0; i < Target.length; ++i) out.write_shift(1, Target.charCodeAt(i) & 0xFF);
out.write_shift(1, 0);
out.write_shift(2, 0xFFFF);
out.write_shift(2, 0xDEAD);
for(i = 0; i < 6; ++i) out.write_shift(4, 0);
}
return out.slice(0, out.l);
}
/* 2.5.178 LongRGBA */ /* 2.5.178 LongRGBA */
function parse_LongRGBA(blob, length) { var r = blob.read_shift(1), g = blob.read_shift(1), b = blob.read_shift(1), a = blob.read_shift(1); return [r,g,b,a]; } function parse_LongRGBA(blob, length) { var r = blob.read_shift(1), g = blob.read_shift(1), b = blob.read_shift(1), a = blob.read_shift(1); return [r,g,b,a]; }
@ -5063,8 +5097,9 @@ function parse_Lbl(blob, length, opts) {
var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2); var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
var itab = 0; var itab = 0;
if(!opts || opts.biff >= 5) { if(!opts || opts.biff >= 5) {
blob.l += 2; if(opts.biff != 5) blob.l += 2;
itab = blob.read_shift(2); itab = blob.read_shift(2);
if(opts.biff == 5) blob.l += 2;
blob.l += 4; blob.l += 4;
} }
var name = parse_XLUnicodeStringNoCch(blob, cch, opts); var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
@ -5249,6 +5284,16 @@ function parse_HLink(blob, length) {
var hlink = parse_Hyperlink(blob, length-24); var hlink = parse_Hyperlink(blob, length-24);
return [ref, hlink]; return [ref, hlink];
} }
function write_HLink(hl) {
var O = new_buf(24);
var ref = decode_cell(hl[0]);
O.write_shift(2, ref.r); O.write_shift(2, ref.r);
O.write_shift(2, ref.c); O.write_shift(2, ref.c);
var clsid = "d0 c9 ea 79 f9 ba ce 11 8c 82 00 aa 00 4b a9 0b".split(" ");
for(var i = 0; i < 16; ++i) O.write_shift(1, parseInt(clsid[i], 16));
return bconcat([O, write_Hyperlink(hl[1])]);
}
/* 2.4.141 */ /* 2.4.141 */
function parse_HLinkTooltip(blob, length) { function parse_HLinkTooltip(blob, length) {
@ -5259,6 +5304,17 @@ function parse_HLinkTooltip(blob, length) {
wzTooltip = wzTooltip.replace(chr0,""); wzTooltip = wzTooltip.replace(chr0,"");
return [ref, wzTooltip]; return [ref, wzTooltip];
} }
function write_HLinkTooltip(hl) {
var TT = hl[1].Tooltip;
var O = new_buf(10 + 2 * (TT.length + 1));
O.write_shift(2, 0x0800);
var ref = decode_cell(hl[0]);
O.write_shift(2, ref.r); O.write_shift(2, ref.r);
O.write_shift(2, ref.c); O.write_shift(2, ref.c);
for(var i = 0; i < TT.length; ++i) O.write_shift(2, TT.charCodeAt(i));
O.write_shift(2, 0);
return O;
}
/* 2.4.63 */ /* 2.4.63 */
function parse_Country(blob, length) { function parse_Country(blob, length) {
@ -7026,19 +7082,19 @@ function parse_EncryptionHeader(blob, length) {
o.KeySize = blob.read_shift(4); o.KeySize = blob.read_shift(4);
o.ProviderType = blob.read_shift(4); o.ProviderType = blob.read_shift(4);
blob.l += 8; blob.l += 8;
o.CSPName = blob.read_shift((tgt-blob.l)>>1, 'utf16le').slice(0,-1); o.CSPName = blob.read_shift((tgt-blob.l)>>1, 'utf16le');
blob.l = tgt; blob.l = tgt;
return o; return o;
} }
/* [MS-OFFCRYPTO] 2.3.3 Encryption Verifier */ /* [MS-OFFCRYPTO] 2.3.3 Encryption Verifier */
function parse_EncryptionVerifier(blob, length) { function parse_EncryptionVerifier(blob, length) {
var o = {}; var o = {}, tgt = blob.l + length;
blob.l += 4; // SaltSize must be 0x10 blob.l += 4; // SaltSize must be 0x10
o.Salt = blob.slice(blob.l, blob.l+16); blob.l += 16; o.Salt = blob.slice(blob.l, blob.l+16); blob.l += 16;
o.Verifier = blob.slice(blob.l, blob.l+16); blob.l += 16; o.Verifier = blob.slice(blob.l, blob.l+16); blob.l += 16;
var sz = blob.read_shift(4); var sz = blob.read_shift(4);
o.VerifierHash = blob.slice(blob.l, blob.l + sz); blob.l += sz; o.VerifierHash = blob.slice(blob.l, tgt); blob.l = tgt;
return o; return o;
} }
@ -11387,11 +11443,16 @@ function csf_to_ods_formula(f) {
return o.replace(/;/g, "|").replace(/,/g,";"); return o.replace(/;/g, "|").replace(/,/g,";");
} }
function ods_to_csf_range_3D(r) { function ods_to_csf_3D(r) {
var a = r.split(":"); var a = r.split(":");
var s = a[0].split(".")[0]; var s = a[0].split(".")[0];
return [s, a[0].split(".")[1] + ":" + a[1].split(".")[1]]; return [s, a[0].split(".")[1] + (a.length > 1 ? (":" + (a[1].split(".")[1] || a[1].split(".")[0])) : "")];
} }
function csf_to_ods_3D(r) {
return r.replace(/\./,"!");
}
var strs = {}; // shared strings var strs = {}; // shared strings
var _ssfopts = {}; // spreadsheet formatting options var _ssfopts = {}; // spreadsheet formatting options
@ -11615,16 +11676,15 @@ function parse_ws_xml_hlinks(s, data, rels) {
for(var i = 0; i != data.length; ++i) { for(var i = 0; i != data.length; ++i) {
var val = parsexmltag(utf8read(data[i]), true); var val = parsexmltag(utf8read(data[i]), true);
if(!val.ref) return; if(!val.ref) return;
var rel = rels ? rels['!id'][val.id] : null; var rel = ((rels || {})['!id']||[])[val.id];
if(rel) { if(rel) {
val.Target = rel.Target; val.Target = rel.Target;
if(val.location) val.Target += "#"+val.location; if(val.location) val.Target += "#"+val.location;
val.Rel = rel;
} else { } else {
val.Target = val.location; val.Target = "#" + val.location;
rel = {Target: val.location, TargetMode: 'Internal'}; rel = {Target: val.Target, TargetMode: 'Internal'};
val.Rel = rel;
} }
val.Rel = rel;
if(val.tooltip) { val.Tooltip = val.tooltip; delete val.tooltip; } if(val.tooltip) { val.Tooltip = val.tooltip; delete val.tooltip; }
var rng = safe_decode_range(val.ref); var rng = safe_decode_range(val.ref);
for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) { for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) {
@ -11998,8 +12058,11 @@ function write_ws_xml(idx, opts, wb, rels) {
o[o.length] = "<hyperlinks>"; o[o.length] = "<hyperlinks>";
ws['!links'].forEach(function(l) { ws['!links'].forEach(function(l) {
if(!l[1].Target) return; if(!l[1].Target) return;
rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#.*$/, ""), RELS.HLINK); rel = ({"ref":l[0]});
rel = ({"ref":l[0], "r:id":"rId"+rId}); if(l[1].Target.charAt(0) != "#") {
rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#.*$/, ""), RELS.HLINK);
rel["r:id"] = "rId"+rId;
}
if((relc = l[1].Target.indexOf("#")) > -1) rel.location = escapexml(l[1].Target.substr(relc+1)); if((relc = l[1].Target.indexOf("#")) > -1) rel.location = escapexml(l[1].Target.substr(relc+1));
if(l[1].Tooltip) rel.tooltip = escapexml(l[1].Tooltip); if(l[1].Tooltip) rel.tooltip = escapexml(l[1].Tooltip);
o[o.length] = writextag("hyperlink",null,rel); o[o.length] = writextag("hyperlink",null,rel);
@ -12312,8 +12375,8 @@ function parse_BrtHLink(data, length, opts) {
if(tooltip) o.Tooltip = tooltip; if(tooltip) o.Tooltip = tooltip;
return o; return o;
} }
function write_BrtHLink(l, rId, o) { function write_BrtHLink(l, rId) {
if(o == null) o = new_buf(50+4*l[1].Target.length); var o = new_buf(50+4*(l[1].Target.length + (l[1].Tooltip || "").length));
write_UncheckedRfX({s:decode_cell(l[0]), e:decode_cell(l[0])}, o); write_UncheckedRfX({s:decode_cell(l[0]), e:decode_cell(l[0])}, o);
write_RelID("rId" + rId, o); write_RelID("rId" + rId, o);
var locidx = l[1].Target.indexOf("#"); var locidx = l[1].Target.indexOf("#");
@ -12539,6 +12602,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
val.Target = rel.Target; val.Target = rel.Target;
if(val.loc) val.Target += "#"+val.loc; if(val.loc) val.Target += "#"+val.loc;
val.Rel = rel; val.Rel = rel;
} else if(val.relId == '') {
val.Target = "#" + val.loc;
} }
for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) { for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) {
if(opts.dense) { if(opts.dense) {
@ -13461,8 +13526,9 @@ function parse_BrtName(data, length, opts) {
// unusedstring2: XLNullableWideString // unusedstring2: XLNullableWideString
//} //}
data.l = end; data.l = end;
var out = ({Name:name, Ptg:formula, Comment:comment}); var out = ({Name:name, Ptg:formula});
if(itab < 0xFFFFFFF) out.Sheet = itab; if(itab < 0xFFFFFFF) out.Sheet = itab;
if(comment) out.Comment = comment;
return out; return out;
} }
@ -13970,7 +14036,8 @@ function parse_xlml_xml(d, _opts) {
} else cursheet[encode_col(c) + encode_row(r)] = cell; } else cursheet[encode_col(c) + encode_row(r)] = cell;
} }
if(cell.HRef) { if(cell.HRef) {
cell.l = {Target:cell.HRef, Tooltip:cell.HRefScreenTip}; cell.l = ({Target:cell.HRef});
if(cell.HRefScreenTip) cell.l.Tooltip = cell.HRefScreenTip;
delete cell.HRef; delete cell.HRefScreenTip; delete cell.HRef; delete cell.HRefScreenTip;
} }
if(cell.MergeAcross || cell.MergeDown) { if(cell.MergeAcross || cell.MergeDown) {
@ -17086,6 +17153,15 @@ function write_biff2_buf(wb, opts) {
return ba.end(); return ba.end();
} }
function write_ws_biff8_hlinks(ba, ws) {
for(var R=0; R<ws['!links'].length; ++R) {
var HL = ws['!links'][R];
write_biff_rec(ba, "HLink", write_HLink(HL));
if(HL[1].Tooltip) write_biff_rec(ba, "HLinkTooltip", write_HLinkTooltip(HL));
}
delete ws['!links'];
}
function write_ws_biff8_cell(ba, cell, R, C, opts) { function write_ws_biff8_cell(ba, cell, R, C, opts) {
if(cell.v != null) switch(cell.t) { if(cell.v != null) switch(cell.t) {
case 'd': case 'n': case 'd': case 'n':
@ -17110,6 +17186,7 @@ function write_ws_biff8(idx, opts, wb) {
var dense = Array.isArray(ws); var dense = Array.isArray(ws);
var ref, rr = "", cols = []; var ref, rr = "", cols = [];
var range = safe_decode_range(ws['!ref'] || "A1"); var range = safe_decode_range(ws['!ref'] || "A1");
var b8 = opts.biff == 8, b5 = opts.biff == 5;
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts)); write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
/* ... */ /* ... */
write_biff_rec(ba, "CalcMode", writeuint16(1)); write_biff_rec(ba, "CalcMode", writeuint16(1));
@ -17129,6 +17206,7 @@ function write_ws_biff8(idx, opts, wb) {
write_biff_rec(ba, "Dimensions", write_Dimensions(range, opts)); write_biff_rec(ba, "Dimensions", write_Dimensions(range, opts));
/* ... */ /* ... */
if(b8) ws['!links'] = [];
for(var R = range.s.r; R <= range.e.r; ++R) { for(var R = range.s.r; R <= range.e.r; ++R) {
rr = encode_row(R); rr = encode_row(R);
for(var C = range.s.c; C <= range.e.c; ++C) { for(var C = range.s.c; C <= range.e.c; ++C) {
@ -17138,9 +17216,13 @@ function write_ws_biff8(idx, opts, wb) {
if(!cell) continue; if(!cell) continue;
/* write cell */ /* write cell */
write_ws_biff8_cell(ba, cell, R, C, opts); write_ws_biff8_cell(ba, cell, R, C, opts);
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
} }
} }
var cname = _sheet.CodeName || _sheet.name || s; var cname = _sheet.CodeName || _sheet.name || s;
/* ... */
if(b8) write_ws_biff8_hlinks(ba, ws);
/* ... */
write_biff_rec(ba, "CodeName", write_XLUnicodeString(cname, opts)); write_biff_rec(ba, "CodeName", write_XLUnicodeString(cname, opts));
/* ... */ /* ... */
write_biff_rec(ba, "EOF"); write_biff_rec(ba, "EOF");
@ -17257,32 +17339,25 @@ var HTML_ = (function() {
var tag = parsexmltag(cell.slice(0, cell.indexOf(">"))); var tag = parsexmltag(cell.slice(0, cell.indexOf(">")));
CS = tag.colspan ? +tag.colspan : 1; CS = tag.colspan ? +tag.colspan : 1;
if((RS = +tag.rowspan)>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}}); if((RS = +tag.rowspan)>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
var _t = tag.t || "";
/* TODO: generate stub cells */ /* TODO: generate stub cells */
if(!m.length) { C += CS; continue; } if(!m.length) { C += CS; continue; }
m = htmldecode(unescapexml(m)); m = htmldecode(unescapexml(m));
if(range.s.r > R) range.s.r = R; if(range.s.r > R) range.s.r = R; if(range.e.r < R) range.e.r = R;
if(range.e.r < R) range.e.r = R; if(range.s.c > C) range.s.c = C; if(range.e.c < C) range.e.c = C;
if(range.s.c > C) range.s.c = C; if(!m.length) continue;
if(range.e.c < C) range.e.c = C; var o = {t:'s', v:m};
if(opts.dense) { if(opts.raw || !m.trim().length || _t == 's'){}
if(!ws[R]) ws[R] = []; else if(m === 'TRUE') o = {t:'b', v:true};
if(!m.length){} else if(m === 'FALSE') o = {t:'b', v:false};
else if(opts.raw || !m.trim().length) ws[R][C] = {t:'s', v:m}; else if(!isNaN(fuzzynum(m))) o = {t:'n', v:fuzzynum(m)};
else if(m === 'TRUE') ws[R][C] = {t:'b', v:true}; else if(!isNaN(fuzzydate(m).getDate())) {
else if(m === 'FALSE') ws[R][C] = {t:'b', v:false}; o = ({t:'d', v:parseDate(m)});
else if(!isNaN(fuzzynum(m))) ws[R][C] = {t:'n', v:fuzzynum(m)}; if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
else ws[R][C] = {t:'s', v:m}; o.z = opts.dateNF || SSF._table[14];
} else {
var coord = encode_cell({r:R, c:C});
/* TODO: value parsing */
if(!m.length){}
else if(opts.raw) ws[coord] = {t:'s', v:m};
else if(opts.raw || !m.trim().length) ws[coord] = {t:'s', v:m};
else if(m === 'TRUE') ws[coord] = {t:'b', v:true};
else if(m === 'FALSE') ws[coord] = {t:'b', v:false};
else if(!isNaN(fuzzynum(m))) ws[coord] = {t:'n', v:fuzzynum(m)};
else ws[coord] = {t:'s', v:m};
} }
if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; }
else ws[encode_cell({r:R, c:C})] = o;
C += CS; C += CS;
} }
} }
@ -17313,6 +17388,7 @@ var HTML_ = (function() {
var sp = {}; var sp = {};
if(RS > 1) sp.rowspan = RS; if(RS > 1) sp.rowspan = RS;
if(CS > 1) sp.colspan = CS; if(CS > 1) sp.colspan = CS;
sp.t = cell.t;
if(o.editable) w = '<span contenteditable="true">' + w + '</span>'; if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
sp.id = "sjs-" + coord; sp.id = "sjs-" + coord;
oo.push(writextag('td', w, sp)); oo.push(writextag('td', w, sp));
@ -17371,10 +17447,10 @@ function parse_dom_table(table, _opts) {
CS = +elt.getAttribute("colspan") || 1; CS = +elt.getAttribute("colspan") || 1;
if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}}); if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
var o = {t:'s', v:v}; var o = {t:'s', v:v};
var _t = elt.getAttribute("t") || "";
if(v != null) { if(v != null) {
if(v.length == 0) o.t = 'z'; if(v.length == 0) o.t = _t || 'z';
else if(opts.raw){} else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(v.trim().length == 0) o.t = 's';
else if(v === 'TRUE') o = {t:'b', v:true}; else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false}; else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)}; else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -17448,9 +17524,12 @@ var parse_content_xml = (function() {
var merges = [], mrange = {}, mR = 0, mC = 0; var merges = [], mrange = {}, mR = 0, mC = 0;
var rowinfo = [], rowpeat = 1, colpeat = 1; var rowinfo = [], rowpeat = 1, colpeat = 1;
var arrayf = []; var arrayf = [];
var WB = {Names:[]};
var atag = ({});
var _Ref = ["", ""];
var comments = [], comment = {}; var comments = [], comment = {};
var creator = "", creatoridx = 0; var creator = "", creatoridx = 0;
var isstub = false; var isstub = false, intable = false;
var i = 0; var i = 0;
xlmlregex.lastIndex = 0; xlmlregex.lastIndex = 0;
str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,""); str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
@ -17464,6 +17543,7 @@ var parse_content_xml = (function() {
sheetag.name = utf8read(sheetag['名称'] || sheetag.name); sheetag.name = utf8read(sheetag['名称'] || sheetag.name);
SheetNames.push(sheetag.name); SheetNames.push(sheetag.name);
Sheets[sheetag.name] = ws; Sheets[sheetag.name] = ws;
intable = false;
} }
else if(Rn[0].charAt(Rn[0].length-2) !== '/') { else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
sheetag = parsexmltag(Rn[0], false); sheetag = parsexmltag(Rn[0], false);
@ -17471,6 +17551,7 @@ var parse_content_xml = (function() {
range.s.r = range.s.c = 10000000; range.e.r = range.e.c = 0; range.s.r = range.s.c = 10000000; range.e.r = range.e.c = 0;
ws = opts.dense ? ([]) : ({}); merges = []; ws = opts.dense ? ([]) : ({}); merges = [];
rowinfo = []; rowinfo = [];
intable = true;
} }
break; break;
@ -17567,6 +17648,7 @@ var parse_content_xml = (function() {
q.v = textp || ''; q.v = textp || '';
isstub = textpidx == 0; isstub = textpidx == 0;
} }
if(atag.Target) q.l = atag;
if(comments.length > 0) { q.c = comments; comments = []; } if(comments.length > 0) { q.c = comments; comments = []; }
if(textp && opts.cellText !== false) q.w = textp; if(textp && opts.cellText !== false) q.w = textp;
if(!isstub || opts.sheetStubs) { if(!isstub || opts.sheetStubs) {
@ -17590,6 +17672,7 @@ var parse_content_xml = (function() {
q = {}; q = {};
textp = ""; textp = "";
} }
atag = ({});
break; // 9.1.4 <table:table-cell> break; // 9.1.4 <table:table-cell>
/* pure state */ /* pure state */
@ -17720,6 +17803,15 @@ var parse_content_xml = (function() {
} }
else pidx = Rn.index + Rn[0].length; else pidx = Rn.index + Rn[0].length;
break; break;
case 'named-range': // 9.4.12 <table:named-range>
tag = parsexmltag(Rn[0], false);
_Ref = ods_to_csf_3D(tag['cell-range-address']);
var nrange = ({Name:tag.name, Ref:_Ref[0] + '!' + _Ref[1]});
if(intable) nrange.Sheet = SheetNames.length;
WB.Names.push(nrange);
break;
case 'text-content': break; // 16.27.27 <number:text-content> case 'text-content': break; // 16.27.27 <number:text-content>
case 'text-properties': break; // 16.27.27 <style:text-properties> case 'text-properties': break; // 16.27.27 <style:text-properties>
case 'embedded-text': break; // 16.27.4 <number:embedded-text> case 'embedded-text': break; // 16.27.4 <number:embedded-text>
@ -17740,7 +17832,6 @@ var parse_content_xml = (function() {
case 'graphic-properties': break; // 17.21 <style:graphic-properties> case 'graphic-properties': break; // 17.21 <style:graphic-properties>
case 'calculation-settings': break; // 9.4.1 <table:calculation-settings> case 'calculation-settings': break; // 9.4.1 <table:calculation-settings>
case 'named-expressions': break; // 9.4.11 <table:named-expressions> case 'named-expressions': break; // 9.4.11 <table:named-expressions>
case 'named-range': break; // 9.4.12 <table:named-range>
case 'label-range': break; // 9.4.9 <table:label-range> case 'label-range': break; // 9.4.9 <table:label-range>
case 'label-ranges': break; // 9.4.10 <table:label-ranges> case 'label-ranges': break; // 9.4.10 <table:label-ranges>
case 'named-expression': break; // 9.4.13 <table:named-expression> case 'named-expression': break; // 9.4.13 <table:named-expression>
@ -17760,8 +17851,8 @@ var parse_content_xml = (function() {
case 'database-range': // 9.4.15 <table:database-range> case 'database-range': // 9.4.15 <table:database-range>
if(Rn[1]==='/') break; if(Rn[1]==='/') break;
try { try {
var AutoFilter = ods_to_csf_range_3D(parsexmltag(Rn[0])['target-range-address']); _Ref = ods_to_csf_3D(parsexmltag(Rn[0])['target-range-address']);
Sheets[AutoFilter[0]]['!autofilter'] = { ref: AutoFilter[1] }; Sheets[_Ref[0]]['!autofilter'] = { ref:_Ref[1] };
} catch(e) {/* empty */} } catch(e) {/* empty */}
break; break;
@ -17876,7 +17967,17 @@ var parse_content_xml = (function() {
case 'properties': break; // 13.7 <form:properties> case 'properties': break; // 13.7 <form:properties>
case 'property': break; // 13.8 <form:property> case 'property': break; // 13.8 <form:property>
case 'a': break; // 6.1.8 hyperlink case 'a': // 6.1.8 hyperlink
if(Rn[1]!== '/') {
atag = parsexmltag(Rn[0], false);
if(!atag.href) break;
atag.Target = atag.href; delete atag.href;
if(atag.Target.charAt(0) == "#" && atag.Target.indexOf(".") > -1) {
_Ref = ods_to_csf_3D(atag.Target.slice(1));
atag.Target = "#" + _Ref[0] + "!" + _Ref[1];
}
}
break;
/* non-standard */ /* non-standard */
case 'table-protection': break; case 'table-protection': break;
@ -17899,10 +18000,11 @@ var parse_content_xml = (function() {
default: if(opts.WTF) throw new Error(Rn); default: if(opts.WTF) throw new Error(Rn);
} }
} }
var out = { var out = ({
Sheets: Sheets, Sheets: Sheets,
SheetNames: SheetNames SheetNames: SheetNames,
}; Workbook: WB
});
if(opts.bookSheets) delete out.Sheets; if(opts.bookSheets) delete out.Sheets;
return out; return out;
}; };
@ -18014,7 +18116,12 @@ var write_content_ods = (function() {
//case 'e': //case 'e':
default: o.push(null_cell_xml); continue; default: o.push(null_cell_xml); continue;
} }
o.push(' ' + writextag('table:table-cell', writextag('text:p', write_text_p(textp), {}), ct) + '\n'); var text_p = write_text_p(textp);
if(cell.l && cell.l.Target) {
var _tgt = cell.l.Target; _tgt = _tgt.charAt(0) == "#" ? "#" + csf_to_ods_3D(_tgt.slice(1)) : _tgt;
text_p = writextag('text:a', text_p, {'xlink:href': _tgt});
}
o.push(' ' + writextag('table:table-cell', writextag('text:p', text_p, {}), ct) + '\n');
} }
o.push(' </table:table-row>\n'); o.push(' </table:table-row>\n');
} }
@ -18421,6 +18528,7 @@ function parse_xlsxcfb(cfb, _opts) {
data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f); data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
if(einfo[0] == 0x04 && typeof decrypt_agile !== 'undefined') return decrypt_agile(einfo[1], data.content, opts.password || "", opts); if(einfo[0] == 0x04 && typeof decrypt_agile !== 'undefined') return decrypt_agile(einfo[1], data.content, opts.password || "", opts);
if(einfo[0] == 0x02 && typeof decrypt_std76 !== 'undefined') return decrypt_std76(einfo[1], data.content, opts.password || "", opts);
throw new Error("File is password-protected"); throw new Error("File is password-protected");
} }
@ -19102,6 +19210,7 @@ utils.cell_set_hyperlink = function(cell, target, tooltip) {
} }
return cell; return cell;
}; };
utils.cell_set_internal_link = function(cell, range, tooltip) { return utils.cell_set_hyperlink(cell, "#" + range, tooltip); };
/* add to cell comments */ /* add to cell comments */
utils.cell_add_comment = function(cell, text, author) { utils.cell_add_comment = function(cell, text, author) {