forked from sheetjs/sheetjs
		
	version bump 0.12.1: BIFF5 features
- BIFF5 write number formats and other features - XLSX/XLSB/BIFF8 Suppress "Number stored as Text" errors - codename awareness (fixes #992 h/t @samusstrike) - updated CFB to 1.0.3 - demo refresh
This commit is contained in:
		
							parent
							
								
									f002afae4b
								
							
						
					
					
						commit
						19620da30b
					
				| @ -62,6 +62,7 @@ APIs | ||||
| ArrayBuffer | ||||
| Base64 | ||||
| Booleans | ||||
| FileReader | ||||
| JS | ||||
| NoSQL | ||||
| README | ||||
|  | ||||
							
								
								
									
										36
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										36
									
								
								README.md
									
									
									
									
									
								
							| @ -430,6 +430,8 @@ function handleFile(e) { | ||||
| input_dom_element.addEventListener('change', handleFile, false); | ||||
| ``` | ||||
| 
 | ||||
| The [`oldie` demo](demos/oldie/) shows an IE-compatible fallback scenario. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| More specialized cases, including mobile app file processing, are covered in the | ||||
| @ -849,11 +851,13 @@ for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
| 
 | ||||
| ### Cell Object | ||||
| 
 | ||||
| Cell objects are plain JS objects with keys and values following the convention: | ||||
| 
 | ||||
| | Key | Description                                                            | | ||||
| | --- | ---------------------------------------------------------------------- | | ||||
| | `v` | raw value (see Data Types section for more info)                       | | ||||
| | `w` | formatted text (if applicable)                                         | | ||||
| | `t` | cell type: `b` Boolean, `n` Number, `e` error, `s` String, `d` Date    | | ||||
| | `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub | | ||||
| | `f` | cell formula encoded as an A1-style string (if applicable)             | | ||||
| | `F` | range of enclosing array if formula is array formula (if applicable)   | | ||||
| | `r` | rich text encoding (if applicable)                                     | | ||||
| @ -873,11 +877,18 @@ array range.  Other cells in the range will omit the `f` field. | ||||
| 
 | ||||
| #### Data Types | ||||
| 
 | ||||
| The raw value is stored in the `v` field, interpreted based on the `t` field. | ||||
| The raw value is stored in the `v` value property, interpreted based on the `t` | ||||
| type property.  This separation allows for representation of numbers as well as | ||||
| numeric text.  There are 6 valid cell types: | ||||
| 
 | ||||
| Type `b` is the Boolean type.  `v` is interpreted according to JS truth tables. | ||||
| 
 | ||||
| Type `e` is the Error type. `v` holds the number and `w` holds the common name: | ||||
| | Type | Description                                                           | | ||||
| | :--: | :-------------------------------------------------------------------- | | ||||
| | `b`  | Boolean: value interpreted as JS `boolean`                            | | ||||
| | `e`  | Error: value is a numeric code and `w` property stores common name ** | | ||||
| | `n`  | Number: value is a JS `number` **                                     | | ||||
| | `d`  | Date: value is a JS `Date` object or string to be parsed as Date **   | | ||||
| | `s`  | Text: value interpreted as JS `string` and written as text **         | | ||||
| | `z`  | Stub: blank stub cell that is ignored by data processing utilities ** | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Error values and interpretation</b> (click to show)</summary> | ||||
| @ -906,14 +917,17 @@ Since JSON does not have a natural Date type, parsers are generally expected to | ||||
| store ISO 8601 Date strings like you would get from `date.toISOString()`.  On | ||||
| the other hand, writers and exporters should be able to handle date strings and | ||||
| JS Date objects.  Note that Excel disregards timezone modifiers and treats all | ||||
| dates in the local timezone.  js-xlsx does not correct for this error. | ||||
| dates in the local timezone.  The library does not correct for this error. | ||||
| 
 | ||||
| Type `s` is the String type.  `v` should be explicitly stored as a string to | ||||
| avoid possible confusion. | ||||
| Type `s` is the String type.  Values are explicitly stored as text.  Excel will | ||||
| interpret these cells as "number stored as text".  Generated Excel files | ||||
| automatically suppress that class of error, but other formats may elicit errors. | ||||
| 
 | ||||
| Type `z` represents blank stub cells.  They are generated in cases where cells | ||||
| have no assigned value but hold comments or other metadata. They are ignored by | ||||
| the core library data processing utility functions.  By default these cells are | ||||
| not generated; the parser `sheetStubs` option must be set to `true`. | ||||
| 
 | ||||
| Type `z` represents blank stub cells.  These do not have any data or type, and | ||||
| are not processed by any of the core library functions.  By default these cells | ||||
| will not be generated; the parser `sheetStubs` option must be set to `true`. | ||||
| 
 | ||||
| #### Dates | ||||
| 
 | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| XLSX.version = '0.12.0'; | ||||
| XLSX.version = '0.12.1'; | ||||
|  | ||||
| @ -18,6 +18,46 @@ var XLMLFormatMap/*{[string]:string}*/ = ({ | ||||
| 	"On/Off": '"Yes";"Yes";"No";@' | ||||
| }/*:any*/); | ||||
| 
 | ||||
| var SSFImplicit/*{[number]:string}*/ = ({ | ||||
| 	"5": '"$"#,##0_);\\("$"#,##0\\)', | ||||
| 	"6": '"$"#,##0_);[Red]\\("$"#,##0\\)', | ||||
| 	"7": '"$"#,##0.00_);\\("$"#,##0.00\\)', | ||||
| 	"8": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)', | ||||
| 	"23": 'General', "24": 'General', "25": 'General', "26": 'General', | ||||
| 	"27": 'm/d/yy', "28": 'm/d/yy', "29": 'm/d/yy', "30": 'm/d/yy', "31": 'm/d/yy', | ||||
| 	"32": 'h:mm:ss', "33": 'h:mm:ss', "34": 'h:mm:ss', "35": 'h:mm:ss', | ||||
| 	"36": 'm/d/yy', | ||||
| 	"41": '_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)', | ||||
| 	"42": '_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)', | ||||
| 	"43": '_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)', | ||||
| 	"44": '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)', | ||||
| 	"50": 'm/d/yy', "51": 'm/d/yy', "52": 'm/d/yy', "53": 'm/d/yy', "54": 'm/d/yy', | ||||
| 	"55": 'm/d/yy', "56": 'm/d/yy', "57": 'm/d/yy', "58": 'm/d/yy', | ||||
| 	"59": '0', | ||||
| 	"60": '0.00', | ||||
| 	"61": '#,##0', | ||||
| 	"62": '#,##0.00', | ||||
| 	"63": '"$"#,##0_);\\("$"#,##0\\)', | ||||
| 	"64": '"$"#,##0_);[Red]\\("$"#,##0\\)', | ||||
| 	"65": '"$"#,##0.00_);\\("$"#,##0.00\\)', | ||||
| 	"66": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)', | ||||
| 	"67": '0%', | ||||
| 	"68": '0.00%', | ||||
| 	"69": '# ?/?', | ||||
| 	"70": '# ??/??', | ||||
| 	"71": 'm/d/yy', | ||||
| 	"72": 'm/d/yy', | ||||
| 	"73": 'd-mmm-yy', | ||||
| 	"74": 'd-mmm', | ||||
| 	"75": 'mmm-yy', | ||||
| 	"76": 'h:mm', | ||||
| 	"77": 'h:mm:ss', | ||||
| 	"78": 'm/d/yy h:mm', | ||||
| 	"79": 'mm:ss', | ||||
| 	"80": '[h]:mm:ss', | ||||
| 	"81": 'mmss.0' | ||||
| }/*:any*/); | ||||
| 
 | ||||
| /* dateNF parse TODO: move to SSF */ | ||||
| var dateNFregex = /[dD]+|[mM]+|[yYeE]+|[Hh]+|[Ss]+/g; | ||||
| function dateNF_regex(dateNF/*:string|number*/)/*:RegExp*/ { | ||||
|  | ||||
| @ -38,7 +38,7 @@ type CFBFiles = {[n:string]:CFBEntry}; | ||||
| /* [MS-CFB] v20130118 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; | ||||
| exports.version = '1.0.2'; | ||||
| exports.version = '1.0.3'; | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function namecmp(l/*:string*/, r/*:string*/)/*:number*/ { | ||||
| 	var L = l.split("/"), R = r.split("/"); | ||||
| @ -353,14 +353,14 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector | ||||
| 			if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz); | ||||
| 			sector_list[o.start].name = o.name; | ||||
| 			o.content = (sector_list[o.start].data.slice(0,o.size)/*:any*/); | ||||
| 			prep_blob(o.content, 0); | ||||
| 		} else { | ||||
| 			o.storage = 'minifat'; | ||||
| 			if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) { | ||||
| 			if(o.size < 0) o.size = 0; | ||||
| 			else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) { | ||||
| 				o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data); | ||||
| 				prep_blob(o.content, 0); | ||||
| 			} | ||||
| 		} | ||||
| 		if(o.content) prep_blob(o.content, 0); | ||||
| 		files[name] = o; | ||||
| 		FileIndex.push(o); | ||||
| 	} | ||||
|  | ||||
| @ -2,7 +2,7 @@ function keys(o/*:any*/)/*:Array<any>*/ { return Object.keys(o); } | ||||
| 
 | ||||
