forked from sheetjs/sheetjs
		
	works minutiae
This commit is contained in:
		
							parent
							
								
									b3bc49afe8
								
							
						
					
					
						commit
						d6161103b1
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -15,7 +15,7 @@ tmp
 | 
			
		||||
*.[pP][dD][fF]
 | 
			
		||||
*.[sS][lL][kK]
 | 
			
		||||
*.socialcalc
 | 
			
		||||
*.[xX][lL][sSwWcCaAtTmM]
 | 
			
		||||
*.[xX][lL][sSwWcCaAtTmMrR]
 | 
			
		||||
*.[xX][lL][sSaAtT][xXmMbB]
 | 
			
		||||
*.[oO][dD][sS]
 | 
			
		||||
*.[fF][oO][dD][sS]
 | 
			
		||||
@ -23,6 +23,7 @@ tmp
 | 
			
		||||
*.[uU][oO][sS]
 | 
			
		||||
*.[wW][kKqQbB][S1234567890]
 | 
			
		||||
*.[qQ][pP][wW]
 | 
			
		||||
*.[fF][mM][3tT]
 | 
			
		||||
*.[bB][iI][fF][fF][23458]
 | 
			
		||||
*.[rR][tT][fF]
 | 
			
		||||
*.[eE][tT][hH]
 | 
			
		||||
 | 
			
		||||
@ -59,6 +59,15 @@ webpack
 | 
			
		||||
weex
 | 
			
		||||
 | 
			
		||||
# Other terms
 | 
			
		||||
1.x
 | 
			
		||||
2.x
 | 
			
		||||
3.x
 | 
			
		||||
4.x
 | 
			
		||||
5.x
 | 
			
		||||
6.x
 | 
			
		||||
7.x
 | 
			
		||||
8.x
 | 
			
		||||
9.x
 | 
			
		||||
ActiveX
 | 
			
		||||
APIs
 | 
			
		||||
ArrayBuffer
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										49
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										49
									
								
								Makefile
									
									
									
									
									
								
							@ -25,7 +25,7 @@ FLOWAUX=$(patsubst %.js,%.flow.js,$(AUXTARGETS))
 | 
			
		||||
AUXSCPTS=xlsxworker.js
 | 
			
		||||
FLOWTGTS=$(TARGET) $(AUXTARGETS) $(AUXSCPTS) $(MINITGT)
 | 
			
		||||
UGLIFYOPTS=--support-ie8 -m
 | 
			
		||||
# CLOSURE=/usr/local/lib/node_modules/google-closure-compiler/compiler.jar
 | 
			
		||||
CLOSURE=/usr/local/lib/node_modules/google-closure-compiler/compiler.jar
 | 
			
		||||
 | 
			
		||||
## Main Targets
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ DISTHDR=misc/suppress_export.js
 | 
			
		||||
.PHONY: dist
 | 
			
		||||
dist: dist-deps $(TARGET) bower.json ## Prepare JS files for distribution
 | 
			
		||||
	mkdir -p dist
 | 
			
		||||
	<$(TARGET) sed "s/require('stream')/{}/g;s/require('....*')/undefined/g" > dist/$(TARGET)
 | 
			
		||||
	<$(TARGET) sed "s/require('....*')/undefined/g" > dist/$(TARGET)
 | 
			
		||||
	cp LICENSE dist/
 | 
			
		||||
	uglifyjs shim.js $(UGLIFYOPTS) -o dist/shim.min.js --preamble "$$(head -n 1 bits/00_header.js)"
 | 
			
		||||
	uglifyjs $(DISTHDR) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)"
 | 
			
		||||
@ -148,47 +148,6 @@ ctest: ## Build browser test fixtures
 | 
			
		||||
ctestserv: ## Start a test server on port 8000
 | 
			
		||||
	@cd tests && python -mSimpleHTTPServer
 | 
			
		||||
 | 
			
		||||
## Demos
 | 
			
		||||
 | 
			
		||||
DEMOS=angular angular-new browserify requirejs rollup systemjs webpack
 | 
			
		||||
DEMOTGTS=$(patsubst %,demo-%,$(DEMOS))
 | 
			
		||||
.PHONY: demos
 | 
			
		||||
demos: $(DEMOTGTS)
 | 
			
		||||
 | 
			
		||||
.PHONY: demo-angular
 | 
			
		||||
demo-angular: ## Run angular demo build
 | 
			
		||||
	#make -C demos/angular
 | 
			
		||||
	@echo "start a local server and go to demos/angular/angular.html"
 | 
			
		||||
 | 
			
		||||
.PHONY: demo-angular-new
 | 
			
		||||
demo-angular-new: ## Run angular 2 demo build
 | 
			
		||||
	make -C demos/angular2
 | 
			
		||||
	@echo "go to demos/angular/angular.html and run 'ng serve'"
 | 
			
		||||
 | 
			
		||||
.PHONY: demo-browserify
 | 
			
		||||
demo-browserify: ## Run browserify demo build
 | 
			
		||||
	make -C demos/browserify
 | 
			
		||||
	@echo "start a local server and go to demos/browserify/browserify.html"
 | 
			
		||||
 | 
			
		||||
