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