forked from sheetjs/sheetjs
updating to 0.8.2
This commit is contained in:
parent
2625935376
commit
fd679a376a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
test_files/
|
||||
node_modules/
|
||||
|
287
dist/ods.js
vendored
287
dist/ods.js
vendored
@ -21,6 +21,14 @@ function cc2str(arr) {
|
||||
for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
|
||||
return o;
|
||||
}
|
||||
|
||||
function dup(o) {
|
||||
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
|
||||
if(typeof o != 'object' || !o) return o;
|
||||
var out = {};
|
||||
for(var k in o) if(o.hasOwnProperty(k)) out[k] = dup(o[k]);
|
||||
return out;
|
||||
}
|
||||
function getdata(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return data.data;
|
||||
@ -67,7 +75,7 @@ function parsexmltag(tag, skip_root) {
|
||||
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
|
||||
if(!skip_root) z[0] = tag.substr(0, eq);
|
||||
if(eq === tag.length) return z;
|
||||
var m = tag.match(attregexg), j=0, w="", v="", i=0, q="", cc="";
|
||||
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="";
|
||||
if(m) for(i = 0; i != m.length; ++i) {
|
||||
cc = m[i];
|
||||
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
|
||||
@ -108,7 +116,7 @@ function escapexml(text){
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
|
||||
}
|
||||
|
||||
function parsexmlbool(value, tag) {
|
||||
function parsexmlbool(value) {
|
||||
switch(value) {
|
||||
case '1': case 'true': case 'TRUE': return true;
|
||||
/* case '0': case 'false': case 'FALSE':*/
|
||||
@ -147,6 +155,8 @@ function parse_isodur(s) {
|
||||
}
|
||||
return sec;
|
||||
}
|
||||
|
||||
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
|
||||
/* copied from js-xls (C) SheetJS Apache2 license */
|
||||
function xlml_normalize(d) {
|
||||
if(has_buf && Buffer.isBuffer(d)) return d.toString('utf8');
|
||||
@ -157,14 +167,14 @@ function xlml_normalize(d) {
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/mg;
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
var CT_ODS = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
var parse_manifest = function(d, opts) {
|
||||
function parse_manifest(d, opts) {
|
||||
var str = xlml_normalize(d);
|
||||
var Rn;
|
||||
var FEtag;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
case 'manifest': break; // 4.2 <manifest:manifest>
|
||||
case 'file-entry': // 4.3 <manifest:file-entry>
|
||||
FEtag = parsexmltag(Rn[0]);
|
||||
FEtag = parsexmltag(Rn[0], false);
|
||||
if(FEtag.path == '/' && FEtag.type !== CT_ODS) throw new Error("This OpenDocument is not a spreadsheet");
|
||||
break;
|
||||
case 'encryption-data': // 4.4 <manifest:encryption-data>
|
||||
@ -172,11 +182,46 @@ var parse_manifest = function(d, opts) {
|
||||
case 'start-key-generation': // 4.6 <manifest:start-key-generation>
|
||||
case 'key-derivation': // 4.7 <manifest:key-derivation>
|
||||
throw new Error("Unsupported ODS Encryption");
|
||||
default: throw Rn;
|
||||
default: if(opts && opts.WTF) throw Rn;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function write_manifest(manifest, opts) {
|
||||
var o = [XML_HEADER];
|
||||
o.push('<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">\n');
|
||||
o.push(' <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>\n');
|
||||
for(var i = 0; i < manifest.length; ++i) o.push(' <manifest:file-entry manifest:full-path="' + manifest[i][0] + '" manifest:media-type="' + manifest[i][1] + '"/>\n');
|
||||
o.push('</manifest:manifest>');
|
||||
return o.join("");
|
||||
}
|
||||
/* Part 3 Section 6 Metadata Manifest File */
|
||||
function write_rdf_type(file, res, tag) {
|
||||
return [
|
||||
' <rdf:Description rdf:about="' + file + '">\n',
|
||||
' <rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/' + (tag || "odf") + '#' + res + '"/>\n',
|
||||
' </rdf:Description>\n'
|
||||
].join("");
|
||||
}
|
||||
function write_rdf_has(base, file) {
|
||||
return [
|
||||
' <rdf:Description rdf:about="' + base + '">\n',
|
||||
' <ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="' + file + '"/>\n',
|
||||
' </rdf:Description>\n'
|
||||
].join("");
|
||||
}
|
||||
function write_rdf(rdf, opts) {
|
||||
var o = [XML_HEADER];
|
||||
o.push('<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\n');
|
||||
for(var i = 0; i != rdf.length; ++i) {
|
||||
o.push(write_rdf_type(rdf[i][0], rdf[i][1]));
|
||||
o.push(write_rdf_has("",rdf[i][0]));
|
||||
}
|
||||
o.push(write_rdf_type("","Document", "pkg"));
|
||||
o.push('</rdf:RDF>');
|
||||
return o.join("");
|
||||
}
|
||||
var parse_text_p = function(text, tag) {
|
||||
return utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,""));
|
||||
return unescapexml(utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,"")));
|
||||
};
|
||||
|
||||
var utf8read = function utf8reada(orig) {
|
||||
@ -213,27 +258,29 @@ var parse_content_xml = (function() {
|
||||
var str = xlml_normalize(d);
|
||||
var state = [], tmp;
|
||||
var tag;
|
||||
var NFtag, NF, pidx;
|
||||
var NFtag = {name:""}, NF = "", pidx = 0;
|
||||
var sheetag;
|
||||
var Sheets = {}, SheetNames = [], ws = {};
|
||||
var Rn, q;
|
||||
var ctag;
|
||||
var textp, textpidx, textptag;
|
||||
var R, C, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
|
||||
var ctag = {value:""};
|
||||
var textp = "", textpidx = 0, textptag;
|
||||
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
|
||||
var number_format_map = {};
|
||||
var merges = [], mrange = {}, mR = 0, mC = 0;
|
||||
|
||||
var rept = 1;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
|
||||
case 'table': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = get_utils().encode_range(range);
|
||||
if(merges.length) ws['!merges'] = merges;
|
||||
sheetag.name = utf8read(sheetag.name);
|
||||
SheetNames.push(sheetag.name);
|
||||
Sheets[sheetag.name] = ws;
|
||||
}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
|
||||
sheetag = parsexmltag(Rn[0]);
|
||||
sheetag = parsexmltag(Rn[0], false);
|
||||
R = C = -1;
|
||||
range.s.r = range.s.c = 10000000; range.e.r = range.e.c = 0;
|
||||
ws = {}; merges = [];
|
||||
@ -247,17 +294,18 @@ var parse_content_xml = (function() {
|
||||
++C; break; /* stub */
|
||||
case 'table-cell':
|
||||
if(Rn[0].charAt(Rn[0].length-2) === '/') {
|
||||
ctag = parsexmltag(Rn[0]);
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
if(ctag['number-columns-repeated']) C+= parseInt(ctag['number-columns-repeated'], 10);
|
||||
else ++C;
|
||||
}
|
||||
else if(Rn[1]!=='/') {
|
||||
++C;
|
||||
rept = 1;
|
||||
if(C > range.e.c) range.e.c = C;
|
||||
if(R > range.e.r) range.e.r = R;
|
||||
if(C < range.s.c) range.s.c = C;
|
||||
if(R < range.s.r) range.s.r = R;
|
||||
ctag = parsexmltag(Rn[0]);
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
q = {t:ctag['value-type'], v:null};
|
||||
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
|
||||
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
|
||||
@ -265,6 +313,10 @@ var parse_content_xml = (function() {
|
||||
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
|
||||
merges.push(mrange);
|
||||
}
|
||||
|
||||
/* 19.675.2 table:number-columns-repeated */
|
||||
if(ctag['number-columns-repeated']) rept = parseInt(ctag['number-columns-repeated'], 10);
|
||||
|
||||
/* 19.385 office:value-type */
|
||||
switch(q.t) {
|
||||
case 'boolean': q.t = 'b'; q.v = parsexmlbool(ctag['boolean-value']); break;
|
||||
@ -273,14 +325,22 @@ var parse_content_xml = (function() {
|
||||
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||
case 'date': q.t = 'n'; q.v = datenum(ctag['date-value']); q.z = 'm/d/yy'; break;
|
||||
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400; break;
|
||||
case 'string': q.t = 's'; break;
|
||||
default: throw new Error('Unsupported value type ' + q.t);
|
||||
default:
|
||||
if(q.t === 'string' || !q.t) {
|
||||
q.t = 's';
|
||||
if(ctag['string-value'] != null) textp = ctag['string-value'];
|
||||
} else throw new Error('Unsupported value type ' + q.t);
|
||||
}
|
||||
} else {
|
||||
if(q.t === 's') q.v = textp;
|
||||
if(q.t === 's') q.v = textp || '';
|
||||
if(textp) q.w = textp;
|
||||
if(!(opts.sheetRows && opts.sheetRows < R)) ws[get_utils().encode_cell({r:R,c:C})] = q;
|
||||
q = null;
|
||||
if(!(opts.sheetRows && opts.sheetRows < R)) {
|
||||
ws[get_utils().encode_cell({r:R,c:C})] = q;
|
||||
while(--rept > 0) ws[get_utils().encode_cell({r:R,c:++C})] = dup(q);
|
||||
if(range.e.c <= C) range.e.c = C;
|
||||
}
|
||||
q = {};
|
||||
textp = "";
|
||||
}
|
||||
break; // 9.1.4 <table:table-cell>
|
||||
|
||||
@ -296,6 +356,13 @@ var parse_content_xml = (function() {
|
||||
/* ignore state */
|
||||
case 'shapes': // 9.2.8 <table:shapes>
|
||||
case 'frame': // 10.4.2 <draw:frame>
|
||||
case 'text-box': // 10.4.3 <draw:text-box>
|
||||
case 'image': // 10.4.4 <draw:image>
|
||||
case 'data-pilot-tables': // 9.6.2 <table:data-pilot-tables>
|
||||
case 'list-style': // 16.30 <text:list-style>
|
||||
case 'form': // 13.13 <form:form>
|
||||
case 'dde-links': // 9.8 <table:dde-links>
|
||||
case 'annotation': // 14.1 <office:annotation>
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
|
||||
break;
|
||||
@ -309,7 +376,7 @@ var parse_content_xml = (function() {
|
||||
if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;
|
||||
} else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
|
||||
NF = "";
|
||||
NFtag = parsexmltag(Rn[0]);
|
||||
NFtag = parsexmltag(Rn[0], false);
|
||||
state.push([Rn[3], true]);
|
||||
} break;
|
||||
|
||||
@ -317,6 +384,7 @@ var parse_content_xml = (function() {
|
||||
case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
|
||||
|
||||
case 'style': break; // 16.2 <style:style>
|
||||
case 'map': break; // 16.3 <style:map>
|
||||
case 'font-face': break; // 16.21 <style:font-face>
|
||||
|
||||
case 'paragraph-properties': break; // 17.6 <style:paragraph-properties>
|
||||
@ -329,10 +397,12 @@ var parse_content_xml = (function() {
|
||||
switch(state[state.length-1][0]) {
|
||||
case 'time-style':
|
||||
case 'date-style':
|
||||
tag = parsexmltag(Rn[0]);
|
||||
tag = parsexmltag(Rn[0], false);
|
||||
NF += number_formats[Rn[3]][tag.style==='long'?1:0]; break;
|
||||
} break;
|
||||
|
||||
case 'fraction': break; // TODO 16.27.6 <number:fraction>
|
||||
|
||||
case 'day': // 16.27.11 <number:day>
|
||||
case 'month': // 16.27.12 <number:month>
|
||||
case 'year': // 16.27.13 <number:year>
|
||||
@ -347,7 +417,7 @@ var parse_content_xml = (function() {
|
||||
switch(state[state.length-1][0]) {
|
||||
case 'time-style':
|
||||
case 'date-style':
|
||||
tag = parsexmltag(Rn[0]);
|
||||
tag = parsexmltag(Rn[0], false);
|
||||
NF += number_formats[Rn[3]][tag.style==='long'?1:0]; break;
|
||||
} break;
|
||||
|
||||
@ -373,30 +443,114 @@ var parse_content_xml = (function() {
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
|
||||
case 'graphic-properties': break;
|
||||
case 'null-date': break; // 9.4.2 <table:null-date> TODO: date1904
|
||||
|
||||
case 'graphic-properties': break; // 17.21 <style:graphic-properties>
|
||||
case 'calculation-settings': break; // 9.4.1 <table:calculation-settings>
|
||||
case 'named-expressions': break; // 9.4.11 <table:named-expressions>
|
||||
case 'named-range': break; // 9.4.11 <table:named-range>
|
||||
case 'named-range': break; // 9.4.12 <table:named-range>
|
||||
case 'named-expression': break; // 9.4.13 <table:named-expression>
|
||||
case 'sort': break; // 9.4.19 <table:sort>
|
||||
case 'sort-by': break; // 9.4.20 <table:sort-by>
|
||||
case 'sort-groups': break; // 9.4.22 <table:sort-groups>
|
||||
|
||||
case 'span': break; // <text:span>
|
||||
case 'line-break': break; // 6.1.5 <text:line-break>
|
||||
case 'p':
|
||||
if(Rn[1]==='/') textp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
else { textptag = parsexmltag(Rn[0]); textpidx = Rn.index + Rn[0].length; }
|
||||
else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
|
||||
break; // <text:p>
|
||||
case 's': break; // <text:s>
|
||||
case 'date': break; // <*:date>
|
||||
case 'annotation': break;
|
||||
|
||||
case 'object': break; // 10.4.6.2 <draw:object>
|
||||
case 'title': break; // <*:title>
|
||||
case 'desc': break; // <*:desc>
|
||||
|
||||
case 'table-source': break; // 9.2.6
|
||||
|
||||
case 'iteration': break; // 9.4.3 <table:iteration>
|
||||
case 'content-validations': break; // 9.4.4 <table:
|
||||
case 'content-validation': break; // 9.4.5 <table:
|
||||
case 'error-message': break; // 9.4.7 <table:
|
||||
case 'database-ranges': break; // 9.4.14 <table:database-ranges>
|
||||
case 'database-range': break; // 9.4.15 <table:database-range>
|
||||
case 'filter': break; // 9.5.2 <table:filter>
|
||||
case 'filter-and': break; // 9.5.3 <table:filter-and>
|
||||
case 'filter-or': break; // 9.5.4 <table:filter-or>
|
||||
case 'filter-condition': break; // 9.5.5 <table:filter-condition>
|
||||
default: if(opts.WTF) throw Rn;
|
||||
|
||||
case 'list-level-style-bullet': break; // 16.31 <text:
|
||||
case 'list-level-style-number': break; // 16.32 <text:
|
||||
case 'list-level-properties': break; // 17.19 <style:
|
||||
|
||||
/* 7.3 Document Fields */
|
||||
case 'sender-firstname': // 7.3.6.2
|
||||
case 'sender-lastname': // 7.3.6.3
|
||||
case 'sender-initials': // 7.3.6.4
|
||||
case 'sender-title': // 7.3.6.5
|
||||
case 'sender-position': // 7.3.6.6
|
||||
case 'sender-email': // 7.3.6.7
|
||||
case 'sender-phone-private': // 7.3.6.8
|
||||
case 'sender-fax': // 7.3.6.9
|
||||
case 'sender-company': // 7.3.6.10
|
||||
case 'sender-phone-work': // 7.3.6.11
|
||||
case 'sender-street': // 7.3.6.12
|
||||
case 'sender-city': // 7.3.6.13
|
||||
case 'sender-postal-code': // 7.3.6.14
|
||||
case 'sender-country': // 7.3.6.15
|
||||
case 'sender-state-or-province': // 7.3.6.16
|
||||
case 'author-name': // 7.3.7.1
|
||||
case 'author-initials': // 7.3.7.2
|
||||
case 'chapter': // 7.3.8
|
||||
case 'file-name': // 7.3.9
|
||||
case 'template-name': // 7.3.9
|
||||
case 'sheet-name': // 7.3.9
|
||||
break;
|
||||
|
||||
/* 9.6 Data Pilot Tables <table: */
|
||||
case 'data-pilot-table': // 9.6.3
|
||||
case 'source-cell-range': // 9.6.5
|
||||
case 'source-service': // 9.6.6
|
||||
case 'data-pilot-field': // 9.6.7
|
||||
case 'data-pilot-level': // 9.6.8
|
||||
case 'data-pilot-subtotals': // 9.6.9
|
||||
case 'data-pilot-subtotal': // 9.6.10
|
||||
case 'data-pilot-members': // 9.6.11
|
||||
case 'data-pilot-member': // 9.6.12
|
||||
case 'data-pilot-display-info': // 9.6.13
|
||||
case 'data-pilot-sort-info': // 9.6.14
|
||||
case 'data-pilot-layout-info': // 9.6.15
|
||||
case 'data-pilot-field-reference': // 9.6.16
|
||||
case 'data-pilot-groups': // 9.6.17
|
||||
case 'data-pilot-group': // 9.6.18
|
||||
case 'data-pilot-group-member': // 9.6.19
|
||||
break;
|
||||
|
||||
/* 10.3 Drawing Shapes */
|
||||
case 'rect': // 10.3.2
|
||||
break;
|
||||
|
||||
/* 14.6 DDE Connections */
|
||||
case 'dde-connection-decls': // 14.6.2 <text:
|
||||
case 'dde-connection-decl': // 14.6.3 <text:
|
||||
case 'dde-link': // 14.6.4 <table:
|
||||
case 'dde-source': // 14.6.5 <office:
|
||||
break;
|
||||
|
||||
case 'properties': break; // 13.7 <form:properties>
|
||||
case 'property': break; // 13.8 <form:property>
|
||||
|
||||
case 'a': break; // 6.1.8 hyperlink
|
||||
|
||||
/* non-standard */
|
||||
case 'table-protection': break;
|
||||
case 'data-pilot-grand-total': break; // <table:
|
||||
default:
|
||||
if(Rn[2] === 'dc:') break; // TODO: properties
|
||||
if(Rn[2] === 'draw:') break; // TODO: drawing
|
||||
if(Rn[2] === 'calcext:') break; // ignore undocumented extensions
|
||||
if(opts.WTF) throw Rn;
|
||||
}
|
||||
var out = {
|
||||
Sheets: Sheets,
|
||||
@ -405,10 +559,81 @@ var parse_content_xml = (function() {
|
||||
return out;
|
||||
};
|
||||
})();
|
||||
var write_content_xml = (function() {
|
||||
var null_cell_xml = ' <table:table-cell />\n';
|
||||
var write_ws = function(ws, wb, i, opts) {
|
||||
/* Section 9 Tables */
|
||||
var o = [];
|
||||
o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '">\n');
|
||||
var R=0,C=0, range = get_utils().decode_range(ws['!ref']);
|
||||
for(R = 0; R < range.s.r; ++R) o.push(' <table:table-row></table:table-row>\n');
|
||||
for(; R <= range.e.r; ++R) {
|
||||
o.push(' <table:table-row>\n');
|
||||
for(C=0; C < range.s.c; ++C) o.push(null_cell_xml);
|
||||
for(; C <= range.e.c; ++C) {
|
||||
var ref = get_utils().encode_cell({r:R, c:C}), cell = ws[ref];
|
||||
if(cell) switch(cell.t) {
|
||||
case 'b': o.push(' <table:table-cell office:value-type="boolean" office:boolean-value="' + (cell.v ? 'true' : 'false') + '"><text:p>' + (cell.v ? 'TRUE' : 'FALSE') + '</text:p></table:table-cell>\n'); break;
|
||||
case 'n': o.push(' <table:table-cell office:value-type="float" office:value="' + cell.v + '"><text:p>' + (cell.w||cell.v) + '</text:p></table:table-cell>\n'); break;
|
||||
case 's': case 'str': o.push(' <table:table-cell office:value-type="string"><text:p>' + escapexml(cell.v) + '</text:p></table:table-cell>\n'); break;
|
||||
//case 'd': // TODO
|
||||
//case 'e':
|
||||
default: o.push(null_cell_xml);
|
||||
} else o.push(null_cell_xml);
|
||||
}
|
||||
o.push(' </table:table-row>\n');
|
||||
}
|
||||
o.push(' </table:table>\n');
|
||||
return o.join("");
|
||||
};
|
||||
|
||||
return function wcx(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
/* 3.1.3.2 */
|
||||
o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
o.push(' <office:body>\n');
|
||||
o.push(' <office:spreadsheet>\n');
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
|
||||
o.push(' </office:spreadsheet>\n');
|
||||
o.push(' </office:body>\n');
|
||||
o.push('</office:document-content>');
|
||||
return o.join("");
|
||||
};
|
||||
})();
|
||||
/* Part 3: Packages */
|
||||
var parse_ods = function(zip, opts) {
|
||||
//var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'));
|
||||
function parse_ods(zip, opts) {
|
||||
opts = opts || ({});
|
||||
var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
return parse_content_xml(getzipdata(zip, 'content.xml'), opts);
|
||||
};
|
||||
}
|
||||
function write_ods(wb, opts) {
|
||||
var zip = new jszip();
|
||||
var f = "";
|
||||
|
||||
var manifest = [];
|
||||
var rdf = [];
|
||||
|
||||
/* 3:3.3 and 2:2.2.4 */
|
||||
f = "mimetype";
|
||||
zip.file(f, "application/vnd.oasis.opendocument.spreadsheet");
|
||||
|
||||
/* Part 2 Section 2.2 Documents */
|
||||
f = "content.xml";
|
||||
zip.file(f, write_content_xml(wb, opts));
|
||||
manifest.push([f, "text/xml"]);
|
||||
rdf.push([f, "ContentFile"]);
|
||||
|
||||
/* Part 3 Section 6 Metadata Manifest File */
|
||||
f = "manifest.rdf";
|
||||
zip.file(f, write_rdf(rdf, opts));
|
||||
manifest.push([f, "application/rdf+xml"]);
|
||||
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
f = "META-INF/manifest.xml";
|
||||
zip.file(f, write_manifest(manifest, opts));
|
||||
|
||||
return zip;
|
||||
}
|
||||
ODS.parse_ods = parse_ods;
|
||||
ODS.write_ods = write_ods;
|
||||
})(typeof exports !== 'undefined' ? exports : ODS);
|
||||
|
287
ods.js
287
ods.js
@ -21,6 +21,14 @@ function cc2str(arr) {
|
||||
for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
|
||||
return o;
|
||||
}
|
||||
|
||||
function dup(o) {
|
||||
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
|
||||
if(typeof o != 'object' || !o) return o;
|
||||
var out = {};
|
||||
for(var k in o) if(o.hasOwnProperty(k)) out[k] = dup(o[k]);
|
||||
return out;
|
||||
}
|
||||
function getdata(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return data.data;
|
||||
@ -67,7 +75,7 @@ function parsexmltag(tag, skip_root) {
|
||||
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
|
||||
if(!skip_root) z[0] = tag.substr(0, eq);
|
||||
if(eq === tag.length) return z;
|
||||
var m = tag.match(attregexg), j=0, w="", v="", i=0, q="", cc="";
|
||||
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="";
|
||||
if(m) for(i = 0; i != m.length; ++i) {
|
||||
cc = m[i];
|
||||
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
|
||||
@ -108,7 +116,7 @@ function escapexml(text){
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
|
||||
}
|
||||
|
||||
function parsexmlbool(value, tag) {
|
||||
function parsexmlbool(value) {
|
||||
switch(value) {
|
||||
case '1': case 'true': case 'TRUE': return true;
|
||||
/* case '0': case 'false': case 'FALSE':*/
|
||||
@ -147,6 +155,8 @@ function parse_isodur(s) {
|
||||
}
|
||||
return sec;
|
||||
}
|
||||
|
||||
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
|
||||
/* copied from js-xls (C) SheetJS Apache2 license */
|
||||
function xlml_normalize(d) {
|
||||
if(has_buf && Buffer.isBuffer(d)) return d.toString('utf8');
|
||||
@ -157,14 +167,14 @@ function xlml_normalize(d) {
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/mg;
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
var CT_ODS = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
var parse_manifest = function(d, opts) {
|
||||
function parse_manifest(d, opts) {
|
||||
var str = xlml_normalize(d);
|
||||
var Rn;
|
||||
var FEtag;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
case 'manifest': break; // 4.2 <manifest:manifest>
|
||||
case 'file-entry': // 4.3 <manifest:file-entry>
|
||||
FEtag = parsexmltag(Rn[0]);
|
||||
FEtag = parsexmltag(Rn[0], false);
|
||||
if(FEtag.path == '/' && FEtag.type !== CT_ODS) throw new Error("This OpenDocument is not a spreadsheet");
|
||||
break;
|
||||
case 'encryption-data': // 4.4 <manifest:encryption-data>
|
||||
@ -172,11 +182,46 @@ var parse_manifest = function(d, opts) {
|
||||
case 'start-key-generation': // 4.6 <manifest:start-key-generation>
|
||||
case 'key-derivation': // 4.7 <manifest:key-derivation>
|
||||
throw new Error("Unsupported ODS Encryption");
|
||||
default: throw Rn;
|
||||
default: if(opts && opts.WTF) throw Rn;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function write_manifest(manifest, opts) {
|
||||
var o = [XML_HEADER];
|
||||
o.push('<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">\n');
|
||||
o.push(' <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>\n');
|
||||
for(var i = 0; i < manifest.length; ++i) o.push(' <manifest:file-entry manifest:full-path="' + manifest[i][0] + '" manifest:media-type="' + manifest[i][1] + '"/>\n');
|
||||
o.push('</manifest:manifest>');
|
||||
return o.join("");
|
||||
}
|
||||
/* Part 3 Section 6 Metadata Manifest File */
|
||||
function write_rdf_type(file, res, tag) {
|
||||
return [
|
||||
' <rdf:Description rdf:about="' + file + '">\n',
|
||||
' <rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/' + (tag || "odf") + '#' + res + '"/>\n',
|
||||
' </rdf:Description>\n'
|
||||
].join("");
|
||||
}
|
||||
function write_rdf_has(base, file) {
|
||||
return [
|
||||
' <rdf:Description rdf:about="' + base + '">\n',
|
||||
' <ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="' + file + '"/>\n',
|
||||
' </rdf:Description>\n'
|
||||
].join("");
|
||||
}
|
||||
function write_rdf(rdf, opts) {
|
||||
var o = [XML_HEADER];
|
||||
o.push('<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\n');
|
||||
for(var i = 0; i != rdf.length; ++i) {
|
||||
o.push(write_rdf_type(rdf[i][0], rdf[i][1]));
|
||||
o.push(write_rdf_has("",rdf[i][0]));
|
||||
}
|
||||
o.push(write_rdf_type("","Document", "pkg"));
|
||||
o.push('</rdf:RDF>');
|
||||
return o.join("");
|
||||
}
|
||||
var parse_text_p = function(text, tag) {
|
||||
return utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,""));
|
||||
return unescapexml(utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,"")));
|
||||
};
|
||||
|
||||
var utf8read = function utf8reada(orig) {
|
||||
@ -213,27 +258,29 @@ var parse_content_xml = (function() {
|
||||
var str = xlml_normalize(d);
|
||||
var state = [], tmp;
|
||||
var tag;
|
||||
var NFtag, NF, pidx;
|
||||
var NFtag = {name:""}, NF = "", pidx = 0;
|
||||
var sheetag;
|
||||
var Sheets = {}, SheetNames = [], ws = {};
|
||||
var Rn, q;
|
||||
var ctag;
|
||||
var textp, textpidx, textptag;
|
||||
var R, C, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
|
||||
var ctag = {value:""};
|
||||
var textp = "", textpidx = 0, textptag;
|
||||
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
|
||||
var number_format_map = {};
|
||||
var merges = [], mrange = {}, mR = 0, mC = 0;
|
||||
|
||||
var rept = 1;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
|
||||
case 'table': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = get_utils().encode_range(range);
|
||||
if(merges.length) ws['!merges'] = merges;
|
||||
sheetag.name = utf8read(sheetag.name);
|
||||
SheetNames.push(sheetag.name);
|
||||
Sheets[sheetag.name] = ws;
|
||||
}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
|
||||
sheetag = parsexmltag(Rn[0]);
|
||||
sheetag = parsexmltag(Rn[0], false);
|
||||
R = C = -1;
|
||||
range.s.r = range.s.c = 10000000; range.e.r = range.e.c = 0;
|
||||
ws = {}; merges = [];
|
||||
@ -247,17 +294,18 @@ var parse_content_xml = (function() {
|
||||
++C; break; /* stub */
|
||||
case 'table-cell':
|
||||
if(Rn[0].charAt(Rn[0].length-2) === '/') {
|
||||
ctag = parsexmltag(Rn[0]);
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
if(ctag['number-columns-repeated']) C+= parseInt(ctag['number-columns-repeated'], 10);
|
||||
else ++C;
|
||||
}
|
||||
else if(Rn[1]!=='/') {
|
||||
++C;
|
||||
rept = 1;
|
||||
if(C > range.e.c) range.e.c = C;
|
||||
if(R > range.e.r) range.e.r = R;
|
||||
if(C < range.s.c) range.s.c = C;
|
||||
if(R < range.s.r) range.s.r = R;
|
||||
ctag = parsexmltag(Rn[0]);
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
q = {t:ctag['value-type'], v:null};
|
||||
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
|
||||
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
|
||||
@ -265,6 +313,10 @@ var parse_content_xml = (function() {
|
||||
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
|
||||
merges.push(mrange);
|
||||
}
|
||||
|
||||
/* 19.675.2 table:number-columns-repeated */
|
||||
if(ctag['number-columns-repeated']) rept = parseInt(ctag['number-columns-repeated'], 10);
|
||||
|
||||
/* 19.385 office:value-type */
|
||||
switch(q.t) {
|
||||
case 'boolean': q.t = 'b'; q.v = parsexmlbool(ctag['boolean-value']); break;
|
||||
@ -273,14 +325,22 @@ var parse_content_xml = (function() {
|
||||
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||
case 'date': q.t = 'n'; q.v = datenum(ctag['date-value']); q.z = 'm/d/yy'; break;
|
||||
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400; break;
|
||||
case 'string': q.t = 's'; break;
|
||||
default: throw new Error('Unsupported value type ' + q.t);
|
||||
default:
|
||||
if(q.t === 'string' || !q.t) {
|
||||
q.t = 's';
|
||||
if(ctag['string-value'] != null) textp = ctag['string-value'];
|
||||
} else throw new Error('Unsupported value type ' + q.t);
|
||||
}
|
||||
} else {
|
||||
if(q.t === 's') q.v = textp;
|
||||
if(q.t === 's') q.v = textp || '';
|
||||
if(textp) q.w = textp;
|
||||
if(!(opts.sheetRows && opts.sheetRows < R)) ws[get_utils().encode_cell({r:R,c:C})] = q;
|
||||
q = null;
|
||||
if(!(opts.sheetRows && opts.sheetRows < R)) {
|
||||
ws[get_utils().encode_cell({r:R,c:C})] = q;
|
||||
while(--rept > 0) ws[get_utils().encode_cell({r:R,c:++C})] = dup(q);
|
||||
if(range.e.c <= C) range.e.c = C;
|
||||
}
|
||||
q = {};
|
||||
textp = "";
|
||||
}
|
||||
break; // 9.1.4 <table:table-cell>
|
||||
|
||||
@ -296,6 +356,13 @@ var parse_content_xml = (function() {
|
||||
/* ignore state */
|
||||
case 'shapes': // 9.2.8 <table:shapes>
|
||||
case 'frame': // 10.4.2 <draw:frame>
|
||||
case 'text-box': // 10.4.3 <draw:text-box>
|
||||
case 'image': // 10.4.4 <draw:image>
|
||||
case 'data-pilot-tables': // 9.6.2 <table:data-pilot-tables>
|
||||
case 'list-style': // 16.30 <text:list-style>
|
||||
case 'form': // 13.13 <form:form>
|
||||
case 'dde-links': // 9.8 <table:dde-links>
|
||||
case 'annotation': // 14.1 <office:annotation>
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
|
||||
break;
|
||||
@ -309,7 +376,7 @@ var parse_content_xml = (function() {
|
||||
if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;
|
||||
} else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
|
||||
NF = "";
|
||||
NFtag = parsexmltag(Rn[0]);
|
||||
NFtag = parsexmltag(Rn[0], false);
|
||||
state.push([Rn[3], true]);
|
||||
} break;
|
||||
|
||||
@ -317,6 +384,7 @@ var parse_content_xml = (function() {
|
||||
case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
|
||||
|
||||
case 'style': break; // 16.2 <style:style>
|
||||
case 'map': break; // 16.3 <style:map>
|
||||
case 'font-face': break; // 16.21 <style:font-face>
|
||||
|
||||
case 'paragraph-properties': break; // 17.6 <style:paragraph-properties>
|
||||
@ -329,10 +397,12 @@ var parse_content_xml = (function() {
|
||||
switch(state[state.length-1][0]) {
|
||||
case 'time-style':
|
||||
case 'date-style':
|
||||
tag = parsexmltag(Rn[0]);
|
||||
tag = parsexmltag(Rn[0], false);
|
||||
NF += number_formats[Rn[3]][tag.style==='long'?1:0]; break;
|
||||
} break;
|
||||
|
||||
case 'fraction': break; // TODO 16.27.6 <number:fraction>
|
||||
|
||||
case 'day': // 16.27.11 <number:day>
|
||||
case 'month': // 16.27.12 <number:month>
|
||||
case 'year': // 16.27.13 <number:year>
|
||||
@ -347,7 +417,7 @@ var parse_content_xml = (function() {
|
||||
switch(state[state.length-1][0]) {
|
||||
case 'time-style':
|
||||
case 'date-style':
|
||||
tag = parsexmltag(Rn[0]);
|
||||
tag = parsexmltag(Rn[0], false);
|
||||
NF += number_formats[Rn[3]][tag.style==='long'?1:0]; break;
|
||||
} break;
|
||||
|
||||
@ -373,30 +443,114 @@ var parse_content_xml = (function() {
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
|
||||
case 'graphic-properties': break;
|
||||
case 'null-date': break; // 9.4.2 <table:null-date> TODO: date1904
|
||||
|
||||
case 'graphic-properties': break; // 17.21 <style:graphic-properties>
|
||||
case 'calculation-settings': break; // 9.4.1 <table:calculation-settings>
|
||||
case 'named-expressions': break; // 9.4.11 <table:named-expressions>
|
||||
case 'named-range': break; // 9.4.11 <table:named-range>
|
||||
case 'named-range': break; // 9.4.12 <table:named-range>
|
||||
case 'named-expression': break; // 9.4.13 <table:named-expression>
|
||||
case 'sort': break; // 9.4.19 <table:sort>
|
||||
case 'sort-by': break; // 9.4.20 <table:sort-by>
|
||||
case 'sort-groups': break; // 9.4.22 <table:sort-groups>
|
||||
|
||||
case 'span': break; // <text:span>
|
||||
case 'line-break': break; // 6.1.5 <text:line-break>
|
||||
case 'p':
|
||||
if(Rn[1]==='/') textp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
else { textptag = parsexmltag(Rn[0]); textpidx = Rn.index + Rn[0].length; }
|
||||
else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
|
||||
break; // <text:p>
|
||||
case 's': break; // <text:s>
|
||||
case 'date': break; // <*:date>
|
||||
case 'annotation': break;
|
||||
|
||||
case 'object': break; // 10.4.6.2 <draw:object>
|
||||
case 'title': break; // <*:title>
|
||||
case 'desc': break; // <*:desc>
|
||||
|
||||
case 'table-source': break; // 9.2.6
|
||||
|
||||
case 'iteration': break; // 9.4.3 <table:iteration>
|
||||
case 'content-validations': break; // 9.4.4 <table:
|
||||
case 'content-validation': break; // 9.4.5 <table:
|
||||
case 'error-message': break; // 9.4.7 <table:
|
||||
case 'database-ranges': break; // 9.4.14 <table:database-ranges>
|
||||
case 'database-range': break; // 9.4.15 <table:database-range>
|
||||
case 'filter': break; // 9.5.2 <table:filter>
|
||||
case 'filter-and': break; // 9.5.3 <table:filter-and>
|
||||
case 'filter-or': break; // 9.5.4 <table:filter-or>
|
||||
case 'filter-condition': break; // 9.5.5 <table:filter-condition>
|
||||
default: if(opts.WTF) throw Rn;
|
||||
|
||||
case 'list-level-style-bullet': break; // 16.31 <text:
|
||||
case 'list-level-style-number': break; // 16.32 <text:
|
||||
case 'list-level-properties': break; // 17.19 <style:
|
||||
|
||||
/* 7.3 Document Fields */
|
||||
case 'sender-firstname': // 7.3.6.2
|
||||
case 'sender-lastname': // 7.3.6.3
|
||||
case 'sender-initials': // 7.3.6.4
|
||||
case 'sender-title': // 7.3.6.5
|
||||
case 'sender-position': // 7.3.6.6
|
||||
case 'sender-email': // 7.3.6.7
|
||||
case 'sender-phone-private': // 7.3.6.8
|
||||
case 'sender-fax': // 7.3.6.9
|
||||
case 'sender-company': // 7.3.6.10
|
||||
case 'sender-phone-work': // 7.3.6.11
|
||||
case 'sender-street': // 7.3.6.12
|
||||
case 'sender-city': // 7.3.6.13
|
||||
case 'sender-postal-code': // 7.3.6.14
|
||||
case 'sender-country': // 7.3.6.15
|
||||
case 'sender-state-or-province': // 7.3.6.16
|
||||
case 'author-name': // 7.3.7.1
|
||||
case 'author-initials': // 7.3.7.2
|
||||
case 'chapter': // 7.3.8
|
||||
case 'file-name': // 7.3.9
|
||||
case 'template-name': // 7.3.9
|
||||
case 'sheet-name': // 7.3.9
|
||||
break;
|
||||
|
||||
/* 9.6 Data Pilot Tables <table: */
|
||||
case 'data-pilot-table': // 9.6.3
|
||||
case 'source-cell-range': // 9.6.5
|
||||
case 'source-service': // 9.6.6
|
||||
case 'data-pilot-field': // 9.6.7
|
||||
case 'data-pilot-level': // 9.6.8
|
||||
case 'data-pilot-subtotals': // 9.6.9
|
||||
case 'data-pilot-subtotal': // 9.6.10
|
||||
case 'data-pilot-members': // 9.6.11
|
||||
case 'data-pilot-member': // 9.6.12
|
||||
case 'data-pilot-display-info': // 9.6.13
|
||||
case 'data-pilot-sort-info': // 9.6.14
|
||||
case 'data-pilot-layout-info': // 9.6.15
|
||||
case 'data-pilot-field-reference': // 9.6.16
|
||||
case 'data-pilot-groups': // 9.6.17
|
||||
case 'data-pilot-group': // 9.6.18
|
||||
case 'data-pilot-group-member': // 9.6.19
|
||||
break;
|
||||
|
||||
/* 10.3 Drawing Shapes */
|
||||
case 'rect': // 10.3.2
|
||||
break;
|
||||
|
||||
/* 14.6 DDE Connections */
|
||||
case 'dde-connection-decls': // 14.6.2 <text:
|
||||
case 'dde-connection-decl': // 14.6.3 <text:
|
||||
case 'dde-link': // 14.6.4 <table:
|
||||
case 'dde-source': // 14.6.5 <office:
|
||||
break;
|
||||
|
||||
case 'properties': break; // 13.7 <form:properties>
|
||||
case 'property': break; // 13.8 <form:property>
|
||||
|
||||
case 'a': break; // 6.1.8 hyperlink
|
||||
|
||||
/* non-standard */
|
||||
case 'table-protection': break;
|
||||
case 'data-pilot-grand-total': break; // <table:
|
||||
default:
|
||||
if(Rn[2] === 'dc:') break; // TODO: properties
|
||||
if(Rn[2] === 'draw:') break; // TODO: drawing
|
||||
if(Rn[2] === 'calcext:') break; // ignore undocumented extensions
|
||||
if(opts.WTF) throw Rn;
|
||||
}
|
||||
var out = {
|
||||
Sheets: Sheets,
|
||||
@ -405,10 +559,81 @@ var parse_content_xml = (function() {
|
||||
return out;
|
||||
};
|
||||
})();
|
||||
var write_content_xml = (function() {
|
||||
var null_cell_xml = ' <table:table-cell />\n';
|
||||
var write_ws = function(ws, wb, i, opts) {
|
||||
/* Section 9 Tables */
|
||||
var o = [];
|
||||
o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '">\n');
|
||||
var R=0,C=0, range = get_utils().decode_range(ws['!ref']);
|
||||
for(R = 0; R < range.s.r; ++R) o.push(' <table:table-row></table:table-row>\n');
|
||||
for(; R <= range.e.r; ++R) {
|
||||
o.push(' <table:table-row>\n');
|
||||
for(C=0; C < range.s.c; ++C) o.push(null_cell_xml);
|
||||
for(; C <= range.e.c; ++C) {
|
||||
var ref = get_utils().encode_cell({r:R, c:C}), cell = ws[ref];
|
||||
if(cell) switch(cell.t) {
|
||||
case 'b': o.push(' <table:table-cell office:value-type="boolean" office:boolean-value="' + (cell.v ? 'true' : 'false') + '"><text:p>' + (cell.v ? 'TRUE' : 'FALSE') + '</text:p></table:table-cell>\n'); break;
|
||||
case 'n': o.push(' <table:table-cell office:value-type="float" office:value="' + cell.v + '"><text:p>' + (cell.w||cell.v) + '</text:p></table:table-cell>\n'); break;
|
||||
case 's': case 'str': o.push(' <table:table-cell office:value-type="string"><text:p>' + escapexml(cell.v) + '</text:p></table:table-cell>\n'); break;
|
||||
//case 'd': // TODO
|
||||
//case 'e':
|
||||
default: o.push(null_cell_xml);
|
||||
} else o.push(null_cell_xml);
|
||||
}
|
||||
o.push(' </table:table-row>\n');
|
||||
}
|
||||
o.push(' </table:table>\n');
|
||||
return o.join("");
|
||||
};
|
||||
|
||||
return function wcx(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
/* 3.1.3.2 */
|
||||
o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
o.push(' <office:body>\n');
|
||||
o.push(' <office:spreadsheet>\n');
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
|
||||
o.push(' </office:spreadsheet>\n');
|
||||
o.push(' </office:body>\n');
|
||||
o.push('</office:document-content>');
|
||||
return o.join("");
|
||||
};
|
||||
})();
|
||||
/* Part 3: Packages */
|
||||
var parse_ods = function(zip, opts) {
|
||||
//var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'));
|
||||
function parse_ods(zip, opts) {
|
||||
opts = opts || ({});
|
||||
var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
return parse_content_xml(getzipdata(zip, 'content.xml'), opts);
|
||||
};
|
||||
}
|
||||
function write_ods(wb, opts) {
|
||||
var zip = new jszip();
|
||||
var f = "";
|
||||
|
||||
var manifest = [];
|
||||
var rdf = [];
|
||||
|
||||
/* 3:3.3 and 2:2.2.4 */
|
||||
f = "mimetype";
|
||||
zip.file(f, "application/vnd.oasis.opendocument.spreadsheet");
|
||||
|
||||
/* Part 2 Section 2.2 Documents */
|
||||
f = "content.xml";
|
||||
zip.file(f, write_content_xml(wb, opts));
|
||||
manifest.push([f, "text/xml"]);
|
||||
rdf.push([f, "ContentFile"]);
|
||||
|
||||
/* Part 3 Section 6 Metadata Manifest File */
|
||||
f = "manifest.rdf";
|
||||
zip.file(f, write_rdf(rdf, opts));
|
||||
manifest.push([f, "application/rdf+xml"]);
|
||||
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
f = "META-INF/manifest.xml";
|
||||
zip.file(f, write_manifest(manifest, opts));
|
||||
|
||||
return zip;
|
||||
}
|
||||
ODS.parse_ods = parse_ods;
|
||||
ODS.write_ods = write_ods;
|
||||
})(typeof exports !== 'undefined' ? exports : ODS);
|
||||
|
172
xlsx.js
172
xlsx.js
@ -4,7 +4,7 @@
|
||||
/*jshint funcscope:true, eqnull:true */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.8.1';
|
||||
XLSX.version = '0.8.2';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
|
||||
@ -1645,7 +1645,8 @@ function WriteShift(t, val, f) {
|
||||
size = 2 * val.length;
|
||||
} else switch(t) {
|
||||
case 1: size = 1; this[this.l] = val&255; break;
|
||||
case 3: size = 3; this[this.l+2] = val & 255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l] = val&255; break;
|
||||
case 2: size = 2; this[this.l] = val&255; val >>>= 8; this[this.l+1] = val&255; break;
|
||||
case 3: size = 3; this[this.l] = val&255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l+2] = val&255; break;
|
||||
case 4: size = 4; this.writeUInt32LE(val, this.l); break;
|
||||
case 8: size = 8; if(f === 'f') { this.writeDoubleLE(val, this.l); break; }
|
||||
/* falls through */
|
||||
@ -1706,7 +1707,7 @@ function buf_array() {
|
||||
var curbuf = newblk(blksz);
|
||||
|
||||
var endbuf = function ba_endbuf() {
|
||||
curbuf.length = curbuf.l;
|
||||
if(curbuf.length > curbuf.l) curbuf = curbuf.slice(0, curbuf.l);
|
||||
if(curbuf.length > 0) bufs.push(curbuf);
|
||||
curbuf = null;
|
||||
};
|
||||
@ -1893,6 +1894,15 @@ function parse_RkNumber(data) {
|
||||
var RK = fInt === 0 ? __double([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
|
||||
return fX100 ? RK/100 : RK;
|
||||
}
|
||||
function write_RkNumber(data, o) {
|
||||
if(o == null) o = new_buf(4);
|
||||
var fX100 = 0, fInt = 0, d100 = data * 100;
|
||||
if(data == (data | 0) && data >= -(1<<29) && data < (1 << 29)) { fInt = 1; }
|
||||
else if(d100 == (d100 | 0) && d100 >= -(1<<29) && d100 < (1 << 29)) { fInt = 1; fX100 = 1; }
|
||||
if(fInt) o.write_shift(-4, ((fX100 ? d100 : data) << 2) + (fX100 + 2));
|
||||
else throw new Error("unsupported RkNumber " + data); // TODO
|
||||
}
|
||||
|
||||
|
||||
/* [MS-XLSB] 2.5.153 */
|
||||
function parse_UncheckedRfX(data) {
|
||||
@ -1915,8 +1925,9 @@ function write_UncheckedRfX(r, o) {
|
||||
|
||||
/* [MS-XLSB] 2.5.171 */
|
||||
/* [MS-XLS] 2.5.342 */
|
||||
/* TODO: error checking, NaN and Infinity values are not valid Xnum */
|
||||
function parse_Xnum(data, length) { return data.read_shift(8, 'f'); }
|
||||
function write_Xnum(data, o) { return (o || new_buf(8)).write_shift(8, 'f', data); }
|
||||
function write_Xnum(data, o) { return (o || new_buf(8)).write_shift(8, data, 'f'); }
|
||||
|
||||
/* [MS-XLSB] 2.5.198.2 */
|
||||
var BErr = {
|
||||
@ -2730,7 +2741,7 @@ function parse_cust_props(data, opts) {
|
||||
p[name] = unescapexml(text);
|
||||
break;
|
||||
default:
|
||||
if(typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
|
||||
if(opts.WTF && typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
|
||||
}
|
||||
} else if(x.substr(0,2) === "</") {
|
||||
} else if(opts.WTF) throw new Error(x);
|
||||
@ -7286,7 +7297,7 @@ function parse_ws_xml(data, opts, rels) {
|
||||
var mergecells = [];
|
||||
if(data.indexOf("</mergeCells>")!==-1) {
|
||||
var merges = data.match(mergecregex);
|
||||
for(ridx = 0; ridx != merges.length; ++ridx)
|
||||
if(merges) for(ridx = 0; ridx != merges.length; ++ridx)
|
||||
mergecells[ridx] = safe_decode_range(merges[ridx].substr(merges[ridx].indexOf("\"")+1));
|
||||
}
|
||||
|
||||
@ -7298,7 +7309,7 @@ function parse_ws_xml(data, opts, rels) {
|
||||
parse_ws_xml_cols(columns, cols);
|
||||
}
|
||||
|
||||
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
|
||||
|
||||
/* 18.3.1.80 sheetData CT_SheetData ? */
|
||||
var mtch=data.match(sheetdataregex);
|
||||
@ -7573,6 +7584,45 @@ function parse_BrtRowHdr(data, length) {
|
||||
data.l += length-4;
|
||||
return z;
|
||||
}
|
||||
function write_BrtRowHdr(R, range, ws) {
|
||||
var o = new_buf(17+8*16);
|
||||
o.write_shift(4, R);
|
||||
|
||||
/* TODO: flags styles */
|
||||
o.write_shift(4, 0);
|
||||
o.write_shift(2, 0x0140);
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(1, 0);
|
||||
|
||||
/* [MS-XLSB] 2.5.8 BrtColSpan explains the mechanism */
|
||||
var ncolspan = 0, lcs = o.l;
|
||||
o.l += 4;
|
||||
|
||||
var caddr = {r:R, c:0};
|
||||
for(var i = 0; i < 16; ++i) {
|
||||
if(range.s.c > ((i+1) << 10) || range.e.c < (i << 10)) continue;
|
||||
var first = -1, last = -1;
|
||||
for(var j = (i<<10); j < ((i+1)<<10); ++j) {
|
||||
caddr.c = j;
|
||||
if(ws[encode_cell(caddr)]) { if(first < 0) first = j; last = j; }
|
||||
}
|
||||
if(first < 0) continue;
|
||||
++ncolspan;
|
||||
o.write_shift(4, first);
|
||||
o.write_shift(4, last);
|
||||
}
|
||||
|
||||
var l = o.l;
|
||||
o.l = lcs;
|
||||
o.write_shift(4, ncolspan);
|
||||
o.l = l;
|
||||
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
function write_row_header(ba, ws, range, R) {
|
||||
var o = write_BrtRowHdr(R, range, ws);
|
||||
if(o.length > 17) write_record(ba, 'BrtRowHdr', o);
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.812 BrtWsDim */
|
||||
var parse_BrtWsDim = parse_UncheckedRfX;
|
||||
@ -7592,9 +7642,9 @@ function parse_BrtCellBlank(data, length) {
|
||||
var cell = parse_XLSBCell(data);
|
||||
return [cell];
|
||||
}
|
||||
function write_BrtCellBlank(cell, val, o) {
|
||||
function write_BrtCellBlank(cell, ncell, o) {
|
||||
if(o == null) o = new_buf(8);
|
||||
return write_XLSBCell(val, o);
|
||||
return write_XLSBCell(ncell, o);
|
||||
}
|
||||
|
||||
|
||||
@ -7604,12 +7654,18 @@ function parse_BrtCellBool(data, length) {
|
||||
var fBool = data.read_shift(1);
|
||||
return [cell, fBool, 'b'];
|
||||
}
|
||||
function write_BrtCellBool(cell, ncell, o) {
|
||||
if(o == null) o = new_buf(9);
|
||||
write_XLSBCell(ncell, o);
|
||||
o.write_shift(1, cell.v ? 1 : 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.305 BrtCellError */
|
||||
function parse_BrtCellError(data, length) {
|
||||
var cell = parse_XLSBCell(data);
|
||||
var fBool = data.read_shift(1);
|
||||
return [cell, fBool, 'e'];
|
||||
var bError = data.read_shift(1);
|
||||
return [cell, bError, 'e'];
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.308 BrtCellIsst */
|
||||
@ -7618,6 +7674,12 @@ function parse_BrtCellIsst(data, length) {
|
||||
var isst = data.read_shift(4);
|
||||
return [cell, isst, 's'];
|
||||
}
|
||||
function write_BrtCellIsst(cell, ncell, o) {
|
||||
if(o == null) o = new_buf(12);
|
||||
write_XLSBCell(ncell, o);
|
||||
o.write_shift(4, ncell.v);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.310 BrtCellReal */
|
||||
function parse_BrtCellReal(data, length) {
|
||||
@ -7625,6 +7687,12 @@ function parse_BrtCellReal(data, length) {
|
||||
var value = parse_Xnum(data);
|
||||
return [cell, value, 'n'];
|
||||
}
|
||||
function write_BrtCellReal(cell, ncell, o) {
|
||||
if(o == null) o = new_buf(16);
|
||||
write_XLSBCell(ncell, o);
|
||||
write_Xnum(cell.v, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.311 BrtCellRk */
|
||||
function parse_BrtCellRk(data, length) {
|
||||
@ -7632,6 +7700,13 @@ function parse_BrtCellRk(data, length) {
|
||||
var value = parse_RkNumber(data);
|
||||
return [cell, value, 'n'];
|
||||
}
|
||||
function write_BrtCellRk(cell, ncell, o) {
|
||||
if(o == null) o = new_buf(12);
|
||||
write_XLSBCell(ncell, o);
|
||||
write_RkNumber(cell.v, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/* [MS-XLSB] 2.4.314 BrtCellSt */
|
||||
function parse_BrtCellSt(data, length) {
|
||||
@ -7639,6 +7714,12 @@ function parse_BrtCellSt(data, length) {
|
||||
var value = parse_XLWideString(data);
|
||||
return [cell, value, 'str'];
|
||||
}
|
||||
function write_BrtCellSt(cell, ncell, o) {
|
||||
if(o == null) o = new_buf(12 + 4 * cell.v.length);
|
||||
write_XLSBCell(ncell, o);
|
||||
write_XLWideString(cell.v, o);
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.647 BrtFmlaBool */
|
||||
function parse_BrtFmlaBool(data, length, opts) {
|
||||
@ -7714,12 +7795,13 @@ function parse_ws_bin(data, opts, rels) {
|
||||
var s = {};
|
||||
|
||||
var ref;
|
||||
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
|
||||
|
||||
var pass = false, end = false;
|
||||
var row, p, cf, R, C, addr, sstr, rr;
|
||||
var mergecells = [];
|
||||
recordhopper(data, function ws_parse(val, R) {
|
||||
//console.log(R);
|
||||
if(end) return;
|
||||
switch(R.n) {
|
||||
case 'BrtWsDim': ref = val; break;
|
||||
@ -7896,7 +7978,7 @@ function parse_ws_bin(data, opts, rels) {
|
||||
default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n);
|
||||
}
|
||||
}, opts);
|
||||
if(!s["!ref"] && (refguess.s.r < 1000000 || ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0)) s["!ref"] = encode_range(ref);
|
||||
if(!s["!ref"] && (refguess.s.r < 2000000 || ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0)) s["!ref"] = encode_range(ref);
|
||||
if(opts.sheetRows && s["!ref"]) {
|
||||
var tmpref = safe_decode_range(s["!ref"]);
|
||||
if(opts.sheetRows < +tmpref.e.r) {
|
||||
@ -7929,12 +8011,23 @@ function write_ws_bin_cell(ba, cell, R, C, opts) {
|
||||
case 's': case 'str':
|
||||
if(opts.bookSST) {
|
||||
vv = get_sst_id(opts.Strings, cell.v);
|
||||
o.t = "s"; break;
|
||||
o.t = "s"; o.v = vv;
|
||||
write_record(ba, "BrtCellIsst", write_BrtCellIsst(cell, o));
|
||||
} else {
|
||||
o.t = "str";
|
||||
write_record(ba, "BrtCellSt", write_BrtCellSt(cell, o));
|
||||
}
|
||||
o.t = "str"; break;
|
||||
case 'n': break;
|
||||
case 'b': o.t = "b"; break;
|
||||
case 'e': o.t = "e"; break;
|
||||
return;
|
||||
case 'n':
|
||||
/* TODO: determine threshold for Real vs RK */
|
||||
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) write_record(ba, "BrtCellRk", write_BrtCellRk(cell, o));
|
||||
else write_record(ba, "BrtCellReal", write_BrtCellReal(cell, o));
|
||||
return;
|
||||
case 'b':
|
||||
o.t = "b";
|
||||
write_record(ba, "BrtCellBool", write_BrtCellBool(cell, o));
|
||||
return;
|
||||
case 'e': /* TODO: error */ o.t = "e"; break;
|
||||
}
|
||||
write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o));
|
||||
}
|
||||
@ -7946,6 +8039,7 @@ function write_CELLTABLE(ba, ws, idx, opts, wb) {
|
||||
rr = encode_row(R);
|
||||
/* [ACCELLTABLE] */
|
||||
/* BrtRowHdr */
|
||||
write_row_header(ba, ws, range, R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
/* *16384CELL */
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
@ -8258,7 +8352,7 @@ function write_BrtBundleSh(data, o) {
|
||||
o.write_shift(4, data.iTabID);
|
||||
write_RelID(data.strRelID, o);
|
||||
write_XLWideString(data.name.substr(0,31), o);
|
||||
return o;
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.807 BrtWbProp */
|
||||
@ -8366,7 +8460,7 @@ function write_BrtFileVersion(data, o) {
|
||||
write_XLWideString(XLSX.version, o);
|
||||
write_XLWideString("7262", o);
|
||||
o.length = o.l;
|
||||
return o;
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.60 Workbook */
|
||||
@ -8389,6 +8483,7 @@ function write_BrtCalcProp(data, o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.640 BrtFileRecover */
|
||||
function write_BrtFileRecover(data, o) {
|
||||
if(!o) o = new_buf(1);
|
||||
o.write_shift(1,0);
|
||||
@ -8401,22 +8496,22 @@ function write_wb_bin(wb, opts) {
|
||||
write_record(ba, "BrtBeginBook");
|
||||
write_record(ba, "BrtFileVersion", write_BrtFileVersion());
|
||||
/* [[BrtFileSharingIso] BrtFileSharing] */
|
||||
write_record(ba, "BrtWbProp", write_BrtWbProp());
|
||||
if(0) write_record(ba, "BrtWbProp", write_BrtWbProp());
|
||||
/* [ACABSPATH] */
|
||||
/* [[BrtBookProtectionIso] BrtBookProtection] */
|
||||
write_BOOKVIEWS(ba, wb, opts);
|
||||
if(0) write_BOOKVIEWS(ba, wb, opts);
|
||||
write_BUNDLESHS(ba, wb, opts);
|
||||
/* [FNGROUP] */
|
||||
/* [EXTERNALS] */
|
||||
/* *BrtName */
|
||||
write_record(ba, "BrtCalcProp", write_BrtCalcProp());
|
||||
if(0) write_record(ba, "BrtCalcProp", write_BrtCalcProp());
|
||||
/* [BrtOleSize] */
|
||||
/* *(BrtUserBookView *FRT) */
|
||||
/* [PIVOTCACHEIDS] */
|
||||
/* [BrtWbFactoid] */
|
||||
/* [SMARTTAGTYPES] */
|
||||
/* [BrtWebOpt] */
|
||||
write_record(ba, "BrtFileRecover", write_BrtFileRecover());
|
||||
if(0) write_record(ba, "BrtFileRecover", write_BrtFileRecover());
|
||||
/* [WEBPUBITEMS] */
|
||||
/* [CRERRS] */
|
||||
/* FRTWORKBOOK */
|
||||
@ -8625,7 +8720,7 @@ function parse_xlml_xml(d, opts) {
|
||||
var sheets = {}, sheetnames = [], cursheet = {}, sheetname = "";
|
||||
var table = {}, cell = {}, row = {}, dtag, didx;
|
||||
var c = 0, r = 0;
|
||||
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
|
||||
var styles = {}, stag = {};
|
||||
var ss = "", fidx = 0;
|
||||
var mergecells = [];
|
||||
@ -8685,7 +8780,7 @@ function parse_xlml_xml(d, opts) {
|
||||
if(mergecells.length) cursheet["!merges"] = mergecells;
|
||||
sheets[sheetname] = cursheet;
|
||||
} else {
|
||||
refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||
refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
|
||||
r = c = 0;
|
||||
state.push([Rn[3], false]);
|
||||
tmp = xlml_parsexmltag(Rn[0]);
|
||||
@ -11080,12 +11175,17 @@ var XLSRecordEnum = {
|
||||
};
|
||||
|
||||
|
||||
/* Helper function to call out to ODS parser */
|
||||
/* Helper functions to call out to ODS */
|
||||
function parse_ods(zip, opts) {
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined' && typeof ODS === 'undefined') ODS = require('./od' + 's');
|
||||
if(typeof ODS === 'undefined' || !ODS.parse_ods) throw new Error("Unsupported ODS");
|
||||
return ODS.parse_ods(zip, opts);
|
||||
}
|
||||
function write_ods(wb, opts) {
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined' && typeof ODS === 'undefined') ODS = require('./od' + 's');
|
||||
if(typeof ODS === 'undefined' || !ODS.write_ods) throw new Error("Unsupported ODS");
|
||||
return ODS.write_ods(wb, opts);
|
||||
}
|
||||
function fix_opts_func(defaults) {
|
||||
return function fix_opts(opts) {
|
||||
for(var i = 0; i != defaults.length; ++i) {
|
||||
@ -11124,6 +11224,8 @@ var fix_write_opts = fix_opts_func([
|
||||
|
||||
['bookType', 'xlsx'], /* Type of workbook (xlsx/m/b) */
|
||||
|
||||
['compression', false], /* Use file compression */
|
||||
|
||||
['WTF', false] /* WTF mode (throws errors) */
|
||||
]);
|
||||
function safe_parse_wbrels(wbrels, sheets) {
|
||||
@ -11278,6 +11380,7 @@ function add_rels(rels, rId, f, type, relobj) {
|
||||
}
|
||||
|
||||
function write_zip(wb, opts) {
|
||||
if(opts.bookType == "ods") return write_ods(wb, opts);
|
||||
if(wb && !wb.SSF) {
|
||||
wb.SSF = SSF.get_table();
|
||||
}
|
||||
@ -11405,13 +11508,17 @@ function readFileSync(data, opts) {
|
||||
function write_zip_type(wb, opts) {
|
||||
var o = opts||{};
|
||||
var z = write_zip(wb, o);
|
||||
var oopts = {};
|
||||
if(opts.compression) oopts.compression = 'DEFLATE';
|
||||
switch(o.type) {
|
||||
case "base64": return z.generate({type:"base64"});
|
||||
case "binary": return z.generate({type:"string"});
|
||||
case "buffer": return z.generate({type:"nodebuffer"});
|
||||
case "file": return _fs.writeFileSync(o.file, z.generate({type:"nodebuffer"}));
|
||||
case "base64": oopts.type = "base64"; break;
|
||||
case "binary": oopts.type = "string"; break;
|
||||
case "buffer":
|
||||
case "file": oopts.type = "nodebuffer"; break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
if(o.type === "file") return _fs.writeFileSync(o.file, z.generate(oopts));
|
||||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
function writeSync(wb, opts) {
|
||||
@ -11425,13 +11532,14 @@ function writeSync(wb, opts) {
|
||||
function writeFileSync(wb, filename, opts) {
|
||||
var o = opts||{}; o.type = 'file';
|
||||
o.file = filename;
|
||||
switch(o.file.substr(-5).toLowerCase()) {
|
||||
if(!o.bookType) switch(o.file.substr(-5).toLowerCase()) {
|
||||
case '.xlsx': o.bookType = 'xlsx'; break;
|
||||
case '.xlsm': o.bookType = 'xlsm'; break;
|
||||
case '.xlsb': o.bookType = 'xlsb'; break;
|
||||
default: switch(o.file.substr(-4).toLowerCase()) {
|
||||
case '.xls': o.bookType = 'xls'; break;
|
||||
case '.xml': o.bookType = 'xml'; break;
|
||||
case '.ods': o.bookType = 'ods'; break;
|
||||
}}
|
||||
return writeSync(wb, o);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user