.PHONY: demo-webpack
 | 
			
		||||
demo-webpack: ## Run webpack demo build
 | 
			
		||||
	make -C demos/webpack
 | 
			
		||||
	@echo "start a local server and go to demos/webpack/webpack.html"
 | 
			
		||||
 | 
			
		||||
.PHONY: demo-requirejs
 | 
			
		||||
demo-requirejs: ## Run requirejs demo build
 | 
			
		||||
	make -C demos/requirejs
 | 
			
		||||
	@echo "start a local server and go to demos/requirejs/requirejs.html"
 | 
			
		||||
 | 
			
		||||
.PHONY: demo-rollup
 | 
			
		||||
demo-rollup: ## Run rollup demo build
 | 
			
		||||
	make -C demos/rollup
 | 
			
		||||
	@echo "start a local server and go to demos/rollup/rollup.html"
 | 
			
		||||
 | 
			
		||||
.PHONY: demo-systemjs
 | 
			
		||||
demo-systemjs: ## Run systemjs demo build
 | 
			
		||||
	make -C demos/systemjs
 | 
			
		||||
 | 
			
		||||
## Code Checking
 | 
			
		||||
 | 
			
		||||
.PHONY: fullint
 | 
			
		||||
@ -197,7 +156,7 @@ fullint: lint mdlint ## Run all checks (removed: old-lint, tslint, flow)
 | 
			
		||||
.PHONY: lint
 | 
			
		||||
lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks
 | 
			
		||||
	@./node_modules/.bin/eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json
 | 
			
		||||
	if [ -n "$(CLOSURE-)" ] && [ -e "${CLOSURE}" ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
 | 
			
		||||
	@if [ -x "$(CLOSURE)" ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
 | 
			
		||||
 | 
			
		||||
.PHONY: old-lint
 | 
			
		||||
old-lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
 | 
			
		||||
@ -206,7 +165,7 @@ old-lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
 | 
			
		||||
	@./node_modules/.bin/jshint --show-non-errors package.json bower.json test.js
 | 
			
		||||
	@./node_modules/.bin/jshint --show-non-errors --extract=always $(HTMLLINT)
 | 
			
		||||
	@./node_modules/.bin/jscs $(TARGET) $(AUXTARGETS) test.js
 | 
			
		||||
	if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
 | 
			
		||||
	@if [ -x "$(CLOSURE)" ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
 | 
			
		||||
 | 
			
		||||
.PHONY: tslint
 | 
			
		||||
tslint: $(TARGET) ## Run typescript checks
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
var n = "xlsx";
 | 
			
		||||
var X = require('../');
 | 
			
		||||
try { X = require('../xlsx.flow'); } catch(e) {}
 | 
			
		||||
require('exit-on-epipe');
 | 
			
		||||
try { require('exit-on-epipe'); } catch(e) {}
 | 
			
		||||
var fs = require('fs'), program;
 | 
			
		||||
try { program = require('commander'); } catch(e) {
 | 
			
		||||
	[
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ function parse_rels(data/*:?string*/, currentFilePath/*:string*/) {
 | 
			
		||||
		var y = parsexmltag(x);
 | 
			
		||||
		/* 9.3.2.2 OPC_Relationships */
 | 
			
		||||
		if (y[0] === '<Relationship') {
 | 
			
		||||
			var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
 | 
			
		||||
			var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; if(y.TargetMode) rel.TargetMode = y.TargetMode;
 | 
			
		||||
			var canonictarget = y.TargetMode === 'External' ? y.Target : resolve_path(y.Target, currentFilePath);
 | 
			
		||||
			rels[canonictarget] = rel;
 | 
			
		||||
			hash[y.Id] = rel;
 | 
			
		||||
 | 
			
		||||
@ -701,7 +701,9 @@ function parse_Lbl(blob, length, opts) {
 | 
			
		||||
	var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
 | 
			
		||||
	if(flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
 | 
			
		||||
	var npflen = target - blob.l; if(opts && opts.biff == 2) --npflen;
 | 
			
		||||
	/*jshint -W018 */
 | 
			
		||||
	var rgce = (target == blob.l || cce === 0 || !(npflen > 0)) ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
 | 
			
		||||
	/*jshint +W018 */
 | 
			
		||||
	return {
 | 
			
		||||
		chKey: chKey,
 | 
			
		||||
		Name: name,
 | 
			
		||||
 | 
			
		||||
@ -28,12 +28,18 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
		if(!d) return d;
 | 
			
		||||
		var o = opts || {};
 | 
			
		||||
		if(DENSE != null && o.dense == null) o.dense = DENSE;
 | 
			
		||||
		var s/*:Worksheet*/ = ((o.dense ? [] : {})/*:any*/), n = "Sheet1", sidx = 0;
 | 
			
		||||
		var sheets = {}, snames = [n], realnames = [];
 | 
			
		||||
		var s/*:Worksheet*/ = ((o.dense ? [] : {})/*:any*/), n = "Sheet1", next_n = "", sidx = 0;
 | 
			
		||||
		var sheets = {}, snames = [], realnames = [];
 | 
			
		||||
 | 
			
		||||
		var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
 | 
			
		||||
		var sheetRows = o.sheetRows || 0;
 | 
			
		||||
 | 
			
		||||
		if(d[2] == 0x00) {
 | 
			
		||||
			if(d[3] == 0x08 || d[3] == 0x09) {
 | 
			
		||||
				if(d.length >= 16 && d[14] == 0x05 && d[15] === 0x6c) throw new Error("Unsupported Works 3 for Mac file");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(d[2] == 0x02) {
 | 
			
		||||
			o.Enum = WK1Enum;
 | 
			
		||||
			lotushopper(d, function(val, R, RT) { switch(RT) {
 | 
			
		||||
@ -42,6 +48,8 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
					if(val >= 0x1000) o.qpro = true;
 | 
			
		||||
					break;
 | 
			
		||||
				case 0x06: refguess = val; break; /* RANGE */
 | 
			
		||||
				case 0xCC: if(val) next_n = val; break; /* SHEETNAMECS */
 | 
			
		||||
				case 0xDE: next_n = val; break; /* SHEETNAMELP */
 | 
			
		||||
				case 0x0F: /* LABEL */
 | 
			
		||||
				case 0x33: /* STRING */
 | 
			
		||||
					if(!o.qpro) val[1].v = val[1].v.slice(1);
 | 
			
		||||
@ -54,6 +62,18 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
						val[1].z = o.dateNF || SSF._table[14];
 | 
			
		||||
						if(o.cellDates) { val[1].t = 'd'; val[1].v = numdate(val[1].v); }
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if(o.qpro) {
 | 
			
		||||
						if(val[3] > sidx) {
 | 
			
		||||
							s["!ref"] = encode_range(refguess);
 | 
			
		||||
							sheets[n] = s;
 | 
			
		||||
							snames.push(n);
 | 
			
		||||
							s = (o.dense ? [] : {});
 | 
			
		||||
							refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
 | 
			
		||||
							sidx = val[3]; n = next_n || "Sheet" + (sidx + 1); next_n = "";
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					var tmpcell = o.dense ? (s[val[0].r]||[])[val[0].c] : s[encode_cell(val[0])];
 | 
			
		||||
					if(tmpcell) {
 | 
			
		||||
						tmpcell.t = val[1].t; tmpcell.v = val[1].v;
 | 
			
		||||
@ -72,6 +92,7 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
			o.Enum = WK3Enum;
 | 
			
		||||
			if(d[2] == 0x0E) { o.qpro = true; d.l = 0; }
 | 
			
		||||
			lotushopper(d, function(val, R, RT) { switch(RT) {
 | 
			
		||||
				case 0xCC: n = val; break; /* SHEETNAMECS */
 | 
			
		||||
				case 0x16: /* LABEL16 */
 | 
			
		||||
					val[1].v = val[1].v.slice(1);
 | 
			
		||||
					/* falls through */
 | 
			
		||||
@ -84,10 +105,10 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
					if(val[3] > sidx) {
 | 
			
		||||
						s["!ref"] = encode_range(refguess);
 | 
			
		||||
						sheets[n] = s;
 | 
			
		||||
						snames.push(n);
 | 
			
		||||
						s = (o.dense ? [] : {});
 | 
			
		||||
						refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
 | 
			
		||||
						sidx = val[3]; n = "Sheet" + (sidx + 1);
 | 
			
		||||
						snames.push(n);
 | 
			
		||||
					}
 | 
			
		||||
					if(sheetRows > 0 && val[0].r >= sheetRows) break;
 | 
			
		||||
					if(o.dense) {
 | 
			
		||||
@ -100,17 +121,23 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
				case 0x1B: /* XFORMAT */
 | 
			
		||||
					if(val[0x36b0]) realnames[val[0x36b0][0]] = val[0x36b0][1];
 | 
			
		||||
					break;
 | 
			
		||||
				case 0x0601: /* SHEETINFOQP */
 | 
			
		||||
					realnames[val[0]] = val[1]; if(val[0] == sidx) n = val[1]; break;
 | 
			
		||||
				default: break;
 | 
			
		||||
			}}, o);
 | 
			
		||||
		} else throw new Error("Unrecognized LOTUS BOF " + d[2]);
 | 
			
		||||
 | 
			
		||||
		s["!ref"] = encode_range(refguess);
 | 
			
		||||
		sheets[n] = s;
 | 
			
		||||
		sheets[next_n || n] = s;
 | 
			
		||||
		snames.push(next_n || n);
 | 
			
		||||
		if(!realnames.length) return { SheetNames: snames, Sheets: sheets };
 | 
			
		||||
		var osheets = {}, rnames = [];
 | 
			
		||||
		/* TODO: verify no collisions */
 | 
			
		||||
		for(var i = 0; i < realnames.length; ++i) if(sheets[snames[i]]) {
 | 
			
		||||
			rnames.push(realnames[i] || snames[i]);
 | 
			
		||||
			osheets[realnames[i]] = sheets[realnames[i]] || sheets[snames[i]];
 | 
			
		||||
		} else {
 | 
			
		||||
			rnames.push(realnames[i]);
 | 
			
		||||
			osheets[realnames[i]] = sheets[snames[i]];
 | 
			
		||||
			osheets[realnames[i]] = ({ "!ref": "A1" });
 | 
			
		||||
		}
 | 
			
		||||
		return { SheetNames: rnames, Sheets: osheets };
 | 
			
		||||
	}
 | 
			
		||||
@ -126,7 +153,8 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
 | 
			
		||||
		write_biff_rec(ba, 0x00, write_BOF_WK1(0x0406));
 | 
			
		||||
		write_biff_rec(ba, 0x06, write_RANGE(range));
 | 
			
		||||
		for(var R = range.s.r; R <= range.e.r; ++R) {
 | 
			
		||||
		var max_R = Math.min(range.e.r, 8191);
 | 
			
		||||
		for(var R = range.s.r; R <= max_R; ++R) {
 | 
			
		||||
			var rr = encode_row(R);
 | 
			
		||||
			for(var C = range.s.c; C <= range.e.c; ++C) {
 | 
			
		||||
				if(R === range.s.r) cols[C] = encode_col(C);
 | 
			
		||||
@ -165,7 +193,8 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
			var range = safe_decode_range(ws["!ref"]);
 | 
			
		||||
			var dense = Array.isArray(ws);
 | 
			
		||||
			var cols = [];
 | 
			
		||||
			for(var R = range.s.r; R <= range.e.r; ++R) {
 | 
			
		||||
			var max_R = Math.min(range.e.r, 8191);
 | 
			
		||||
			for(var R = range.s.r; R <= max_R; ++R) {
 | 
			
		||||
				var rr = encode_row(R);
 | 
			
		||||
				for(var C = range.s.c; C <= range.e.c; ++C) {
 | 
			
		||||
					if(R === range.s.r) cols[C] = encode_col(C);
 | 
			
		||||
@ -211,6 +240,7 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
			if(rows < range.e.r) rows = range.e.r;
 | 
			
		||||
			if(cols < range.e.c) cols = range.e.c;
 | 
			
		||||
		}
 | 
			
		||||
		if(rows > 8191) rows = 8191;
 | 
			
		||||
		out.write_shift(2, rows);
 | 
			
		||||
		out.write_shift(1, wscnt);
 | 
			
		||||
		out.write_shift(1, cols);
 | 
			
		||||
@ -223,12 +253,23 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
		return out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parse_RANGE(blob) {
 | 
			
		||||
	function parse_RANGE(blob, length, opts) {
 | 
			
		||||
		var o = {s:{c:0,r:0},e:{c:0,r:0}};
 | 
			
		||||
		if(length == 8 && opts.qpro) {
 | 
			
		||||
			o.s.c = blob.read_shift(1);
 | 
			
		||||
			blob.l++;
 | 
			
		||||
			o.s.r = blob.read_shift(2);
 | 
			
		||||
			o.e.c = blob.read_shift(1);
 | 
			
		||||
			blob.l++;
 | 
			
		||||
			o.e.r = blob.read_shift(2);
 | 
			
		||||
			return o;
 | 
			
		||||
		}
 | 
			
		||||
		o.s.c = blob.read_shift(2);
 | 
			
		||||
		o.s.r = blob.read_shift(2);
 | 
			
		||||
		if(length == 12 && opts.qpro) blob.l += 2;
 | 
			
		||||
		o.e.c = blob.read_shift(2);
 | 
			
		||||
		o.e.r = blob.read_shift(2);
 | 
			
		||||
		if(length == 12 && opts.qpro) blob.l += 2;
 | 
			
		||||
		if(o.s.c == 0xFFFF) o.s.c = o.e.c = o.s.r = o.e.r = 0;
 | 
			
		||||
		return o;
 | 
			
		||||
	}
 | 
			
		||||
@ -242,10 +283,10 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parse_cell(blob, length, opts) {
 | 
			
		||||
		var o = [{c:0,r:0}, {t:'n',v:0}, 0];
 | 
			
		||||
		var o = [{c:0,r:0}, {t:'n',v:0}, 0, 0];
 | 
			
		||||
		if(opts.qpro && opts.vers != 0x5120) {
 | 
			
		||||
			o[0].c = blob.read_shift(1);
 | 
			
		||||
			blob.l++;
 | 
			
		||||
			o[3] = blob.read_shift(1);
 | 
			
		||||
			o[0].r = blob.read_shift(2);
 | 
			
		||||
			blob.l+=2;
 | 
			
		||||
		} else {
 | 
			
		||||
@ -357,7 +398,7 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
 | 
			
		||||
	function wk1_fmla_to_csf(blob, o) {
 | 
			
		||||
		prep_blob(blob, 0);
 | 
			
		||||
		var out = [], argc = 0, R = "", C = "";
 | 
			
		||||
		var out = [], argc = 0, R = "", C = "", argL = "", argR = "";
 | 
			
		||||
		while(blob.l < blob.length) {
 | 
			
		||||
			var cc = blob[blob.l++];
 | 
			
		||||
			switch(cc) {
 | 
			
		||||
@ -390,7 +431,7 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
				case 0x16: out.push("NOT(" + out.pop() + ")"); break;
 | 
			
		||||
 | 
			
		||||
				case 0x14: case 0x15: {
 | 
			
		||||
					var argR = out.pop(), argL = out.pop();
 | 
			
		||||
					argR = out.pop(); argL = out.pop();
 | 
			
		||||
					out.push(["AND", "OR"][cc - 0x14] + "(" + argL + "," + argR + ")");
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
@ -536,6 +577,27 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
		return o;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parse_SHEETNAMECS(blob, length) {
 | 
			
		||||
		return blob[blob.l + length - 1] == 0 ? blob.read_shift(length, 'cstr') : "";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parse_SHEETNAMELP(blob, length) {
 | 
			
		||||
		var len = blob[blob.l++];
 | 
			
		||||
		if(len > length - 1) len = length - 1;
 | 
			
		||||
		var o = ""; while(o.length < len) o += String.fromCharCode(blob[blob.l++]);
 | 
			
		||||
		return o;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parse_SHEETINFOQP(blob, length, opts) {
 | 
			
		||||
		if(!opts.qpro || length < 21) return;
 | 
			
		||||
		var id = blob.read_shift(1);
 | 
			
		||||
		blob.l += 17;
 | 
			
		||||
		var len = blob.read_shift(1);
 | 
			
		||||
		blob.l += 2;
 | 
			
		||||
		var nm = blob.read_shift(length - 21, 'cstr');
 | 
			
		||||
		return [id, nm];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parse_XFORMAT(blob, length) {
 | 
			
		||||
		var o = {}, tgt = blob.l + length;
 | 
			
		||||
		while(blob.l < tgt) {
 | 
			
		||||
@ -623,6 +685,8 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
		/*::[*/0x0067/*::]*/: { n:"RRANGES??" },
 | 
			
		||||
		/*::[*/0x0068/*::]*/: { n:"FNAME??" },
 | 
			
		||||
		/*::[*/0x0069/*::]*/: { n:"MRANGES??" },
 | 
			
		||||
		/*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
 | 
			
		||||
		/*::[*/0x00DE/*::]*/: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
 | 
			
		||||
		/*::[*/0xFFFF/*::]*/: { n:"" }
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
@ -688,6 +752,7 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
		/*::[*/0x00BC/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x00C3/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x00C9/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
 | 
			
		||||
		/*::[*/0x00CD/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x00CE/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x00CF/*::]*/: { n:"??" },
 | 
			
		||||
@ -732,6 +797,7 @@ var WK_ = /*#__PURE__*/ (function() {
 | 
			
		||||
		/*::[*/0x029A/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x0300/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x0304/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x0601/*::]*/: { n:"SHEETINFOQP", f:parse_SHEETINFOQP },
 | 
			
		||||
		/*::[*/0x0640/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x0642/*::]*/: { n:"??" },
 | 
			
		||||
		/*::[*/0x0701/*::]*/: { n:"??" },
 | 
			
		||||
 | 
			
		||||
@ -855,7 +855,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
	if(!options.bookSheets) wb.Sheets=Sheets;
 | 
			
		||||
	if(!wb.SheetNames.length && Preamble["!ref"]) {
 | 
			
		||||
		wb.SheetNames.push("Sheet1");
 | 
			
		||||
		/*jshint -W069 */
 | 
			
		||||
		if(wb.Sheets) wb.Sheets["Sheet1"] = Preamble;
 | 
			
		||||
		/*jshint +W069 */
 | 
			
		||||
	} else wb.Preamble=Preamble;
 | 
			
		||||
	if(wb.Sheets) FilterDatabases.forEach(function(r,i) { wb.Sheets[wb.SheetNames[i]]['!autofilter'] = r; });
 | 
			
		||||
	wb.Strings = sst;
 | 
			
		||||
@ -950,6 +952,8 @@ else/*:: if(cfb instanceof CFBContainer) */ {
 | 
			
		||||
	else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
 | 
			
		||||
	/* Quattro Pro 9 */
 | 
			
		||||
	else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
 | 
			
		||||
	/* Works 4 for Mac */
 | 
			
		||||
	else if((_data=CFB.find(cfb, 'MN0')) && _data.content) throw new Error("Unsupported Works 4 for Mac file");
 | 
			
		||||
	else throw new Error("Cannot find Workbook stream");
 | 
			
		||||
	if(options.bookVBA && cfb.FullPaths && CFB.find(cfb, '/_VBA_PROJECT_CUR/VBA/dir')) WorkbookP.vbaraw = make_vba_xls(cfb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -842,7 +842,9 @@ var XLSBRecordEnum = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var XLSBRE = evert_key(XLSBRecordEnum, 'n');
 | 
			
		||||
/*jshint -W069 */
 | 
			
		||||
XLSBRE["BrtFRTArchID$"] = 0x0010;
 | 
			
		||||
/*jshint +W069 */
 | 
			
		||||
 | 
			
		||||
/* [MS-XLS] 2.3 Record Enumeration (and other sources) */
 | 
			
		||||
var XLSRecordEnum = {
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,15 @@
 | 
			
		||||
/* OpenDocument */
 | 
			
		||||
var write_styles_ods/*:{(wb:any, opts:any):string}*/ = (function() {
 | 
			
		||||
	var master_styles = '<office:master-styles>'
 | 
			
		||||
	+ '<style:master-page style:name="mp1" style:page-layout-name="mp1">'
 | 
			
		||||
	+ '<style:header/>'
 | 
			
		||||
	+ '<style:header-left style:display="false"/>'
 | 
			
		||||
	+ '<style:footer/>'
 | 
			
		||||
	+ '<style:footer-left style:display="false"/>'
 | 
			
		||||
	+ '</style:master-page>'
 | 
			
		||||
	+ '</office:master-styles>';
 | 
			
		||||
	var master_styles = [
 | 
			
		||||
		'<office:master-styles>',
 | 
			
		||||
			'<style:master-page style:name="mp1" style:page-layout-name="mp1">',
 | 
			
		||||
				'<style:header/>',
 | 
			
		||||
				'<style:header-left style:display="false"/>',
 | 
			
		||||
				'<style:footer/>',
 | 
			
		||||
				'<style:footer-left style:display="false"/>',
 | 
			
		||||
			'</style:master-page>',
 | 
			
		||||
		'</office:master-styles>'
 | 
			
		||||
	].join("");
 | 
			
		||||
 | 
			
		||||
	var payload = '<office:document-styles ' + wxt_helper({
 | 
			
		||||
		'xmlns:office':   "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
 | 
			
		||||
 | 
			
		||||
@ -91,12 +91,20 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
		case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break;
 | 
			
		||||
		case 0x50: return (n[1] === 0x4B && n[2] < 0x09 && n[3] < 0x09) ? read_zip(d, o) : read_prn(data, d, o, str);
 | 
			
		||||
		case 0xEF: return n[3] === 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
 | 
			
		||||
		case 0xFF: if(n[1] === 0xFE) { return read_utf16(d, o); } break;
 | 
			
		||||
		case 0x00: if(n[1] === 0x00 && n[2] >= 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o); break;
 | 
			
		||||
		case 0xFF:
 | 
			
		||||
			if(n[1] === 0xFE) { return read_utf16(d, o); }
 | 
			
		||||
			else if(n[1] === 0x00 && n[2] === 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o);
 | 
			
		||||
			break;
 | 
			
		||||
		case 0x00:
 | 
			
		||||
			if(n[1] === 0x00) {
 | 
			
		||||
				if(n[2] >= 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o);
 | 
			
		||||
				if(n[2] === 0x00 && (n[3] === 0x08 || n[3] === 0x09)) return WK_.to_workbook(d, o);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case 0x03: case 0x83: case 0x8B: case 0x8C: return DBF.to_workbook(d, o);
 | 
			
		||||
		case 0x7B: if(n[1] === 0x5C && n[2] === 0x72 && n[3] === 0x74) return RTF.to_workbook(d, o); break;
 | 
			
		||||
		case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
 | 
			
		||||
		case 0x89: if(n[1] === 0x50 && n[2] === 0x4E && n[3] === 0x47) throw new Error("PNG Image File is not a spreadsheet"); break; 
 | 
			
		||||
		case 0x89: if(n[1] === 0x50 && n[2] === 0x4E && n[3] === 0x47) throw new Error("PNG Image File is not a spreadsheet"); break;
 | 
			
		||||
	}
 | 
			
		||||
	if(DBF.versions.indexOf(n[0]) > -1 && n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
 | 
			
		||||
	return read_prn(data, d, o, str);
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,8 @@
 | 
			
		||||
if(has_buf && typeof require != 'undefined') (function() {
 | 
			
		||||
	var Readable = require('stream').Readable;
 | 
			
		||||
	var strmod = require('stream');
 | 
			
		||||
	if(!strmod) return;
 | 
			
		||||
	var Readable = strmod.Readable;
 | 
			
		||||
	if(!Readable) return;
 | 
			
		||||
 | 
			
		||||
	var write_csv_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
 | 
			
		||||
		var stream = Readable();
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,6 @@ else if(typeof module !== 'undefined' && module.exports) make_xlsx_lib(module.ex
 | 
			
		||||
else if(typeof define === 'function' && define.amd) define('xlsx', function() { if(!XLSX.version) make_xlsx_lib(XLSX); return XLSX; });
 | 
			
		||||
else make_xlsx_lib(XLSX);
 | 
			
		||||
/* NOTE: the following extra line is needed for "Lightning Locker Service" */
 | 
			
		||||
if(typeof window !== 'undefined' && !window.XLSX) window.XLSX = XLSX;
 | 
			
		||||
if(typeof window !== 'undefined' && !window.XLSX) try { window.XLSX = XLSX; } catch(e) {}
 | 
			
		||||
/*exported XLS, ODS */
 | 
			
		||||
var XLS = XLSX, ODS = XLSX;
 | 
			
		||||
 | 
			
		||||
@ -85,7 +85,7 @@ file but Excel will know how to handle it.  This library applies similar logic:
 | 
			
		||||
 | 
			
		||||
| Byte 0 | Raw File Type | Spreadsheet Types                                   |
 | 
			
		||||
|:-------|:--------------|:----------------------------------------------------|
 | 
			
		||||
| `0xD0` | CFB Container | BIFF 5/8 or password-protected XLSX/XLSB or WQ3/QPW |
 | 
			
		||||
| `0xD0` | CFB Container | BIFF 5/8 or protected XLSX/XLSB or WQ3/QPW or XLR   |
 | 
			
		||||
| `0x09` | BIFF Stream   | BIFF 2/3/4/5                                        |
 | 
			
		||||
| `0x3C` | XML/HTML      | SpreadsheetML / Flat ODS / UOS1 / HTML / plain text |
 | 
			
		||||
| `0x50` | ZIP Archive   | XLSB or XLSX/M or ODS or UOS2 or plain text         |
 | 
			
		||||
@ -102,6 +102,8 @@ file but Excel will know how to handle it.  This library applies similar logic:
 | 
			
		||||
DBF files are detected based on the first byte as well as the third and fourth
 | 
			
		||||
bytes (corresponding to month and day of the file date)
 | 
			
		||||
 | 
			
		||||
Works for Windows files are detected based on the BOF record with type `0xFF`
 | 
			
		||||
 | 
			
		||||
Plain text format guessing follows the priority order:
 | 
			
		||||
 | 
			
		||||
| Format | Test                                                                |
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,8 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
 | 
			
		||||
| Lotus 1-2-3 (WK1/WK3)                                        |   ✔   |   ✔   |
 | 
			
		||||
| Lotus 1-2-3 (WKS/WK2/WK4/123)                                |   ✔   |       |
 | 
			
		||||
| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW)            |   ✔   |       |
 | 
			
		||||
| Works 1.x-3.x DOS / 2.x-5.x Windows Spreadsheet (WKS)        |   ✔   |       |
 | 
			
		||||
| Works 6.x-9.x Spreadsheet (XLR)                              |   ✔   |       |
 | 
			
		||||
| **Other Common Spreadsheet Output Formats**                  |:-----:|:-----:|
 | 
			
		||||
| HTML Tables                                                  |   ✔   |   ✔   |
 | 
			
		||||
| Rich Text Format tables (RTF)                                |       |   ✔   |
 | 
			
		||||
@ -44,6 +46,8 @@ range limits will be silently truncated:
 | 
			
		||||
| Excel 4.0 (XLS BIFF4)                     | IV16384    |      256 |    16384 |
 | 
			
		||||
| Excel 3.0 (XLS BIFF3)                     | IV16384    |      256 |    16384 |
 | 
			
		||||
| Excel 2.0/2.1 (XLS BIFF2)                 | IV16384    |      256 |    16384 |
 | 
			
		||||
| Lotus 1-2-3 R2 - R5 (WK1/WK3/WK4)         | IV8192     |      256 |     8192 |
 | 
			
		||||
| Lotus 1-2-3 R1 (WKS)                      | IV2048     |      256 |     2048 |
 | 
			
		||||
 | 
			
		||||
Excel 2003 SpreadsheetML range limits are governed by the version of Excel and
 | 
			
		||||
are not enforced by the writer.
 | 
			
		||||
@ -180,6 +184,27 @@ BIFF8 XLS.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
#### Works for DOS / Windows Spreadsheet (WKS/XLR)
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
  <summary>(click to show)</summary>
 | 
			
		||||
 | 
			
		||||
All versions of Works were limited to a single worksheet.
 | 
			
		||||
 | 
			
		||||
Works for DOS 1.x - 3.x and Works for Windows 2.x extends the Lotus WKS format
 | 
			
		||||
with additional record types.
 | 
			
		||||
 | 
			
		||||
Works for Windows 3.x - 5.x uses the same format and WKS extension.  The BOF
 | 
			
		||||
record has type `FF`
 | 
			
		||||
 | 
			
		||||
Works for Windows 6.x - 9.x use the XLR format.  XLR is nearly identical to
 | 
			
		||||
BIFF8 XLS: it uses the CFB container with a Workbook stream.  Works 9 saves the
 | 
			
		||||
exact Workbook stream for the XLR and the 97-2003 XLS export.  Works 6 XLS
 | 
			
		||||
includes two empty worksheets but the main worksheet has an identical encoding.
 | 
			
		||||
XLR also includes a `WksSSWorkBook` stream similar to Lotus FM3/FMT files.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
#### OpenDocument Spreadsheet (ODS/FODS)
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								formats.png
									
									
									
									
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								formats.png
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 443 KiB After Width: | Height: | Size: 191 KiB  | 
@ -2,8 +2,12 @@
 | 
			
		||||
const fs = require('fs');
 | 
			
		||||
const coarse = require('coarse');
 | 
			
		||||
 
 | 
			
		||||
const svg = fs.readFileSync(process.argv[2]);
 | 
			
		||||
const roughened = coarse(svg);
 | 
			
		||||
const svg = fs.readFileSync(process.argv[2], "utf8");
 | 
			
		||||
let roughened = coarse(svg);
 | 
			
		||||
const viewbox = roughened.match(/viewBox="(.*?)"/)[1].split(/\s+/);
 | 
			
		||||
const v = viewbox.map(x => parseFloat(x));
 | 
			
		||||
v[0] -= 40; v[1] += 40; v[2] += 80; v[3] += 80;
 | 
			
		||||
roughened = roughened.replace(/<title>G<\/title>/, `$&<polygon fill="white" stroke="" points="${v[0]},${v[1]} ${v[0]},${v[1]-v[3]} ${v[0]+v[2]},${v[1]-v[3]} ${v[0]+v[2]},${v[1]} ${v[0]},${v[1]}"/>`);
 | 
			
		||||
 
 | 
			
		||||
fs.writeFileSync(process.argv[3], roughened);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,9 +27,15 @@ digraph G {
 | 
			
		||||
		slk   [label="SYLK"];
 | 
			
		||||
		prn   [label="PRN"];
 | 
			
		||||
		rtf   [label="RTF"];
 | 
			
		||||
		wk1   [label="WK1/2\n123"];
 | 
			
		||||
		wk3   [label="WK3/4"];
 | 
			
		||||
		wqb   [label="WQ*\nWB*"];
 | 
			
		||||
		wk1   [label="WK1"];
 | 
			
		||||
		wksl  [label="WKS\nLotus"];
 | 
			
		||||
		wk3   [label="WK3"];
 | 
			
		||||
		wk4   [label="WK4"]
 | 
			
		||||
		123   [label="123"];
 | 
			
		||||
		wksm  [label="WKS\nWorks"];
 | 
			
		||||
		xlr   [label="XLR"];
 | 
			
		||||
		wq1   [label="WQ1"];
 | 
			
		||||
		wq2   [label="WQ2\nWB*"];
 | 
			
		||||
		qpw   [label="QPW"];
 | 
			
		||||
		eth   [label="ETH"];
 | 
			
		||||
	}
 | 
			
		||||
@ -46,6 +52,7 @@ digraph G {
 | 
			
		||||
		xls5 -> csf
 | 
			
		||||
		csf -> xls8
 | 
			
		||||
		xls8 -> csf
 | 
			
		||||
		wq2 -> csf
 | 
			
		||||
		ods -> csf
 | 
			
		||||
		csf -> ods
 | 
			
		||||
		fods -> csf
 | 
			
		||||
@ -53,6 +60,8 @@ digraph G {
 | 
			
		||||
		uos -> csf
 | 
			
		||||
		wk3 -> csf
 | 
			
		||||
		csf -> wk3
 | 
			
		||||
		wk4 -> csf
 | 
			
		||||
		123 -> csf
 | 
			
		||||
		qpw -> csf
 | 
			
		||||
	}
 | 
			
		||||
	subgraph WORKSHEET {
 | 
			
		||||
@ -68,7 +77,10 @@ digraph G {
 | 
			
		||||
		csf -> dif
 | 
			
		||||
		wk1 -> csf
 | 
			
		||||
		csf -> wk1
 | 
			
		||||
		wqb -> csf
 | 
			
		||||
		xlr -> csf
 | 
			
		||||
		wq1 -> csf
 | 
			
		||||
		wksl -> csf
 | 
			
		||||
		wksm -> csf
 | 
			
		||||
		dif -> csf
 | 
			
		||||
		csf -> rtf
 | 
			
		||||
		prn -> csf
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								test.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								test.js
									
									
									
									
									
								
							@ -524,9 +524,11 @@ describe('parse options', function() {
 | 
			
		||||
			} } };
 | 
			
		||||
			var str = X.write(wb, {bookType: "xlsx", type: "binary"});
 | 
			
		||||
			var wb2 = X.read(str, {type: "binary"});
 | 
			
		||||
			/*jshint -W069 */
 | 
			
		||||
			assert.equal(wb2.Sheets.Sheet1["A1"].f, "IFS(2>3,1,3>2,2)");
 | 
			
		||||
			var wb3 = X.read(str, {type: "binary", xlfn: true});
 | 
			
		||||
			assert.equal(wb3.Sheets.Sheet1["A1"].f, "_xlfn.IFS(2>3,1,3>2,2)");
 | 
			
		||||
			/*jshint +W069 */
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
	describe('sheet', function() {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								tests/core.js
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								tests/core.js
									
									
									
										generated
									
									
									
								
							@ -524,9 +524,11 @@ describe('parse options', function() {
 | 
			
		||||
			} } };
 | 
			
		||||
			var str = X.write(wb, {bookType: "xlsx", type: "binary"});
 | 
			
		||||
			var wb2 = X.read(str, {type: "binary"});
 | 
			
		||||
			/*jshint -W069 */
 | 
			
		||||
			assert.equal(wb2.Sheets.Sheet1["A1"].f, "IFS(2>3,1,3>2,2)");
 | 
			
		||||
			var wb3 = X.read(str, {type: "binary", xlfn: true});
 | 
			
		||||
			assert.equal(wb3.Sheets.Sheet1["A1"].f, "_xlfn.IFS(2>3,1,3>2,2)");
 | 
			
		||||
			/*jshint +W069 */
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
	describe('sheet', function() {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user