forked from sheetjs/sheetjs
		
	version bump 0.9.7: write features
- write !cols widths : XLSX XLSB XLML - write hyperlinks : XLML - XLSB convert date cell to numeric on write - fixed issue with assigning self in jszip issues: - closes #607 h/t @jscheid - closes #195 h/t @asfman
This commit is contained in:
		
							parent
							
								
									085150db3b
								
							
						
					
					
						commit
						b89a876076
					
				| @ -8,6 +8,7 @@ changes may not be included if they are not expected to break existing code. | ||||
| ## Unreleased | ||||
| 
 | ||||
| * XLS legacy `!range` field removed | ||||
| * Hyperlink tooltip is stored in the `Tooltip` field | ||||
| 
 | ||||
| ## 0.9.6 (2017-03-25) | ||||
| 
 | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| XLSX.version = '0.9.6'; | ||||
| XLSX.version = '0.9.7'; | ||||
|  | ||||
| @ -95,7 +95,7 @@ function ReadShift(size/*:number*/, t/*:?string*/) { | ||||
| 		case 'cstr': size = 0; o = ""; | ||||
| 			while((w=__readUInt8(this, this.l + size++))!==0) oo.push(_getchar(w)); | ||||
| 			o = oo.join(""); break; | ||||
| 		case 'wstr': size = 0; o = ""; | ||||
| 		case '_wstr': size = 0; o = ""; | ||||
| 			while((w=__readUInt16LE(this,this.l +size))!==0){oo.push(_getchar(w));size+=2;} | ||||
| 			size+=2; o = oo.join(""); break; | ||||
| 
 | ||||
|  | ||||
| @ -226,6 +226,15 @@ var CTYPE_XML_ROOT = writextag('Types', null, { | ||||
| var CTYPE_DEFAULTS = [ | ||||
| 	['xml', 'application/xml'], | ||||
| 	['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'], | ||||
| 	/* from test files */ | ||||
| 	['bmp', 'image/bmp'], | ||||
| 	['png', 'image/png'], | ||||
| 	['gif', 'image/gif'], | ||||
| 	['emf', 'image/x-emf'], | ||||
| 	['wmf', 'image/x-wmf'], | ||||
| 	['jpg', 'image/jpeg'], ['jpeg', 'image/jpeg'], | ||||
| 	['tif', 'image/tiff'], ['tiff', 'image/tiff'], | ||||
| 	['pdf', 'application/pdf'], | ||||
| 	['rels', type2ct.rels[0]] | ||||
| ].map(function(x) { | ||||
| 	return writextag('Default', null, {'Extension':x[0], 'ContentType': x[1]}); | ||||
| @ -267,6 +276,7 @@ function write_ct(ct, opts)/*:string*/ { | ||||
| 	['strs', 'styles'].forEach(f1); | ||||
| 	['coreprops', 'extprops', 'custprops'].forEach(f3); | ||||
| 	f3('vba'); | ||||
| 	f3('comments'); | ||||
| 	if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); } | ||||
| 	return o.join(""); | ||||
| } | ||||
|  | ||||
| @ -18,7 +18,7 @@ function parse_cust_props(data/*:string*/, opts) { | ||||
| 				var type = toks[0].substring(4), text = toks[1]; | ||||
| 				/* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */ | ||||
| 				switch(type) { | ||||
| 					case 'lpstr': case 'lpwstr': case 'bstr': case 'lpwstr': | ||||
| 					case 'lpstr': case 'bstr': case 'lpwstr': | ||||
| 						p[name] = unescapexml(text); | ||||
| 						break; | ||||
| 					case 'bool': | ||||
|  | ||||
| @ -51,7 +51,7 @@ function rgb_tint(hex, tint) { | ||||
| 
 | ||||
| /* 18.3.1.13 width calculations */ | ||||
| /* [MS-OI29500] 2.1.595 Column Width & Formatting */ | ||||
| var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW; | ||||
| var DEF_MDW = 6, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW; | ||||
| function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); } | ||||
| function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; } | ||||
| function char2width(chr) { return (Math.round((chr * MDW + 5)/MDW*256))/256; } | ||||
|  | ||||
| @ -75,8 +75,8 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '</fill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 
 | ||||
| 			/* 18.8.24 gradientFill CT_GradientFill */ | ||||
| 			case '<fill>': break; | ||||
| 			case '</fill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 			case '<gradientFill>': break; | ||||
| 			case '</gradientFill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 
 | ||||
| 			/* 18.8.32 patternFill CT_PatternFill */ | ||||
| 			case '<patternFill': case '<patternFill>': | ||||
|  | ||||
| @ -11,6 +11,18 @@ function get_sst_id(sst/*:SST*/, str/*:string*/)/*:number*/ { | ||||
| 	sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len; | ||||
| } | ||||
| 
 | ||||
| function col_obj_w(C/*:number*/, col) { | ||||
| 	var p = ({min:C+1,max:C+1}/*:any*/); | ||||
| 	/* wch (chars), wpx (pixels) */ | ||||
| 	var width = -1; | ||||
| 	if(col.MDW) MDW = col.MDW; | ||||
| 	if(col.width != null) p.customWidth = 1; | ||||
| 	else if(col.wpx != null) width = px2char(col.wpx); | ||||
| 	else if(col.wch != null) width = col.wch; | ||||
| 	if(width > -1) { p.width = char2width(width); p.customWidth = 1; } | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| function get_cell_style(styles, cell, opts) { | ||||
| 	var z = opts.revssf[cell.z != null ? cell.z : "General"]; | ||||
| 	for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i; | ||||
|  | ||||
| @ -70,7 +70,7 @@ function write_ws_xml_merges(merges) { | ||||
| 	return o + '</mergeCells>'; | ||||
| } | ||||
| 
 | ||||
| function parse_ws_xml_hlinks(s, data, rels) { | ||||
| function parse_ws_xml_hlinks(s, data/*:Array<string>*/, rels) { | ||||
| 	for(var i = 0; i != data.length; ++i) { | ||||
| 		var val = parsexmltag(data[i], true); | ||||
| 		if(!val.ref) return; | ||||
| @ -84,6 +84,7 @@ function parse_ws_xml_hlinks(s, data, rels) { | ||||
| 			rel = {Target: val.location, TargetMode: 'Internal'}; | ||||
| 			val.Rel = rel; | ||||
| 		} | ||||
| 		if(val.tooltip) { val.Tooltip = val.tooltip; delete val.tooltip; } | ||||
| 		var rng = safe_decode_range(val.ref); | ||||
| 		for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) { | ||||
| 			var addr = encode_cell({c:C,r:R}); | ||||
| @ -109,15 +110,7 @@ function write_ws_xml_cols(ws, cols)/*:string*/ { | ||||
| 	var o = ["<cols>"], col, width; | ||||
| 	for(var i = 0; i != cols.length; ++i) { | ||||
| 		if(!(col = cols[i])) continue; | ||||
| 		var p = ({min:i+1,max:i+1}/*:any*/); | ||||
| 		/* wch (chars), wpx (pixels) */ | ||||
| 		width = -1; | ||||
| 		if(col.MDW) MDW = col.MDW; | ||||
| 		if(col.width); | ||||
| 		else if(col.wpx) width = px2char(col.wpx); | ||||
| 		else if(col.wch) width = col.wch; | ||||
| 		if(width > -1) { p.width = char2width(width); p.customWidth= 1; } | ||||
| 		o[o.length] = (writextag('col', null, p)); | ||||
| 		o[o.length] = (writextag('col', null, col_obj_w(i, col))); | ||||
| 	} | ||||
| 	o[o.length] = "</cols>"; | ||||
| 	return o.join(""); | ||||
| @ -328,14 +321,16 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ { | ||||
| 
 | ||||
| 	if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols'])); | ||||
| 	o[sidx = o.length] = '<sheetData/>'; | ||||
| 	if(ws['!ref'] !== undefined) { | ||||
| 	if(ws['!ref'] != null) { | ||||
| 		rdata = write_ws_xml_data(ws, opts, idx, wb); | ||||
| 		if(rdata.length > 0) o[o.length] = (rdata); | ||||
| 	} | ||||
| 	if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); } | ||||
| 
 | ||||
| 	if(ws['!merges'] !== undefined && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges'])); | ||||
| 	if(ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges'])); | ||||
| 
 | ||||
| 	if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); } | ||||
| 
 | ||||
| 	delete ws['!links']; | ||||
| 	return o.join(""); | ||||
| } | ||||
|  | ||||
| @ -226,7 +226,7 @@ function parse_BrtHLink(data, length, opts) { | ||||
| 	var tooltip = parse_XLWideString(data); | ||||
| 	var display = parse_XLWideString(data); | ||||
| 	data.l = end; | ||||
| 	return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display}; | ||||
| 	return {rfx:rfx, relId:relId, loc:loc, Tooltip:tooltip, display:display}; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.6 BrtArrFmla */ | ||||
| @ -255,6 +255,20 @@ function parse_BrtShrFmla(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.323 BrtColInfo */ | ||||
| /* TODO: once XLS ColInfo is set, combine the functions */ | ||||
| function write_BrtColInfo(C/*:number*/, col, o) { | ||||
| 	if(o == null) o = new_buf(18); | ||||
| 	var p = col_obj_w(C, col); | ||||
| 	o.write_shift(-4, C); | ||||
| 	o.write_shift(-4, C); | ||||
| 	o.write_shift(4, p.width * 256); | ||||
| 	o.write_shift(4, 0/*ixfe*/); // style
 | ||||
| 	o.write_shift(1, 2); // bit flag
 | ||||
| 	o.write_shift(1, 0); // bit flag
 | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.61 Worksheet */ | ||||
| function parse_ws_bin(data, opts, rels, wb, themes, styles)/*:Worksheet*/ { | ||||
| 	if(!data) return data; | ||||
| @ -521,9 +535,15 @@ function parse_ws_bin(data, opts, rels, wb, themes, styles)/*:Worksheet*/ { | ||||
| /* TODO: something useful -- this is a stub */ | ||||
| function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) { | ||||
| 	if(cell.v === undefined) return ""; | ||||
| 	var vv = ""; | ||||
| 	var vv = ""; var olddate = null; | ||||
| 	switch(cell.t) { | ||||
| 		case 'b': vv = cell.v ? "1" : "0"; break; | ||||
| 		case 'd': // no BrtCellDate :(
 | ||||
| 			cell.z = cell.z || SSF._table[14]; | ||||
| 			olddate = cell.v; | ||||
| 			cell.v = datenum((cell.v/*:any*/)); cell.t = 'n'; | ||||
| 			break; | ||||
| 		/* falls through */ | ||||
| 		case 'n': case 'e': vv = ''+cell.v; break; | ||||
| 		default: vv = cell.v; break; | ||||
| 	} | ||||
| @ -533,7 +553,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num | ||||
| 	switch(cell.t) { | ||||
| 		case 's': case 'str': | ||||
| 			if(opts.bookSST) { | ||||
| 				vv = get_sst_id(opts.Strings, cell.v); | ||||
| 				vv = get_sst_id(opts.Strings, (cell.v/*:any*/)); | ||||
| 				o.t = "s"; o.v = vv; | ||||
| 				write_record(ba, "BrtCellIsst", write_BrtCellIsst(cell, o)); | ||||
| 			} else { | ||||
| @ -545,6 +565,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num | ||||
| 			/* TODO: determine threshold for Real vs RK */ | ||||
| 			if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) write_record(ba, "BrtCellRk", write_BrtCellRk(cell, o)); | ||||
| 			else write_record(ba, "BrtCellReal", write_BrtCellReal(cell, o)); | ||||
| 			if(olddate) { cell.t = 'd'; cell.v = olddate; } | ||||
| 			return; | ||||
| 		case 'b': | ||||
| 			o.t = "b"; | ||||
| @ -555,7 +576,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num | ||||
| 	write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o)); | ||||
| } | ||||
| 
 | ||||
| function write_CELLTABLE(ba, ws, idx, opts, wb) { | ||||
| function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = []; | ||||
| 	write_record(ba, 'BrtBeginSheetData'); | ||||
| 	for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
| @ -582,6 +603,13 @@ function write_MERGECELLS(ba, ws/*:Worksheet*/) { | ||||
| 	write_record(ba, 'BrtEndMergeCells'); | ||||
| } | ||||
| 
 | ||||
| function write_COLINFOS(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	if(!ws || !ws['!cols']) return; | ||||
| 	write_record(ba, 'BrtBeginColInfos'); | ||||
| 	ws['!cols'].forEach(function(m, i) { if(m) write_record(ba, 'BrtColInfo', write_BrtColInfo(i, m)); }); | ||||
| 	write_record(ba, 'BrtEndColInfos'); | ||||
| } | ||||
| 
 | ||||
| function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	var ba = buf_array(); | ||||
| 	var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}; | ||||
| @ -591,7 +619,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	write_record(ba, "BrtWsDim", write_BrtWsDim(r)); | ||||
| 	/* [WSVIEWS2] */ | ||||
| 	/* [WSFMTINFO] */ | ||||
| 	/* *COLINFOS */ | ||||
| 	write_COLINFOS(ba, ws, idx, opts, wb); | ||||
| 	write_CELLTABLE(ba, ws, idx, opts, wb); | ||||
| 	/* [BrtSheetCalcProp] */ | ||||
| 	/* [[BrtSheetProtectionIso] BrtSheetProtection] */ | ||||
|  | ||||
| @ -199,8 +199,8 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { | ||||
| 				if(comments.length > 0) cell.c = comments; | ||||
| 				if((!opts.sheetRows || opts.sheetRows > r) && cell.v !== undefined) cursheet[encode_col(c) + encode_row(r)] = cell; | ||||
| 				if(cell.HRef) { | ||||
| 					cell.l = {Target:cell.HRef, tooltip:cell.HRefScreenTip}; | ||||
| 					cell.HRef = cell.HRefScreenTip = undefined; | ||||
| 					cell.l = {Target:cell.HRef, Tooltip:cell.HRefScreenTip}; | ||||
| 					delete cell.HRef; delete cell.HRefScreenTip; | ||||
| 				} | ||||
| 				if(cell.MergeAcross || cell.MergeDown) { | ||||
| 					var cc = c + (parseInt(cell.MergeAcross,10)|0); | ||||
| @ -787,6 +787,11 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{ | ||||
| 		attr["ss:ArrayRange"] = "RC:R" + (end.r == addr.r ? "" : "[" + (end.r - addr.r) + "]") + "C" + (end.c == addr.c ? "" : "[" + (end.c - addr.c) + "]"); | ||||
| 	} | ||||
| 
 | ||||
| 	if(cell.l && cell.l.Target) { | ||||
| 		attr["ss:HRef"] = escapexml(cell.l.Target); | ||||
| 		if(cell.l.Tooltip) attr["x:HRefScreenTip"] = escapexml(cell.l.Tooltip); | ||||
| 	} | ||||
| 
 | ||||
| 	if(ws['!merges']) { | ||||
| 		var marr = ws['!merges']; | ||||
| 		for(var mi = 0; mi != marr.length; ++mi) { | ||||
| @ -822,6 +827,10 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo | ||||
| 	var range = safe_decode_range(ws['!ref']); | ||||
| 	var marr = ws['!merges'] || [], mi = 0; | ||||
| 	var o = []; | ||||
| 	if(ws['!cols']) ws['!cols'].forEach(function(n, i) { | ||||
| 		var p = col_obj_w(i, n); | ||||
| 		o.push(writextag("Column",null, {"ss:Index":i+1, "ss:Width":width2px(p.width)})); | ||||
| 	}); | ||||
| 	for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
| 		var row = ['<Row ss:Index="' + (R+1) + '">']; | ||||
| 		for(var C = range.s.c; C <= range.e.c; ++C) { | ||||
|  | ||||
| @ -432,7 +432,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 					for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) | ||||
| 						for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) | ||||
| 							if(out[encode_cell({c:rngC,r:rngR})]) | ||||
| 								out[encode_cell({c:rngC,r:rngR})].l.tooltip = val[1]; | ||||
| 								out[encode_cell({c:rngC,r:rngR})].l.Tooltip = val[1]; | ||||
| 				} break; | ||||
| 
 | ||||
| 				/* Comments */ | ||||
|  | ||||
							
								
								
									
										1
									
								
								dist/jszip.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								dist/jszip.js
									
									
									
									
										vendored
									
									
								
							| @ -13,7 +13,6 @@ https://github.com/nodeca/pako/blob/master/LICENSE | ||||
| 	if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e(); | ||||
| 	else if("function"==typeof define&&define.amd){JSZip=e();define([],e);} | ||||
| 	else{ | ||||
| 		if(typeof self == 'undefined' && typeof app != 'undefined') self = app; | ||||
| 		var f; | ||||
| 		"undefined"!=typeof window?f=window: | ||||
| 		"undefined"!=typeof global?f=global: | ||||
|  | ||||
							
								
								
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										41
									
								
								dist/xlsx.full.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										41
									
								
								dist/xlsx.full.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										637
									
								
								dist/xlsx.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										637
									
								
								dist/xlsx.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										24
									
								
								dist/xlsx.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										24
									
								
								dist/xlsx.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -11,7 +11,7 @@ | ||||
| | `h` | HTML rendering of the rich text (if applicable)                        | | ||||
| | `c` | comments associated with the cell                                      | | ||||
| | `z` | number format string associated with the cell (if requested)           | | ||||
| | `l` | cell hyperlink object (.Target holds link, .tooltip is tooltip)        | | ||||
| | `l` | cell hyperlink object (.Target holds link, .Tooltip is tooltip)        | | ||||
| | `s` | the style/theme of the cell (if applicable)                            | | ||||
| 
 | ||||
| Built-in export utilities (such as the CSV exporter) will use the `w` text if it | ||||
|  | ||||
							
								
								
									
										17
									
								
								docbits/64_cellprops.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										17
									
								
								docbits/64_cellprops.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| #### Hyperlinks | ||||
| 
 | ||||
| Hyperlinks are stored in the `l` key of cell objects.  The `Target` field of the | ||||
| hyperlink object is the target of the link, including the URI fragment. Tooltips | ||||
| are stored in the `Tooltip` field and are displayed when you move your mouse | ||||
| over the text. | ||||
| 
 | ||||
| For example, the following snippet creates a link from cell `A3` to | ||||
| <http://sheetjs.com> with the tip `"Find us @ SheetJS.com!"`: | ||||
| 
 | ||||
| ```js | ||||
| ws['A3'].l = { Target:"http://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" }; | ||||
| ``` | ||||
| 
 | ||||
| Note that Excel does not automatically style hyperlinks -- they will generally | ||||
| be displayed as normal text. | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								jszip.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								jszip.js
									
									
									
									
									
								
							| @ -13,7 +13,6 @@ https://github.com/nodeca/pako/blob/master/LICENSE | ||||
| 	if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e(); | ||||
| 	else if("function"==typeof define&&define.amd){JSZip=e();define([],e);} | ||||
| 	else{ | ||||
| 		if(typeof self == 'undefined' && typeof app != 'undefined') self = app; | ||||
| 		var f; | ||||
| 		"undefined"!=typeof window?f=window: | ||||
| 		"undefined"!=typeof global?f=global: | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "xlsx", | ||||
| 	"version": "0.9.6", | ||||
| 	"version": "0.9.7", | ||||
| 	"author": "sheetjs", | ||||
| 	"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS (ODS/FODS/UOS) spreadsheet parser and writer", | ||||
| 	"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "office", "spreadsheet" ], | ||||
|  | ||||
							
								
								
									
										41
									
								
								test.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										41
									
								
								test.js
									
									
									
									
									
								
							| @ -602,6 +602,19 @@ function diffsty(ws, r1,r2) { | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| function hlink(wb) { | ||||
| 	var ws = wb.Sheets.Sheet1; | ||||
| 	assert.equal(ws.A1.l.Target, "http://www.sheetjs.com"); | ||||
| 	assert.equal(ws.A2.l.Target, "http://oss.sheetjs.com"); | ||||
| 	assert.equal(ws.A3.l.Target, "http://oss.sheetjs.com#foo"); | ||||
| 	assert.equal(ws.A4.l.Target, "mailto:dev@sheetjs.com"); | ||||
| 	assert.equal(ws.A5.l.Target, "mailto:dev@sheetjs.com?subject=hyperlink"); | ||||
| 	assert.equal(ws.A6.l.Target, "../../sheetjs/Documents/Test.xlsx"); | ||||
| 	assert.equal(ws.A7.l.Target, "http://sheetjs.com"); | ||||
| 	assert.equal(ws.A7.l.Tooltip, "foo bar baz"); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| describe('parse features', function() { | ||||
| 	if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){ | ||||
| 		var X = require(modp); | ||||
| @ -760,17 +773,6 @@ describe('parse features', function() { | ||||
| 		if(typeof before != 'undefined') before(bef); | ||||
| 		else it('before', bef); | ||||
| 
 | ||||
| 		function hlink(wb) { | ||||
| 			var ws = wb.Sheets.Sheet1; | ||||
| 			assert.equal(ws.A1.l.Target, "http://www.sheetjs.com"); | ||||
| 			assert.equal(ws.A2.l.Target, "http://oss.sheetjs.com"); | ||||
| 			assert.equal(ws.A3.l.Target, "http://oss.sheetjs.com#foo"); | ||||
| 			assert.equal(ws.A4.l.Target, "mailto:dev@sheetjs.com"); | ||||
| 			assert.equal(ws.A5.l.Target, "mailto:dev@sheetjs.com?subject=hyperlink"); | ||||
| 			assert.equal(ws.A6.l.Target, "../../sheetjs/Documents/Test.xlsx"); | ||||
| 			assert.equal(ws.A7.l.Target, "http://sheetjs.com"); | ||||
| 		} | ||||
| 
 | ||||
| 		it(N1, function() { hlink(wb1); }); | ||||
| 		it(N2, function() { hlink(wb2); }); | ||||
| 		it(N3, function() { hlink(wb3); }); | ||||
| @ -977,14 +979,27 @@ describe('roundtrip features', function() { | ||||
| 		].forEach(function(w) { | ||||
| 			it(w[0], function() { | ||||
| 				var wb1 = X.readFile(w[1], {cellFormula:true}); | ||||
| 				if(w[0] == 'ods') X.writeFile(wb1, "./tmp/_.ods", {bookType:"ods"}); | ||||
| 				var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {cellFormula:true, type:"buffer"}); | ||||
| 				var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"}); | ||||
| 				wb1.SheetNames.forEach(function(n) { | ||||
| 					assert.equal( X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"), X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n") ); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| 
 | ||||
| 	describe('should preserve hyperlink', function() { [ | ||||
| 			['xlml', paths.hlxml], | ||||
| 			//['xlsx', paths.hlxlsx], // TODO
 | ||||
| 			//['xlsb', paths.hlxlsb] // TODO
 | ||||
| 		].forEach(function(w) { | ||||
| 			it(w[0], function() { | ||||
| 				var wb1 = X.readFile(w[1]); | ||||
| 				var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"}); | ||||
| 				hlink(wb1); | ||||
| 				hlink(wb2); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| function password_file(x){return x.match(/^password.*\.xls$/); } | ||||
|  | ||||
| @ -444,6 +444,19 @@ function diffsty(ws, r1,r2) { | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| function hlink(wb) { | ||||
| 	var ws = wb.Sheets.Sheet1; | ||||
| 	assert.equal(ws.A1.l.Target, "http://www.sheetjs.com"); | ||||
| 	assert.equal(ws.A2.l.Target, "http://oss.sheetjs.com"); | ||||
| 	assert.equal(ws.A3.l.Target, "http://oss.sheetjs.com#foo"); | ||||
| 	assert.equal(ws.A4.l.Target, "mailto:dev@sheetjs.com"); | ||||
| 	assert.equal(ws.A5.l.Target, "mailto:dev@sheetjs.com?subject=hyperlink"); | ||||
| 	assert.equal(ws.A6.l.Target, "../../sheetjs/Documents/Test.xlsx"); | ||||
| 	assert.equal(ws.A7.l.Target, "http://sheetjs.com"); | ||||
| 	assert.equal(ws.A7.l.Tooltip, "foo bar baz"); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| describe('parse features', function() { | ||||
| 	if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){ | ||||
| 		var X = require(modp); | ||||
| @ -602,17 +615,6 @@ describe('parse features', function() { | ||||
| 		if(typeof before != 'undefined') before(bef); | ||||
| 		else it('before', bef); | ||||
| 
 | ||||
| 		function hlink(wb) { | ||||
| 			var ws = wb.Sheets.Sheet1; | ||||
| 			assert.equal(ws.A1.l.Target, "http://www.sheetjs.com"); | ||||
| 			assert.equal(ws.A2.l.Target, "http://oss.sheetjs.com"); | ||||
| 			assert.equal(ws.A3.l.Target, "http://oss.sheetjs.com#foo"); | ||||
| 			assert.equal(ws.A4.l.Target, "mailto:dev@sheetjs.com"); | ||||
| 			assert.equal(ws.A5.l.Target, "mailto:dev@sheetjs.com?subject=hyperlink"); | ||||
| 			assert.equal(ws.A6.l.Target, "../../sheetjs/Documents/Test.xlsx"); | ||||
| 			assert.equal(ws.A7.l.Target, "http://sheetjs.com"); | ||||
| 		} | ||||
| 
 | ||||
| 		it(N1, function() { hlink(wb1); }); | ||||
| 		it(N2, function() { hlink(wb2); }); | ||||
| 		it(N3, function() { hlink(wb3); }); | ||||
| @ -825,6 +827,20 @@ describe('roundtrip features', function() { | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| 
 | ||||
| 	describe('should preserve hyperlink', function() { [ | ||||
| 			['xlml', paths.hlxml], | ||||
| 			//['xlsx', paths.hlxlsx], // TODO
 | ||||
| 			//['xlsb', paths.hlxlsb] // TODO
 | ||||
| 		].forEach(function(w) { | ||||
| 			it(w[0], function() { | ||||
| 				var wb1 = X.read(fs.readFileSync(w[1]), {type:"binary"}); | ||||
| 				var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"binary"}), {type:"binary"}); | ||||
| 				hlink(wb1); | ||||
| 				hlink(wb2); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| function password_file(x){return x.match(/^password.*\.xls$/); } | ||||
|  | ||||
| @ -12,10 +12,10 @@ var data = [ | ||||
| var ws_name = "SheetJS"; | ||||
| 
 | ||||
| var wscols = [ | ||||
| 	{wch:6}, | ||||
| 	{wch:7}, | ||||
| 	{wch:6}, // "characters"
 | ||||
| 	{wpx:50}, // "pixels"
 | ||||
| 	{wch:10}, | ||||
| 	{wch:20} | ||||
| 	{wpx:125} | ||||
| ]; | ||||
| 
 | ||||
| 
 | ||||
| @ -28,52 +28,11 @@ console.log("Columns :"); for(i=0; i!=wscols.length;++i) console.log(wscols[i]); | ||||
| /* require XLSX */ | ||||
| if(typeof XLSX === "undefined") { try { XLSX = require('./'); } catch(e) { XLSX = require('../'); } } | ||||
| 
 | ||||
| /* dummy workbook constructor */ | ||||
| function Workbook() { | ||||
| 	if(!(this instanceof Workbook)) return new Workbook(); | ||||
| 	this.SheetNames = []; | ||||
| 	this.Sheets = {}; | ||||
| } | ||||
| var wb = new Workbook(); | ||||
| 
 | ||||
| 
 | ||||
| function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ { | ||||
| 	var epoch = v.getTime(); | ||||
| 	if(date1904) epoch += 1462*24*60*60*1000; | ||||
| 	return (epoch + 2209161600000) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| /* blank workbook constructor */ | ||||
| var wb = { SheetNames: [], Sheets: {} }; | ||||
| 
 | ||||
| /* convert an array of arrays in JS to a CSF spreadsheet */ | ||||
| function sheet_from_array_of_arrays(data, opts) { | ||||
| 	var ws = {}; | ||||
| 	var range = {s: {c:10000000, r:10000000}, e: {c:0, r:0 }}; | ||||
| 	for(var R = 0; R != data.length; ++R) { | ||||
| 		for(var C = 0; C != data[R].length; ++C) { | ||||
| 			if(range.s.r > R) range.s.r = R; | ||||
| 			if(range.s.c > C) range.s.c = C; | ||||
| 			if(range.e.r < R) range.e.r = R; | ||||
| 			if(range.e.c < C) range.e.c = C; | ||||
| 			var cell = {v: data[R][C] }; | ||||
| 			if(cell.v == null) continue; | ||||
| 			var cell_ref = XLSX.utils.encode_cell({c:C,r:R}); | ||||
| 
 | ||||
| 			/* TEST: proper cell types and value handling */ | ||||
| 			if(typeof cell.v === 'number') cell.t = 'n'; | ||||
| 			else if(typeof cell.v === 'boolean') cell.t = 'b'; | ||||
| 			else if(cell.v instanceof Date) { | ||||
| 				cell.t = 'n'; cell.z = XLSX.SSF._table[14]; | ||||
| 				cell.v = datenum(cell.v); | ||||
| 			} | ||||
| 			else cell.t = 's'; | ||||
| 			ws[cell_ref] = cell; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* TEST: proper range */ | ||||
| 	if(range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range); | ||||
| 	return ws; | ||||
| } | ||||
| var ws = sheet_from_array_of_arrays(data); | ||||
| var ws = XLSX.utils.aoa_to_sheet(data, {cellDates:true}); | ||||
| 
 | ||||
| /* TEST: add worksheet to workbook */ | ||||
| wb.SheetNames.push(ws_name); | ||||
| @ -96,8 +55,18 @@ ws["!ref"] = "A1:E4"; | ||||
| /* TEST: column widths */ | ||||
| ws['!cols'] = wscols; | ||||
| 
 | ||||
| /* TEST: hyperlink note: Excel does not automatically style hyperlinks */ | ||||
| ws['A3'].l = { Target: "http://sheetjs.com", Tooltip: "Visit us <SheetJS.com!>" }; | ||||
| 
 | ||||
| /* TEST: built-in format */ | ||||
| //ws['A1'].z = "0%"; wb.SSF[9] = "0%"; // Format Code 9
 | ||||
| 
 | ||||
| /* TEST: custom format */ | ||||
| //ws['B2'].z = "0.0"; wb.SSF[60] = "0.0"; // Custom
 | ||||
| console.log("JSON Data: "); console.log(XLSX.utils.sheet_to_json(ws, {header:1})); | ||||
| 
 | ||||
| console.log("Worksheet Model:") | ||||
| console.log(ws); | ||||
| 
 | ||||
| /* write file */ | ||||
| XLSX.writeFile(wb, 'sheetjs.xlsx', {bookSST:true}); | ||||
|  | ||||
							
								
								
									
										106
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										106
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -5,7 +5,7 @@ | ||||
| /*exported XLSX */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.9.6'; | ||||
| XLSX.version = '0.9.7'; | ||||
| var current_codepage = 1200, current_cptable; | ||||
| /*:: declare var cptable:any; */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| @ -1830,7 +1830,7 @@ function ReadShift(size/*:number*/, t/*:?string*/) { | ||||
| 		case 'cstr': size = 0; o = ""; | ||||
| 			while((w=__readUInt8(this, this.l + size++))!==0) oo.push(_getchar(w)); | ||||
| 			o = oo.join(""); break; | ||||
| 		case 'wstr': size = 0; o = ""; | ||||
| 		case '_wstr': size = 0; o = ""; | ||||
| 			while((w=__readUInt16LE(this,this.l +size))!==0){oo.push(_getchar(w));size+=2;} | ||||
| 			size+=2; o = oo.join(""); break; | ||||
| 
 | ||||
| @ -2780,6 +2780,15 @@ var CTYPE_XML_ROOT = writextag('Types', null, { | ||||
| var CTYPE_DEFAULTS = [ | ||||
| 	['xml', 'application/xml'], | ||||
| 	['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'], | ||||
| 	/* from test files */ | ||||
| 	['bmp', 'image/bmp'], | ||||
| 	['png', 'image/png'], | ||||
| 	['gif', 'image/gif'], | ||||
| 	['emf', 'image/x-emf'], | ||||
| 	['wmf', 'image/x-wmf'], | ||||
| 	['jpg', 'image/jpeg'], ['jpeg', 'image/jpeg'], | ||||
| 	['tif', 'image/tiff'], ['tiff', 'image/tiff'], | ||||
| 	['pdf', 'application/pdf'], | ||||
| 	['rels', type2ct.rels[0]] | ||||
| ].map(function(x) { | ||||
| 	return writextag('Default', null, {'Extension':x[0], 'ContentType': x[1]}); | ||||
| @ -2821,6 +2830,7 @@ function write_ct(ct, opts)/*:string*/ { | ||||
| 	['strs', 'styles'].forEach(f1); | ||||
| 	['coreprops', 'extprops', 'custprops'].forEach(f3); | ||||
| 	f3('vba'); | ||||
| 	f3('comments'); | ||||
| 	if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); } | ||||
| 	return o.join(""); | ||||
| } | ||||
| @ -3128,7 +3138,7 @@ function parse_cust_props(data/*:string*/, opts) { | ||||
| 				var type = toks[0].substring(4), text = toks[1]; | ||||
| 				/* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */ | ||||
| 				switch(type) { | ||||
| 					case 'lpstr': case 'lpwstr': case 'bstr': case 'lpwstr': | ||||
| 					case 'lpstr': case 'bstr': case 'lpwstr': | ||||
| 						p[name] = unescapexml(text); | ||||
| 						break; | ||||
| 					case 'bool': | ||||
| @ -5393,7 +5403,7 @@ function rgb_tint(hex, tint) { | ||||
| 
 | ||||
| /* 18.3.1.13 width calculations */ | ||||
| /* [MS-OI29500] 2.1.595 Column Width & Formatting */ | ||||
| var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW; | ||||
| var DEF_MDW = 6, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW; | ||||
| function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); } | ||||
| function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; } | ||||
| function char2width(chr) { return (Math.round((chr * MDW + 5)/MDW*256))/256; } | ||||
| @ -5527,8 +5537,8 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '</fill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 
 | ||||
| 			/* 18.8.24 gradientFill CT_GradientFill */ | ||||
| 			case '<fill>': break; | ||||
| 			case '</fill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 			case '<gradientFill>': break; | ||||
| 			case '</gradientFill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 
 | ||||
| 			/* 18.8.32 patternFill CT_PatternFill */ | ||||
| 			case '<patternFill': case '<patternFill>': | ||||
| @ -8812,6 +8822,18 @@ function get_sst_id(sst/*:SST*/, str/*:string*/)/*:number*/ { | ||||
| 	sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len; | ||||
| } | ||||
| 
 | ||||
| function col_obj_w(C/*:number*/, col) { | ||||
| 	var p = ({min:C+1,max:C+1}/*:any*/); | ||||
| 	/* wch (chars), wpx (pixels) */ | ||||
| 	var width = -1; | ||||
| 	if(col.MDW) MDW = col.MDW; | ||||
| 	if(col.width != null) p.customWidth = 1; | ||||
| 	else if(col.wpx != null) width = px2char(col.wpx); | ||||
| 	else if(col.wch != null) width = col.wch; | ||||
| 	if(width > -1) { p.width = char2width(width); p.customWidth = 1; } | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| function get_cell_style(styles, cell, opts) { | ||||
| 	var z = opts.revssf[cell.z != null ? cell.z : "General"]; | ||||
| 	for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i; | ||||
| @ -8932,7 +8954,7 @@ function write_ws_xml_merges(merges) { | ||||
| 	return o + '</mergeCells>'; | ||||
| } | ||||
| 
 | ||||
| function parse_ws_xml_hlinks(s, data, rels) { | ||||
| function parse_ws_xml_hlinks(s, data/*:Array<string>*/, rels) { | ||||
| 	for(var i = 0; i != data.length; ++i) { | ||||
| 		var val = parsexmltag(data[i], true); | ||||
| 		if(!val.ref) return; | ||||
| @ -8946,6 +8968,7 @@ function parse_ws_xml_hlinks(s, data, rels) { | ||||
| 			rel = {Target: val.location, TargetMode: 'Internal'}; | ||||
| 			val.Rel = rel; | ||||
| 		} | ||||
| 		if(val.tooltip) { val.Tooltip = val.tooltip; delete val.tooltip; } | ||||
| 		var rng = safe_decode_range(val.ref); | ||||
| 		for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) { | ||||
| 			var addr = encode_cell({c:C,r:R}); | ||||
| @ -8971,15 +8994,7 @@ function write_ws_xml_cols(ws, cols)/*:string*/ { | ||||
| 	var o = ["<cols>"], col, width; | ||||
| 	for(var i = 0; i != cols.length; ++i) { | ||||
| 		if(!(col = cols[i])) continue; | ||||
| 		var p = ({min:i+1,max:i+1}/*:any*/); | ||||
| 		/* wch (chars), wpx (pixels) */ | ||||
| 		width = -1; | ||||
| 		if(col.MDW) MDW = col.MDW; | ||||
| 		if(col.width); | ||||
| 		else if(col.wpx) width = px2char(col.wpx); | ||||
| 		else if(col.wch) width = col.wch; | ||||
| 		if(width > -1) { p.width = char2width(width); p.customWidth= 1; } | ||||
| 		o[o.length] = (writextag('col', null, p)); | ||||
| 		o[o.length] = (writextag('col', null, col_obj_w(i, col))); | ||||
| 	} | ||||
| 	o[o.length] = "</cols>"; | ||||
| 	return o.join(""); | ||||
| @ -9190,15 +9205,17 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ { | ||||
| 
 | ||||
| 	if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols'])); | ||||
| 	o[sidx = o.length] = '<sheetData/>'; | ||||
| 	if(ws['!ref'] !== undefined) { | ||||
| 	if(ws['!ref'] != null) { | ||||
| 		rdata = write_ws_xml_data(ws, opts, idx, wb); | ||||
| 		if(rdata.length > 0) o[o.length] = (rdata); | ||||
| 	} | ||||
| 	if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); } | ||||
| 
 | ||||
| 	if(ws['!merges'] !== undefined && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges'])); | ||||
| 	if(ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges'])); | ||||
| 
 | ||||
| 	if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); } | ||||
| 
 | ||||
| 	delete ws['!links']; | ||||
| 	return o.join(""); | ||||
| } | ||||
| 
 | ||||
| @ -9429,7 +9446,7 @@ function parse_BrtHLink(data, length, opts) { | ||||
| 	var tooltip = parse_XLWideString(data); | ||||
| 	var display = parse_XLWideString(data); | ||||
| 	data.l = end; | ||||
| 	return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display}; | ||||
| 	return {rfx:rfx, relId:relId, loc:loc, Tooltip:tooltip, display:display}; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.6 BrtArrFmla */ | ||||
| @ -9458,6 +9475,20 @@ function parse_BrtShrFmla(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.323 BrtColInfo */ | ||||
| /* TODO: once XLS ColInfo is set, combine the functions */ | ||||
| function write_BrtColInfo(C/*:number*/, col, o) { | ||||
| 	if(o == null) o = new_buf(18); | ||||
| 	var p = col_obj_w(C, col); | ||||
| 	o.write_shift(-4, C); | ||||
| 	o.write_shift(-4, C); | ||||
| 	o.write_shift(4, p.width * 256); | ||||
| 	o.write_shift(4, 0/*ixfe*/); // style
 | ||||
| 	o.write_shift(1, 2); // bit flag
 | ||||
| 	o.write_shift(1, 0); // bit flag
 | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.61 Worksheet */ | ||||
| function parse_ws_bin(data, opts, rels, wb, themes, styles)/*:Worksheet*/ { | ||||
| 	if(!data) return data; | ||||
| @ -9724,9 +9755,15 @@ function parse_ws_bin(data, opts, rels, wb, themes, styles)/*:Worksheet*/ { | ||||
| /* TODO: something useful -- this is a stub */ | ||||
| function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) { | ||||
| 	if(cell.v === undefined) return ""; | ||||
| 	var vv = ""; | ||||
| 	var vv = ""; var olddate = null; | ||||
| 	switch(cell.t) { | ||||
| 		case 'b': vv = cell.v ? "1" : "0"; break; | ||||
| 		case 'd': // no BrtCellDate :(
 | ||||
| 			cell.z = cell.z || SSF._table[14]; | ||||
| 			olddate = cell.v; | ||||
| 			cell.v = datenum((cell.v/*:any*/)); cell.t = 'n'; | ||||
| 			break; | ||||
| 		/* falls through */ | ||||
| 		case 'n': case 'e': vv = ''+cell.v; break; | ||||
| 		default: vv = cell.v; break; | ||||
| 	} | ||||
| @ -9736,7 +9773,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num | ||||
| 	switch(cell.t) { | ||||
| 		case 's': case 'str': | ||||
| 			if(opts.bookSST) { | ||||
| 				vv = get_sst_id(opts.Strings, cell.v); | ||||
| 				vv = get_sst_id(opts.Strings, (cell.v/*:any*/)); | ||||
| 				o.t = "s"; o.v = vv; | ||||
| 				write_record(ba, "BrtCellIsst", write_BrtCellIsst(cell, o)); | ||||
| 			} else { | ||||
| @ -9748,6 +9785,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num | ||||
| 			/* TODO: determine threshold for Real vs RK */ | ||||
| 			if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) write_record(ba, "BrtCellRk", write_BrtCellRk(cell, o)); | ||||
| 			else write_record(ba, "BrtCellReal", write_BrtCellReal(cell, o)); | ||||
| 			if(olddate) { cell.t = 'd'; cell.v = olddate; } | ||||
| 			return; | ||||
| 		case 'b': | ||||
| 			o.t = "b"; | ||||
| @ -9758,7 +9796,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num | ||||
| 	write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o)); | ||||
| } | ||||
| 
 | ||||
| function write_CELLTABLE(ba, ws, idx, opts, wb) { | ||||
| function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = []; | ||||
| 	write_record(ba, 'BrtBeginSheetData'); | ||||
| 	for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
| @ -9785,6 +9823,13 @@ function write_MERGECELLS(ba, ws/*:Worksheet*/) { | ||||
| 	write_record(ba, 'BrtEndMergeCells'); | ||||
| } | ||||
| 
 | ||||
| function write_COLINFOS(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	if(!ws || !ws['!cols']) return; | ||||
| 	write_record(ba, 'BrtBeginColInfos'); | ||||
| 	ws['!cols'].forEach(function(m, i) { if(m) write_record(ba, 'BrtColInfo', write_BrtColInfo(i, m)); }); | ||||
| 	write_record(ba, 'BrtEndColInfos'); | ||||
| } | ||||
| 
 | ||||
| function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	var ba = buf_array(); | ||||
| 	var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}; | ||||
| @ -9794,7 +9839,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	write_record(ba, "BrtWsDim", write_BrtWsDim(r)); | ||||
| 	/* [WSVIEWS2] */ | ||||
| 	/* [WSFMTINFO] */ | ||||
| 	/* *COLINFOS */ | ||||
| 	write_COLINFOS(ba, ws, idx, opts, wb); | ||||
| 	write_CELLTABLE(ba, ws, idx, opts, wb); | ||||
| 	/* [BrtSheetCalcProp] */ | ||||
| 	/* [[BrtSheetProtectionIso] BrtSheetProtection] */ | ||||
| @ -10674,8 +10719,8 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { | ||||
| 				if(comments.length > 0) cell.c = comments; | ||||
| 				if((!opts.sheetRows || opts.sheetRows > r) && cell.v !== undefined) cursheet[encode_col(c) + encode_row(r)] = cell; | ||||
| 				if(cell.HRef) { | ||||
| 					cell.l = {Target:cell.HRef, tooltip:cell.HRefScreenTip}; | ||||
| 					cell.HRef = cell.HRefScreenTip = undefined; | ||||
| 					cell.l = {Target:cell.HRef, Tooltip:cell.HRefScreenTip}; | ||||
| 					delete cell.HRef; delete cell.HRefScreenTip; | ||||
| 				} | ||||
| 				if(cell.MergeAcross || cell.MergeDown) { | ||||
| 					var cc = c + (parseInt(cell.MergeAcross,10)|0); | ||||
| @ -11262,6 +11307,11 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{ | ||||
| 		attr["ss:ArrayRange"] = "RC:R" + (end.r == addr.r ? "" : "[" + (end.r - addr.r) + "]") + "C" + (end.c == addr.c ? "" : "[" + (end.c - addr.c) + "]"); | ||||
| 	} | ||||
| 
 | ||||
| 	if(cell.l && cell.l.Target) { | ||||
| 		attr["ss:HRef"] = escapexml(cell.l.Target); | ||||
| 		if(cell.l.Tooltip) attr["x:HRefScreenTip"] = escapexml(cell.l.Tooltip); | ||||
| 	} | ||||
| 
 | ||||
| 	if(ws['!merges']) { | ||||
| 		var marr = ws['!merges']; | ||||
| 		for(var mi = 0; mi != marr.length; ++mi) { | ||||
| @ -11297,6 +11347,10 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo | ||||
| 	var range = safe_decode_range(ws['!ref']); | ||||
| 	var marr = ws['!merges'] || [], mi = 0; | ||||
| 	var o = []; | ||||
| 	if(ws['!cols']) ws['!cols'].forEach(function(n, i) { | ||||
| 		var p = col_obj_w(i, n); | ||||
| 		o.push(writextag("Column",null, {"ss:Index":i+1, "ss:Width":width2px(p.width)})); | ||||
| 	}); | ||||
| 	for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
| 		var row = ['<Row ss:Index="' + (R+1) + '">']; | ||||
| 		for(var C = range.s.c; C <= range.e.c; ++C) { | ||||
| @ -11780,7 +11834,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 					for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) | ||||
| 						for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) | ||||
| 							if(out[encode_cell({c:rngC,r:rngR})]) | ||||
| 								out[encode_cell({c:rngC,r:rngR})].l.tooltip = val[1]; | ||||
| 								out[encode_cell({c:rngC,r:rngR})].l.Tooltip = val[1]; | ||||
| 				} break; | ||||
| 
 | ||||
| 				/* Comments */ | ||||
|  | ||||
							
								
								
									
										102
									
								
								xlsx.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										102
									
								
								xlsx.js
									
									
									
									
									
								
							| @ -5,7 +5,7 @@ | ||||
| /*exported XLSX */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.9.6'; | ||||
| XLSX.version = '0.9.7'; | ||||
| var current_codepage = 1200, current_cptable; | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| 	if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js'); | ||||
| @ -1781,7 +1781,7 @@ function ReadShift(size, t) { | ||||
| 		case 'cstr': size = 0; o = ""; | ||||
| 			while((w=__readUInt8(this, this.l + size++))!==0) oo.push(_getchar(w)); | ||||
| 			o = oo.join(""); break; | ||||
| 		case 'wstr': size = 0; o = ""; | ||||
| 		case '_wstr': size = 0; o = ""; | ||||
| 			while((w=__readUInt16LE(this,this.l +size))!==0){oo.push(_getchar(w));size+=2;} | ||||
| 			size+=2; o = oo.join(""); break; | ||||
| 
 | ||||
| @ -2728,6 +2728,15 @@ var CTYPE_XML_ROOT = writextag('Types', null, { | ||||
| var CTYPE_DEFAULTS = [ | ||||
| 	['xml', 'application/xml'], | ||||
| 	['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'], | ||||
| 	/* from test files */ | ||||
| 	['bmp', 'image/bmp'], | ||||
| 	['png', 'image/png'], | ||||
| 	['gif', 'image/gif'], | ||||
| 	['emf', 'image/x-emf'], | ||||
| 	['wmf', 'image/x-wmf'], | ||||
| 	['jpg', 'image/jpeg'], ['jpeg', 'image/jpeg'], | ||||
| 	['tif', 'image/tiff'], ['tiff', 'image/tiff'], | ||||
| 	['pdf', 'application/pdf'], | ||||
| 	['rels', type2ct.rels[0]] | ||||
| ].map(function(x) { | ||||
| 	return writextag('Default', null, {'Extension':x[0], 'ContentType': x[1]}); | ||||
| @ -2769,6 +2778,7 @@ function write_ct(ct, opts) { | ||||
| 	['strs', 'styles'].forEach(f1); | ||||
| 	['coreprops', 'extprops', 'custprops'].forEach(f3); | ||||
| 	f3('vba'); | ||||
| 	f3('comments'); | ||||
| 	if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); } | ||||
| 	return o.join(""); | ||||
| } | ||||
| @ -3076,7 +3086,7 @@ function parse_cust_props(data, opts) { | ||||
| 				var type = toks[0].substring(4), text = toks[1]; | ||||
| 				/* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */ | ||||
| 				switch(type) { | ||||
| 					case 'lpstr': case 'lpwstr': case 'bstr': case 'lpwstr': | ||||
| 					case 'lpstr': case 'bstr': case 'lpwstr': | ||||
| 						p[name] = unescapexml(text); | ||||
| 						break; | ||||
| 					case 'bool': | ||||
| @ -5339,7 +5349,7 @@ function rgb_tint(hex, tint) { | ||||
| 
 | ||||
| /* 18.3.1.13 width calculations */ | ||||
| /* [MS-OI29500] 2.1.595 Column Width & Formatting */ | ||||
| var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW; | ||||
| var DEF_MDW = 6, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW; | ||||
| function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); } | ||||
| function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; } | ||||
| function char2width(chr) { return (Math.round((chr * MDW + 5)/MDW*256))/256; } | ||||
| @ -5473,8 +5483,8 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '</fill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 
 | ||||
| 			/* 18.8.24 gradientFill CT_GradientFill */ | ||||
| 			case '<fill>': break; | ||||
| 			case '</fill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 			case '<gradientFill>': break; | ||||
| 			case '</gradientFill>': styles.Fills.push(fill); fill = {}; break; | ||||
| 
 | ||||
| 			/* 18.8.32 patternFill CT_PatternFill */ | ||||
| 			case '<patternFill': case '<patternFill>': | ||||
| @ -8757,6 +8767,18 @@ function get_sst_id(sst, str) { | ||||
| 	sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len; | ||||
| } | ||||
| 
 | ||||
| function col_obj_w(C, col) { | ||||
| 	var p = ({min:C+1,max:C+1}); | ||||
| 	/* wch (chars), wpx (pixels) */ | ||||
| 	var width = -1; | ||||
| 	if(col.MDW) MDW = col.MDW; | ||||
| 	if(col.width != null) p.customWidth = 1; | ||||
| 	else if(col.wpx != null) width = px2char(col.wpx); | ||||
| 	else if(col.wch != null) width = col.wch; | ||||
| 	if(width > -1) { p.width = char2width(width); p.customWidth = 1; } | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| function get_cell_style(styles, cell, opts) { | ||||
| 	var z = opts.revssf[cell.z != null ? cell.z : "General"]; | ||||
| 	for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i; | ||||
| @ -8891,6 +8913,7 @@ function parse_ws_xml_hlinks(s, data, rels) { | ||||
| 			rel = {Target: val.location, TargetMode: 'Internal'}; | ||||
| 			val.Rel = rel; | ||||
| 		} | ||||
| 		if(val.tooltip) { val.Tooltip = val.tooltip; delete val.tooltip; } | ||||
| 		var rng = safe_decode_range(val.ref); | ||||
| 		for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) { | ||||
| 			var addr = encode_cell({c:C,r:R}); | ||||
| @ -8916,15 +8939,7 @@ function write_ws_xml_cols(ws, cols) { | ||||
| 	var o = ["<cols>"], col, width; | ||||
| 	for(var i = 0; i != cols.length; ++i) { | ||||
| 		if(!(col = cols[i])) continue; | ||||
| 		var p = ({min:i+1,max:i+1}); | ||||
| 		/* wch (chars), wpx (pixels) */ | ||||
| 		width = -1; | ||||
| 		if(col.MDW) MDW = col.MDW; | ||||
| 		if(col.width); | ||||
| 		else if(col.wpx) width = px2char(col.wpx); | ||||
| 		else if(col.wch) width = col.wch; | ||||
| 		if(width > -1) { p.width = char2width(width); p.customWidth= 1; } | ||||
| 		o[o.length] = (writextag('col', null, p)); | ||||
| 		o[o.length] = (writextag('col', null, col_obj_w(i, col))); | ||||
| 	} | ||||
| 	o[o.length] = "</cols>"; | ||||
| 	return o.join(""); | ||||
| @ -9135,15 +9150,17 @@ function write_ws_xml(idx, opts, wb) { | ||||
| 
 | ||||
| 	if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols'])); | ||||
| 	o[sidx = o.length] = '<sheetData/>'; | ||||
| 	if(ws['!ref'] !== undefined) { | ||||
| 	if(ws['!ref'] != null) { | ||||
| 		rdata = write_ws_xml_data(ws, opts, idx, wb); | ||||
| 		if(rdata.length > 0) o[o.length] = (rdata); | ||||
| 	} | ||||
| 	if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); } | ||||
| 
 | ||||
| 	if(ws['!merges'] !== undefined && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges'])); | ||||
| 	if(ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges'])); | ||||
| 
 | ||||
| 	if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); } | ||||
| 
 | ||||
| 	delete ws['!links']; | ||||
| 	return o.join(""); | ||||
| } | ||||
| 
 | ||||
| @ -9374,7 +9391,7 @@ function parse_BrtHLink(data, length, opts) { | ||||
| 	var tooltip = parse_XLWideString(data); | ||||
| 	var display = parse_XLWideString(data); | ||||
| 	data.l = end; | ||||
| 	return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display}; | ||||
| 	return {rfx:rfx, relId:relId, loc:loc, Tooltip:tooltip, display:display}; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.6 BrtArrFmla */ | ||||
| @ -9403,6 +9420,20 @@ function parse_BrtShrFmla(data, length, opts) { | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.4.323 BrtColInfo */ | ||||
| /* TODO: once XLS ColInfo is set, combine the functions */ | ||||
| function write_BrtColInfo(C, col, o) { | ||||
| 	if(o == null) o = new_buf(18); | ||||
| 	var p = col_obj_w(C, col); | ||||
| 	o.write_shift(-4, C); | ||||
| 	o.write_shift(-4, C); | ||||
| 	o.write_shift(4, p.width * 256); | ||||
| 	o.write_shift(4, 0/*ixfe*/); // style
 | ||||
| 	o.write_shift(1, 2); // bit flag
 | ||||
| 	o.write_shift(1, 0); // bit flag
 | ||||
| 	return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-XLSB] 2.1.7.61 Worksheet */ | ||||
| function parse_ws_bin(data, opts, rels, wb, themes, styles) { | ||||
| 	if(!data) return data; | ||||
| @ -9669,9 +9700,15 @@ function parse_ws_bin(data, opts, rels, wb, themes, styles) { | ||||
| /* TODO: something useful -- this is a stub */ | ||||
| function write_ws_bin_cell(ba, cell, R, C, opts) { | ||||
| 	if(cell.v === undefined) return ""; | ||||
| 	var vv = ""; | ||||
| 	var vv = ""; var olddate = null; | ||||
| 	switch(cell.t) { | ||||
| 		case 'b': vv = cell.v ? "1" : "0"; break; | ||||
| 		case 'd': // no BrtCellDate :(
 | ||||
| 			cell.z = cell.z || SSF._table[14]; | ||||
| 			olddate = cell.v; | ||||
| 			cell.v = datenum((cell.v)); cell.t = 'n'; | ||||
| 			break; | ||||
| 		/* falls through */ | ||||
| 		case 'n': case 'e': vv = ''+cell.v; break; | ||||
| 		default: vv = cell.v; break; | ||||
| 	} | ||||
| @ -9681,7 +9718,7 @@ function write_ws_bin_cell(ba, cell, R, C, opts) { | ||||
| 	switch(cell.t) { | ||||
| 		case 's': case 'str': | ||||
| 			if(opts.bookSST) { | ||||
| 				vv = get_sst_id(opts.Strings, cell.v); | ||||
| 				vv = get_sst_id(opts.Strings, (cell.v)); | ||||
| 				o.t = "s"; o.v = vv; | ||||
| 				write_record(ba, "BrtCellIsst", write_BrtCellIsst(cell, o)); | ||||
| 			} else { | ||||
| @ -9693,6 +9730,7 @@ function write_ws_bin_cell(ba, cell, R, C, opts) { | ||||
| 			/* TODO: determine threshold for Real vs RK */ | ||||
| 			if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) write_record(ba, "BrtCellRk", write_BrtCellRk(cell, o)); | ||||
| 			else write_record(ba, "BrtCellReal", write_BrtCellReal(cell, o)); | ||||
| 			if(olddate) { cell.t = 'd'; cell.v = olddate; } | ||||
| 			return; | ||||
| 		case 'b': | ||||
| 			o.t = "b"; | ||||
| @ -9730,6 +9768,13 @@ function write_MERGECELLS(ba, ws) { | ||||
| 	write_record(ba, 'BrtEndMergeCells'); | ||||
| } | ||||
| 
 | ||||
| function write_COLINFOS(ba, ws, idx, opts, wb) { | ||||
| 	if(!ws || !ws['!cols']) return; | ||||
| 	write_record(ba, 'BrtBeginColInfos'); | ||||
| 	ws['!cols'].forEach(function(m, i) { if(m) write_record(ba, 'BrtColInfo', write_BrtColInfo(i, m)); }); | ||||
| 	write_record(ba, 'BrtEndColInfos'); | ||||
| } | ||||
| 
 | ||||
| function write_ws_bin(idx, opts, wb) { | ||||
| 	var ba = buf_array(); | ||||
| 	var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}; | ||||
| @ -9739,7 +9784,7 @@ function write_ws_bin(idx, opts, wb) { | ||||
| 	write_record(ba, "BrtWsDim", write_BrtWsDim(r)); | ||||
| 	/* [WSVIEWS2] */ | ||||
| 	/* [WSFMTINFO] */ | ||||
| 	/* *COLINFOS */ | ||||
| 	write_COLINFOS(ba, ws, idx, opts, wb); | ||||
| 	write_CELLTABLE(ba, ws, idx, opts, wb); | ||||
| 	/* [BrtSheetCalcProp] */ | ||||
| 	/* [[BrtSheetProtectionIso] BrtSheetProtection] */ | ||||
| @ -10617,8 +10662,8 @@ function parse_xlml_xml(d, opts) { | ||||
| 				if(comments.length > 0) cell.c = comments; | ||||
| 				if((!opts.sheetRows || opts.sheetRows > r) && cell.v !== undefined) cursheet[encode_col(c) + encode_row(r)] = cell; | ||||
| 				if(cell.HRef) { | ||||
| 					cell.l = {Target:cell.HRef, tooltip:cell.HRefScreenTip}; | ||||
| 					cell.HRef = cell.HRefScreenTip = undefined; | ||||
| 					cell.l = {Target:cell.HRef, Tooltip:cell.HRefScreenTip}; | ||||
| 					delete cell.HRef; delete cell.HRefScreenTip; | ||||
| 				} | ||||
| 				if(cell.MergeAcross || cell.MergeDown) { | ||||
| 					var cc = c + (parseInt(cell.MergeAcross,10)|0); | ||||
| @ -11203,6 +11248,11 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){ | ||||
| 		attr["ss:ArrayRange"] = "RC:R" + (end.r == addr.r ? "" : "[" + (end.r - addr.r) + "]") + "C" + (end.c == addr.c ? "" : "[" + (end.c - addr.c) + "]"); | ||||
| 	} | ||||
| 
 | ||||
| 	if(cell.l && cell.l.Target) { | ||||
| 		attr["ss:HRef"] = escapexml(cell.l.Target); | ||||
| 		if(cell.l.Tooltip) attr["x:HRefScreenTip"] = escapexml(cell.l.Tooltip); | ||||
| 	} | ||||
| 
 | ||||
| 	if(ws['!merges']) { | ||||
| 		var marr = ws['!merges']; | ||||
| 		for(var mi = 0; mi != marr.length; ++mi) { | ||||
| @ -11238,6 +11288,10 @@ function write_ws_xlml_table(ws, opts, idx, wb) { | ||||
| 	var range = safe_decode_range(ws['!ref']); | ||||
| 	var marr = ws['!merges'] || [], mi = 0; | ||||
| 	var o = []; | ||||
| 	if(ws['!cols']) ws['!cols'].forEach(function(n, i) { | ||||
| 		var p = col_obj_w(i, n); | ||||
| 		o.push(writextag("Column",null, {"ss:Index":i+1, "ss:Width":width2px(p.width)})); | ||||
| 	}); | ||||
| 	for(var R = range.s.r; R <= range.e.r; ++R) { | ||||
| 		var row = ['<Row ss:Index="' + (R+1) + '">']; | ||||
| 		for(var C = range.s.c; C <= range.e.c; ++C) { | ||||
| @ -11721,7 +11775,7 @@ function parse_workbook(blob, options) { | ||||
| 					for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) | ||||
| 						for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) | ||||
| 							if(out[encode_cell({c:rngC,r:rngR})]) | ||||
| 								out[encode_cell({c:rngC,r:rngR})].l.tooltip = val[1]; | ||||
| 								out[encode_cell({c:rngC,r:rngR})].l.Tooltip = val[1]; | ||||
| 				} break; | ||||
| 
 | ||||
| 				/* Comments */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user