| function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ { | ||||
| 	var o = ([]/*:any*/), K = keys(obj); | ||||
| 	for(var i = 0; i !== K.length; ++i) o[obj[K[i]][key]] = K[i]; | ||||
| 	for(var i = 0; i !== K.length; ++i) if(o[obj[K[i]][key]] == null) o[obj[K[i]][key]] = K[i]; | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -188,7 +188,7 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/)/*:any*/ | ||||
| 		} return this; | ||||
| 	} else if(f === 'utf16le') { | ||||
| 			/*:: if(typeof val !== "string") throw new Error("unreachable"); */ | ||||
| 			var end/*:number*/ = this.l + t; | ||||
| 			var end/*:number*/ = Math.min(this.l + t, this.length); | ||||
| 			for(i = 0; i < Math.min(val.length, t); ++i) { | ||||
| 				var cc = val.charCodeAt(i); | ||||
| 				this[this.l++] = (cc & 0xff); | ||||
|  | ||||
| @ -27,7 +27,7 @@ function write_StrRun(run, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.121 */ | ||||
| /* [MS-XLSB] 2.5.121 */ | ||||
| function parse_RichStr(data, length/*:number*/)/*:XLString*/ { | ||||
| 	var start = data.l; | ||||
| 	var flags = data.read_shift(1); | ||||
| @ -54,7 +54,7 @@ function write_RichStr(str/*:XLString*/, o/*:?Block*/)/*:Block*/ { | ||||
| 	write_XLWideString(str.t, o); | ||||
| 	return _null ? o.slice(0, o.l) : o; | ||||
| } | ||||
| /* [MS-XLSB] 2.4.325 BrtCommentText (RichStr w/1 run) */ | ||||
| /* [MS-XLSB] 2.4.328 BrtCommentText (RichStr w/1 run) */ | ||||
| var parse_BrtCommentText = parse_RichStr; | ||||
| function write_BrtCommentText(str/*:XLString*/, o/*:?Block*/)/*:Block*/ { | ||||
| 	/* TODO: formatted string */ | ||||
| @ -108,8 +108,7 @@ var parse_RelID = parse_XLNullableWideString; | ||||
| var write_RelID = write_XLNullableWideString; | ||||
| 
 | ||||
| 
 | ||||
| /* [MS-XLSB] 2.5.122 */ | ||||
| /* [MS-XLS] 2.5.217 */ | ||||
| /* [MS-XLS] 2.5.217 ; [MS-XLSB] 2.5.122 */ | ||||
| function parse_RkNumber(data)/*:number*/ { | ||||
| 	var b = data.slice(data.l, data.l+4); | ||||
| 	var fX100 = (b[0] & 1), fInt = (b[0] & 2); | ||||
| @ -137,7 +136,6 @@ function parse_RfX(data /*::, length*/)/*:Range*/ { | ||||
| 	cell.e.c = data.read_shift(4); | ||||
| 	return cell; | ||||
| } | ||||
| 
 | ||||
| function write_RfX(r/*:Range*/, o) { | ||||
| 	if(!o) o = new_buf(16); | ||||
| 	o.write_shift(4, r.s.r); | ||||
| @ -151,13 +149,12 @@ function write_RfX(r/*:Range*/, o) { | ||||
| var parse_UncheckedRfX = parse_RfX; | ||||
| var write_UncheckedRfX = write_RfX; | ||||
| 
 | ||||
| /* [MS-XLSB] 2.5.171 */ | ||||
| /* [MS-XLS] 2.5.342 */ | ||||
| /* [MS-XLS] 2.5.342 ; [MS-XLSB] 2.5.171 */ | ||||
| /* 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, data, 'f'); } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.5.198.2 */ | ||||
| /* [MS-XLSB] 2.5.97.2 */ | ||||
| var BErr = { | ||||
| 	/*::[*/0x00/*::]*/: "#NULL!", | ||||
| 	/*::[*/0x07/*::]*/: "#DIV/0!", | ||||
| @ -171,7 +168,7 @@ var BErr = { | ||||
| }; | ||||
| var RBErr = evert_num(BErr); | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.321 BrtColor */ | ||||
| /* [MS-XLSB] 2.4.324 BrtColor */ | ||||
| function parse_BrtColor(data/*::, length*/) { | ||||
| 	var out = {}; | ||||
| 	var d = data.read_shift(1); | ||||
|  | ||||
| @ -184,7 +184,7 @@ var XLSFillPattern = [ | ||||
| function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); } | ||||
| 
 | ||||
| /* [MS-XLS] 2.5.161 */ | ||||
| /* [MS-XLSB] 2.5.75 */ | ||||
| /* [MS-XLSB] 2.5.75 Icv */ | ||||
| var XLSIcv = rgbify([ | ||||
| 	/* Color Constants */ | ||||
| 	0x000000, | ||||
|  | ||||
| @ -1,8 +1,7 @@ | ||||
| /* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */ | ||||
| /* 12.3 Part Summary <SpreadsheetML> */ | ||||
| /* 14.2 Part Summary <DrawingML> */ | ||||
| /* [MS-XLSX] 2.1 Part Enumerations */ | ||||
| /* [MS-XLSB] 2.1.7 Part Enumeration */ | ||||
| /* [MS-XLSX] 2.1 Part Enumerations ; [MS-XLSB] 2.1.7 Part Enumeration */ | ||||
| var ct2type/*{[string]:string}*/ = ({ | ||||
| 	/* Workbook */ | ||||
| 	"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks", | ||||
|  | ||||
| @ -213,7 +213,7 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.21 PropertySetStream */ | ||||
| function parse_PropertySetStream(file, PIDSI) { | ||||
| function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| 	var blob = file.content; | ||||
| 	if(!blob) return ({}/*:any*/); | ||||
| 	prep_blob(blob, 0); | ||||
| @ -223,7 +223,8 @@ function parse_PropertySetStream(file, PIDSI) { | ||||
| 
 | ||||
| 	/*var vers = */blob.read_shift(2); // TODO: check version
 | ||||
| 	var SystemIdentifier = blob.read_shift(4); | ||||
| 	blob.chk(CFB.utils.consts.HEADER_CLSID, 'CLSID: '); | ||||
| 	var CLSID = blob.read_shift(16); | ||||
| 	if(CLSID !== CFB.utils.consts.HEADER_CLSID && CLSID !== clsid) throw new Error("Bad PropertySet CLSID " + CLSID); | ||||
| 	NumSets = blob.read_shift(4); | ||||
| 	if(NumSets !== 1 && NumSets !== 2) throw new Error("Unrecognized #Sets: " + NumSets); | ||||
| 	FMTID0 = blob.read_shift(16); Offset0 = blob.read_shift(4); | ||||
| @ -274,7 +275,7 @@ function parse_Bes(blob/*::, length*/) { | ||||
| function write_Bes(v, t/*:string*/, o) { | ||||
| 	if(!o) o = new_buf(2); | ||||
| 	o.write_shift(1, +v); | ||||
| 	o.write_shift(1, t == 'e' ? 1 : 0); | ||||
| 	o.write_shift(1, ((t == 'e') ? 1 : 0)); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,4 @@ | ||||
| /* --- MS-XLS --- */ | ||||
| 
 | ||||
| /* 2.5.19 */ | ||||
| /* [MS-XLS] 2.5.19 */ | ||||
| function parse_XLSCell(blob/*::, length*/)/*:Cell*/ { | ||||
| 	var rw = blob.read_shift(2); // 0-indexed
 | ||||
| 	var col = blob.read_shift(2); | ||||
| @ -15,7 +13,7 @@ function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:?number*/, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.134 */ | ||||
| /* [MS-XLS] 2.5.134 */ | ||||
| function parse_frtHeader(blob) { | ||||
| 	var rt = blob.read_shift(2); | ||||
| 	var flags = blob.read_shift(2); // TODO: parse these flags
 | ||||
| @ -27,21 +25,21 @@ function parse_frtHeader(blob) { | ||||
| 
 | ||||
| function parse_OptXLUnicodeString(blob, length, opts) { return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts); } | ||||
| 
 | ||||
| /* 2.5.344 */ | ||||
| /* [MS-XLS] 2.5.344 */ | ||||
| function parse_XTI(blob, length, opts) { | ||||
| 	var w = opts.biff > 8 ? 4 : 2; | ||||
| 	var iSupBook = blob.read_shift(w), itabFirst = blob.read_shift(w,'i'), itabLast = blob.read_shift(w,'i'); | ||||
| 	return [iSupBook, itabFirst, itabLast]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.218 */ | ||||
| /* [MS-XLS] 2.5.218 */ | ||||
| function parse_RkRec(blob) { | ||||
| 	var ixfe = blob.read_shift(2); | ||||
| 	var RK = parse_RkNumber(blob); | ||||
| 	return [ixfe, RK]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.1 */ | ||||
| /* [MS-XLS] 2.5.1 */ | ||||
| function parse_AddinUdf(blob, length, opts) { | ||||
| 	blob.l += 4; length -= 4; | ||||
| 	var l = blob.l + length; | ||||
| @ -53,7 +51,7 @@ function parse_AddinUdf(blob, length, opts) { | ||||
| 	return udfName; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.209 TODO: Check sizes */ | ||||
| /* [MS-XLS] 2.5.209 TODO: Check sizes */ | ||||
| function parse_Ref8U(blob/*::, length*/) { | ||||
| 	var rwFirst = blob.read_shift(2); | ||||
| 	var rwLast = blob.read_shift(2); | ||||
| @ -70,7 +68,7 @@ function write_Ref8U(r/*:Range*/, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.211 */ | ||||
| /* [MS-XLS] 2.5.211 */ | ||||
| function parse_RefU(blob/*::, length*/) { | ||||
| 	var rwFirst = blob.read_shift(2); | ||||
| 	var rwLast = blob.read_shift(2); | ||||
| @ -79,10 +77,10 @@ function parse_RefU(blob/*::, length*/) { | ||||
| 	return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}}; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.207 */ | ||||
| /* [MS-XLS] 2.5.207 */ | ||||
| var parse_Ref = parse_RefU; | ||||
| 
 | ||||
| /* 2.5.143 */ | ||||
| /* [MS-XLS] 2.5.143 */ | ||||
| function parse_FtCmo(blob/*::, length*/) { | ||||
| 	blob.l += 4; | ||||
| 	var ot = blob.read_shift(2); | ||||
| @ -92,7 +90,7 @@ function parse_FtCmo(blob/*::, length*/) { | ||||
| 	return [id, ot, flags]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.149 */ | ||||
| /* [MS-XLS] 2.5.149 */ | ||||
| function parse_FtNts(blob) { | ||||
| 	var out = {}; | ||||
| 	blob.l += 4; | ||||
| @ -102,7 +100,7 @@ function parse_FtNts(blob) { | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.142 */ | ||||
| /* [MS-XLS] 2.5.142 */ | ||||
| function parse_FtCf(blob) { | ||||
| 	var out = {}; | ||||
| 	blob.l += 4; | ||||
| @ -110,7 +108,7 @@ function parse_FtCf(blob) { | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.140 - 2.5.154 and friends */ | ||||
| /* [MS-XLS] 2.5.140 - 2.5.154 and friends */ | ||||
| function parse_FtSkip(blob) { blob.l += 2; blob.l += blob.read_shift(2); } | ||||
| var FtTab = { | ||||
| 	/*::[*/0x00/*::]*/: parse_FtSkip,      /* FtEnd */ | ||||
| @ -149,7 +147,7 @@ function parse_FtArray(blob, length/*::, ot*/) { | ||||
| 
 | ||||
| /* --- 2.4 Records --- */ | ||||
| 
 | ||||
| /* 2.4.21 */ | ||||
| /* [MS-XLS] 2.4.21 */ | ||||
| function parse_BOF(blob, length) { | ||||
| 	var o = {BIFFVer:0, dt:0}; | ||||
| 	o.BIFFVer = blob.read_shift(2); length -= 2; | ||||
| @ -191,7 +189,7 @@ function write_BOF(wb/*:Workbook*/, t/*:number*/, o) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.4.146 */ | ||||
| /* [MS-XLS] 2.4.146 */ | ||||
| function parse_InterfaceHdr(blob, length) { | ||||
| 	if(length === 0) return 0x04b0; | ||||
| 	if((blob.read_shift(2))!==0x04b0){/* empty */} | ||||
| @ -199,7 +197,7 @@ function parse_InterfaceHdr(blob, length) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.4.349 */ | ||||
| /* [MS-XLS] 2.4.349 */ | ||||
| function parse_WriteAccess(blob, length, opts) { | ||||
| 	if(opts.enc) { blob.l += length; return ""; } | ||||
| 	var l = blob.l; | ||||
| @ -212,20 +210,20 @@ function write_WriteAccess(s/*:string*/, opts) { | ||||
| 	var b8 = !opts || opts.biff == 8; | ||||
| 	var o = new_buf(b8 ? 112 : 54); | ||||
| 	o.write_shift(opts.biff == 8 ? 2 : 1, 7); | ||||
| 	o.write_shift(1, 0); | ||||
| 	if(b8) o.write_shift(1, 0); | ||||
| 	o.write_shift(4, 0x33336853); | ||||
| 	o.write_shift(4, 0x00534A74); | ||||
| 	while(o.l < o.length) o.write_shift(1, 0); | ||||
| 	o.write_shift(4, (0x00534A74 | (b8 ? 0 : 0x20000000))); | ||||
| 	while(o.l < o.length) o.write_shift(1, (b8 ? 0 : 32)); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.351 */ | ||||
| /* [MS-XLS] 2.4.351 */ | ||||
| function parse_WsBool(blob, length, opts) { | ||||
| 	var flags = opts && opts.biff == 8 || length == 2 ? blob.read_shift(2) : (blob.l += length, 0); | ||||
| 	return { fDialog: flags & 0x10 }; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.28 */ | ||||
| /* [MS-XLS] 2.4.28 */ | ||||
| function parse_BoundSheet8(blob, length, opts) { | ||||
| 	var pos = blob.read_shift(4); | ||||
| 	var hidden = blob.read_shift(1) & 0x03; | ||||
| @ -253,7 +251,7 @@ function write_BoundSheet8(data, opts) { | ||||
| 	out.l = o.l; return out; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.265 TODO */ | ||||
| /* [MS-XLS] 2.4.265 TODO */ | ||||
| function parse_SST(blob, length)/*:SST*/ { | ||||
| 	var end = blob.l + length; | ||||
| 	var cnt = blob.read_shift(4); | ||||
| @ -266,7 +264,7 @@ function parse_SST(blob, length)/*:SST*/ { | ||||
| 	return strs; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.107 */ | ||||
| /* [MS-XLS] 2.4.107 */ | ||||
| function parse_ExtSST(blob, length) { | ||||
| 	var extsst = {}; | ||||
| 	extsst.dsst = blob.read_shift(2); | ||||
| @ -275,7 +273,7 @@ function parse_ExtSST(blob, length) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.4.221 TODO: check BIFF2-4 */ | ||||
| /* [MS-XLS] 2.4.221 TODO: check BIFF2-4 */ | ||||
| function parse_Row(blob) { | ||||
| 	var z = ({}/*:any*/); | ||||
| 	z.r = blob.read_shift(2); | ||||
| @ -293,7 +291,7 @@ function parse_Row(blob) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.4.125 */ | ||||
| /* [MS-XLS] 2.4.125 */ | ||||
| function parse_ForceFullCalculation(blob) { | ||||
| 	var header = parse_frtHeader(blob); | ||||
| 	if(header.type != 0x08A3) throw new Error("Invalid Future Record " + header.type); | ||||
| @ -305,13 +303,13 @@ function parse_ForceFullCalculation(blob) { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* 2.4.215 rt */ | ||||
| /* [MS-XLS] 2.4.215 rt */ | ||||
| function parse_RecalcId(blob) { | ||||
| 	blob.read_shift(2); | ||||
| 	return blob.read_shift(4); | ||||
| } | ||||
| 
 | ||||
| /* 2.4.87 */ | ||||
| /* [MS-XLS] 2.4.87 */ | ||||
| function parse_DefaultRowHeight(blob, length, opts) { | ||||
| 	var f = 0; | ||||
| 	if(!(opts && opts.biff == 2)) { | ||||
| @ -325,7 +323,7 @@ function parse_DefaultRowHeight(blob, length, opts) { | ||||
| 	return [fl, miyRw]; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.345 TODO */ | ||||
| /* [MS-XLS] 2.4.345 TODO */ | ||||
| function parse_Window1(blob) { | ||||
| 	var xWn = blob.read_shift(2), yWn = blob.read_shift(2), dxWn = blob.read_shift(2), dyWn = blob.read_shift(2); | ||||
| 	var flags = blob.read_shift(2), iTabCur = blob.read_shift(2), iTabFirst = blob.read_shift(2); | ||||
| @ -346,7 +344,7 @@ function write_Window1(/*::opts*/) { | ||||
| 	o.write_shift(2, 0x01f4); | ||||
| 	return o; | ||||
| } | ||||
| /* 2.4.346 TODO */ | ||||
| /* [MS-XLS] 2.4.346 TODO */ | ||||
| function parse_Window2(blob, length, opts) { | ||||
| 	if(opts && opts.biff >= 2 && opts.biff < 8) return {}; | ||||
| 	var f = blob.read_shift(2); | ||||
| @ -363,13 +361,13 @@ function write_Window2(view) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.122 TODO */ | ||||
| /* [MS-XLS] 2.4.122 TODO */ | ||||
| function parse_Font(blob, length, opts) { | ||||
| 	var o/*:any*/ = { | ||||
| 		dyHeight: blob.read_shift(2), | ||||
| 		fl: blob.read_shift(2) | ||||
| 	}; | ||||
| 	switch(opts && opts.biff || 8) { | ||||
| 	switch((opts && opts.biff) || 8) { | ||||
| 		case 2: break; | ||||
| 		case 3: case 4: blob.l += 2; break; | ||||
| 		default: blob.l += 10; break; | ||||
| @ -377,15 +375,29 @@ function parse_Font(blob, length, opts) { | ||||
| 	o.name = parse_ShortXLUnicodeString(blob, 0, opts); | ||||
| 	return o; | ||||
| } | ||||
| function write_Font(data, opts) { | ||||
| 	var name = data.name || "Arial"; | ||||
| 	var b5 = (opts && (opts.biff == 5)), w = (b5 ? (15 + name.length) : (16 + 2 * name.length)); | ||||
| 	var o = new_buf(w); | ||||
| 	o.write_shift(2, (data.sz || 12) * 20); | ||||
| 	o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 400); | ||||
| 	o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 0); | ||||
| 	o.write_shift(1, name.length); | ||||
| 	if(!b5) o.write_shift(1, 1); | ||||
| 	o.write_shift((b5 ? 1 : 2) * name.length, name, (b5 ? "sbcs" : "utf16le")); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.149 */ | ||||
| /* [MS-XLS] 2.4.149 */ | ||||
| function parse_LabelSst(blob) { | ||||
| 	var cell = parse_XLSCell(blob); | ||||
| 	cell.isst = blob.read_shift(4); | ||||
| 	return cell; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.148 */ | ||||
| /* [MS-XLS] 2.4.148 */ | ||||
| function parse_Label(blob, length, opts) { | ||||
| 	var target = blob.l + length; | ||||
| 	var cell = parse_XLSCell(blob, 6); | ||||
| @ -405,23 +417,26 @@ function write_Label(R/*:number*/, C/*:number*/, v/*:string*/, os/*:number*/, op | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.4.126 Number Formats */ | ||||
| /* [MS-XLS] 2.4.126 Number Formats */ | ||||
| function parse_Format(blob, length, opts) { | ||||
| 	var numFmtId = blob.read_shift(2); | ||||
| 	var fmtstr = parse_XLUnicodeString2(blob, 0, opts); | ||||
| 	return [numFmtId, fmtstr]; | ||||
| } | ||||
| function write_Format(i/*:number*/, f/*:string*/, o) { | ||||
| 	if(!o) o = new_buf(6 + 4 * f.length); | ||||
| function write_Format(i/*:number*/, f/*:string*/, opts, o) { | ||||
| 	var b5 = (opts && (opts.biff == 5)); | ||||
| 	if(!o) o = new_buf(b5 ? (3 + f.length) : (5 + 2 * f.length)); | ||||
| 	o.write_shift(2, i); | ||||
| 	write_XLUnicodeString(f, null, o); | ||||
| 	o.write_shift((b5 ? 1 : 2), f.length); | ||||
| 	if(!b5) o.write_shift(1, 1); | ||||
| 	o.write_shift((b5 ? 1 : 2) * f.length, f, (b5 ? 'sbcs' : 'utf16le')); | ||||
| 	var out = (o.length > o.l) ? o.slice(0, o.l) : o; | ||||
| 	if(o.l == null) o.l = o.length; | ||||
| 	if(out.l == null) out.l = out.length; | ||||
| 	return out; | ||||
| } | ||||
| var parse_BIFF2Format = parse_XLUnicodeString2; | ||||
| 
 | ||||
| /* 2.4.90 */ | ||||
| /* [MS-XLS] 2.4.90 */ | ||||
| function parse_Dimensions(blob, length, opts) { | ||||
| 	var end = blob.l + length; | ||||
| 	var w = opts.biff == 8 || !opts.biff ? 4 : 2; | ||||
| @ -441,14 +456,14 @@ function write_Dimensions(range, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.220 */ | ||||
| /* [MS-XLS] 2.4.220 */ | ||||
| function parse_RK(blob) { | ||||
| 	var rw = blob.read_shift(2), col = blob.read_shift(2); | ||||
| 	var rkrec = parse_RkRec(blob); | ||||
| 	return {r:rw, c:col, ixfe:rkrec[0], rknum:rkrec[1]}; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.175 */ | ||||
| /* [MS-XLS] 2.4.175 */ | ||||
| function parse_MulRk(blob, length) { | ||||
| 	var target = blob.l + length - 2; | ||||
| 	var rw = blob.read_shift(2), col = blob.read_shift(2); | ||||
| @ -459,7 +474,7 @@ function parse_MulRk(blob, length) { | ||||
| 	if(rkrecs.length != lastcol - col + 1) throw new Error("MulRK length mismatch"); | ||||
| 	return {r:rw, c:col, C:lastcol, rkrec:rkrecs}; | ||||
| } | ||||
| /* 2.4.174 */ | ||||
| /* [MS-XLS] 2.4.174 */ | ||||
| function parse_MulBlank(blob, length) { | ||||
| 	var target = blob.l + length - 2; | ||||
| 	var rw = blob.read_shift(2), col = blob.read_shift(2); | ||||
| @ -471,7 +486,7 @@ function parse_MulBlank(blob, length) { | ||||
| 	return {r:rw, c:col, C:lastcol, ixfe:ixfes}; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.20 2.5.249 TODO: interpret values here */ | ||||
| /* [MS-XLS] 2.5.20 2.5.249 TODO: interpret values here */ | ||||
| function parse_CellStyleXF(blob, length, style, opts) { | ||||
| 	var o = {}; | ||||
| 	var a = blob.read_shift(4), b = blob.read_shift(4); | ||||
| @ -515,7 +530,7 @@ function parse_CellStyleXF(blob, length, style, opts) { | ||||
| //function parse_CellXF(blob, length, opts) {return parse_CellStyleXF(blob,length,0, opts);}
 | ||||
| //function parse_StyleXF(blob, length, opts) {return parse_CellStyleXF(blob,length,1, opts);}
 | ||||
| 
 | ||||
| /* 2.4.353 TODO: actually do this right */ | ||||
| /* [MS-XLS] 2.4.353 TODO: actually do this right */ | ||||
| function parse_XF(blob, length, opts) { | ||||
| 	var o = {}; | ||||
| 	o.ifnt = blob.read_shift(2); o.numFmtId = blob.read_shift(2); o.flags = blob.read_shift(2); | ||||
| @ -524,19 +539,25 @@ function parse_XF(blob, length, opts) { | ||||
| 	o.data = parse_CellStyleXF(blob, length, o.fStyle, opts); | ||||
| 	return o; | ||||
| } | ||||
| function write_XF(data, ixfeP, o) { | ||||
| 	if(!o) o = new_buf(20); | ||||
| 	o.write_shift(2, 0); | ||||
| 	o.write_shift(2, data.numFmtId||0); | ||||
| function write_XF(data, ixfeP, opts, o) { | ||||
| 	var b5 = (opts && (opts.biff == 5)); | ||||
| 	if(!o) o = new_buf(b5 ? 16 : 20); | ||||
| 	o.write_shift(2, 0); | ||||
| 	if(data.style) { | ||||
| 		o.write_shift(2, (data.numFmtId||0)); | ||||
| 		o.write_shift(2, 0xFFF4); | ||||
| 	} else { | ||||
| 		o.write_shift(2, (data.numFmtId||0)); | ||||
| 		o.write_shift(2, (ixfeP<<4)); | ||||
| 	} | ||||
| 	o.write_shift(4, 0); | ||||
| 	o.write_shift(4, 0); | ||||
| 	o.write_shift(4, 0); | ||||
| 	if(!b5) o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 0); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.134 */ | ||||
| /* [MS-XLS] 2.4.134 */ | ||||
| function parse_Guts(blob) { | ||||
| 	blob.l += 4; | ||||
| 	var out = [blob.read_shift(2), blob.read_shift(2)]; | ||||
| @ -553,7 +574,7 @@ function write_Guts(guts/*:Array<number>*/) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.24 */ | ||||
| /* [MS-XLS] 2.4.24 */ | ||||
| function parse_BoolErr(blob, length, opts) { | ||||
| 	var cell = parse_XLSCell(blob, 6); | ||||
| 	if(opts.biff == 2) ++blob.l; | ||||
| @ -569,7 +590,7 @@ function write_BoolErr(R/*:number*/, C/*:number*/, v, os/*:number*/, opts, t/*:s | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.180 Number */ | ||||
| /* [MS-XLS] 2.4.180 Number */ | ||||
| function parse_Number(blob) { | ||||
| 	var cell = parse_XLSCell(blob, 6); | ||||
| 	var xnum = parse_Xnum(blob, 8); | ||||
| @ -585,7 +606,7 @@ function write_Number(R/*:number*/, C/*:number*/, v, os/*:: :number, opts*/) { | ||||
| 
 | ||||
| var parse_XLHeaderFooter = parse_OptXLUnicodeString; // TODO: parse 2.4.136
 | ||||
| 
 | ||||
| /* 2.4.271 */ | ||||
| /* [MS-XLS] 2.4.271 */ | ||||
| function parse_SupBook(blob, length, opts) { | ||||
| 	var end = blob.l + length; | ||||
| 	var ctab = blob.read_shift(2); | ||||
| @ -600,7 +621,7 @@ function parse_SupBook(blob, length, opts) { | ||||
| 	return [cch, ctab, virtPath, rgst]; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.105 TODO */ | ||||
| /* [MS-XLS] 2.4.105 TODO */ | ||||
| function parse_ExternName(blob, length, opts) { | ||||
| 	var flags = blob.read_shift(2); | ||||
| 	var body; | ||||
| @ -620,7 +641,7 @@ function parse_ExternName(blob, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.150 TODO */ | ||||
| /* [MS-XLS] 2.4.150 TODO */ | ||||
| var XLSLblBuiltIn = [ | ||||
| 	"_xlnm.Consolidate_Area", | ||||
| 	"_xlnm.Auto_Open", | ||||
| @ -662,7 +683,7 @@ function parse_Lbl(blob, length, opts) { | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.106 TODO: verify filename encoding */ | ||||
| /* [MS-XLS] 2.4.106 TODO: verify filename encoding */ | ||||
| function parse_ExternSheet(blob, length, opts) { | ||||
| 	if(opts.biff < 8) return parse_BIFF5ExternSheet(blob, length, opts); | ||||
| 	var o = [], target = blob.l + length, len = blob.read_shift(opts.biff > 8 ? 4 : 2); | ||||
| @ -677,7 +698,7 @@ function parse_BIFF5ExternSheet(blob, length, opts) { | ||||
| 	return o.charCodeAt(0) == 0x03 ? o.slice(1) : o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.176 TODO: check older biff */ | ||||
| /* [MS-XLS] 2.4.176 TODO: check older biff */ | ||||
| function parse_NameCmt(blob, length, opts) { | ||||
| 	if(opts.biff < 8) { blob.l += length; return; } | ||||
| 	var cchName = blob.read_shift(2); | ||||
| @ -687,7 +708,7 @@ function parse_NameCmt(blob, length, opts) { | ||||
| 	return [name, comment]; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.260 */ | ||||
| /* [MS-XLS] 2.4.260 */ | ||||
| function parse_ShrFmla(blob, length, opts) { | ||||
| 	var ref = parse_RefU(blob, 6); | ||||
| 	blob.l++; | ||||
| @ -696,7 +717,7 @@ function parse_ShrFmla(blob, length, opts) { | ||||
| 	return [parse_SharedParsedFormula(blob, length, opts), cUse, ref]; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.4 TODO */ | ||||
| /* [MS-XLS] 2.4.4 TODO */ | ||||
| function parse_Array(blob, length, opts) { | ||||
| 	var ref = parse_Ref(blob, 6); | ||||
| 	/* TODO: fAlwaysCalc */ | ||||
| @ -708,7 +729,7 @@ function parse_Array(blob, length, opts) { | ||||
| 	return [ref, parse_ArrayParsedFormula(blob, length, opts, ref)]; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.173 */ | ||||
| /* [MS-XLS] 2.4.173 */ | ||||
| function parse_MTRSettings(blob) { | ||||
| 	var fMTREnabled = blob.read_shift(4) !== 0x00; | ||||
| 	var fUserSetThreadCount = blob.read_shift(4) !== 0x00; | ||||
| @ -716,7 +737,7 @@ function parse_MTRSettings(blob) { | ||||
| 	return [fMTREnabled, fUserSetThreadCount, cUserThreadCount]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.186 TODO: BIFF5 */ | ||||
| /* [MS-XLS] 2.5.186 TODO: BIFF5 */ | ||||
| function parse_NoteSh(blob, length, opts) { | ||||
| 	if(opts.biff < 8) return; | ||||
| 	var row = blob.read_shift(2), col = blob.read_shift(2); | ||||
| @ -726,13 +747,13 @@ function parse_NoteSh(blob, length, opts) { | ||||
| 	return [{r:row,c:col}, stAuthor, idObj, flags]; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.179 */ | ||||
| /* [MS-XLS] 2.4.179 */ | ||||
| function parse_Note(blob, length, opts) { | ||||
| 	/* TODO: Support revisions */ | ||||
| 	return parse_NoteSh(blob, length, opts); | ||||
| } | ||||
| 
 | ||||
| /* 2.4.168 */ | ||||
| /* [MS-XLS] 2.4.168 */ | ||||
| function parse_MergeCells(blob, length)/*:Array<Range>*/ { | ||||
| 	var merges/*:Array<Range>*/ = []; | ||||
| 	var cmcs = blob.read_shift(2); | ||||
| @ -746,7 +767,7 @@ function write_MergeCells(merges/*:Array<Range>*/) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.181 TODO: parse all the things! */ | ||||
| /* [MS-XLS] 2.4.181 TODO: parse all the things! */ | ||||
| function parse_Obj(blob, length, opts) { | ||||
| 	if(opts && opts.biff < 8) return parse_BIFF5Obj(blob, length, opts); | ||||
| 	var cmo = parse_FtCmo(blob, 22); // id, ot, flags
 | ||||
| @ -791,7 +812,7 @@ function parse_BIFF5Obj(blob, length, opts) { | ||||
| 	return { cmo: [id, ot, grbit], ft:fts }; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.329 TODO: parse properly */ | ||||
| /* [MS-XLS] 2.4.329 TODO: parse properly */ | ||||
| function parse_TxO(blob, length, opts) { | ||||
| 	var s = blob.l; | ||||
| 	var texts = ""; | ||||
| @ -820,7 +841,7 @@ try { | ||||
| 	} | ||||
| 
 | ||||
| 	blob.l = s + length; | ||||
| 	/* 2.5.272 TxORuns */ | ||||
| 	/* [MS-XLS] 2.5.272 TxORuns */ | ||||
| //	var rgTxoRuns = [];
 | ||||
| //	for(var j = 0; j != cbRuns/8-1; ++j) blob.l += 8;
 | ||||
| //	var cchText2 = blob.read_shift(2);
 | ||||
| @ -831,7 +852,7 @@ try { | ||||
| } catch(e) { blob.l = s + length; return { t: texts }; } | ||||
| } | ||||
| 
 | ||||
| /* 2.4.140 */ | ||||
| /* [MS-XLS] 2.4.140 */ | ||||
| function parse_HLink(blob, length) { | ||||
| 	var ref = parse_Ref8U(blob, 8); | ||||
| 	blob.l += 16; /* CLSID */ | ||||
| @ -849,7 +870,7 @@ function write_HLink(hl) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.4.141 */ | ||||
| /* [MS-XLS] 2.4.141 */ | ||||
| function parse_HLinkTooltip(blob, length) { | ||||
| 	blob.read_shift(2); | ||||
| 	var ref = parse_Ref8U(blob, 8); | ||||
| @ -869,7 +890,7 @@ function write_HLinkTooltip(hl) { | ||||
| 	return O; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.63 */ | ||||
| /* [MS-XLS] 2.4.63 */ | ||||
| function parse_Country(blob)/*:[string|number, string|number]*/ { | ||||
| 	var o = [0,0], d; | ||||
| 	d = blob.read_shift(2); o[0] = CountryEnum[d] || d; | ||||
| @ -883,7 +904,7 @@ function write_Country(o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.50 ClrtClient */ | ||||
| /* [MS-XLS] 2.4.50 ClrtClient */ | ||||
| function parse_ClrtClient(blob) { | ||||
| 	var ccv = blob.read_shift(2); | ||||
| 	var o = []; | ||||
| @ -891,7 +912,7 @@ function parse_ClrtClient(blob) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.188 */ | ||||
| /* [MS-XLS] 2.4.188 */ | ||||
| function parse_Palette(blob) { | ||||
| 	var ccv = blob.read_shift(2); | ||||
| 	var o = []; | ||||
| @ -899,7 +920,7 @@ function parse_Palette(blob) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.354 */ | ||||
| /* [MS-XLS] 2.4.354 */ | ||||
| function parse_XFCRC(blob) { | ||||
| 	blob.l += 2; | ||||
| 	var o = {cxfs:0, crc:0}; | ||||
| @ -908,7 +929,7 @@ function parse_XFCRC(blob) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.53 TODO: parse flags */ | ||||
| /* [MS-XLS] 2.4.53 TODO: parse flags */ | ||||
| /* [MS-XLSB] 2.4.323 TODO: parse flags */ | ||||
| function parse_ColInfo(blob, length, opts) { | ||||
| 	if(!opts.cellStyles) return parsenoop(blob, length); | ||||
| @ -922,9 +943,10 @@ function parse_ColInfo(blob, length, opts) { | ||||
| 	return {s:colFirst, e:colLast, w:coldx, ixfe:ixfe, flags:flags}; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.257 */ | ||||
| function parse_Setup(blob/*, length*/) { | ||||
| /* [MS-XLS] 2.4.257 */ | ||||
| function parse_Setup(blob, length) { | ||||
| 	var o = {}; | ||||
| 	if(length < 32) return o; | ||||
| 	blob.l += 16; | ||||
| 	o.header = parse_Xnum(blob, 8); | ||||
| 	o.footer = parse_Xnum(blob, 8); | ||||
| @ -932,7 +954,7 @@ function parse_Setup(blob/*, length*/) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.261 */ | ||||
| /* [MS-XLS] 2.4.261 */ | ||||
| function parse_ShtProps(blob, length, opts) { | ||||
| 	var def = {area:false}; | ||||
| 	if(opts.biff != 5) { blob.l += length; return def; } | ||||
| @ -941,16 +963,16 @@ function parse_ShtProps(blob, length, opts) { | ||||
| 	return def; | ||||
| } | ||||
| 
 | ||||
| /* 2.4.241 */ | ||||
| /* [MS-XLS] 2.4.241 */ | ||||
| function write_RRTabId(n/*:number*/) { | ||||
| 	var out = new_buf(2 * n); | ||||
| 	for(var i = 0; i < n; ++i) out.write_shift(2, i+1); | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| var parse_Blank = parse_XLSCell; /* 2.4.20 Just the cell */ | ||||
| var parse_Scl = parseuint16a; /* 2.4.247 num, den */ | ||||
| var parse_String = parse_XLUnicodeString; /* 2.4.268 */ | ||||
| var parse_Blank = parse_XLSCell; /* [MS-XLS] 2.4.20 Just the cell */ | ||||
| var parse_Scl = parseuint16a; /* [MS-XLS] 2.4.247 num, den */ | ||||
| var parse_String = parse_XLUnicodeString; /* [MS-XLS] 2.4.268 */ | ||||
| 
 | ||||
| /* --- Specific to versions before BIFF8 --- */ | ||||
| function parse_ImData(blob) { | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* [MS-XLSB] 2.4.219 BrtBeginSst */ | ||||
| /* [MS-XLSB] 2.4.221 BrtBeginSst */ | ||||
| function parse_BrtBeginSst(data) { | ||||
| 	return [data.read_shift(4), data.read_shift(4)]; | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* [MS-XLSB] 2.4.651 BrtFmt */ | ||||
| /* [MS-XLSB] 2.4.657 BrtFmt */ | ||||
| function parse_BrtFmt(data, length/*:number*/) { | ||||
| 	var numFmtId = data.read_shift(2); | ||||
| 	var stFmtCode = parse_XLWideString(data,length-2); | ||||
| @ -13,7 +13,7 @@ function write_BrtFmt(i/*:number*/, f/*:string*/, o) { | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.653 BrtFont TODO */ | ||||
| /* [MS-XLSB] 2.4.659 BrtFont TODO */ | ||||
| function parse_BrtFont(data, length/*:number*/, opts) { | ||||
| 	var out = ({}/*:any*/); | ||||
| 
 | ||||
| @ -80,7 +80,7 @@ function write_BrtFont(font, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.644 BrtFill */ | ||||
| /* [MS-XLSB] 2.4.650 BrtFill */ | ||||
| var XLSBFillPTNames = [ | ||||
| 	"none", | ||||
| 	"solid", | ||||
| @ -134,7 +134,7 @@ function write_BrtFill(fill, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.816 BrtXF */ | ||||
| /* [MS-XLSB] 2.4.824 BrtXF */ | ||||
| function parse_BrtXF(data, length/*:number*/) { | ||||
| 	var tgt = data.l + length; | ||||
| 	var ixfeParent = data.read_shift(2); | ||||
| @ -167,7 +167,7 @@ function write_Blxf(data, o) { | ||||
| 	o.write_shift(4, 0); /* color */ | ||||
| 	return o; | ||||
| } | ||||
| /* [MS-XLSB] 2.4.299 BrtBorder TODO */ | ||||
| /* [MS-XLSB] 2.4.302 BrtBorder TODO */ | ||||
| var parse_BrtBorder = parsenoop; | ||||
| function write_BrtBorder(border, o) { | ||||
| 	if(!o) o = new_buf(51); | ||||
| @ -180,7 +180,7 @@ function write_BrtBorder(border, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.755 BrtStyle TODO */ | ||||
| /* [MS-XLSB] 2.4.763 BrtStyle TODO */ | ||||
| function write_BrtStyle(style, o) { | ||||
| 	if(!o) o = new_buf(12+4*10); | ||||
| 	o.write_shift(4, style.xfId); | ||||
| @ -191,7 +191,7 @@ function write_BrtStyle(style, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.269 BrtBeginTableStyles */ | ||||
| /* [MS-XLSB] 2.4.272 BrtBeginTableStyles */ | ||||
| function write_BrtBeginTableStyles(cnt, defTableStyle, defPivotStyle) { | ||||
| 	var o = new_buf(4+256*2*4); | ||||
| 	o.write_shift(4, cnt); | ||||
|  | ||||
| @ -41,17 +41,17 @@ function parse_XFExtGradient(blob, length) { | ||||
| 	return parsenoop(blob, length); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.108 */ | ||||
| /* [MS-XLS] 2.5.108 */ | ||||
| function parse_ExtProp(blob/*::, length*/)/*:Array<any>*/ { | ||||
| 	var extType = blob.read_shift(2); | ||||
| 	var cb = blob.read_shift(2); | ||||
| 	var cb = blob.read_shift(2) - 4; | ||||
| 	var o = [extType]; | ||||
| 	switch(extType) { | ||||
| 		case 0x04: case 0x05: case 0x07: case 0x08: | ||||
| 		case 0x09: case 0x0A: case 0x0B: case 0x0D: | ||||
| 			o[1] = parse_FullColorExt(blob, cb); break; | ||||
| 		case 0x06: o[1] = parse_XFExtGradient(blob, cb); break; | ||||
| 		case 0x0E: case 0x0F: o[1] = blob.read_shift(cb === 5 ? 1 : 2); break; | ||||
| 		case 0x0E: case 0x0F: o[1] = blob.read_shift(cb === 1 ? 1 : 2); break; | ||||
| 		default: throw new Error("Unrecognized ExtProp type: " + extType + " " + cb); | ||||
| 	} | ||||
| 	return o; | ||||
|  | ||||
| @ -19,7 +19,7 @@ function write_BrtBeginComment(data, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.324 BrtCommentAuthor */ | ||||
| /* [MS-XLSB] 2.4.327 BrtCommentAuthor */ | ||||
| var parse_BrtCommentAuthor = parse_XLWideString; | ||||
| function write_BrtCommentAuthor(data) { return write_XLWideString(data.slice(0, 54)); } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										281
									
								
								bits/62_fxls.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										281
									
								
								bits/62_fxls.js
									
									
									
									
									
								
							| @ -1,17 +1,12 @@ | ||||
| /* --- formula references point to MS-XLS --- */ | ||||
| /* Small helpers */ | ||||
| function parseread1(blob) { blob.l+=1; return; } | ||||
| 
 | ||||
| /* Rgce Helpers */ | ||||
| 
 | ||||
| /* 2.5.51 */ | ||||
| /* [MS-XLS] 2.5.51 */ | ||||
| function parse_ColRelU(blob, length) { | ||||
| 	var c = blob.read_shift(length == 1 ? 1 : 2); | ||||
| 	return [c & 0x3FFF, (c >> 14) & 1, (c >> 15) & 1]; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.5.198.105 */ | ||||
| /* [MS-XLSB] 2.5.97.89 */ | ||||
| /* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.89 */ | ||||
| function parse_RgceArea(blob, length, opts) { | ||||
| 	var w = 2; | ||||
| 	if(opts) { | ||||
| @ -31,7 +26,7 @@ function parse_RgceArea_BIFF2(blob/*::, length, opts*/) { | ||||
| 	return { s:{r:r[0], c:c, cRel:r[1], rRel:r[2]}, e:{r:R[0], c:C, cRel:R[1], rRel:R[2]} }; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.105 TODO */ | ||||
| /* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.90 */ | ||||
| function parse_RgceAreaRel(blob, length/*::, opts*/) { | ||||
| 	var r=blob.read_shift(length == 12 ? 4 : 2), R=blob.read_shift(length == 12 ? 4 : 2); | ||||
| 	var c=parse_ColRelU(blob, 2); | ||||
| @ -39,7 +34,7 @@ function parse_RgceAreaRel(blob, length/*::, opts*/) { | ||||
| 	return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} }; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.109 */ | ||||
| /* [MS-XLS] 2.5.198.109 ; [MS-XLSB] 2.5.97.91 */ | ||||
| function parse_RgceLoc(blob, length, opts) { | ||||
| 	if(opts && opts.biff >= 2 && opts.biff <= 5) return parse_RgceLoc_BIFF2(blob, length, opts); | ||||
| 	var r = blob.read_shift(opts && opts.biff == 12 ? 4 : 2); | ||||
| @ -52,15 +47,14 @@ function parse_RgceLoc_BIFF2(blob/*::, length, opts*/) { | ||||
| 	return {r:r[0], c:c, cRel:r[1], rRel:r[2]}; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.107 , 2.5.47 */ | ||||
| /* [MS-XLS] 2.5.198.107, 2.5.47 */ | ||||
| function parse_RgceElfLoc(blob/*::, length, opts*/) { | ||||
| 	var r = blob.read_shift(2); | ||||
| 	var c = blob.read_shift(2); | ||||
| 	return {r:r, c:c & 0xFF, fQuoted:!!(c & 0x4000), cRel:c>>15, rRel:c>>15 }; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.5.198.111 TODO */ | ||||
| /* [MS-XLSB] 2.5.97.92 TODO */ | ||||
| /* [MS-XLS] 2.5.198.111 ; [MS-XLSB] 2.5.97.92 TODO */ | ||||
| function parse_RgceLocRel(blob, length, opts) { | ||||
| 	var biff = opts && opts.biff ? opts.biff : 8; | ||||
| 	if(biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts); | ||||
| @ -82,17 +76,14 @@ function parse_RgceLocRel_BIFF2(blob/*::, length:number, opts*/) { | ||||
| 	return {r:rl,c:c,cRel:cRel,rRel:rRel}; | ||||
| } | ||||
| 
 | ||||
| /* Ptg Tokens */ | ||||
| 
 | ||||
| /* 2.5.198.27 */ | ||||
| /* [MS-XLS] 2.5.198.27 ; [MS-XLSB] 2.5.97.18 */ | ||||
| function parse_PtgArea(blob, length, opts) { | ||||
| 	var type = (blob[blob.l++] & 0x60) >> 5; | ||||
| 	var area = parse_RgceArea(blob, opts.biff >= 2 && opts.biff <= 5 ? 6 : 8, opts); | ||||
| 	return [type, area]; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.5.198.28 */ | ||||
| /* [MS-XLSB] 2.5.97.19 */ | ||||
| /* [MS-XLS] 2.5.198.28 ; [MS-XLSB] 2.5.97.19 */ | ||||
| function parse_PtgArea3d(blob, length, opts) { | ||||
| 	var type = (blob[blob.l++] & 0x60) >> 5; | ||||
| 	var ixti = blob.read_shift(2, 'i'); | ||||
| @ -105,13 +96,13 @@ function parse_PtgArea3d(blob, length, opts) { | ||||
| 	return [type, ixti, area]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.29 */ | ||||
| /* [MS-XLS] 2.5.198.29 ; [MS-XLSB] 2.5.97.20 */ | ||||
| function parse_PtgAreaErr(blob, length, opts) { | ||||
| 	var type = (blob[blob.l++] & 0x60) >> 5; | ||||
| 	blob.l += opts && opts.biff > 8 ? 12 : 8; | ||||
| 	return [type]; | ||||
| } | ||||
| /* 2.5.198.30 */ | ||||
| /* [MS-XLS] 2.5.198.30 ; [MS-XLSB] 2.5.97.21 */ | ||||
| function parse_PtgAreaErr3d(blob, length, opts) { | ||||
| 	var type = (blob[blob.l++] & 0x60) >> 5; | ||||
| 	var ixti = blob.read_shift(2); | ||||
| @ -124,22 +115,21 @@ function parse_PtgAreaErr3d(blob, length, opts) { | ||||
| 	return [type, ixti]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.31 */ | ||||
| /* [MS-XLS] 2.5.198.31 ; [MS-XLSB] 2.5.97.22 */ | ||||
| function parse_PtgAreaN(blob, length, opts) { | ||||
| 	var type = (blob[blob.l++] & 0x60) >> 5; | ||||
| 	var area = parse_RgceAreaRel(blob, opts && opts.biff > 8 ? 12 : 8, opts); | ||||
| 	return [type, area]; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.5.198.32 */ | ||||
| /* [MS-XLSB] 2.5.97.23 */ | ||||
| /* [MS-XLS] 2.5.198.32 ; [MS-XLSB] 2.5.97.23 */ | ||||
| function parse_PtgArray(blob, length, opts) { | ||||
| 	var type = (blob[blob.l++] & 0x60) >> 5; | ||||
| 	blob.l += opts.biff == 2 ? 6 : opts.biff == 12 ? 14 : 7; | ||||
| 	return [type]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.33 */ | ||||
| /* [MS-XLS] 2.5.198.33 ; [MS-XLSB] 2.5.97.24 */ | ||||
| function parse_PtgAttrBaxcel(blob) { | ||||
| 	var bitSemi = blob[blob.l+1] & 0x01; /* 1 = volatile */ | ||||
| 	var bitBaxcel = 1; | ||||
| @ -147,7 +137,7 @@ function parse_PtgAttrBaxcel(blob) { | ||||
| 	return [bitSemi, bitBaxcel]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.34 */ | ||||
| /* [MS-XLS] 2.5.198.34 ; [MS-XLSB] 2.5.97.25 */ | ||||
| function parse_PtgAttrChoose(blob, length, opts)/*:Array<number>*/ { | ||||
| 	blob.l +=2; | ||||
| 	var offset = blob.read_shift(opts && opts.biff == 2 ? 1 : 2); | ||||
| @ -157,14 +147,14 @@ function parse_PtgAttrChoose(blob, length, opts)/*:Array<number>*/ { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.35 */ | ||||
| /* [MS-XLS] 2.5.198.35 ; [MS-XLSB] 2.5.97.26 */ | ||||
| function parse_PtgAttrGoto(blob, length, opts) { | ||||
| 	var bitGoto = (blob[blob.l+1] & 0xFF) ? 1 : 0; | ||||
| 	blob.l += 2; | ||||
| 	return [bitGoto, blob.read_shift(opts && opts.biff == 2 ? 1 : 2)]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.36 */ | ||||
| /* [MS-XLS] 2.5.198.36 ; [MS-XLSB] 2.5.97.27 */ | ||||
| function parse_PtgAttrIf(blob, length, opts) { | ||||
| 	var bitIf = (blob[blob.l+1] & 0xFF) ? 1 : 0; | ||||
| 	blob.l += 2; | ||||
| @ -178,32 +168,32 @@ function parse_PtgAttrIfError(blob) { | ||||
| 	return [bitIf, blob.read_shift(2)]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.37 */ | ||||
| /* [MS-XLS] 2.5.198.37 ; [MS-XLSB] 2.5.97.29 */ | ||||
| function parse_PtgAttrSemi(blob, length, opts) { | ||||
| 	var bitSemi = (blob[blob.l+1] & 0xFF) ? 1 : 0; | ||||
| 	blob.l += opts && opts.biff == 2 ? 3 : 4; | ||||
| 	return [bitSemi]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.40 (used by PtgAttrSpace and PtgAttrSpaceSemi) */ | ||||
| /* [MS-XLS] 2.5.198.40 ; [MS-XLSB] 2.5.97.32 */ | ||||
| function parse_PtgAttrSpaceType(blob/*::, length*/) { | ||||
| 	var type = blob.read_shift(1), cch = blob.read_shift(1); | ||||
| 	return [type, cch]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.38 */ | ||||
| /* [MS-XLS] 2.5.198.38 ; [MS-XLSB] 2.5.97.30 */ | ||||
| function parse_PtgAttrSpace(blob) { | ||||
| 	blob.read_shift(2); | ||||
| 	return parse_PtgAttrSpaceType(blob, 2); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.39 */ | ||||
| /* [MS-XLS] 2.5.198.39 ; [MS-XLSB] 2.5.97.31 */ | ||||
| function parse_PtgAttrSpaceSemi(blob) { | ||||
| 	blob.read_shift(2); | ||||
| 	return parse_PtgAttrSpaceType(blob, 2); | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.84 TODO */ | ||||
| /* [MS-XLS] 2.5.198.84 ; [MS-XLSB] 2.5.97.68 TODO */ | ||||
| function parse_PtgRef(blob, length, opts) { | ||||
| 	//var ptg = blob[blob.l] & 0x1F;
 | ||||
| 	var type = (blob[blob.l] & 0x60)>>5; | ||||
| @ -212,7 +202,7 @@ function parse_PtgRef(blob, length, opts) { | ||||
| 	return [type, loc]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.88 TODO */ | ||||
| /* [MS-XLS] 2.5.198.88 ; [MS-XLSB] 2.5.97.72 TODO */ | ||||
| function parse_PtgRefN(blob, length, opts) { | ||||
| 	var type = (blob[blob.l] & 0x60)>>5; | ||||
| 	blob.l += 1; | ||||
| @ -220,17 +210,18 @@ function parse_PtgRefN(blob, length, opts) { | ||||
| 	return [type, loc]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.85 TODO */ | ||||
| /* [MS-XLS] 2.5.198.85 ; [MS-XLSB] 2.5.97.69 TODO */ | ||||
| function parse_PtgRef3d(blob, length, opts) { | ||||
| 	var type = (blob[blob.l] & 0x60)>>5; | ||||
| 	blob.l += 1; | ||||
| 	var ixti = blob.read_shift(2); // XtiIndex
 | ||||
| 	if(opts && opts.biff == 5) blob.l += 12; | ||||
| 	var loc = parse_RgceLoc(blob, 0, opts); // TODO: or RgceLocRel
 | ||||
| 	return [type, ixti, loc]; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.5.198.62 TODO */ | ||||
| /* [MS-XLS] 2.5.198.62 ; [MS-XLSB] 2.5.97.45 TODO */ | ||||
| function parse_PtgFunc(blob, length, opts) { | ||||
| 	//var ptg = blob[blob.l] & 0x1F;
 | ||||
| 	var type = (blob[blob.l] & 0x60)>>5; | ||||
| @ -238,7 +229,7 @@ function parse_PtgFunc(blob, length, opts) { | ||||
| 	var iftab = blob.read_shift(opts && opts.biff <= 3 ? 1 : 2); | ||||
| 	return [FtabArgc[iftab], Ftab[iftab], type]; | ||||
| } | ||||
| /* 2.5.198.63 TODO */ | ||||
| /* [MS-XLS] 2.5.198.63 ; [MS-XLSB] 2.5.97.46 TODO */ | ||||
| function parse_PtgFuncVar(blob, length, opts) { | ||||
| 	blob.l++; | ||||
| 	var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [0, blob.read_shift(1)]: parsetab(blob); | ||||
| @ -249,12 +240,12 @@ function parsetab(blob) { | ||||
| 	return [blob[blob.l+1]>>7, blob.read_shift(2) & 0x7FFF]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.41 */ | ||||
| /* [MS-XLS] 2.5.198.41 ; [MS-XLSB] 2.5.97.33 */ | ||||
| function parse_PtgAttrSum(blob, length, opts) { | ||||
| 	blob.l += opts && opts.biff == 2 ? 3 : 4; return; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.58 */ | ||||
| /* [MS-XLS] 2.5.198.58 ; [MS-XLSB] 2.5.97.40 */ | ||||
| function parse_PtgExp(blob, length, opts) { | ||||
| 	blob.l++; | ||||
| 	if(opts && opts.biff == 12) return [blob.read_shift(4, 'i'), 0]; | ||||
| @ -263,19 +254,19 @@ function parse_PtgExp(blob, length, opts) { | ||||
| 	return [row, col]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.57 */ | ||||
| /* [MS-XLS] 2.5.198.57 ; [MS-XLSB] 2.5.97.39 */ | ||||
| function parse_PtgErr(blob) { blob.l++; return BErr[blob.read_shift(1)]; } | ||||
| 
 | ||||
| /* 2.5.198.66 */ | ||||
| /* [MS-XLS] 2.5.198.66 ; [MS-XLSB] 2.5.97.49 */ | ||||
| function parse_PtgInt(blob) { blob.l++; return blob.read_shift(2); } | ||||
| 
 | ||||
| /* 2.5.198.42 */ | ||||
| /* [MS-XLS] 2.5.198.42 ; [MS-XLSB] 2.5.97.34 */ | ||||
| function parse_PtgBool(blob) { blob.l++; return blob.read_shift(1)!==0;} | ||||
| 
 | ||||
| /* 2.5.198.79 */ | ||||
| /* [MS-XLS] 2.5.198.79 ; [MS-XLSB] 2.5.97.63 */ | ||||
| function parse_PtgNum(blob) { blob.l++; return parse_Xnum(blob, 8); } | ||||
| 
 | ||||
| /* 2.5.198.89 */ | ||||
| /* [MS-XLS] 2.5.198.89 ; [MS-XLSB] 2.5.97.74 */ | ||||
| function parse_PtgStr(blob, length, opts) { blob.l++; return parse_ShortXLUnicodeString(blob, length-1, opts); } | ||||
| 
 | ||||
| /* [MS-XLS] 2.5.192.112 + 2.5.192.11{3,4,5,6,7} */ | ||||
| @ -289,37 +280,32 @@ function parse_SerAr(blob, biff/*:number*/) { | ||||
| 		case 0x01: val[0] = 0x02; break; /* SerStr */ | ||||
| 	} | ||||
| 	switch(val[0]) { | ||||
| 		/* 2.5.192.113 */ | ||||
| 		case 0x04: /* SerBool -- boolean */ | ||||
| 			val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE'; | ||||
| 			blob.l += 7; break; | ||||
| 		/* 2.5.192.114 */ | ||||
| 			if(biff != 12) blob.l += 7; break; | ||||
| 		case 0x10: /* SerErr -- error */ | ||||
| 			val[1] = BErr[blob[blob.l]]; | ||||
| 			blob.l += 8; break; | ||||
| 		/* 2.5.192.115 */ | ||||
| 			blob.l += ((biff == 12) ? 4 : 8); break; | ||||
| 		case 0x00: /* SerNil -- honestly, I'm not sure how to reproduce this */ | ||||
| 			blob.l += 8; break; | ||||
| 		/* 2.5.192.116 */ | ||||
| 		case 0x01: /* SerNum -- Xnum */ | ||||
| 			val[1] = parse_Xnum(blob, 8); break; | ||||
| 		/* 2.5.192.117 */ | ||||
| 		case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */ | ||||
| 			val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break; | ||||
| 		// default: throw "Bad SerAr: " + val[0]; /* Unreachable */
 | ||||
| 		default: throw "Bad SerAr: " + val[0]; /* Unreachable */ | ||||
| 	} | ||||
| 	return val; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.61 */ | ||||
| function parse_PtgExtraMem(blob/*::, cce*/) { | ||||
| 	var count = blob.read_shift(2); | ||||
| /* [MS-XLS] 2.5.198.61 ; [MS-XLSB] 2.5.97.44 */ | ||||
| function parse_PtgExtraMem(blob, cce, opts) { | ||||
| 	var count = blob.read_shift((opts.biff == 12) ? 4 : 2); | ||||
| 	var out/*:Array<Range>*/ = []; | ||||
| 	for(var i = 0; i != count; ++i) out.push(parse_Ref8U(blob, 8)); | ||||
| 	for(var i = 0; i != count; ++i) out.push(((opts.biff == 12) ? parse_UncheckedRfX : parse_Ref8U)(blob, 8)); | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.59 */ | ||||
| /* [MS-XLS] 2.5.198.59 ; [MS-XLSB] 2.5.97.41 */ | ||||
| function parse_PtgExtraArray(blob, length, opts) { | ||||
| 	var rows = 0, cols = 0; | ||||
| 	if(opts.biff == 12) { | ||||
| @ -336,7 +322,7 @@ function parse_PtgExtraArray(blob, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.76 */ | ||||
| /* [MS-XLS] 2.5.198.76 ; [MS-XLSB] 2.5.97.60 */ | ||||
| function parse_PtgName(blob, length, opts) { | ||||
| 	var type = (blob.read_shift(1) >>> 5) & 0x03; | ||||
| 	var w = (!opts || (opts.biff >= 8)) ? 4 : 2; | ||||
| @ -349,7 +335,7 @@ function parse_PtgName(blob, length, opts) { | ||||
| 	return [type, 0, nameindex]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.77 */ | ||||
| /* [MS-XLS] 2.5.198.77 ; [MS-XLSB] 2.5.97.61 */ | ||||
| function parse_PtgNameX(blob, length, opts) { | ||||
| 	if(opts.biff == 5) return parse_PtgNameX_BIFF5(blob, length, opts); | ||||
| 	var type = (blob.read_shift(1) >>> 5) & 0x03; | ||||
| @ -366,7 +352,7 @@ function parse_PtgNameX_BIFF5(blob/*::, length, opts*/) { | ||||
| 	return [type, ixti, nameindex]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.70 */ | ||||
| /* [MS-XLS] 2.5.198.70 ; [MS-XLSB] 2.5.97.54 */ | ||||
| function parse_PtgMemArea(blob, length, opts) { | ||||
| 	var type = (blob.read_shift(1) >>> 5) & 0x03; | ||||
| 	blob.l += (opts && opts.biff == 2 ? 3 : 4); | ||||
| @ -374,7 +360,7 @@ function parse_PtgMemArea(blob, length, opts) { | ||||
| 	return [type, cce]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.72 */ | ||||
| /* [MS-XLS] 2.5.198.72 ; [MS-XLSB] 2.5.97.56 */ | ||||
| function parse_PtgMemFunc(blob, length, opts) { | ||||
| 	var type = (blob.read_shift(1) >>> 5) & 0x03; | ||||
| 	var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2); | ||||
| @ -382,7 +368,7 @@ function parse_PtgMemFunc(blob, length, opts) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* 2.5.198.86 */ | ||||
| /* [MS-XLS] 2.5.198.86 ; [MS-XLSB] 2.5.97.69 */ | ||||
| function parse_PtgRefErr(blob, length, opts) { | ||||
| 	var type = (blob.read_shift(1) >>> 5) & 0x03; | ||||
| 	blob.l += 4; | ||||
| @ -390,24 +376,24 @@ function parse_PtgRefErr(blob, length, opts) { | ||||
| 	return [type]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.87 */ | ||||
| /* [MS-XLS] 2.5.198.87 ; [MS-XLSB] 2.5.97.71 */ | ||||
| function parse_PtgRefErr3d(blob, length, opts) { | ||||
| 	var type = (blob[blob.l++] & 0x60) >> 5; | ||||
| 	var ixti = blob.read_shift(2); | ||||
| 	var w = 4; | ||||
| 	if(opts) switch(opts.biff) { | ||||
| 		case 5: throw new Error("PtgRefErr3d -- 5"); // TODO: find test case
 | ||||
| 		case 5: w = 15; break; | ||||
| 		case 12: w = 6; break; | ||||
| 	} | ||||
| 	blob.l += w; | ||||
| 	return [type, ixti]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.71 */ | ||||
| /* [MS-XLS] 2.5.198.71 ; [MS-XLSB] 2.5.97.55 */ | ||||
| var parse_PtgMemErr = parsenoop; | ||||
| /* 2.5.198.73 */ | ||||
| /* [MS-XLS] 2.5.198.73  ; [MS-XLSB] 2.5.97.57 */ | ||||
| var parse_PtgMemNoMem = parsenoop; | ||||
| /* 2.5.198.92 */ | ||||
| /* [MS-XLS] 2.5.198.92 */ | ||||
| var parse_PtgTbl = parsenoop; | ||||
| 
 | ||||
| function parse_PtgElfLoc(blob, length, opts) { | ||||
| @ -418,28 +404,28 @@ function parse_PtgElfNoop(blob/*::, length, opts*/) { | ||||
| 	blob.l += 6; | ||||
| 	return []; | ||||
| } | ||||
| /* 2.5.198.46 */ | ||||
| /* [MS-XLS] 2.5.198.46 */ | ||||
| var parse_PtgElfCol = parse_PtgElfLoc; | ||||
| /* 2.5.198.47 */ | ||||
| /* [MS-XLS] 2.5.198.47 */ | ||||
| var parse_PtgElfColS = parse_PtgElfNoop; | ||||
| /* 2.5.198.48 */ | ||||
| /* [MS-XLS] 2.5.198.48 */ | ||||
| var parse_PtgElfColSV = parse_PtgElfNoop; | ||||
| /* 2.5.198.49 */ | ||||
| /* [MS-XLS] 2.5.198.49 */ | ||||
| var parse_PtgElfColV = parse_PtgElfLoc; | ||||
| /* 2.5.198.50 */ | ||||
| /* [MS-XLS] 2.5.198.50 */ | ||||
| function parse_PtgElfLel(blob/*::, length, opts*/) { | ||||
| 	blob.l += 2; | ||||
| 	return [parseuint16(blob), blob.read_shift(2) & 0x01]; | ||||
| } | ||||
| /* 2.5.198.51 */ | ||||
| /* [MS-XLS] 2.5.198.51 */ | ||||
| var parse_PtgElfRadical = parse_PtgElfLoc; | ||||
| /* 2.5.198.52 */ | ||||
| /* [MS-XLS] 2.5.198.52 */ | ||||
| var parse_PtgElfRadicalLel = parse_PtgElfLel; | ||||
| /* 2.5.198.53 */ | ||||
| /* [MS-XLS] 2.5.198.53 */ | ||||
| var parse_PtgElfRadicalS = parse_PtgElfNoop; | ||||
| /* 2.5.198.54 */ | ||||
| /* [MS-XLS] 2.5.198.54 */ | ||||
| var parse_PtgElfRw = parse_PtgElfLoc; | ||||
| /* 2.5.198.55 */ | ||||
| /* [MS-XLS] 2.5.198.55 */ | ||||
| var parse_PtgElfRwV = parse_PtgElfLoc; | ||||
| 
 | ||||
| /* [MS-XLSB] 2.5.97.52 */ | ||||
| @ -449,13 +435,13 @@ function parse_PtgList(blob/*::, length, opts*/) { | ||||
| 	blob.l += 10; | ||||
| 	return {ixti: ixti}; | ||||
| } | ||||
| /* 2.5.198.91 */ | ||||
| /* [MS-XLS] 2.5.198.91 ; [MS-XLSB] 2.5.97.76 */ | ||||
| function parse_PtgSxName(blob/*::, length, opts*/) { | ||||
| 	blob.l += 2; | ||||
| 	return [blob.read_shift(4)]; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.25 */ | ||||
| /* [MS-XLS] 2.5.198.25 ; [MS-XLSB] 2.5.97.16 */ | ||||
| var PtgTypes = { | ||||
| 	/*::[*/0x01/*::]*/: { n:'PtgExp', f:parse_PtgExp }, | ||||
| 	/*::[*/0x02/*::]*/: { n:'PtgTbl', f:parse_PtgTbl }, | ||||
| @ -558,7 +544,7 @@ var Ptg19 = { | ||||
| }; | ||||
| Ptg19[0x21] = Ptg19[0x20]; | ||||
| 
 | ||||
| /* 2.5.198.103 */ | ||||
| /* [MS-XLS] 2.5.198.103 ; [MS-XLSB] 2.5.97.87 */ | ||||
| function parse_RgbExtra(blob, length, rgce, opts) { | ||||
| 	if(opts.biff < 8) return parsenoop(blob, length); | ||||
| 	var target = blob.l + length; | ||||
| @ -570,7 +556,7 @@ function parse_RgbExtra(blob, length, rgce, opts) { | ||||
| 				o.push(rgce[i][1]); | ||||
| 				break; | ||||
| 			case 'PtgMemArea': /* PtgMemArea -> PtgExtraMem */ | ||||
| 				rgce[i][2] = parse_PtgExtraMem(blob, rgce[i][1]); | ||||
| 				rgce[i][2] = parse_PtgExtraMem(blob, rgce[i][1], opts); | ||||
| 				o.push(rgce[i][2]); | ||||
| 				break; | ||||
| 			case 'PtgExp': /* PtgExp -> PtgExtraCol */ | ||||
| @ -593,7 +579,7 @@ function parse_RgbExtra(blob, length, rgce, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* 2.5.198.104 */ | ||||
| /* [MS-XLS] 2.5.198.104 ; [MS-XLSB] 2.5.97.88 */ | ||||
| function parse_Rgce(blob, length, opts) { | ||||
| 	var target = blob.l + length; | ||||
| 	var R, id, ptgs = []; | ||||
| @ -631,8 +617,7 @@ function stringify_array(f/*:Array<Array<string>>*/)/*:string*/ { | ||||
| 	return o.join(";"); | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLS] 2.2.2 TODO */ | ||||
| /* [MS-XLSB] 2.2.2 */ | ||||
| /* [MS-XLS] 2.2.2 ; [MS-XLSB] 2.2.2 TODO */ | ||||
| var PtgBinOp = { | ||||
| 	PtgAdd: "+", | ||||
| 	PtgConcat: "&", | ||||
| @ -697,25 +682,25 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 	for(var ff = 0, fflen = formula[0].length; ff < fflen; ++ff) { | ||||
| 		var f = formula[0][ff]; | ||||
| 		switch(f[0]) { | ||||
| 			case 'PtgUminus': /* 2.5.198.93 */ | ||||
| 			case 'PtgUminus': /* [MS-XLS] 2.5.198.93 */ | ||||
| 				stack.push("-" + stack.pop()); break; | ||||
| 			case 'PtgUplus': /* 2.5.198.95 */ | ||||
| 			case 'PtgUplus': /* [MS-XLS] 2.5.198.95 */ | ||||
| 				stack.push("+" + stack.pop()); break; | ||||
| 			case 'PtgPercent': /* 2.5.198.81 */ | ||||
| 			case 'PtgPercent': /* [MS-XLS] 2.5.198.81 */ | ||||
| 				stack.push(stack.pop() + "%"); break; | ||||
| 
 | ||||
| 			case 'PtgAdd':    /* 2.5.198.26 */ | ||||
| 			case 'PtgConcat': /* 2.5.198.43 */ | ||||
| 			case 'PtgDiv':    /* 2.5.198.45 */ | ||||
| 			case 'PtgEq':     /* 2.5.198.56 */ | ||||
| 			case 'PtgGe':     /* 2.5.198.64 */ | ||||
| 			case 'PtgGt':     /* 2.5.198.65 */ | ||||
| 			case 'PtgLe':     /* 2.5.198.68 */ | ||||
| 			case 'PtgLt':     /* 2.5.198.69 */ | ||||
| 			case 'PtgMul':    /* 2.5.198.75 */ | ||||
| 			case 'PtgNe':     /* 2.5.198.78 */ | ||||
| 			case 'PtgPower':  /* 2.5.198.82 */ | ||||
| 			case 'PtgSub':    /* 2.5.198.90 */ | ||||
| 			case 'PtgAdd':    /* [MS-XLS] 2.5.198.26 */ | ||||
| 			case 'PtgConcat': /* [MS-XLS] 2.5.198.43 */ | ||||
| 			case 'PtgDiv':    /* [MS-XLS] 2.5.198.45 */ | ||||
| 			case 'PtgEq':     /* [MS-XLS] 2.5.198.56 */ | ||||
| 			case 'PtgGe':     /* [MS-XLS] 2.5.198.64 */ | ||||
| 			case 'PtgGt':     /* [MS-XLS] 2.5.198.65 */ | ||||
| 			case 'PtgLe':     /* [MS-XLS] 2.5.198.68 */ | ||||
| 			case 'PtgLt':     /* [MS-XLS] 2.5.198.69 */ | ||||
| 			case 'PtgMul':    /* [MS-XLS] 2.5.198.75 */ | ||||
| 			case 'PtgNe':     /* [MS-XLS] 2.5.198.78 */ | ||||
| 			case 'PtgPower':  /* [MS-XLS] 2.5.198.82 */ | ||||
| 			case 'PtgSub':    /* [MS-XLS] 2.5.198.90 */ | ||||
| 				e1 = stack.pop(); e2 = stack.pop(); | ||||
| 				if(last_sp >= 0) { | ||||
| 					switch(formula[0][last_sp][1][0]) { | ||||
| @ -736,46 +721,46 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 				stack.push(e2+PtgBinOp[f[0]]+e1); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgIsect': /* 2.5.198.67 */ | ||||
| 			case 'PtgIsect': /* [MS-XLS] 2.5.198.67 */ | ||||
| 				e1 = stack.pop(); e2 = stack.pop(); | ||||
| 				stack.push(e2+" "+e1); | ||||
| 				break; | ||||
| 			case 'PtgUnion': /* 2.5.198.94 */ | ||||
| 			case 'PtgUnion': /* [MS-XLS] 2.5.198.94 */ | ||||
| 				e1 = stack.pop(); e2 = stack.pop(); | ||||
| 				stack.push(e2+","+e1); | ||||
| 				break; | ||||
| 			case 'PtgRange': /* 2.5.198.83 */ | ||||
| 			case 'PtgRange': /* [MS-XLS] 2.5.198.83 */ | ||||
| 				e1 = stack.pop(); e2 = stack.pop(); | ||||
| 				stack.push(e2+":"+e1); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgAttrChoose': /* 2.5.198.34 */ | ||||
| 			case 'PtgAttrChoose': /* [MS-XLS] 2.5.198.34 */ | ||||
| 				break; | ||||
| 			case 'PtgAttrGoto': /* 2.5.198.35 */ | ||||
| 			case 'PtgAttrGoto': /* [MS-XLS] 2.5.198.35 */ | ||||
| 				break; | ||||
| 			case 'PtgAttrIf': /* 2.5.198.36 */ | ||||
| 			case 'PtgAttrIf': /* [MS-XLS] 2.5.198.36 */ | ||||
| 				break; | ||||
| 			case 'PtgAttrIfError': /* [MS-XLSB] 2.5.97.28 */ | ||||
| 				break; | ||||
| 
 | ||||
| 
 | ||||
| 			case 'PtgRef': /* 2.5.198.84 */ | ||||
| 			case 'PtgRef': /* [MS-XLS] 2.5.198.84 */ | ||||
| 				/*::type = f[1][0]; */c = shift_cell_xls((f[1][1]/*:any*/), _range, opts); | ||||
| 				stack.push(encode_cell_xls(c)); | ||||
| 				break; | ||||
| 			case 'PtgRefN': /* 2.5.198.88 */ | ||||
| 			case 'PtgRefN': /* [MS-XLS] 2.5.198.88 */ | ||||
| 				/*::type = f[1][0]; */c = cell ? shift_cell_xls((f[1][1]/*:any*/), cell, opts) : (f[1][1]/*:any*/); | ||||
| 				stack.push(encode_cell_xls(c)); | ||||
| 				break; | ||||
| 			case 'PtgRef3d': /* 2.5.198.85 */ | ||||
| 			case 'PtgRef3d': /* [MS-XLS] 2.5.198.85 */ | ||||
| 				/*::type = f[1][0]; */ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls((f[1][2]/*:any*/), _range, opts); | ||||
| 				sname = get_ixti(supbooks, ixti, opts); | ||||
| 				var w = sname; /* IE9 fails on defined names */ // eslint-disable-line no-unused-vars
 | ||||
| 				stack.push(sname + "!" + encode_cell_xls(c)); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgFunc': /* 2.5.198.62 */ | ||||
| 			case 'PtgFuncVar': /* 2.5.198.63 */ | ||||
| 			case 'PtgFunc': /* [MS-XLS] 2.5.198.62 */ | ||||
| 			case 'PtgFuncVar': /* [MS-XLS] 2.5.198.63 */ | ||||
| 				/* f[1] = [argc, func, type] */ | ||||
| 				var argc/*:number*/ = (f[1][0]/*:any*/), func/*:string*/ = (f[1][1]/*:any*/); | ||||
| 				if(!argc) argc = 0; | ||||
| @ -785,38 +770,38 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 				stack.push(func + "(" + args.join(",") + ")"); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgBool': /* 2.5.198.42 */ | ||||
| 			case 'PtgBool': /* [MS-XLS] 2.5.198.42 */ | ||||
| 				stack.push(f[1] ? "TRUE" : "FALSE"); break; | ||||
| 			case 'PtgInt': /* 2.5.198.66 */ | ||||
| 			case 'PtgInt': /* [MS-XLS] 2.5.198.66 */ | ||||
| 				stack.push(/*::String(*/f[1]/*::)*/); break; | ||||
| 			case 'PtgNum': /* 2.5.198.79 TODO: precision? */ | ||||
| 			case 'PtgNum': /* [MS-XLS] 2.5.198.79 TODO: precision? */ | ||||
| 				stack.push(String(f[1])); break; | ||||
| 			case 'PtgStr': /* 2.5.198.89 */ | ||||
| 			case 'PtgStr': /* [MS-XLS] 2.5.198.89 */ | ||||
| 				// $FlowIgnore
 | ||||
| 				stack.push('"' + f[1] + '"'); break; | ||||
| 			case 'PtgErr': /* 2.5.198.57 */ | ||||
| 			case 'PtgErr': /* [MS-XLS] 2.5.198.57 */ | ||||
| 				stack.push(/*::String(*/f[1]/*::)*/); break; | ||||
| 			case 'PtgAreaN': /* 2.5.198.31 TODO */ | ||||
| 			case 'PtgAreaN': /* [MS-XLS] 2.5.198.31 TODO */ | ||||
| 				/*::type = f[1][0]; */r = shift_range_xls(f[1][1], cell ? {s:cell} : _range, opts); | ||||
| 				stack.push(encode_range_xls((r/*:any*/), opts)); | ||||
| 				break; | ||||
| 			case 'PtgArea': /* 2.5.198.27 TODO: fixed points */ | ||||
| 			case 'PtgArea': /* [MS-XLS] 2.5.198.27 TODO: fixed points */ | ||||
| 				/*::type = f[1][0]; */r = shift_range_xls(f[1][1], _range, opts); | ||||
| 				stack.push(encode_range_xls((r/*:any*/), opts)); | ||||
| 				break; | ||||
| 			case 'PtgArea3d': /* 2.5.198.28 TODO */ | ||||
| 			case 'PtgArea3d': /* [MS-XLS] 2.5.198.28 TODO */ | ||||
| 				/*::type = f[1][0]; */ixti = /*::Number(*/f[1][1]/*::)*/; r = f[1][2]; | ||||
| 				sname = get_ixti(supbooks, ixti, opts); | ||||
| 				stack.push(sname + "!" + encode_range_xls((r/*:any*/), opts)); | ||||
| 				break; | ||||
| 			case 'PtgAttrSum': /* 2.5.198.41 */ | ||||
| 			case 'PtgAttrSum': /* [MS-XLS] 2.5.198.41 */ | ||||
| 				stack.push("SUM(" + stack.pop() + ")"); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgAttrSemi': /* 2.5.198.37 */ | ||||
| 			case 'PtgAttrSemi': /* [MS-XLS] 2.5.198.37 */ | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgName': /* 2.5.97.60 TODO: revisions */ | ||||
| 			case 'PtgName': /* [MS-XLS] 2.5.198.76 ; [MS-XLSB] 2.5.97.60 TODO: revisions */ | ||||
| 				/* f[1] = type, 0, nameindex */ | ||||
| 				nameidx = (f[1][2]/*:any*/); | ||||
| 				var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx]; | ||||
| @ -825,7 +810,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 				stack.push(name); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgNameX': /* 2.5.97.61 TODO: revisions */ | ||||
| 			case 'PtgNameX': /* [MS-XLS] 2.5.198.77 ; [MS-XLSB] 2.5.97.61 TODO: revisions */ | ||||
| 				/* f[1] = type, ixti, nameindex */ | ||||
| 				var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = (f[1][2]/*:any*/); var externbook; | ||||
| 				/* TODO: Properly handle missing values */ | ||||
| @ -851,7 +836,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 				stack.push(externbook.Name); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgParen': /* 2.5.198.80 */ | ||||
| 			case 'PtgParen': /* [MS-XLS] 2.5.198.80 */ | ||||
| 				var lp = '(', rp = ')'; | ||||
| 				if(last_sp >= 0) { | ||||
| 					sp = ""; | ||||
| @ -872,13 +857,13 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 				} | ||||
| 				stack.push(lp + stack.pop() + rp); break; | ||||
| 
 | ||||
| 			case 'PtgRefErr': /* 2.5.198.86 */ | ||||
| 			case 'PtgRefErr': /* [MS-XLS] 2.5.198.86 */ | ||||
| 				stack.push('#REF!'); break; | ||||
| 
 | ||||
| 			case 'PtgRefErr3d': /* 2.5.198.87 */ | ||||
| 			case 'PtgRefErr3d': /* [MS-XLS] 2.5.198.87 */ | ||||
| 				stack.push('#REF!'); break; | ||||
| 
 | ||||
| 			case 'PtgExp': /* 2.5.198.58 TODO */ | ||||
| 			case 'PtgExp': /* [MS-XLS] 2.5.198.58 TODO */ | ||||
| 				c = {c:(f[1][1]/*:any*/),r:(f[1][0]/*:any*/)}; | ||||
| 				var q = ({c: cell.c, r:cell.r}/*:any*/); | ||||
| 				if(supbooks.sharedf[encode_cell(c)]) { | ||||
| @ -900,55 +885,55 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, | ||||
| 				} | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgArray': /* 2.5.198.32 TODO */ | ||||
| 			case 'PtgArray': /* [MS-XLS] 2.5.198.32 TODO */ | ||||
| 				stack.push("{" + stringify_array(/*::(*/f[1]/*:: :any)*/) + "}"); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgMemArea': /* 2.5.198.70 TODO: confirm this is a non-display */ | ||||
| 			case 'PtgMemArea': /* [MS-XLS] 2.5.198.70 TODO: confirm this is a non-display */ | ||||
| 				//stack.push("(" + f[2].map(encode_range).join(",") + ")");
 | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgAttrSpace': /* 2.5.198.38 */ | ||||
| 			case 'PtgAttrSpaceSemi': /* 2.5.198.39 */ | ||||
| 			case 'PtgAttrSpace': /* [MS-XLS] 2.5.198.38 */ | ||||
| 			case 'PtgAttrSpaceSemi': /* [MS-XLS] 2.5.198.39 */ | ||||
| 				last_sp = ff; | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgTbl': /* 2.5.198.92 TODO */ | ||||
| 			case 'PtgTbl': /* [MS-XLS] 2.5.198.92 TODO */ | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgMemErr': /* 2.5.198.71 */ | ||||
| 			case 'PtgMemErr': /* [MS-XLS] 2.5.198.71 */ | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgMissArg': /* 2.5.198.74 */ | ||||
| 			case 'PtgMissArg': /* [MS-XLS] 2.5.198.74 */ | ||||
| 				stack.push(""); | ||||
| 				break; | ||||
| 
 | ||||
| 			case 'PtgAreaErr': /* 2.5.198.29 */ | ||||
| 			case 'PtgAreaErr': /* [MS-XLS] 2.5.198.29 */ | ||||
| 				stack.push("#REF!"); break; | ||||
| 
 | ||||
| 			case 'PtgAreaErr3d': /* 2.5.198.30 */ | ||||
| 			case 'PtgAreaErr3d': /* [MS-XLS] 2.5.198.30 */ | ||||
| 				stack.push("#REF!"); break; | ||||
| 
 | ||||
| 			case 'PtgMemFunc': /* 2.5.198.72 TODO */ | ||||
| 			case 'PtgMemFunc': /* [MS-XLS] 2.5.198.72 TODO */ | ||||
| 				break; | ||||
| 			case 'PtgMemNoMem': /* [MS-XLS] 2.5.198.73 TODO */ | ||||
| 				break; | ||||
| 			case 'PtgMemNoMem': /* 2.5.198.73 TODO -- find a test case */ | ||||
| 				throw new Error('Unrecognized Formula Token: ' + String(f)); | ||||
| 
 | ||||
| 			case 'PtgElfCol': /* 2.5.198.46 */ | ||||
| 			case 'PtgElfColS': /* 2.5.198.47 */ | ||||
| 			case 'PtgElfColSV': /* 2.5.198.48 */ | ||||
| 			case 'PtgElfColV': /* 2.5.198.49 */ | ||||
| 			case 'PtgElfLel': /* 2.5.198.50 */ | ||||
| 			case 'PtgElfRadical': /* 2.5.198.51 */ | ||||
| 			case 'PtgElfRadicalLel': /* 2.5.198.52 */ | ||||
| 			case 'PtgElfRadicalS': /* 2.5.198.53 */ | ||||
| 			case 'PtgElfRw': /* 2.5.198.54 */ | ||||
| 			case 'PtgElfRwV': /* 2.5.198.55 */ | ||||
| 			case 'PtgElfCol': /* [MS-XLS] 2.5.198.46 */ | ||||
| 			case 'PtgElfColS': /* [MS-XLS] 2.5.198.47 */ | ||||
| 			case 'PtgElfColSV': /* [MS-XLS] 2.5.198.48 */ | ||||
| 			case 'PtgElfColV': /* [MS-XLS] 2.5.198.49 */ | ||||
| 			case 'PtgElfLel': /* [MS-XLS] 2.5.198.50 */ | ||||
| 			case 'PtgElfRadical': /* [MS-XLS] 2.5.198.51 */ | ||||
| 			case 'PtgElfRadicalLel': /* [MS-XLS] 2.5.198.52 */ | ||||
| 			case 'PtgElfRadicalS': /* [MS-XLS] 2.5.198.53 */ | ||||
| 			case 'PtgElfRw': /* [MS-XLS] 2.5.198.54 */ | ||||
| 			case 'PtgElfRwV': /* [MS-XLS] 2.5.198.55 */ | ||||
| 				throw new Error("Unsupported ELFs"); | ||||
| 
 | ||||
| 			case 'PtgAttrBaxcel': /* 2.5.198.33 TODO -- find a test case*/ | ||||
| 			case 'PtgAttrBaxcel': /* [MS-XLS] 2.5.198.33 TODO -- find a test case*/ | ||||
| 				throw new Error('Unrecognized Formula Token: ' + String(f)); | ||||
| 			case 'PtgSxName': /* 2.5.198.91 TODO -- find a test case */ | ||||
| 			case 'PtgSxName': /* [MS-XLS] 2.5.198.91 TODO -- find a test case */ | ||||
| 				throw new Error('Unrecognized Formula Token: ' + String(f)); | ||||
| 			case 'PtgList': /* [MS-XLSB] 2.5.97.52 TODO -- find a test case */ | ||||
| 				throw new Error('Unrecognized Formula Token: ' + String(f)); | ||||
|  | ||||
| @ -71,7 +71,6 @@ function parse_Formula(blob, length, opts) { | ||||
| 
 | ||||
| /* XLSB Parsed Formula records have the same shape */ | ||||
| function parse_XLSBParsedFormula(data, length, opts) { | ||||
| 	//var end = data.l + length;
 | ||||
| 	var cce = data.read_shift(4); | ||||
| 	var rgce = parse_Rgce(data, cce, opts); | ||||
| 	var cb = data.read_shift(4); | ||||
|  | ||||
| @ -68,6 +68,7 @@ function safe_format(p/*:Cell*/, fmtid/*:number*/, fillid/*:?number*/, opts, the | ||||
| 		if(opts.cellNF) p.z = SSF._table[fmtid]; | ||||
| 	} catch(e) { if(opts.WTF) throw e; } | ||||
| 	if(!opts || opts.cellText !== false) try { | ||||
| 		if(SSF._table[fmtid] == null) SSF.load(SSFImplicit[fmtid] || "General", fmtid); | ||||
| 		if(p.t === 'e') p.w = p.w || BErr[p.v]; | ||||
| 		else if(fmtid === 0) { | ||||
| 			if(p.t === 'n') { | ||||
|  | ||||
| @ -474,9 +474,11 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ { | ||||
| 	ws['!comments'] = []; | ||||
| 	ws['!drawing'] = []; | ||||
| 
 | ||||
| 	var cname = wb.SheetNames[idx]; | ||||
| 	try { if(wb.Workbook) cname = wb.Workbook.Sheets[idx].CodeName || cname; } catch(e) {} | ||||
| 	o[o.length] = (writextag('sheetPr', null, {'codeName': escapexml(cname)})); | ||||
| 	if(opts.bookType !== 'xlsx' && wb.vbaraw) { | ||||
| 		var cname = wb.SheetNames[idx]; | ||||
| 		try { if(wb.Workbook) cname = wb.Workbook.Sheets[idx].CodeName || cname; } catch(e) {} | ||||
| 		o[o.length] = (writextag('sheetPr', null, {'codeName': escapexml(cname)})); | ||||
| 	} | ||||
| 
 | ||||
| 	o[o.length] = (writextag('dimension', null, {'ref': ref})); | ||||
| 
 | ||||
| @ -547,7 +549,9 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ { | ||||
| 	/* colBreaks */ | ||||
| 	/* customProperties */ | ||||
| 	/* cellWatches */ | ||||
| 	/* ignoredErrors */ | ||||
| 
 | ||||
| 	o[o.length] = writetag("ignoredErrors", writextag("ignoredError", null, {numberStoredAsText:1, sqref:ref})); | ||||
| 
 | ||||
| 	/* smartTags */ | ||||
| 
 | ||||
| 	if(ws['!drawing'].length > 0) { | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.718 BrtRowHdr */ | ||||
| /* [MS-XLSB] 2.4.726 BrtRowHdr */ | ||||
| function parse_BrtRowHdr(data, length) { | ||||
| 	var z = ({}/*:any*/); | ||||
| 	var tgt = data.l + length; | ||||
| @ -67,16 +67,16 @@ function write_row_header(ba, ws, range, R) { | ||||
| 	if((o.length > 17) || (ws['!rows']||[])[R]) write_record(ba, 'BrtRowHdr', o); | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.812 BrtWsDim */ | ||||
| /* [MS-XLSB] 2.4.820 BrtWsDim */ | ||||
| var parse_BrtWsDim = parse_UncheckedRfX; | ||||
| var write_BrtWsDim = write_UncheckedRfX; | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.813 BrtWsFmtInfo */ | ||||
| /* [MS-XLSB] 2.4.821 BrtWsFmtInfo */ | ||||
| function parse_BrtWsFmtInfo(/*::data, length*/) { | ||||
| } | ||||
| //function write_BrtWsFmtInfo(ws, o) { }
 | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.815 BrtWsProp */ | ||||
| /* [MS-XLSB] 2.4.823 BrtWsProp */ | ||||
| function parse_BrtWsProp(data, length) { | ||||
| 	var z = {}; | ||||
| 	/* TODO: pull flags */ | ||||
| @ -94,7 +94,7 @@ function write_BrtWsProp(str, o) { | ||||
| 	return o.slice(0, o.l); | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.303 BrtCellBlank */ | ||||
| /* [MS-XLSB] 2.4.306 BrtCellBlank */ | ||||
| function parse_BrtCellBlank(data) { | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| 	return [cell]; | ||||
| @ -105,7 +105,7 @@ function write_BrtCellBlank(cell, ncell, o) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.304 BrtCellBool */ | ||||
| /* [MS-XLSB] 2.4.307 BrtCellBool */ | ||||
| function parse_BrtCellBool(data) { | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| 	var fBool = data.read_shift(1); | ||||
| @ -118,14 +118,14 @@ function write_BrtCellBool(cell, ncell, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.305 BrtCellError */ | ||||
| /* [MS-XLSB] 2.4.308 BrtCellError */ | ||||
| function parse_BrtCellError(data) { | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| 	var bError = data.read_shift(1); | ||||
| 	return [cell, bError, 'e']; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.308 BrtCellIsst */ | ||||
| /* [MS-XLSB] 2.4.311 BrtCellIsst */ | ||||
| function parse_BrtCellIsst(data) { | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| 	var isst = data.read_shift(4); | ||||
| @ -138,7 +138,7 @@ function write_BrtCellIsst(cell, ncell, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.310 BrtCellReal */ | ||||
| /* [MS-XLSB] 2.4.313 BrtCellReal */ | ||||
| function parse_BrtCellReal(data) { | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| 	var value = parse_Xnum(data); | ||||
| @ -151,7 +151,7 @@ function write_BrtCellReal(cell, ncell, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.311 BrtCellRk */ | ||||
| /* [MS-XLSB] 2.4.314 BrtCellRk */ | ||||
| function parse_BrtCellRk(data) { | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| 	var value = parse_RkNumber(data); | ||||
| @ -165,7 +165,7 @@ function write_BrtCellRk(cell, ncell, o) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.314 BrtCellSt */ | ||||
| /* [MS-XLSB] 2.4.317 BrtCellSt */ | ||||
| function parse_BrtCellSt(data) { | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| 	var value = parse_XLWideString(data); | ||||
| @ -178,7 +178,7 @@ function write_BrtCellSt(cell, ncell, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.647 BrtFmlaBool */ | ||||
| /* [MS-XLSB] 2.4.653 BrtFmlaBool */ | ||||
| function parse_BrtFmlaBool(data, length, opts) { | ||||
| 	var end = data.l + length; | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| @ -194,7 +194,7 @@ function parse_BrtFmlaBool(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.648 BrtFmlaError */ | ||||
| /* [MS-XLSB] 2.4.654 BrtFmlaError */ | ||||
| function parse_BrtFmlaError(data, length, opts) { | ||||
| 	var end = data.l + length; | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| @ -210,7 +210,7 @@ function parse_BrtFmlaError(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.649 BrtFmlaNum */ | ||||
| /* [MS-XLSB] 2.4.655 BrtFmlaNum */ | ||||
| function parse_BrtFmlaNum(data, length, opts) { | ||||
| 	var end = data.l + length; | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| @ -226,7 +226,7 @@ function parse_BrtFmlaNum(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.650 BrtFmlaString */ | ||||
| /* [MS-XLSB] 2.4.656 BrtFmlaString */ | ||||
| function parse_BrtFmlaString(data, length, opts) { | ||||
| 	var end = data.l + length; | ||||
| 	var cell = parse_XLSBCell(data); | ||||
| @ -242,17 +242,17 @@ function parse_BrtFmlaString(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.676 BrtMergeCell */ | ||||
| /* [MS-XLSB] 2.4.682 BrtMergeCell */ | ||||
| var parse_BrtMergeCell = parse_UncheckedRfX; | ||||
| var write_BrtMergeCell = write_UncheckedRfX; | ||||
| /* [MS-XLSB] 2.4.108 BrtBeginMergeCells */ | ||||
| /* [MS-XLSB] 2.4.107 BrtBeginMergeCells */ | ||||
| function write_BrtBeginMergeCells(cnt, o) { | ||||
| 	if(o == null) o = new_buf(4); | ||||
| 	o.write_shift(4, cnt); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.656 BrtHLink */ | ||||
| /* [MS-XLSB] 2.4.662 BrtHLink */ | ||||
| function parse_BrtHLink(data, length/*::, opts*/) { | ||||
| 	var end = data.l + length; | ||||
| 	var rfx = parse_UncheckedRfX(data, 16); | ||||
| @ -290,7 +290,7 @@ function parse_BrtArrFmla(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.742 BrtShrFmla */ | ||||
| /* [MS-XLSB] 2.4.750 BrtShrFmla */ | ||||
| function parse_BrtShrFmla(data, length, opts) { | ||||
| 	var end = data.l + length; | ||||
| 	var rfx = parse_UncheckedRfX(data, 16); | ||||
| @ -320,7 +320,7 @@ function write_BrtColInfo(C/*:number*/, col, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.672 BrtMargins */ | ||||
| /* [MS-XLSB] 2.4.678 BrtMargins */ | ||||
| var BrtMarginKeys = ["left","right","top","bottom","header","footer"]; | ||||
| function parse_BrtMargins(data/*::, length, opts*/)/*:Margins*/ { | ||||
| 	var margins = ({}/*:any*/); | ||||
| @ -334,7 +334,7 @@ function write_BrtMargins(margins/*:Margins*/, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.292 BrtBeginWsView */ | ||||
| /* [MS-XLSB] 2.4.299 BrtBeginWsView */ | ||||
| function parse_BrtBeginWsView(data/*::, length, opts*/) { | ||||
| 	var f = data.read_shift(2); | ||||
| 	data.l += 28; | ||||
| @ -360,7 +360,16 @@ function write_BrtBeginWsView(ws, Workbook, o) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.740 BrtSheetProtection */ | ||||
| /* [MS-XLSB] 2.4.309 BrtCellIgnoreEC */ | ||||
| function write_BrtCellIgnoreEC(ref) { | ||||
| 	var o = new_buf(24); | ||||
| 	o.write_shift(4, 4); | ||||
| 	o.write_shift(4, 1); | ||||
| 	write_UncheckedRfX(ref, o); | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.748 BrtSheetProtection */ | ||||
| function write_BrtSheetProtection(sp, o) { | ||||
| 	if(o == null) o = new_buf(16*4+2); | ||||
| 	o.write_shift(2, sp.password ? crypto_CreatePasswordVerifier_Method1(sp.password) : 0); | ||||
| @ -736,6 +745,13 @@ function write_COLINFOS(ba, ws/*:Worksheet*//*::, idx:number, opts, wb:Workbook* | ||||
| 	write_record(ba, 'BrtEndColInfos'); | ||||
| } | ||||
| 
 | ||||
| function write_IGNOREECS(ba, ws/*:Worksheet*/) { | ||||
| 	if(!ws || !ws['!ref']) return; | ||||
| 	write_record(ba, 'BrtBeginCellIgnoreECs'); | ||||
| 	write_record(ba, 'BrtCellIgnoreEC', write_BrtCellIgnoreEC(safe_decode_range(ws['!ref']))); | ||||
| 	write_record(ba, 'BrtEndCellIgnoreECs'); | ||||
| } | ||||
| 
 | ||||
| function write_HLINKS(ba, ws/*:Worksheet*/, rels) { | ||||
| 	/* *BrtHLink */ | ||||
| 	ws['!links'].forEach(function(l) { | ||||
| @ -756,7 +772,7 @@ function write_LEGACYDRAWING(ba, ws/*:Worksheet*/, idx/*:number*/, rels) { | ||||
| 
 | ||||
| function write_AUTOFILTER(ba, ws) { | ||||
| 	if(!ws['!autofilter']) return; | ||||
| 	write_record(ba, "BrtBeginAFilter", write_UncheckedRfX(decode_range(ws['!autofilter'].ref))); | ||||
| 	write_record(ba, "BrtBeginAFilter", write_UncheckedRfX(safe_decode_range(ws['!autofilter'].ref))); | ||||
| 	/* *FILTERCOLUMN */ | ||||
| 	/* [SORTSTATE] */ | ||||
| 	/* BrtEndAFilter */ | ||||
| @ -798,7 +814,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) { | ||||
| 	/* passed back to write_zip and removed there */ | ||||
| 	ws['!comments'] = []; | ||||
| 	write_record(ba, "BrtBeginSheet"); | ||||
| 	write_record(ba, "BrtWsProp", write_BrtWsProp(c)); | ||||
| 	if(wb.vbaraw) write_record(ba, "BrtWsProp", write_BrtWsProp(c)); | ||||
| 	write_record(ba, "BrtWsDim", write_BrtWsDim(r)); | ||||
| 	write_WSVIEWS2(ba, ws, wb.Workbook); | ||||
| 	write_WSFMTINFO(ba, ws); | ||||
| @ -825,7 +841,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) { | ||||
| 	/* [COLBRK] */ | ||||
| 	/* *BrtBigName */ | ||||
| 	/* [CELLWATCHES] */ | ||||
| 	/* [IGNOREECS] */ | ||||
| 	write_IGNOREECS(ba, ws); | ||||
| 	/* [SMARTTAGS] */ | ||||
| 	/* [BrtDrawing] */ | ||||
| 	write_LEGACYDRAWING(ba, ws, idx, rels); | ||||
|  | ||||
| @ -124,15 +124,20 @@ function check_ws_name(n/*:string*/, safe/*:?boolean*/)/*:boolean*/ { | ||||
| 	}); | ||||
| 	return _good; | ||||
| } | ||||
| function check_wb_names(N) { | ||||
| function check_wb_names(N, S, codes) { | ||||
| 	N.forEach(function(n,i) { | ||||
| 		check_ws_name(n); | ||||
| 		for(var j = 0; j < i; ++j) if(n == N[j]) throw new Error("Duplicate Sheet Name: " + n); | ||||
| 		if(codes) { | ||||
| 			var cn = (S && S[i] && S[i].CodeName) || n; | ||||
| 			if(cn.charCodeAt(0) == 95 && cn.length > 22) throw new Error("Bad Code Name: Worksheet" + cn); | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| function check_wb(wb) { | ||||
| 	if(!wb || !wb.SheetNames || !wb.Sheets) throw new Error("Invalid Workbook"); | ||||
| 	if(!wb.SheetNames.length) throw new Error("Workbook is empty"); | ||||
| 	check_wb_names(wb.SheetNames); | ||||
| 	var Sheets = (wb.Workbook && wb.Workbook.Sheets) || []; | ||||
| 	check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw); | ||||
| 	/* TODO: validate workbook */ | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* [MS-XLSB] 2.4.301 BrtBundleSh */ | ||||
| /* [MS-XLSB] 2.4.304 BrtBundleSh */ | ||||
| function parse_BrtBundleSh(data, length/*:number*/) { | ||||
| 	var z = {}; | ||||
| 	z.Hidden = data.read_shift(4); //hsState ST_SheetState
 | ||||
| @ -16,7 +16,7 @@ function write_BrtBundleSh(data, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.807 BrtWbProp */ | ||||
| /* [MS-XLSB] 2.4.815 BrtWbProp */ | ||||
| function parse_BrtWbProp(data, length)/*:WBProps*/ { | ||||
| 	var o/*:WBProps*/ = ({}/*:any*/); | ||||
| 	var flags = data.read_shift(4); | ||||
| @ -61,7 +61,7 @@ function parse_BrtFRTArchID$(data, length) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.680 BrtName */ | ||||
| /* [MS-XLSB] 2.4.687 BrtName */ | ||||
| function parse_BrtName(data, length, opts) { | ||||
| 	var end = data.l + length; | ||||
| 	data.l += 4; //var flags = data.read_shift(4);
 | ||||
| @ -83,7 +83,7 @@ function parse_BrtName(data, length, opts) { | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.60 Workbook */ | ||||
| /* [MS-XLSB] 2.1.7.61 Workbook */ | ||||
| function parse_wb_bin(data, opts)/*:WorkbookFile*/ { | ||||
| 	var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" }; | ||||
| 	var pass = false; | ||||
| @ -185,7 +185,6 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ { | ||||
| 	return wb; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.60 Workbook */ | ||||
| function write_BUNDLESHS(ba, wb/*::, opts*/) { | ||||
| 	write_record(ba, "BrtBeginBundleShs"); | ||||
| 	for(var idx = 0; idx != wb.SheetNames.length; ++idx) { | ||||
| @ -196,7 +195,7 @@ function write_BUNDLESHS(ba, wb/*::, opts*/) { | ||||
| 	write_record(ba, "BrtEndBundleShs"); | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.643 BrtFileVersion */ | ||||
| /* [MS-XLSB] 2.4.649 BrtFileVersion */ | ||||
| function write_BrtFileVersion(data, o) { | ||||
| 	if(!o) o = new_buf(127); | ||||
| 	for(var i = 0; i != 4; ++i) o.write_shift(4, 0); | ||||
| @ -208,7 +207,7 @@ function write_BrtFileVersion(data, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.298 BrtBookView */ | ||||
| /* [MS-XLSB] 2.4.301 BrtBookView */ | ||||
| function write_BrtBookView(idx, o) { | ||||
| 	if(!o) o = new_buf(29); | ||||
| 	o.write_shift(-4, 0); | ||||
| @ -223,7 +222,6 @@ function write_BrtBookView(idx, o) { | ||||
| 	return o.length > o.l ? o.slice(0, o.l) : o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.60 Workbook */ | ||||
| function write_BOOKVIEWS(ba, wb/*::, opts*/) { | ||||
| 	/* required if hidden tab appears before visible tab */ | ||||
| 	if(!wb.Workbook || !wb.Workbook.Sheets) return; | ||||
| @ -240,7 +238,7 @@ function write_BOOKVIEWS(ba, wb/*::, opts*/) { | ||||
| 	write_record(ba, "BrtEndBookViews"); | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.302 BrtCalcProp */ | ||||
| /* [MS-XLSB] 2.4.305 BrtCalcProp */ | ||||
| /*function write_BrtCalcProp(data, o) { | ||||
| 	if(!o) o = new_buf(26); | ||||
| 	o.write_shift(4,0); // force recalc
 | ||||
| @ -253,14 +251,14 @@ function write_BOOKVIEWS(ba, wb/*::, opts*/) { | ||||
| 	return o; | ||||
| }*/ | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.640 BrtFileRecover */ | ||||
| /* [MS-XLSB] 2.4.646 BrtFileRecover */ | ||||
| /*function write_BrtFileRecover(data, o) { | ||||
| 	if(!o) o = new_buf(1); | ||||
| 	o.write_shift(1,0); | ||||
| 	return o; | ||||
| }*/ | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.60 Workbook */ | ||||
| /* [MS-XLSB] 2.1.7.61 Workbook */ | ||||
| function write_wb_bin(wb, opts) { | ||||
| 	var ba = buf_array(); | ||||
| 	write_record(ba, "BrtBeginBook"); | ||||
|  | ||||
| @ -837,15 +837,15 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| function parse_props(cfb/*:CFBContainer*/, props, o) { | ||||
| 	/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ | ||||
| 	var DSI = CFB.find(cfb, '!DocumentSummaryInformation'); | ||||
| 	if(DSI) try { | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); | ||||
| 	if(DSI && DSI.size > 0) try { | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae"); | ||||
| 		for(var d in DocSummary) props[d] = DocSummary[d]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ | ||||
| 	var SI = CFB.find(cfb, '!SummaryInformation'); | ||||
| 	if(SI) try { | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI); | ||||
| 	if(SI && SI.size > 0) try { | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9"); | ||||
| 		for(var s in Summary) if(props[s] == null) props[s] = Summary[s]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| } | ||||
|  | ||||
| @ -631,8 +631,10 @@ var XLSBRecordEnum = { | ||||
| 	/*::[*/0x0422/*::]*/: { n:"BrtBeginSparklineGroups" }, | ||||
| 	/*::[*/0x0423/*::]*/: { n:"BrtEndSparklineGroups" }, | ||||
| 	/*::[*/0x0425/*::]*/: { n:"BrtSXVD14" }, | ||||
| 	/*::[*/0x0426/*::]*/: { n:"BrtBeginSxview14" }, | ||||
| 	/*::[*/0x0427/*::]*/: { n:"BrtEndSxview14" }, | ||||
| 	/*::[*/0x0426/*::]*/: { n:"BrtBeginSXView14" }, | ||||
| 	/*::[*/0x0427/*::]*/: { n:"BrtEndSXView14" }, | ||||
| 	/*::[*/0x0428/*::]*/: { n:"BrtBeginSXView16" }, | ||||
| 	/*::[*/0x0429/*::]*/: { n:"BrtEndSXView16" }, | ||||
| 	/*::[*/0x042A/*::]*/: { n:"BrtBeginPCD14" }, | ||||
| 	/*::[*/0x042B/*::]*/: { n:"BrtEndPCD14" }, | ||||
| 	/*::[*/0x042C/*::]*/: { n:"BrtBeginExtConn14" }, | ||||
| @ -819,6 +821,12 @@ var XLSBRecordEnum = { | ||||
| 	/*::[*/0x0856/*::]*/: { n:"BrtFieldListActiveItem" }, | ||||
| 	/*::[*/0x0857/*::]*/: { n:"BrtPivotCacheIdVersion" }, | ||||
| 	/*::[*/0x0858/*::]*/: { n:"BrtSXDI15" }, | ||||
| 	/*::[*/0x0859/*::]*/: { n:"BrtBeginModelTimeGroupings" }, | ||||
| 	/*::[*/0x085A/*::]*/: { n:"BrtEndModelTimeGroupings" }, | ||||
| 	/*::[*/0x085B/*::]*/: { n:"BrtBeginModelTimeGrouping" }, | ||||
| 	/*::[*/0x085C/*::]*/: { n:"BrtEndModelTimeGrouping" }, | ||||
| 	/*::[*/0x085D/*::]*/: { n:"BrtModelTimeGroupingCalcCol" }, | ||||
| 	/*::[*/0x0C01/*::]*/: { n:"BrtRevisionPtr" }, | ||||
| 	/*::[*/0xFFFF/*::]*/: { n:"" } | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -84,16 +84,45 @@ function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) { | ||||
| 	return ba.end(); | ||||
| } | ||||
| 
 | ||||
| function write_FMTS_biff8(ba, NF/*:?SSFTable*/) { | ||||
| function write_FONTS_biff8(ba, data, opts) { | ||||
| 	write_biff_rec(ba, "Font", write_Font({ | ||||
| 		sz:12, | ||||
| 		color: {theme:1}, | ||||
| 		name: "Arial", | ||||
| 		family: 2, | ||||
| 		scheme: "minor" | ||||
| 	}, opts)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function write_FMTS_biff8(ba, NF/*:?SSFTable*/, opts) { | ||||
| 	if(!NF) return; | ||||
| 	[[5,8],[23,26],[41,44],[/*63*/50,/*66],[164,*/392]].forEach(function(r) { | ||||
| 		/*:: if(!NF) return; */ | ||||
| 		for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_biff_rec(ba, "Format", write_Format(i, NF[i])); | ||||
| 		for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_biff_rec(ba, "Format", write_Format(i, NF[i], opts)); | ||||
| 	}); | ||||
| } | ||||
| function write_CELLXFS_biff8(ba, data) { | ||||
| 	data.forEach(function(c) { | ||||
| 		write_biff_rec(ba, "XF", write_XF(c,0)); | ||||
| 
 | ||||
| function write_FEAT(ba, ws) { | ||||
| 	/* [MS-XLS] 2.4.112 */ | ||||
| 	var o = new_buf(19); | ||||
| 	o.write_shift(4, 0x867); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 1); o.write_shift(4, 0); | ||||
| 	write_biff_rec(ba, "FeatHdr", o); | ||||
| 	/* [MS-XLS] 2.4.111 */ | ||||
| 	o = new_buf(39); | ||||
| 	o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']), o); | ||||
| 	o.write_shift(4, 4); | ||||
| 	write_biff_rec(ba, "Feat", o); | ||||
| } | ||||
| 
 | ||||
| function write_CELLXFS_biff8(ba, opts) { | ||||
| 	for(var i = 0; i < 16; ++i) write_biff_rec(ba, "XF", write_XF({numFmtId:0, style:true}, 0, opts)); | ||||
| 	opts.cellXfs.forEach(function(c) { | ||||
| 		write_biff_rec(ba, "XF", write_XF(c, 0, opts)); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| @ -107,14 +136,14 @@ function write_ws_biff8_hlinks(ba/*:BufArray*/, ws) { | ||||
| } | ||||
| 
 | ||||
| function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) { | ||||
| 	var os = get_cell_style(opts.cellXfs, cell, opts); | ||||
| 	var os = 16 + get_cell_style(opts.cellXfs, cell, opts); | ||||
| 	if(cell.v != null) switch(cell.t) { | ||||
| 		case 'd': case 'n': | ||||
| 			var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v; | ||||
| 			/* TODO: emit RK as appropriate */ | ||||
| 			write_biff_rec(ba, "Number", write_Number(R, C, v, os, opts)); | ||||
| 			return; | ||||
| 		case 'b': case 'e': write_biff_rec(ba, "BoolErr", write_BoolErr(R, C, cell.v, os, opts, cell.t)); return; | ||||
| 		case 'b': case 'e': write_biff_rec(ba, 0x0205, write_BoolErr(R, C, cell.v, os, opts, cell.t)); return; | ||||
| 		/* TODO: codepage, sst */ | ||||
| 		case 's': case 'str': | ||||
| 			write_biff_rec(ba, "Label", write_Label(R, C, cell.v, os, opts)); | ||||
| @ -169,12 +198,14 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	/* ... */ | ||||
| 	if(b8 && _WB.Views) write_biff_rec(ba, "Window2", write_Window2(_WB.Views[0])); | ||||
| 	/* ... */ | ||||
| 	if(b8) write_biff_rec(ba, "MergeCells", write_MergeCells(ws['!merges']||[])); | ||||
| 	if(b8 && (ws['!merges']||[]).length) write_biff_rec(ba, "MergeCells", write_MergeCells(ws['!merges'])); | ||||
| 	/* ... */ | ||||
| 	if(b8) write_ws_biff8_hlinks(ba, ws); | ||||
| 	/* ... */ | ||||
| 	write_biff_rec(ba, "CodeName", write_XLUnicodeString(cname, opts)); | ||||
| 	/* ... */ | ||||
| 	if(b8) write_FEAT(ba, ws); | ||||
| 	/* ... */ | ||||
| 	write_biff_rec(ba, "EOF"); | ||||
| 	return ba.end(); | ||||
| } | ||||
| @ -182,7 +213,9 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| /* [MS-XLS] 2.1.7.20.3 */ | ||||
| function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) { | ||||
| 	var A = buf_array(); | ||||
| 	var _wb/*:WBWBProps*/ = /*::((*/(wb.Workbook||{}).WBProps||{/*::CodeName:"ThisWorkbook"*/}/*:: ):any)*/; | ||||
| 	var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/); | ||||
| 	var _sheets/*:Array<WBWSProp>*/ = (_WB.Sheets||[]); | ||||
| 	var _wb/*:WBProps*/ = /*::((*/_WB.WBProps||{/*::CodeName:"ThisWorkbook"*/}/*:: ):any)*/; | ||||
| 	var b8 = opts.biff == 8, b5 = opts.biff == 5; | ||||
| 	write_biff_rec(A, 0x0809, write_BOF(wb, 0x05, opts)); | ||||
| 	if(opts.bookType == "xla") write_biff_rec(A, "Addin"); | ||||
| @ -194,10 +227,10 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) { | ||||
| 	write_biff_rec(A, "WriteAccess", write_WriteAccess("SheetJS", opts)); | ||||
| 	write_biff_rec(A, "CodePage", writeuint16(b8 ? 0x04b0 : 0x04E4)); | ||||
| 	if(b8) write_biff_rec(A, "DSF", writeuint16(0)); | ||||
| 	if(b8) write_biff_rec(A, "Excel9File"); | ||||
| 	write_biff_rec(A, "RRTabId", write_RRTabId(wb.SheetNames.length)); | ||||
| 	if(b8 && wb.vbaraw) { | ||||
| 		write_biff_rec(A, "ObProj"); | ||||
| 		// $FlowIgnore
 | ||||
| 		var cname/*:string*/ = _wb.CodeName || "ThisWorkbook"; | ||||
| 		write_biff_rec(A, "CodeName", write_XLUnicodeString(cname, opts)); | ||||
| 	} | ||||
| @ -215,8 +248,9 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) { | ||||
| 	if(b8) write_biff_rec(A, "RefreshAll", writebool(false)); | ||||
| 	write_biff_rec(A, "BookBool", writeuint16(0)); | ||||
| 	/* ... */ | ||||
| 	if(b8) write_FMTS_biff8(A, wb.SSF); | ||||
| 	if(b8) write_CELLXFS_biff8(A, opts.cellXfs); | ||||
| 	write_FONTS_biff8(A, wb, opts); | ||||
| 	write_FMTS_biff8(A, wb.SSF, opts); | ||||
| 	write_CELLXFS_biff8(A, opts); | ||||
| 	/* ... */ | ||||
| 	if(b8) write_biff_rec(A, "UsesELFs", writebool(false)); | ||||
| 	var a = A.end(); | ||||
| @ -232,7 +266,8 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) { | ||||
| 	for(j = 0; j < wb.SheetNames.length; ++j) blen += (b8 ? 12 : 11) + (b8 ? 2 : 1) * wb.SheetNames[j].length; | ||||
| 	var start = a.length + blen + c.length; | ||||
| 	for(j = 0; j < wb.SheetNames.length; ++j) { | ||||
| 		write_biff_rec(B, "BoundSheet8", write_BoundSheet8({pos:start, hs:0, dt:0, name:wb.SheetNames[j]}, opts)); | ||||
| 		var _sheet/*:WBWSProp*/ = _sheets[j] || ({}/*:any*/); | ||||
| 		write_biff_rec(B, "BoundSheet8", write_BoundSheet8({pos:start, hs:_sheet.Hidden||0, dt:0, name:wb.SheetNames[j]}, opts)); | ||||
| 		start += bufs[j].length; | ||||
| 	} | ||||
| 	/* 1*BoundSheet8 */ | ||||
|  | ||||
							
								
								
									
										2
									
								
								demos/altjs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								demos/altjs/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| jvm-npm.js | ||||
| sheetjs.* | ||||
| SheetJSSwift | ||||
| duk* | ||||
| *.class | ||||
| *.jar | ||||
|  | ||||
							
								
								
									
										3
									
								
								demos/altjs/.swiftlint.yml
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								demos/altjs/.swiftlint.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| disabled_rules: | ||||
|   - trailing_semicolon | ||||
|   - identifier_name | ||||
| @ -4,49 +4,47 @@ all: duktape nashorn rhinojs swift | ||||
| .PHONY: base | ||||
| base: | ||||
| 	if [ ! -e sheetjs.xlsx ]; then node ../../tests/write.js; fi | ||||
| 	if [ ! -e xlsx.full.min.js ]; then cp ../../dist/xlsx.full.min.js .; fi | ||||
| 
 | ||||
| .PHONY: duktape | ||||
| duktape: base ## duktape demo
 | ||||
| 	bash ./duktape.sh | ||||
| 	gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm | ||||
| 	if [ ! -e xlsx.duktape.js ]; then cp ../../dist/xlsx.full.min.js xlsx.duktape.js; fi | ||||
| 	./sheetjs.duk | ||||
| 
 | ||||
| .PHONY: nashorn | ||||
| nashorn: base ## nashorn demo
 | ||||
| 	if [ ! -e jvm-npm.js ]; then curl -O https://rawgit.com/nodyn/jvm-npm/master/src/main/javascript/jvm-npm.js; fi | ||||
| 	jjs nashorn.js | ||||
| 
 | ||||
| .PHONY: swift | ||||
| swift: base ## swift demo
 | ||||
| 	if [ ! -e xlsx.swift.js ]; then cp ../../dist/xlsx.full.min.js xlsx.swift.js; fi | ||||
| 	./SheetJSCore.swift | ||||
| 	swiftc SheetJSCore.swift main.swift -o SheetJSSwift | ||||
| 	./SheetJSSwift | ||||
| 
 | ||||
| .PHONY: chakra | ||||
| chakra: base ## Chakra demo
 | ||||
| 	node -pe "fs.writeFileSync('payload.js', 'var payload = \"' + fs.readFileSync('sheetjs.xlsx').toString('base64') + '\";')" | ||||
| 	cat global.js ../../dist/xlsx.full.min.js payload.js chakra.js > xlsx.chakra.js | ||||
| 	cat global.js xlsx.full.min.js payload.js chakra.js > xlsx.chakra.js | ||||
| 	chakra ./xlsx.chakra.js | ||||
| 
 | ||||
| .PHONY: rhinojs ## rhino demo
 | ||||
| rhinojs: base SheetJSRhino.class | ||||
| 	java -cp .:SheetJS.jar:rhino.jar SheetJSRhino sheetjs.xlsx | ||||
| 	java -cp .:SheetJS.jar:rhino.jar SheetJSRhino sheetjs.xlsb | ||||
| 	java -cp .:SheetJS.jar:rhino.jar SheetJSRhino sheetjs.xls | ||||
| 	java -cp .:SheetJS.jar:rhino.jar SheetJSRhino sheetjs.xml.xls | ||||
| 	for ext in xlsx xlsb biff8.xls xml.xls; do java -cp .:SheetJS.jar:rhino.jar SheetJSRhino sheetjs.$$ext; done | ||||
| 
 | ||||
| RHDEPS=$(filter-out SheetJSRhino.class,$(patsubst %.java,%.class,$(wildcard com/sheetjs/*.java))) | ||||
| $(RHDEPS): %.class: %.java rhino.jar | ||||
| 	javac -cp .:SheetJS.jar:rhino.jar $*.java | ||||
| 
 | ||||
| SheetJSRhino.class: $(RHDEPS) | ||||
| 	jar -cf SheetJS.jar $^ ../../dist/xlsx.full.min.js | ||||
| 	jar -cf SheetJS.jar $^ xlsx.full.min.js | ||||
| 	javac -cp .:SheetJS.jar:rhino.jar SheetJSRhino.java | ||||
| 
 | ||||
| rhino.jar: | ||||
| 	if [ ! -e rhino ]; then git clone https://github.com/mozilla/rhino; fi | ||||
| 	if [ ! -e rhino/build/rhino*/js.jar ]; then cd rhino; ant jar; fi | ||||
| 	cp rhino/build/rhino*/js.jar rhino.jar | ||||
| 	#if [ ! -e rhino/build/rhino*/js.jar ]; then cd rhino; ant jar; fi | ||||
| 	#cp rhino/build/rhino*/js.jar rhino.jar | ||||
| 	if [ ! -e rhino/buildGradle/libs/rhino*.jar ]; then cd rhino; ./gradlew jar; fi | ||||
| 	cp rhino/buildGradle/libs/rhino*.jar rhino.jar | ||||
| 
 | ||||
| .PHONY: clean | ||||
| clean: | ||||
|  | ||||
| @ -31,7 +31,7 @@ let shared_dir = PlaygroundSupport.playgroundSharedDataDirectory; | ||||
| let lib_path = shared_dir.appendingPathComponent("xlsx.full.min.js"); | ||||
| 
 | ||||
| /* prepare JS context */ | ||||
| var context:JSContext! = JSContext(); | ||||
| var context: JSContext! = JSContext(); | ||||
| var src = "var global = (function(){ return this; }).call(null);"; | ||||
| context.evaluateScript(src); | ||||
| 
 | ||||
| @ -50,17 +50,17 @@ Binary strings can be passed back and forth using `String.Encoding.isoLatin1`: | ||||
| ```swift | ||||
| /* parse sheetjs.xls */ | ||||
| let file_path = shared_dir.appendingPathComponent("sheetjs.xls"); | ||||
| let data:String! = try String(contentsOf: file_path, encoding:String.Encoding.isoLatin1); | ||||
| context.setObject(data, forKeyedSubscript:"payload" as (NSCopying & NSObjectProtocol)!); | ||||
| let data: String! = try String(contentsOf: file_path, encoding: String.Encoding.isoLatin1); | ||||
| context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!); | ||||
| src = "var wb = XLSX.read(payload, {type:'binary'});"; | ||||
| context.evaluateScript(src); | ||||
| 
 | ||||
| /* write to sheetjs.xlsx  */ | ||||
| let out_path = shared_dir.appendingPathComponent("sheetjs.xlsx"); | ||||
| /* write to sheetjsw.xlsx  */ | ||||
| let out_path = shared_dir.appendingPathComponent("sheetjsw.xlsx"); | ||||
| src = "var out = XLSX.write(wb, {type:'binary', bookType:'xlsx'})"; | ||||
| context.evaluateScript(src); | ||||
| let outvalue: JSValue! = context.objectForKeyedSubscript("out"); | ||||
| var out:String! = outvalue.toString(); | ||||
| var out: String! = outvalue.toString(); | ||||
| try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLatin1); | ||||
| ``` | ||||
| 
 | ||||
| @ -70,9 +70,12 @@ try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLat | ||||
| Nashorn ships with Java 8.  It includes a command-line tool `jjs` for running JS | ||||
| scripts.  It is somewhat limited but does offer access to the full Java runtime. | ||||
| 
 | ||||
| `jjs` does not provide a CommonJS `require` implementation.  This demo uses a | ||||
| [`shim`](https://rawgit.com/nodyn/jvm-npm/master/src/main/javascript/jvm-npm.js) | ||||
| and manually requires the library. | ||||
| The `load` function in `jjs` can load the minified source directly: | ||||
| 
 | ||||
| ```js | ||||
| var global = (function(){ return this; }).call(null); | ||||
| load('xlsx.full.min.js'); | ||||
| ``` | ||||
| 
 | ||||
| The Java `nio` API provides the `Files.readAllBytes` method to read a file into | ||||
| a byte array.  To use in `XLSX.read`, the demo copies the bytes into a plain JS | ||||
| @ -115,7 +118,7 @@ duk_put_global_string(ctx, "buf"); | ||||
| duk_eval_string_noresult("workbook = XLSX.read(buf, {type:'buffer'});"); | ||||
| 
 | ||||
| /* write a workbook object to a C char array */ | ||||
| duk_eval_string(ctx, "XLSX.write(workbook, {type:'buffer', bookType:'xlsx'})"); | ||||
| duk_eval_string(ctx, "XLSX.write(workbook, {type:'array', bookType:'xlsx'})"); | ||||
| duk_size_t sz; | ||||
| char *buf = (char *)duk_get_buffer_data(ctx, -1, sz); | ||||
| duk_pop(ctx); | ||||
|  | ||||
| @ -8,7 +8,7 @@ let shared_dir = PlaygroundSupport.playgroundSharedDataDirectory; | ||||
| let lib_path = shared_dir.appendingPathComponent("xlsx.full.min.js"); | ||||
| 
 | ||||
| /* prepare JS context */ | ||||
| var context:JSContext! = JSContext(); | ||||
| var context: JSContext! = JSContext(); | ||||
| var src = "var global = (function(){ return this; }).call(null);"; | ||||
| context.evaluateScript(src); | ||||
| 
 | ||||
| @ -23,15 +23,15 @@ var version  = XLSXversion.toString(); | ||||
| 
 | ||||
| /* parse sheetjs.xls */ | ||||
| let file_path = shared_dir.appendingPathComponent("sheetjs.xls"); | ||||
| let data:String! = try String(contentsOf: file_path, encoding:String.Encoding.isoLatin1); | ||||
| context.setObject(data, forKeyedSubscript:"payload" as (NSCopying & NSObjectProtocol)!); | ||||
| let data: String! = try String(contentsOf: file_path, encoding: String.Encoding.isoLatin1); | ||||
| context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!); | ||||
| src = "var wb = XLSX.read(payload, {type:'binary'});"; | ||||
| context.evaluateScript(src); | ||||
| 
 | ||||
| /* write to sheetjs.xlsx  */ | ||||
| let out_path = shared_dir.appendingPathComponent("sheetjs.xlsx"); | ||||
| /* write to sheetjsw.xlsx  */ | ||||
| let out_path = shared_dir.appendingPathComponent("sheetjsw.xlsx"); | ||||
| src = "var out = XLSX.write(wb, {type:'binary', bookType:'xlsx'})"; | ||||
| context.evaluateScript(src); | ||||
| let outvalue: JSValue! = context.objectForKeyedSubscript("out"); | ||||
| var out:String! = outvalue.toString(); | ||||
| var out: String! = outvalue.toString(); | ||||
| try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLatin1); | ||||
|  | ||||
| @ -1,62 +1,96 @@ | ||||
| #!/usr/bin/env xcrun swift | ||||
| /* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */ | ||||
| import JavaScriptCore; | ||||
| 
 | ||||
| class SheetJS { | ||||
| enum SJSError: Error { | ||||
| 	case badJSContext; | ||||
| 	case badJSWorkbook; | ||||
| 	case badJSWorksheet; | ||||
| }; | ||||
| 
 | ||||
| class SJSWorksheet { | ||||
| 	var context: JSContext!; | ||||
| 	var wb: JSValue!; var ws: JSValue!; | ||||
| 	var idx: Int32; | ||||
| 
 | ||||
| 	func toCSV() throws -> String { | ||||
| 		let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX"); | ||||
| 		let utils: JSValue! = XLSX.objectForKeyedSubscript("utils"); | ||||
| 		let sheet_to_csv: JSValue! = utils.objectForKeyedSubscript("sheet_to_csv"); | ||||
| 		return sheet_to_csv.call(withArguments: [ws]).toString(); | ||||
| 	} | ||||
| 
 | ||||
| 	init(ctx: JSContext, workbook: JSValue, worksheet: JSValue, idx: Int32) throws { | ||||
| 		self.context = ctx; self.wb = workbook; self.ws = worksheet; self.idx = idx; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| class SJSWorkbook { | ||||
| 	var context: JSContext!; | ||||
| 	var wb: JSValue!; var SheetNames: JSValue!; var Sheets: JSValue!; | ||||
| 
 | ||||
| 	func getSheetAtIndex(idx: Int32) throws -> SJSWorksheet { | ||||
| 		let SheetName: String = SheetNames.atIndex(Int(idx)).toString(); | ||||
| 		let ws: JSValue! = Sheets.objectForKeyedSubscript(SheetName); | ||||
| 		return try SJSWorksheet(ctx: context, workbook: wb, worksheet: ws, idx: idx); | ||||
| 	} | ||||
| 
 | ||||
| 	func writeBStr(bookType: String = "xlsx") throws -> String { | ||||
| 		let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX"); | ||||
| 		context.evaluateScript(String(format: "var writeopts = {type:'binary', bookType:'%@'}", bookType)); | ||||
| 		let writeopts: JSValue! = context.objectForKeyedSubscript("writeopts"); | ||||
| 		let writefunc: JSValue! = XLSX.objectForKeyedSubscript("write"); | ||||
| 		return writefunc.call(withArguments: [wb, writeopts]).toString(); | ||||
| 	} | ||||
| 
 | ||||
| 	init(ctx: JSContext, wb: JSValue) throws { | ||||
| 		self.context = ctx; | ||||
| 		self.wb = wb; | ||||
| 		self.SheetNames = wb.objectForKeyedSubscript("SheetNames"); | ||||
| 		self.Sheets = wb.objectForKeyedSubscript("Sheets"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| class SheetJSCore { | ||||
| 	var context: JSContext!; | ||||
| 	var XLSX: JSValue!; | ||||
| 
 | ||||
| 	enum SJSError: Error { | ||||
| 		case badJSContext; | ||||
| 	}; | ||||
| 
 | ||||
| 	func init_context() throws -> JSContext { | ||||
| 		var context: JSContext! | ||||
| 		do { | ||||
| 			context = JSContext(); | ||||
| 			context.exceptionHandler = { ctx, X in if let e = X { print(e.toString()); }; } | ||||
| 			var src = "var global = (function(){ return this; }).call(null);"; | ||||
| 			context.evaluateScript(src); | ||||
| 			src = try String(contentsOfFile: "xlsx.swift.js"); | ||||
| 			context.exceptionHandler = { ctx, X in if let e = X { print(e.toString()); }; }; | ||||
| 			context.evaluateScript("var global = (function(){ return this; }).call(null);"); | ||||
| 			context.evaluateScript("if(typeof wbs == 'undefined') wbs = [];"); | ||||
| 			let src = try String(contentsOfFile: "xlsx.full.min.js"); | ||||
| 			context.evaluateScript(src); | ||||
| 			if context != nil { return context!; } | ||||
| 		} catch { print(error.localizedDescription); } | ||||
| 		throw SheetJS.SJSError.badJSContext; | ||||
| 		throw SJSError.badJSContext; | ||||
| 	} | ||||
| 
 | ||||
| 	func version() throws -> String { | ||||
| 		if let version = XLSX.objectForKeyedSubscript("version") { return version.toString(); } | ||||
| 		throw SheetJS.SJSError.badJSContext; | ||||
| 		throw SJSError.badJSContext; | ||||
| 	} | ||||
| 
 | ||||
| 	func readFileToCSV(file: String) throws -> String { | ||||
| 		let data:String! = try String(contentsOfFile: file, encoding:String.Encoding.isoLatin1); | ||||
| 		self.context.setObject(data, forKeyedSubscript:"payload" as (NSCopying & NSObjectProtocol)!); | ||||
| 	func readFile(file: String) throws -> SJSWorkbook { | ||||
| 		let data: String! = try String(contentsOfFile: file, encoding: String.Encoding.isoLatin1); | ||||
| 		return try readBStr(data: data); | ||||
| 	} | ||||
| 
 | ||||
| 		let src = [ | ||||
| 			"var wb = XLSX.read(payload, {type:'binary'});", | ||||
| 			"var ws = wb.Sheets[wb.SheetNames[0]];", | ||||
| 			"var result = XLSX.utils.sheet_to_csv(ws);" | ||||
| 		].joined(separator: "\n"); | ||||
| 		self.context.evaluateScript(src); | ||||
| 
 | ||||
| 		return context.objectForKeyedSubscript("result").toString(); | ||||
| 	func readBStr(data: String) throws -> SJSWorkbook { | ||||
| 		context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!); | ||||
| 		context.evaluateScript("var wb = XLSX.read(payload, {type:'binary'});"); | ||||
| 		let wb: JSValue! = context.objectForKeyedSubscript("wb"); | ||||
| 		if wb == nil { throw SJSError.badJSWorkbook; } | ||||
| 		return try SJSWorkbook(ctx: context, wb: wb); | ||||
| 	} | ||||
| 
 | ||||
| 	init() throws { | ||||
| 		do { | ||||
| 			self.context = try init_context(); | ||||
| 			self.XLSX = context.objectForKeyedSubscript("XLSX"); | ||||
| 			if self.XLSX == nil { | ||||
| 				throw SheetJS.SJSError.badJSContext; | ||||
| 			} | ||||
| 			self.XLSX = self.context.objectForKeyedSubscript("XLSX"); | ||||
| 			if self.XLSX == nil { throw SJSError.badJSContext; } | ||||
| 		} catch { print(error.localizedDescription); } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| let sheetjs = try SheetJS(); | ||||
| try print(sheetjs.version()); | ||||
| try print(sheetjs.readFileToCSV(file:"sheetjs.xlsx")); | ||||
| try print(sheetjs.readFileToCSV(file:"sheetjs.xlsb")); | ||||
| try print(sheetjs.readFileToCSV(file:"sheetjs.xls")); | ||||
| try print(sheetjs.readFileToCSV(file:"sheetjs.xml.xls")); | ||||
|  | ||||
| @ -17,7 +17,7 @@ public class JSHelper { | ||||
| 		byte[] b = Files.readAllBytes(Paths.get(file)); | ||||
| 		System.out.println(b.length); | ||||
| 		StringBuilder sb = new StringBuilder(); | ||||
| 		for(int i = 0; i < b.length; ++i) sb.append(Character.toString((char)b[i])); | ||||
| 		for(int i = 0; i < b.length; ++i) sb.append(Character.toString((char)(b[i] < 0 ? b[i] + 256 : b[i]))); | ||||
| 		return sb.toString(); | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -26,7 +26,7 @@ public class SheetJS { | ||||
| 		cx.evaluateString(scope, s, "<cmd>", 1, null); | ||||
| 
 | ||||
| 		/* eval library */ | ||||
| 		s = new Scanner(SheetJS.class.getResourceAsStream("/dist/xlsx.full.min.js")).useDelimiter("\\Z").next(); | ||||
| 		s = new Scanner(SheetJS.class.getResourceAsStream("/xlsx.full.min.js")).useDelimiter("\\Z").next(); | ||||
| 		//s = new Scanner(new File("xlsx.full.min.js")).useDelimiter("\\Z").next(); | ||||
| 		cx.evaluateString(scope, s, "<cmd>", 1, null); | ||||
| 
 | ||||
| @ -41,14 +41,14 @@ public class SheetJS { | ||||
| 		String d = JSHelper.read_file(filename); | ||||
| 
 | ||||
| 		/* options argument */ | ||||
| 		NativeObject q = (NativeObject)this.cx.evaluateString(this.scope, "q = {'type':'binary'};", "<cmd>", 2, null); | ||||
| 		NativeObject q = (NativeObject)this.cx.evaluateString(this.scope, "q = {'type':'binary', 'WTF':1};", "<cmd>", 2, null); | ||||
| 
 | ||||
| 		/* set up function arguments */ | ||||
| 		Object functionArgs[] = {d, q}; | ||||
| 		Object args[] = {d, q}; | ||||
| 
 | ||||
| 		/* call read -> wb workbook */ | ||||
| 		Function readfunc = (Function)JSHelper.get_object("XLSX.read",this.scope); | ||||
| 		NativeObject wb = (NativeObject)readfunc.call(this.cx, this.scope, this.nXLSX, functionArgs); | ||||
| 		NativeObject wb = (NativeObject)readfunc.call(this.cx, this.scope, this.nXLSX, args); | ||||
| 
 | ||||
| 		return new SheetJSFile(wb, this); | ||||
| 	} | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| #!/bin/bash | ||||
| DUKTAPE_VER=2.1.1 | ||||
| DUKTAPE_VER=2.2.0 | ||||
| if [ ! -e duktape-$DUKTAPE_VER ]; then | ||||
| 	if [ ! -e duktape-$DUKTAPE_VER.tar ]; then | ||||
| 		if [ ! -e duktape-$DUKTAPE_VER.tar.xz ]; then | ||||
| @ -14,4 +14,3 @@ for f in duktape.{c,h} duk_config.h; do | ||||
| 	cp duktape-$DUKTAPE_VER/src/$f . | ||||
| done | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										21
									
								
								demos/altjs/main.swift
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								demos/altjs/main.swift
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,21 @@ | ||||
| /* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */ | ||||
| 
 | ||||
| let sheetjs = try SheetJSCore(); | ||||
| 
 | ||||
| try print(sheetjs.version()); | ||||
| 
 | ||||
| let filenames: [[String]] = [ | ||||
| 	["xlsx", "xlsx"], | ||||
| 	["xlsb", "xlsb"], | ||||
| 	["biff8.xls", "xls"], | ||||
| 	["xml.xls", "xlml"] | ||||
| ]; | ||||
| 
 | ||||
| for fn in filenames { | ||||
| 	let wb: SJSWorkbook = try sheetjs.readFile(file: "sheetjs." + fn[0]); | ||||
| 	let ws: SJSWorksheet = try wb.getSheetAtIndex(idx: 0); | ||||
| 	let csv: String = try ws.toCSV(); | ||||
|     print(csv); | ||||
|     let wbout: String = try wb.writeBStr(bookType: fn[1]); | ||||
|     try wbout.write(toFile: "sheetjsswift." + fn[0], atomically: false, encoding: String.Encoding.isoLatin1); | ||||
| } | ||||
| @ -1,29 +1,36 @@ | ||||
| #!/usr/bin/env jjs
 | ||||
| /* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */ | ||||
| /* read file */ | ||||
| var path = java.nio.file.Paths.get('sheetjs.xlsx'); | ||||
| var fileArray = java.nio.file.Files.readAllBytes(path); | ||||
| 
 | ||||
| /* convert to plain JS array */ | ||||
| function b2a(b) { | ||||
| 	var out = new Array(b.length); | ||||
| 	for(var i = 0; i < out.length; i++) out[i] = b[i]; | ||||
| 	return out; | ||||
| } | ||||
| var u8a = b2a(fileArray); | ||||
| 
 | ||||
| /* load module */ | ||||
| load('./jvm-npm.js'); | ||||
| JSZip = require('../../jszip.js'); | ||||
| cptable = require('../../dist/cpexcel.js'); | ||||
| XLSX = require('../../xlsx.js'); | ||||
| var global = (function(){ return this; }).call(null); | ||||
| load('xlsx.full.min.js'); | ||||
| 
 | ||||
| /* read file */ | ||||
| var wb = XLSX.read(u8a, {type:"array"}); | ||||
| /* helper to convert byte array to plain JS array */ | ||||
| function b2a(b) { | ||||
| 	var out = new Array(b.length); | ||||
| 	for(var i = 0; i < out.length; i++) out[i] = (b[i] < 0 ? b[i] + 256 : b[i]); | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| /* get first worksheet */ | ||||
| var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| var js = XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| function process_file(path) { | ||||
| 	java.lang.System.out.println(path); | ||||
| 
 | ||||
| /* print out every line */ | ||||
| js.forEach(function(l) { java.lang.System.out.println(JSON.stringify(l)); }); | ||||
| 	/* read file */ | ||||
| 	var path = java.nio.file.Paths.get(path); | ||||
| 	var bytes = java.nio.file.Files.readAllBytes(path); | ||||
| 	var u8a = b2a(bytes); | ||||
| 
 | ||||
| 	/* read data */ | ||||
| 	var wb = XLSX.read(u8a, {type:"array"}); | ||||
| 
 | ||||
| 	/* get first worksheet as an array of arrays */ | ||||
| 	var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 	var js = XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| 
 | ||||
| 	/* print out every line */ | ||||
| 	js.forEach(function(l) { java.lang.System.out.println(JSON.stringify(l)); }); | ||||
| } | ||||
| 
 | ||||
| process_file('sheetjs.xlsx'); | ||||
| process_file('sheetjs.xlsb'); | ||||
| process_file('sheetjs.biff8.xls'); | ||||
|  | ||||
| @ -66,7 +66,7 @@ int main(int argc, char *argv[]) { | ||||
| 	DOIT("var global = (function(){ return this; }).call(null);"); | ||||
| 
 | ||||
| 	/* load library */ | ||||
| 	res = eval_file(ctx, "xlsx.duktape.js"); | ||||
| 	res = eval_file(ctx, "xlsx.full.min.js"); | ||||
| 	if(res != 0) FAIL("library load") | ||||
| 
 | ||||
| 	/* get version string */ | ||||
| @ -75,11 +75,12 @@ int main(int argc, char *argv[]) { | ||||
| 	duk_pop(ctx); | ||||
| 
 | ||||
| 	/* read file */ | ||||
| 	res = load_file(ctx, "sheetjs.xlsx", "buf"); | ||||
| 	if(res != 0) FAIL("load sheetjs.xlsx") | ||||
| #define INFILE "sheetjs.xlsx" | ||||
| 	res = load_file(ctx, INFILE, "buf"); | ||||
| 	if(res != 0) FAIL("load " INFILE) | ||||
| 
 | ||||
| 	/* parse workbook */ | ||||
| 	DOIT("wb = XLSX.read(buf, {type:'buffer'});"); | ||||
| 	DOIT("wb = XLSX.read(buf, {type:'buffer', cellNF:true});"); | ||||
| 	DOIT("ws = wb.Sheets[wb.SheetNames[0]]"); | ||||
| 
 | ||||
| 	/* print CSV */ | ||||
| @ -91,9 +92,15 @@ int main(int argc, char *argv[]) { | ||||
| 	DOIT("ws['A1'].v = 3; delete ws['A1'].w;"); | ||||
| 
 | ||||
| 	/* write file */ | ||||
| 	DOIT("newbuf = XLSX.write(wb, {type:'buffer', bookType:'xlsx'})"); | ||||
| 	res = save_file(ctx, "sheetjsw.xlsx", "newbuf"); | ||||
| 	if(res != 0) FAIL("save sheetjsw.xlsx") | ||||
| #define WRITE_TYPE(BOOKTYPE) \ | ||||
| 	DOIT("newbuf = (XLSX.write(wb, {type:'array', bookType:'" BOOKTYPE "'}));");\ | ||||
| 	res = save_file(ctx, "sheetjsw." BOOKTYPE, "newbuf");\ | ||||
| 	if(res != 0) FAIL("save sheetjsw." BOOKTYPE) | ||||
| 
 | ||||
| 	WRITE_TYPE("xlsb") | ||||
| 	WRITE_TYPE("xlsx") | ||||
| 	WRITE_TYPE("xls") | ||||
| 	WRITE_TYPE("csv") | ||||
| 
 | ||||
| 	/* cleanup */ | ||||
| 	duk_destroy_heap(ctx); | ||||
|  | ||||
| @ -2,10 +2,54 @@ | ||||
| 
 | ||||
| Despite the efforts to deprecate the pertinent operating systems, IE is still | ||||
| very popular, required for various government and corporate websites throughout | ||||
| the world.  The modern download strategies are not available in older versions | ||||
| of IE, but there are alternative approaches. | ||||
| the world.  The modern upload and download strategies are not available in older | ||||
| versions of IE, but there are alternative approaches. | ||||
| 
 | ||||
| ## Strategies | ||||
| 
 | ||||
| ## Upload Strategies | ||||
| 
 | ||||
| #### IE10 and IE11 FileReader | ||||
| 
 | ||||
| IE10 and IE11 support the standard HTML5 FileReader API: | ||||
| 
 | ||||
| ```js | ||||
| function handle_fr(e) { | ||||
| 	var files = e.target.files, f = files[0]; | ||||
| 	var reader = new FileReader(); | ||||
| 	var rABS = !!reader.readAsBinaryString; | ||||
| 	reader.onload = function(e) { | ||||
| 		var data = e.target.result; | ||||
| 		if(!rABS) data = new Uint8Array(data); | ||||
| 		var wb = XLSX.read(data, {type: rABS ? 'binary' : 'array'}); | ||||
| 		process_wb(wb); | ||||
| 	}; | ||||
| 	if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f); | ||||
| } | ||||
| input_dom_element.addEventListener('change', handle_fr, false); | ||||
| ``` | ||||
| 
 | ||||
| #### ActiveX-based Upload | ||||
| 
 | ||||
| Through the `Scripting.FileSystemObject` object model, a script in the VBScript | ||||
| scripting language can read from an arbitrary path on the filesystem.  The shim | ||||
| includes a special `IE_LoadFile` function to read binary strings from file. This | ||||
| should be called from a file input `onchange` event: | ||||
| 
 | ||||
| ```js | ||||
| var input_dom_element = document.getElementById("file"); | ||||
| function handle_ie() { | ||||
| 	/* get data from selected file */ | ||||
| 	var path = input_dom_element.value; | ||||
| 	var bstr = IE_LoadFile(path); | ||||
| 	/* read workbook */ | ||||
| 	var wb = XLSX.read(bstr, {type:'binary'}); | ||||
| 	/* DO SOMETHING WITH workbook HERE */ | ||||
| } | ||||
| input_dom_element.attachEvent('onchange', handle_ie); | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| ## Download Strategies | ||||
| 
 | ||||
| #### IE10 and IE11 File API | ||||
| 
 | ||||
| @ -30,8 +74,11 @@ This approach can be triggered, but it requires the user to enable ActiveX.  It | ||||
| is embedded as a strategy in `writeFile` and used only if the shim script is | ||||
| included in the page and the relevant features are enabled on the target system. | ||||
| 
 | ||||
| 
 | ||||
| ## Demo | ||||
| 
 | ||||
| #### Download | ||||
| 
 | ||||
| The included demo starts from an array of arrays, generating an editable HTML | ||||
| table with `aoa_to_sheet` and adding it to the page: | ||||
| 
 | ||||
| @ -67,4 +114,20 @@ Downloadify.create(element_id, { | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| The demo also includes an HTML file input element for updating the data table: | ||||
| 
 | ||||
| ```js | ||||
| var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| var html_string = XLSX.utils.sheet_to_html(ws, { id: "table", editable: true }); | ||||
| document.getElementById("container").innerHTML = html_string; | ||||
| ``` | ||||
| 
 | ||||
| The specific strategy is determined based on the presence of `IE_LoadFile`: | ||||
| 
 | ||||
| ```js | ||||
| var handler = typeof IE_LoadFile !== 'undefined' ? handle_ie : handle_fr; | ||||
| if(input_dom_element.attachEvent) input_dom_element.attachEvent('onchange', handler); | ||||
| else input_dom_element.addEventListener('change', handler, false); | ||||
| ``` | ||||
| 
 | ||||
| [](https://github.com/SheetJS/js-xlsx) | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| <!-- vim: set ts=2: --> | ||||
| <html> | ||||
| <head> | ||||
| <title>SheetJS JS-XLSX In-Browser HTML Table Export Demo</title> | ||||
| <title>SheetJS JS-XLSX In-Browser HTML Table Demo</title> | ||||
| <meta charset="utf-8" /> | ||||
| <style> | ||||
| .xport, .btn { | ||||
| @ -36,12 +36,15 @@ function doit(type, fn, dl) { | ||||
| } | ||||
| </script> | ||||
| <pre> | ||||
| <h3><a href="//sheetjs.com/">SheetJS</a> JS-XLSX In-Browser HTML Table Export Demo</h3> | ||||
| <h3><a href="//sheetjs.com/">SheetJS</a> JS-XLSX In-Browser HTML Table Demo</h3> | ||||
| <b>Compatibility notes:</b> | ||||
| - Editable table leverages the HTML5 contenteditable feature, supported in most browsers. | ||||
| - IE6-9 requires ActiveX or Flash to download files. | ||||
| - IE6-9 requires ActiveX to upload files and ActiveX or Flash to download files. | ||||
| - iOS Safari file download may not work. <a href="http://git.io/ios_save">This is a known issue</a>. | ||||
| 
 | ||||
| <b>Update Spreadsheet:</b> (submit file to update table; file parsed in browser) | ||||
| <input type="file" id="file" /> | ||||
| 
 | ||||
| <b>Editable Data Table:</b> (click a cell to edit it) | ||||
| </pre> | ||||
| <div id="container"></div> | ||||
| @ -83,6 +86,34 @@ document.getElementById("container").innerHTML = html_string; | ||||
| </table> | ||||
| <pre><b>Powered by the <a href="//sheetjs.com/opensource">community version of js-xlsx</a></b></pre> | ||||
| <script type="text/javascript"> | ||||
| var input_dom_element = document.getElementById("file"); | ||||
| function process_wb(wb) { | ||||
| 	var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 	var html_string = XLSX.utils.sheet_to_html(ws, { id: "data-table", editable: true }); | ||||
| 	document.getElementById("container").innerHTML = html_string; | ||||
| } | ||||
| function handle_ie() { | ||||
| 	var path = input_dom_element.value; | ||||
| 	var data = IE_LoadFile(path); | ||||
| 	var wb = XLSX.read(data, {type:'binary'}); | ||||
| 	process_wb(wb); | ||||
| } | ||||
| function handle_fr(e) { | ||||
| 	var files = e.target.files, f = files[0]; | ||||
| 	var reader = new FileReader(); | ||||
| 	var rABS = !!reader.readAsBinaryString; | ||||
| 	reader.onload = function(e) { | ||||
| 		var data = e.target.result; | ||||
| 		if(!rABS) data = new Uint8Array(data); | ||||
| 		var wb = XLSX.read(data, {type: rABS ? 'binary' : 'array'}); | ||||
| 		process_wb(wb); | ||||
| 	}; | ||||
| 	if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f); | ||||
| } | ||||
| var handler = typeof IE_LoadFile !== 'undefined' ? handle_ie : handle_fr; | ||||
| if(input_dom_element.attachEvent) input_dom_element.attachEvent('onchange', handler); | ||||
| else input_dom_element.addEventListener('change', handler, false); | ||||
| 
 | ||||
| function tableau(pid, iid, fmt, ofile) { | ||||
| 	if(typeof Downloadify !== 'undefined') Downloadify.create(pid,{ | ||||
| 			swf: 'downloadify.swf', | ||||
|  | ||||
							
								
								
									
										2
									
								
								dist/shim.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/shim.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										775
									
								
								dist/xlsx.extendscript.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										775
									
								
								dist/xlsx.extendscript.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										32
									
								
								dist/xlsx.full.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										32
									
								
								dist/xlsx.full.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										760
									
								
								dist/xlsx.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										760
									
								
								dist/xlsx.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										24
									
								
								dist/xlsx.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										24
									
								
								dist/xlsx.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -131,6 +131,8 @@ function handleFile(e) { | ||||
| input_dom_element.addEventListener('change', handleFile, false); | ||||
| ``` | ||||
| 
 | ||||
| The [`oldie` demo](demos/oldie/) shows an IE-compatible fallback scenario. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| More specialized cases, including mobile app file processing, are covered in the | ||||
|  | ||||
| @ -1,10 +1,12 @@ | ||||
| ### Cell Object | ||||
| 
 | ||||
| Cell objects are plain JS objects with keys and values following the convention: | ||||
| 
 | ||||
| | Key | Description                                                            | | ||||
| | --- | ---------------------------------------------------------------------- | | ||||
| | `v` | raw value (see Data Types section for more info)                       | | ||||
| | `w` | formatted text (if applicable)                                         | | ||||
| | `t` | cell type: `b` Boolean, `n` Number, `e` error, `s` String, `d` Date    | | ||||
| | `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub | | ||||
| | `f` | cell formula encoded as an A1-style string (if applicable)             | | ||||
| | `F` | range of enclosing array if formula is array formula (if applicable)   | | ||||
| | `r` | rich text encoding (if applicable)                                     | | ||||
|  | ||||
| @ -1,10 +1,17 @@ | ||||
| #### Data Types | ||||
| 
 | ||||
| The raw value is stored in the `v` field, interpreted based on the `t` field. | ||||
| The raw value is stored in the `v` value property, interpreted based on the `t` | ||||
| type property.  This separation allows for representation of numbers as well as | ||||
| numeric text.  There are 6 valid cell types: | ||||
| 
 | ||||
| Type `b` is the Boolean type.  `v` is interpreted according to JS truth tables. | ||||
| 
 | ||||
| Type `e` is the Error type. `v` holds the number and `w` holds the common name: | ||||
| | Type | Description                                                           | | ||||
| | :--: | :-------------------------------------------------------------------- | | ||||
| | `b`  | Boolean: value interpreted as JS `boolean`                            | | ||||
| | `e`  | Error: value is a numeric code and `w` property stores common name ** | | ||||
| | `n`  | Number: value is a JS `number` **                                     | | ||||
| | `d`  | Date: value is a JS `Date` object or string to be parsed as Date **   | | ||||
| | `s`  | Text: value interpreted as JS `string` and written as text **         | | ||||
| | `z`  | Stub: blank stub cell that is ignored by data processing utilities ** | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Error values and interpretation</b> (click to show)</summary> | ||||
| @ -33,14 +40,17 @@ Since JSON does not have a natural Date type, parsers are generally expected to | ||||
| store ISO 8601 Date strings like you would get from `date.toISOString()`.  On | ||||
| the other hand, writers and exporters should be able to handle date strings and | ||||
| JS Date objects.  Note that Excel disregards timezone modifiers and treats all | ||||
| dates in the local timezone.  js-xlsx does not correct for this error. | ||||
| dates in the local timezone.  The library does not correct for this error. | ||||
| 
 | ||||
| Type `s` is the String type.  `v` should be explicitly stored as a string to | ||||
| avoid possible confusion. | ||||
| Type `s` is the String type.  Values are explicitly stored as text.  Excel will | ||||
| interpret these cells as "number stored as text".  Generated Excel files | ||||
| automatically suppress that class of error, but other formats may elicit errors. | ||||
| 
 | ||||
| Type `z` represents blank stub cells.  They are generated in cases where cells | ||||
| have no assigned value but hold comments or other metadata. They are ignored by | ||||
| the core library data processing utility functions.  By default these cells are | ||||
| not generated; the parser `sheetStubs` option must be set to `true`. | ||||
| 
 | ||||
| Type `z` represents blank stub cells.  These do not have any data or type, and | ||||
| are not processed by any of the core library functions.  By default these cells | ||||
| will not be generated; the parser `sheetStubs` option must be set to `true`. | ||||
| 
 | ||||
| #### Dates | ||||
| 
 | ||||
|  | ||||
| @ -398,6 +398,8 @@ function handleFile(e) { | ||||
| input_dom_element.addEventListener('change', handleFile, false); | ||||
| ``` | ||||
| 
 | ||||
| The [`oldie` demo](demos/oldie/) shows an IE-compatible fallback scenario. | ||||
| 
 | ||||
| 
 | ||||
| More specialized cases, including mobile app file processing, are covered in the | ||||
| [included demos](demos/) | ||||
| @ -777,11 +779,13 @@ for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
| 
 | ||||
| ### Cell Object | ||||
| 
 | ||||
| Cell objects are plain JS objects with keys and values following the convention: | ||||
| 
 | ||||
| | Key | Description                                                            | | ||||
| | --- | ---------------------------------------------------------------------- | | ||||
| | `v` | raw value (see Data Types section for more info)                       | | ||||
| | `w` | formatted text (if applicable)                                         | | ||||
| | `t` | cell type: `b` Boolean, `n` Number, `e` error, `s` String, `d` Date    | | ||||
| | `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub | | ||||
| | `f` | cell formula encoded as an A1-style string (if applicable)             | | ||||
| | `F` | range of enclosing array if formula is array formula (if applicable)   | | ||||
| | `r` | rich text encoding (if applicable)                                     | | ||||
| @ -801,11 +805,18 @@ array range.  Other cells in the range will omit the `f` field. | ||||
| 
 | ||||
| #### Data Types | ||||
| 
 | ||||
| The raw value is stored in the `v` field, interpreted based on the `t` field. | ||||
| The raw value is stored in the `v` value property, interpreted based on the `t` | ||||
| type property.  This separation allows for representation of numbers as well as | ||||
| numeric text.  There are 6 valid cell types: | ||||
| 
 | ||||
| Type `b` is the Boolean type.  `v` is interpreted according to JS truth tables. | ||||
| 
 | ||||
| Type `e` is the Error type. `v` holds the number and `w` holds the common name: | ||||
| | Type | Description                                                           | | ||||
| | :--: | :-------------------------------------------------------------------- | | ||||
| | `b`  | Boolean: value interpreted as JS `boolean`                            | | ||||
| | `e`  | Error: value is a numeric code and `w` property stores common name ** | | ||||
| | `n`  | Number: value is a JS `number` **                                     | | ||||
| | `d`  | Date: value is a JS `Date` object or string to be parsed as Date **   | | ||||
| | `s`  | Text: value interpreted as JS `string` and written as text **         | | ||||
| | `z`  | Stub: blank stub cell that is ignored by data processing utilities ** | | ||||
| 
 | ||||
| 
 | ||||
| |  Value | Error Meaning   | | ||||
| @ -831,14 +842,17 @@ Since JSON does not have a natural Date type, parsers are generally expected to | ||||
| store ISO 8601 Date strings like you would get from `date.toISOString()`.  On | ||||
| the other hand, writers and exporters should be able to handle date strings and | ||||
| JS Date objects.  Note that Excel disregards timezone modifiers and treats all | ||||
| dates in the local timezone.  js-xlsx does not correct for this error. | ||||
| dates in the local timezone.  The library does not correct for this error. | ||||
| 
 | ||||
| Type `s` is the String type.  `v` should be explicitly stored as a string to | ||||
| avoid possible confusion. | ||||
| Type `s` is the String type.  Values are explicitly stored as text.  Excel will | ||||
| interpret these cells as "number stored as text".  Generated Excel files | ||||
| automatically suppress that class of error, but other formats may elicit errors. | ||||
| 
 | ||||
| Type `z` represents blank stub cells.  They are generated in cases where cells | ||||
| have no assigned value but hold comments or other metadata. They are ignored by | ||||
| the core library data processing utility functions.  By default these cells are | ||||
| not generated; the parser `sheetStubs` option must be set to `true`. | ||||
| 
 | ||||
| Type `z` represents blank stub cells.  These do not have any data or type, and | ||||
| are not processed by any of the core library functions.  By default these cells | ||||
| will not be generated; the parser `sheetStubs` option must be set to `true`. | ||||
| 
 | ||||
| #### Dates | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "xlsx", | ||||
| 	"version": "0.12.0", | ||||
| 	"version": "0.12.1", | ||||
| 	"author": "sheetjs", | ||||
| 	"description": "SheetJS Spreadsheet data parser and writer", | ||||
| 	"keywords": [ | ||||
| @ -31,7 +31,7 @@ | ||||
| 	}, | ||||
| 	"dependencies": { | ||||
| 		"adler-32": "~1.2.0", | ||||
| 		"cfb": "~1.0.2", | ||||
| 		"cfb": "~1.0.3", | ||||
| 		"codepage": "~1.12.0", | ||||
| 		"commander": "~2.13.0", | ||||
| 		"crc-32": "~1.2.0", | ||||
|  | ||||
							
								
								
									
										15
									
								
								shim.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										15
									
								
								shim.js
									
									
									
									
									
								
							| @ -368,3 +368,18 @@ var IE_SaveFile = (function() { try { | ||||
| 	} | ||||
| 	return function(data, filename) { return IE_SaveFile_Impl(IE_GetPath(filename), fix_data(data)); }; | ||||
| } catch(e) { return void 0; }})(); | ||||
| var IE_LoadFile = (function() { try { | ||||
| 	if(typeof IE_LoadFile_Impl == "undefined") document.write([ | ||||
| '<script type="text/vbscript" language="vbscript">', | ||||
| 'Function IE_LoadFile_Impl(FileName): Dim out(), plen, i, cc: Set fso = CreateObject("Scripting.FileSystemObject"): Set f = fso.GetFile(FileName): Set stream = f.OpenAsTextStream(1, 0): plen = f.Size: ReDim out(plen): For i = 1 To plen Step 1: cc = Hex(Asc(stream.read(1))): If Len(cc) < 2 Then: cc = "0" & cc: End If: out(i) = cc: Next: IE_LoadFile_Impl = Join(out,""): End Function', | ||||
| '|/script>'.replace("|","<") | ||||
| 	].join("\r\n")); | ||||
| 	if(typeof IE_LoadFile_Impl == "undefined") return void 0; | ||||
| 	function fix_data(data) { | ||||
| 		var out = []; | ||||
| 		for(var i = 0; i < data.length; i+=2) out.push(String.fromCharCode(parseInt(data.slice(i, i+2), 16))); | ||||
| 		var o = out.join(""); | ||||
| 		return o; | ||||
| 	} | ||||
| 	return function(filename) { return fix_data(IE_LoadFile_Impl(filename)); }; | ||||
| } catch(e) { return void 0; }})(); | ||||
|  | ||||
| @ -39,9 +39,6 @@ | ||||
|     <script src="fs_.js"></script> | ||||
|     <script src="fixtures.js"></script> | ||||
|     <script src="xlsx.full.min.js"></script> | ||||
|     <!--[if IE]> | ||||
|       <script type="text/javascript" src="xhr-hack.js"></script> | ||||
|     <![endif]--> | ||||
|     <div id="mocha"></div> | ||||
|     <script src="mocha.js"></script> | ||||
|     <script> | ||||
|  | ||||
| @ -39,9 +39,6 @@ | ||||
|     <script src="fs_.js"></script> | ||||
|     <script src="fixtures.js"></script> | ||||
|     <script src="xlsx.full.min.js"></script> | ||||
|     <!--[if IE]> | ||||
|       <script type="text/javascript" src="xhr-hack.js"></script> | ||||
|     <![endif]--> | ||||
|     <div id="mocha"></div> | ||||
|     <script src="sauce-client.js"></script> | ||||
|     <script src="mocha.js"></script> | ||||
|  | ||||
| @ -1,17 +0,0 @@ | ||||
| var IEBinaryToArray_ByteStr_Script = | ||||
|    "<!-- IEBinaryToArray_ByteStr -->\r\n"+ | ||||
|    "<script type='text/vbscript'>\r\n"+ | ||||
|    "Function IEBinaryToArray_ByteStr(Binary) : IEBinaryToArray_ByteStr = CStr(Binary) : End Function\r\n"+ | ||||
|    "Function IEBinaryToArray_ByteStr_Last(Binary)\r\n"+ | ||||
|    "   Dim lastIndex\r\n"+ | ||||
|    "   lastIndex = LenB(Binary)\r\n"+ | ||||
|    "   if lastIndex mod 2 Then\r\n"+ | ||||
|    "       IEBinaryToArray_ByteStr_Last = Chr( AscB( MidB( Binary, lastIndex, 1 ) ) )\r\n"+ | ||||
|    "   Else\r\n"+ | ||||
|    "       IEBinaryToArray_ByteStr_Last = "+'""'+"\r\n"+ | ||||
|    "   End If\r\n"+ | ||||
|    "End Function\r\n"+ | ||||
|    "</script>\r\n"; | ||||
| 
 | ||||
| document.write(IEBinaryToArray_ByteStr_Script); | ||||
| 
 | ||||
							
								
								
									
										3
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +1,6 @@ | ||||
| /* index.d.ts (C) 2015-present SheetJS and contributors */ | ||||
| // TypeScript Version: 2.2
 | ||||
| import * as CFB from "cfb"; | ||||
| 
 | ||||
| /** Version string */ | ||||
| export const version: string; | ||||
| @ -8,7 +9,7 @@ export const version: string; | ||||
| export const SSF: any; | ||||
| 
 | ||||
| /** CFB Library */ | ||||
| export const CFB: any; | ||||
| export { CFB }; | ||||
| 
 | ||||
| /** NODE ONLY! Attempts to read filename and parse */ | ||||
| export function readFile(filename: string, opts?: ParsingOptions): WorkBook; | ||||
|  | ||||
| @ -48,3 +48,9 @@ const newwb = XLSX.utils.book_new(); | ||||
| XLSX.utils.book_append_sheet(newwb, aoa2, "AOA"); | ||||
| XLSX.utils.book_append_sheet(newwb, js2ws, "JSON"); | ||||
| const bstrxlsx: string = XLSX.write(newwb, {type: "binary", bookType: "xlsx" }); | ||||
| 
 | ||||
| const CFB = XLSX.CFB; | ||||
| const vbawb = XLSX.readFile("test.xlsm", {bookVBA:true}); | ||||
| if(vbawb.vbaraw) { | ||||
| 	const cfb: XLSX.CFB.CFB$Container = CFB.read(vbawb.vbaraw, {type: "buffer"}); | ||||
| } | ||||
|  | ||||
							
								
								
									
										760
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										760
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user