forked from sheetjs/sheetjs
		
	XLML write support
- XLML write (fixes #173 h/t @SheetJSDev) - removed old iteration style from README (see #592) - CellXF & StyleXF fields (fixes #414 h/t @ronnywang)
This commit is contained in:
		
							parent
							
								
									456ab63dc4
								
							
						
					
					
						commit
						7cb978b846
					
				@ -5,6 +5,10 @@ but not limited to API changes and file location changes.  Minor behavioral
 | 
			
		||||
changes may not be included if they are not expected to break existing code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Unreleased
 | 
			
		||||
 | 
			
		||||
* XLML property names are more closely mapped to the XLSX equivalent
 | 
			
		||||
 | 
			
		||||
## 0.9.2 (2017-03-13)
 | 
			
		||||
 | 
			
		||||
* Removed stale TypeScript definition files.  Flowtype comments are used in the
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							@ -140,6 +140,9 @@ misc/coverage.html: $(TARGET) test.js
 | 
			
		||||
coveralls: ## Coverage Test + Send to coveralls.io
 | 
			
		||||
	mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | node ./node_modules/coveralls/bin/coveralls.js
 | 
			
		||||
 | 
			
		||||
.PHONY: readme
 | 
			
		||||
readme: ## Update README Table of Contents
 | 
			
		||||
	markdown-toc -i README.md
 | 
			
		||||
 | 
			
		||||
.PHONY: help
 | 
			
		||||
help:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							@ -274,24 +274,10 @@ var worksheet = workbook.Sheets[first_sheet_name];
 | 
			
		||||
var desired_cell = worksheet[address_of_cell];
 | 
			
		||||
 | 
			
		||||
/* Get the value */
 | 
			
		||||
var desired_value = desired_cell.v;
 | 
			
		||||
var desired_value = (desired_cell ? desired_cell.v : undefined);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This example iterates through every nonempty of every sheet and dumps values:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var sheet_name_list = workbook.SheetNames;
 | 
			
		||||
sheet_name_list.forEach(function(y) { /* iterate through sheets */
 | 
			
		||||
  var worksheet = workbook.Sheets[y];
 | 
			
		||||
  for (var z in worksheet) {
 | 
			
		||||
    /* all keys that do not begin with "!" correspond to cell addresses */
 | 
			
		||||
    if(z[0] === '!') continue;
 | 
			
		||||
    console.log(y + "!" + z + "=" + JSON.stringify(worksheet[z].v));
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Complete examples:
 | 
			
		||||
**Complete examples:**
 | 
			
		||||
 | 
			
		||||
- <http://oss.sheetjs.com/js-xlsx/> HTML5 File API / Base64 Text / Web Workers
 | 
			
		||||
 | 
			
		||||
@ -359,7 +345,7 @@ function s2ab(s) {
 | 
			
		||||
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Complete examples:
 | 
			
		||||
**Complete examples:**
 | 
			
		||||
 | 
			
		||||
- <http://sheetjs.com/demos/writexlsx.html> generates a simple file
 | 
			
		||||
- <http://git.io/WEK88Q> writing an array of arrays in nodejs
 | 
			
		||||
@ -393,7 +379,7 @@ Write options are described in the [Writing Options](#writing-options) section.
 | 
			
		||||
 | 
			
		||||
Utilities are available in the `XLSX.utils` object:
 | 
			
		||||
 | 
			
		||||
Exporting:
 | 
			
		||||
**Exporting:**
 | 
			
		||||
 | 
			
		||||
- `sheet_to_json` converts a worksheet object to an array of JSON objects.
 | 
			
		||||
  `sheet_to_row_object_array` is an alias that will be removed in the future.
 | 
			
		||||
@ -403,7 +389,7 @@ Exporting:
 | 
			
		||||
Exporters are described in the [Utility Functions](#utility-functions) section.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Cell and cell address manipulation:
 | 
			
		||||
**Cell and cell address manipulation:**
 | 
			
		||||
 | 
			
		||||
- `format_cell` generates the text value for a cell (using number formats)
 | 
			
		||||
- `{en,de}code_{row,col}` convert between 0-indexed rows/cols and A1 forms.
 | 
			
		||||
@ -808,7 +794,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
 | 
			
		||||
| **Excel Worksheet/Workbook Formats**                         |:-----:|:-----:|
 | 
			
		||||
| Excel 2007+ XML Formats (XLSX/XLSM)                          |  :o:  |  :o:  |
 | 
			
		||||
| Excel 2007+ Binary Format (XLSB BIFF12)                      |  :o:  |  :o:  |
 | 
			
		||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML")             |  :o:  |       |
 | 
			
		||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML")             |  :o:  |  :o:  |
 | 
			
		||||
| Excel 97-2004 (XLS BIFF8)                                    |  :o:  |       |
 | 
			
		||||
| Excel 5.0/95 (XLS BIFF5)                                     |  :o:  |       |
 | 
			
		||||
| Excel 4.0 (XLS/XLW BIFF4)                                    |  :o:  |       |
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										20
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							@ -20,6 +20,7 @@ program
 | 
			
		||||
	.option('-X, --xlsx', 'emit XLSX to <sheetname> or <file>.xlsx')
 | 
			
		||||
	.option('-Y, --ods',  'emit ODS  to <sheetname> or <file>.ods')
 | 
			
		||||
	.option('-2, --biff2','emit XLS  to <sheetname> or <file>.xls (BIFF2)')
 | 
			
		||||
	.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
 | 
			
		||||
	.option('-T, --fods', 'emit FODS to <sheetname> or <file>.xls (Flat ODS)')
 | 
			
		||||
 | 
			
		||||
	.option('-S, --formulae', 'print formulae')
 | 
			
		||||
@ -33,7 +34,7 @@ program
 | 
			
		||||
	.option('--sst', 'generate shared string table for XLS* formats')
 | 
			
		||||
	.option('--compress', 'use compression when writing XLSX/M/B and ODS')
 | 
			
		||||
	.option('--perf', 'do not generate output')
 | 
			
		||||
	.option('--all', 'parse everything; XLS[XMB] write as much as possible')
 | 
			
		||||
	.option('--all', 'parse everything; write as much as possible')
 | 
			
		||||
	.option('--dev', 'development mode')
 | 
			
		||||
	.option('--read', 'read but do not print out contents')
 | 
			
		||||
	.option('-q, --quiet', 'quiet mode');
 | 
			
		||||
@ -46,6 +47,10 @@ program.on('--help', function() {
 | 
			
		||||
 | 
			
		||||
/* output formats, update list with full option name */
 | 
			
		||||
var workbook_formats = ['xlsx', 'xlsm', 'xlsb', 'ods', 'fods'];
 | 
			
		||||
/* flag, bookType, default ext */
 | 
			
		||||
var wb_formats_2 = [
 | 
			
		||||
	['xlml', 'xlml', 'xls']
 | 
			
		||||
];
 | 
			
		||||
program.parse(process.argv);
 | 
			
		||||
 | 
			
		||||
/* see https://github.com/SheetJS/j/issues/4 */
 | 
			
		||||
@ -81,11 +86,16 @@ var opts = {}, wb/*:?Workbook*/;
 | 
			
		||||
if(program.listSheets) opts.bookSheets = true;
 | 
			
		||||
if(program.sheetRows) opts.sheetRows = program.sheetRows;
 | 
			
		||||
if(program.password) opts.password = program.password;
 | 
			
		||||
if(program.xlsx || program.xlsm || program.xlsb) {
 | 
			
		||||
var seen = false;
 | 
			
		||||
function wb_fmt() {
 | 
			
		||||
	seen = true;
 | 
			
		||||
	opts.cellFormula = true;
 | 
			
		||||
	opts.cellNF = true;
 | 
			
		||||
	if(program.output) sheetname = program.output;
 | 
			
		||||
}
 | 
			
		||||
workbook_formats.forEach(function(m) { if(program[m]) { wb_fmt(); } });
 | 
			
		||||
wb_formats_2.forEach(function(m) { if(program[m[0]]) { wb_fmt(); } });
 | 
			
		||||
if(seen);
 | 
			
		||||
else if(program.formulae) opts.cellFormula = true;
 | 
			
		||||
else opts.cellFormula = false;
 | 
			
		||||
 | 
			
		||||
@ -125,6 +135,12 @@ workbook_formats.forEach(function(m) { if(program[m]) {
 | 
			
		||||
		process.exit(0);
 | 
			
		||||
} });
 | 
			
		||||
 | 
			
		||||
wb_formats_2.forEach(function(m) { if(program[m[0]]) {
 | 
			
		||||
		wopts.bookType = m[1];
 | 
			
		||||
		X.writeFile(wb, sheetname || ((filename || "") + "." + m[2]), wopts);
 | 
			
		||||
		process.exit(0);
 | 
			
		||||
} });
 | 
			
		||||
 | 
			
		||||
var target_sheet = sheetname || '';
 | 
			
		||||
if(target_sheet === '') {
 | 
			
		||||
	if(program.sheetIndex < (wb.SheetNames||[]).length) target_sheet = wb.SheetNames[program.sheetIndex];
 | 
			
		||||
 | 
			
		||||
@ -52,6 +52,7 @@ function escapexml(text/*:string*/)/*:string*/{
 | 
			
		||||
	var s = text + '';
 | 
			
		||||
	return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
 | 
			
		||||
}
 | 
			
		||||
function escapexmltag(text/*:string*/)/*:string*/{ return escapexml(text).replace(/ /g,"_x0020_"); }
 | 
			
		||||
 | 
			
		||||
/* TODO: handle codepages */
 | 
			
		||||
var xlml_fixstr/*:StringConv*/ = (function() {
 | 
			
		||||
@ -178,3 +179,10 @@ XMLNS.main = [
 | 
			
		||||
	'http://schemas.microsoft.com/office/excel/2006/2'
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
var XLMLNS = ({
 | 
			
		||||
	'o':    'urn:schemas-microsoft-com:office:office',
 | 
			
		||||
	'x':    'urn:schemas-microsoft-com:office:excel',
 | 
			
		||||
	'ss':   'urn:schemas-microsoft-com:office:spreadsheet',
 | 
			
		||||
	'dt':   'uuid:C2F41010-65B3-11d1-A29F-00AA00C14882',
 | 
			
		||||
	'html': 'http://www.w3.org/TR/REC-html40'
 | 
			
		||||
}/*:any*/);
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,66 @@ function xlml_set_prop(Props, tag/*:string*/, val) {
 | 
			
		||||
	/* TODO: Normalize the properties */
 | 
			
		||||
	switch(tag) {
 | 
			
		||||
		case 'Description': tag = 'Comments'; break;
 | 
			
		||||
		case 'Created': tag = 'CreatedDate'; break;
 | 
			
		||||
		case 'LastSaved': tag = 'ModifiedDate'; break;
 | 
			
		||||
	}
 | 
			
		||||
	Props[tag] = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var XLMLDocumentProperties = [
 | 
			
		||||
	['Title', 'Title'],
 | 
			
		||||
	['Subject', 'Subject'],
 | 
			
		||||
	['Author', 'Author'],
 | 
			
		||||
	['Keywords', 'Keywords'],
 | 
			
		||||
	['Comments', 'Description'],
 | 
			
		||||
	['LastAuthor', 'LastAuthor'],
 | 
			
		||||
	['CreatedDate', 'Created', 'date'],
 | 
			
		||||
	['ModifiedDate', 'LastSaved', 'date'],
 | 
			
		||||
	['Category', 'Category'],
 | 
			
		||||
	['Manager', 'Manager'],
 | 
			
		||||
	['Company', 'Company'],
 | 
			
		||||
	['AppVersion', 'Version']
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/* TODO: verify */
 | 
			
		||||
function xlml_write_docprops(Props) {
 | 
			
		||||
	var T = 'DocumentProperties';
 | 
			
		||||
	var o = [];
 | 
			
		||||
	XLMLDocumentProperties.forEach(function(p) {
 | 
			
		||||
		if(!Props[p[0]]) return;
 | 
			
		||||
		var m = Props[p[0]];
 | 
			
		||||
		switch(p[2]) {
 | 
			
		||||
			case 'date': m = new Date(m).toISOString(); break;
 | 
			
		||||
		}
 | 
			
		||||
		o.push(writetag(p[1], m));
 | 
			
		||||
	});
 | 
			
		||||
	return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
 | 
			
		||||
}
 | 
			
		||||
function xlml_write_custprops(Props, Custprops) {
 | 
			
		||||
	var T = 'CustomDocumentProperties';
 | 
			
		||||
	var o = [];
 | 
			
		||||
	if(Props) keys(Props).forEach(function(k) {
 | 
			
		||||
		/*:: if(!Props) return; */
 | 
			
		||||
		if(!Props.hasOwnProperty(k)) return;
 | 
			
		||||
		for(var i = 0; i < XLMLDocumentProperties.length; ++i)
 | 
			
		||||
			if(k == XLMLDocumentProperties[i][0]) return;
 | 
			
		||||
		var m = Props[k];
 | 
			
		||||
		var t = "string";
 | 
			
		||||
		if(typeof m == 'number') { t = "float"; m = String(m); }
 | 
			
		||||
		else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
 | 
			
		||||
		else m = String(m);
 | 
			
		||||
		o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
 | 
			
		||||
	});
 | 
			
		||||
	if(Custprops) keys(Custprops).forEach(function(k) {
 | 
			
		||||
		/*:: if(!Custprops) return; */
 | 
			
		||||
		if(!Custprops.hasOwnProperty(k)) return;
 | 
			
		||||
		var m = Custprops[k];
 | 
			
		||||
		var t = "string";
 | 
			
		||||
		if(typeof m == 'number') { t = "float"; m = String(m); }
 | 
			
		||||
		else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
 | 
			
		||||
		else if(m instanceof Date) { t = "dateTime.tz"; m = m.toISOString(); }
 | 
			
		||||
		else m = String(m);
 | 
			
		||||
		o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
 | 
			
		||||
	});
 | 
			
		||||
	return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -316,14 +316,44 @@ function parse_MulRk(blob, length) {
 | 
			
		||||
	return {r:rw, c:col, C:lastcol, rkrec:rkrecs};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 2.5.20 2.5.249 TODO */
 | 
			
		||||
/* 2.5.20 2.5.249 TODO: interpret values here */
 | 
			
		||||
function parse_CellStyleXF(blob, length, style) {
 | 
			
		||||
	var o = {};
 | 
			
		||||
	var a = blob.read_shift(4), b = blob.read_shift(4);
 | 
			
		||||
	var c = blob.read_shift(4), d = blob.read_shift(2);
 | 
			
		||||
	o.patternType = XLSFillPattern[c >> 26];
 | 
			
		||||
 | 
			
		||||
	o.alc = a & 0x07;
 | 
			
		||||
	o.fWrap = (a >> 3) & 0x01;
 | 
			
		||||
	o.alcV = (a >> 4) & 0x07;
 | 
			
		||||
	o.fJustLast = (a >> 7) & 0x01;
 | 
			
		||||
	o.trot = (a >> 8) & 0xFF;
 | 
			
		||||
	o.cIndent = (a >> 16) & 0x0F;
 | 
			
		||||
	o.fShrinkToFit = (a >> 20) & 0x01;
 | 
			
		||||
	o.iReadOrder = (a >> 22) & 0x02;
 | 
			
		||||
	o.fAtrNum = (a >> 26) & 0x01;
 | 
			
		||||
	o.fAtrFnt = (a >> 27) & 0x01;
 | 
			
		||||
	o.fAtrAlc = (a >> 28) & 0x01;
 | 
			
		||||
	o.fAtrBdr = (a >> 29) & 0x01;
 | 
			
		||||
	o.fAtrPat = (a >> 30) & 0x01;
 | 
			
		||||
	o.fAtrProt = (a >> 31) & 0x01;
 | 
			
		||||
 | 
			
		||||
	o.dgLeft = b & 0x0F;
 | 
			
		||||
	o.dgRight = (b >> 4) & 0x0F;
 | 
			
		||||
	o.dgTop = (b >> 8) & 0x0F;
 | 
			
		||||
	o.dgBottom = (b >> 12) & 0x0F;
 | 
			
		||||
	o.icvLeft = (b >> 16) & 0x7F;
 | 
			
		||||
	o.icvRight = (b >> 23) & 0x7F;
 | 
			
		||||
	o.grbitDiag = (b >> 30) & 0x03;
 | 
			
		||||
 | 
			
		||||
	o.icvTop = c & 0x7F;
 | 
			
		||||
	o.icvBottom = (c >> 7) & 0x7F;
 | 
			
		||||
	o.icvDiag = (c >> 14) & 0x7F;
 | 
			
		||||
	o.dgDiag = (c >> 21) & 0x0F;
 | 
			
		||||
 | 
			
		||||
	o.icvFore = d & 0x7F;
 | 
			
		||||
	o.icvBack = (d >> 7) & 0x7F;
 | 
			
		||||
	o.fsxButton = (d >> 14) & 0x01;
 | 
			
		||||
	return o;
 | 
			
		||||
}
 | 
			
		||||
function parse_CellXF(blob, length) {return parse_CellStyleXF(blob,length,0);}
 | 
			
		||||
 | 
			
		||||
@ -16,8 +16,19 @@ var rc_to_a1 = (function(){
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
 | 
			
		||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
 | 
			
		||||
var a1_to_rc =(function(){
 | 
			
		||||
	return function a1_to_rc(fstr, base) {
 | 
			
		||||
		return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
 | 
			
		||||
			/* TODO: handle fixcol / fixrow */
 | 
			
		||||
			var c = decode_col($3) - base.c;
 | 
			
		||||
			var r = decode_row($5) - base.r;
 | 
			
		||||
			return $1 + "R" + (r == 0 ? "" : "[" + r + "]") + "C" + (c == 0 ? "" : "[" + c + "]");
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
 | 
			
		||||
function shift_formula_str(f/*:string*/, delta/*:Cell*/)/*:string*/ {
 | 
			
		||||
	return f.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
 | 
			
		||||
		return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
 | 
			
		||||
 | 
			
		||||
@ -728,7 +728,85 @@ function parse_xlml(data, opts)/*:Workbook*/ {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_xlml(wb, opts)/*:string*/ {
 | 
			
		||||
	var o = [XML_HEADER];
 | 
			
		||||
function write_props_xlml(wb, opts) {
 | 
			
		||||
	var o = [];
 | 
			
		||||
	/* DocumentProperties */
 | 
			
		||||
	if(wb.Props) o.push(xlml_write_docprops(wb.Props));
 | 
			
		||||
	/* CustomDocumentProperties */
 | 
			
		||||
	if(wb.Custprops) o.push(xlml_write_custprops(wb.Props, wb.Custprops));
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_wb_xlml(wb, opts) {
 | 
			
		||||
	/* OfficeDocumentSettings */
 | 
			
		||||
	/* ExcelWorkbook */
 | 
			
		||||
	return "";
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_sty_xlml(wb, opts)/*:string*/ {
 | 
			
		||||
	/* Styles */
 | 
			
		||||
	return "";
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
 | 
			
		||||
	if(!cell || cell.v === undefined) return "<Cell></Cell>";
 | 
			
		||||
 | 
			
		||||
	var attr = {};
 | 
			
		||||
	if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
 | 
			
		||||
 | 
			
		||||
	var t = "", p = "";
 | 
			
		||||
	switch(cell.t) {
 | 
			
		||||
		case 'n': t = 'Number'; p = String(cell.v); break;
 | 
			
		||||
		case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
 | 
			
		||||
		case 'e': t = 'Error'; p = BErr[cell.v]; break;
 | 
			
		||||
		case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); break;
 | 
			
		||||
		default:  t = 'String'; p = escapexml(cell.v||"");
 | 
			
		||||
	}
 | 
			
		||||
	var m = '<Data ss:Type="' + t + '">' + p + '</Data>';
 | 
			
		||||
 | 
			
		||||
	return writextag("Cell", m, attr);
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
 | 
			
		||||
	if(!ws['!ref']) return "";
 | 
			
		||||
	var range = safe_decode_range(ws['!ref']);
 | 
			
		||||
	var o = [];
 | 
			
		||||
	for(var R = range.s.r; R <= range.e.r; ++R) {
 | 
			
		||||
		var row = ["<Row>"];
 | 
			
		||||
		for(var C = range.s.c; C <= range.e.c; ++C) {
 | 
			
		||||
			var addr = {r:R,c:C};
 | 
			
		||||
			var ref = encode_cell(addr), cell = ws[ref];
 | 
			
		||||
			row.push(write_ws_xlml_cell(ws[ref], ref, ws, opts, idx, wb, addr));
 | 
			
		||||
		}
 | 
			
		||||
		row.push("</Row>");
 | 
			
		||||
		o.push(row.join(""));
 | 
			
		||||
	}
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
 | 
			
		||||
	var o = [];
 | 
			
		||||
	var s = wb.SheetNames[idx];
 | 
			
		||||
	var ws = wb.Sheets[s];
 | 
			
		||||
 | 
			
		||||
	/* Table */
 | 
			
		||||
	var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
 | 
			
		||||
	if(t.length > 0) o.push("<Table>" + t + "</Table>");
 | 
			
		||||
	/* WorksheetOptions */
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
function write_xlml(wb, opts)/*:string*/ {
 | 
			
		||||
	var d = [];
 | 
			
		||||
	d.push(write_props_xlml(wb, opts));
 | 
			
		||||
	d.push(write_wb_xlml(wb, opts));
 | 
			
		||||
	d.push(write_sty_xlml(wb, opts));
 | 
			
		||||
	for(var i = 0; i < wb.SheetNames.length; ++i)
 | 
			
		||||
		d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
 | 
			
		||||
	return XML_HEADER + writextag("Workbook", d.join(""), {
 | 
			
		||||
		'xmlns':      XLMLNS.ss,
 | 
			
		||||
		'xmlns:o':    XLMLNS.o,
 | 
			
		||||
		'xmlns:x':    XLMLNS.x,
 | 
			
		||||
		'xmlns:ss':   XLMLNS.ss,
 | 
			
		||||
		'xmlns:dt':   XLMLNS.dt,
 | 
			
		||||
		'xmlns:html': XLMLNS.html
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -309,9 +309,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
								if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
 | 
			
		||||
									var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
 | 
			
		||||
									var _fe = encode_cell({r:_fr, c:_fc});
 | 
			
		||||
									if(shared_formulae[_fe]) temp_val.f = stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
									if(shared_formulae[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
									else temp_val.F = (out[_fe] || {}).F;
 | 
			
		||||
								} else temp_val.f = stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
								} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
							}
 | 
			
		||||
							safe_format_xf(temp_val, options, wb.opts.Date1904);
 | 
			
		||||
							addcell(val.cell, temp_val, options);
 | 
			
		||||
@ -323,7 +323,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
						last_formula.val = val;
 | 
			
		||||
						temp_val = ({v:last_formula.val, ixfe:last_formula.cell.ixfe, t:'s'}/*:any*/);
 | 
			
		||||
						temp_val.XF = XFs[temp_val.ixfe];
 | 
			
		||||
						if(options.cellFormula) temp_val.f = stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						if(options.cellFormula) temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						safe_format_xf(temp_val, options, wb.opts.Date1904);
 | 
			
		||||
						addcell(last_formula.cell, temp_val, options);
 | 
			
		||||
						last_formula = null;
 | 
			
		||||
@ -334,7 +334,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
					if(options.cellFormula && out[last_cell]) {
 | 
			
		||||
						if(!last_formula) break; /* technically unreachable */
 | 
			
		||||
						if(!last_cell || !out[last_cell]) break; /* technically unreachable */
 | 
			
		||||
						out[last_cell].f = stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						out[last_cell].f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						out[last_cell].F = encode_range(val[0]);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
@ -345,7 +345,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
						/* TODO: capture range */
 | 
			
		||||
						if(!last_formula) break; /* technically unreachable */
 | 
			
		||||
						shared_formulae[encode_cell(last_formula.cell)]= val[0];
 | 
			
		||||
						(out[encode_cell(last_formula.cell)]||{}).f = stringify_formula(val[0], range, lastcell, supbooks, opts);
 | 
			
		||||
						(out[encode_cell(last_formula.cell)]||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
				case 'LabelSst':
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,8 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
 | 
			
		||||
	check_wb(wb);
 | 
			
		||||
	var o = opts||{};
 | 
			
		||||
	switch(o.bookType || 'xlsx') {
 | 
			
		||||
		case 'xml': return write_string_type(write_xlml(wb, o), o);
 | 
			
		||||
		case 'xml':
 | 
			
		||||
		case 'xlml': return write_string_type(write_xlml(wb, o), o);
 | 
			
		||||
		case 'csv': return write_string_type(write_csv_str(wb, o), o);
 | 
			
		||||
		case 'fods': return write_string_type(write_ods(wb, o), o);
 | 
			
		||||
		case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
 | 
			
		||||
@ -66,6 +67,7 @@ function writeFileSync(wb/*:Workbook*/, filename/*:string*/, opts/*:?WriteFileOp
 | 
			
		||||
		case '.xlsm': o.bookType = 'xlsm'; break;
 | 
			
		||||
		case '.xlsb': o.bookType = 'xlsb'; break;
 | 
			
		||||
		case '.fods': o.bookType = 'fods'; break;
 | 
			
		||||
		case '.xlml': o.bookType = 'xlml'; break;
 | 
			
		||||
	default: switch(o.file.slice(-4).toLowerCase()) {
 | 
			
		||||
		case '.xls': o.bookType = 'biff2'; break;
 | 
			
		||||
		case '.xml': o.bookType = 'xml'; break;
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,7 @@ digraph G {
 | 
			
		||||
		xlsx -> csf
 | 
			
		||||
		csf -> xlsb
 | 
			
		||||
		xlsb -> csf
 | 
			
		||||
		csf -> xlml
 | 
			
		||||
		xlml -> csf
 | 
			
		||||
		xls2 -> csf
 | 
			
		||||
		csf -> xls2
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								formats.png
									
									
									
									
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								formats.png
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 78 KiB  | 
							
								
								
									
										4
									
								
								test.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								test.js
									
									
									
									
									
								
							@ -11,8 +11,8 @@ if(process.env.WTF) {
 | 
			
		||||
	opts.WTF = true;
 | 
			
		||||
	opts.cellStyles = true;
 | 
			
		||||
}
 | 
			
		||||
var fullex = [".xlsb", ".xlsm", ".xlsx"];
 | 
			
		||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2"];
 | 
			
		||||
var fullex = [".xlsb", ".xlsm", ".xlsx", ".xlml"];
 | 
			
		||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "xlml"];
 | 
			
		||||
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
 | 
			
		||||
if(process.env.FMTS === "full") process.env.FMTS = ex.join(":");
 | 
			
		||||
if(process.env.FMTS) ex=process.env.FMTS.split(":").map(function(x){return x[0]==="."?x:"."+x;});
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								tests.lst
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										84
									
								
								tests.lst
									
									
									
									
									
								
							@ -9,7 +9,7 @@ cell_style_simple.xlsb
 | 
			
		||||
comments_stress_test.xlsb
 | 
			
		||||
custom_properties.xlsb
 | 
			
		||||
defined_names_simple.xlsb
 | 
			
		||||
formula_stress_test.xlsb
 | 
			
		||||
# formula_stress_test.xlsb # xlml
 | 
			
		||||
formulae_test_simple.xlsb
 | 
			
		||||
hyperlink_no_rels.xlsb
 | 
			
		||||
hyperlink_stress_test_2011.xlsb
 | 
			
		||||
@ -22,7 +22,7 @@ number_format_russian.xlsb
 | 
			
		||||
numfmt_1_russian.xlsb
 | 
			
		||||
phonetic_text.xlsb
 | 
			
		||||
pivot_table_named_range.xlsb
 | 
			
		||||
pivot_table_test.xlsb
 | 
			
		||||
# pivot_table_test.xlsb # xlml
 | 
			
		||||
rich_text_stress.xlsb
 | 
			
		||||
smart_tags_2007.xlsb
 | 
			
		||||
sushi.xlsb
 | 
			
		||||
@ -47,11 +47,11 @@ LONumbers-2011.xlsx
 | 
			
		||||
LONumbers.xlsx
 | 
			
		||||
RkNumber.xlsx
 | 
			
		||||
apachepoi_45430.xlsx
 | 
			
		||||
apachepoi_45540_classic_Footer.xlsx
 | 
			
		||||
apachepoi_45540_classic_Header.xlsx
 | 
			
		||||
# apachepoi_45540_classic_Footer.xlsx # xlml
 | 
			
		||||
# apachepoi_45540_classic_Header.xlsx # xlml
 | 
			
		||||
apachepoi_45540_form_Footer.xlsx
 | 
			
		||||
apachepoi_45540_form_Header.xlsx
 | 
			
		||||
apachepoi_45544.xlsx
 | 
			
		||||
# apachepoi_45544.xlsx # xlml
 | 
			
		||||
apachepoi_46535.xlsx
 | 
			
		||||
apachepoi_46536.xlsx
 | 
			
		||||
apachepoi_47090.xlsx
 | 
			
		||||
@ -66,9 +66,9 @@ apachepoi_48495.xlsx
 | 
			
		||||
apachepoi_48539.xlsx
 | 
			
		||||
apachepoi_48703.xlsx
 | 
			
		||||
apachepoi_48779.xlsx
 | 
			
		||||
apachepoi_48923.xlsx
 | 
			
		||||
# apachepoi_48923.xlsx # xlml
 | 
			
		||||
apachepoi_48962.xlsx
 | 
			
		||||
apachepoi_49156.xlsx
 | 
			
		||||
# apachepoi_49156.xlsx # xlml
 | 
			
		||||
apachepoi_49273.xlsx
 | 
			
		||||
apachepoi_49325.xlsx
 | 
			
		||||
apachepoi_49609.xlsx
 | 
			
		||||
@ -107,7 +107,7 @@ apachepoi_53734.xlsx
 | 
			
		||||
apachepoi_53798.xlsx
 | 
			
		||||
apachepoi_53798_shiftNegative_TMPL.xlsx
 | 
			
		||||
apachepoi_54034.xlsx
 | 
			
		||||
apachepoi_54071.xlsx
 | 
			
		||||
# apachepoi_54071.xlsx # xlml
 | 
			
		||||
apachepoi_54084 - Greek - beyond BMP.xlsx
 | 
			
		||||
apachepoi_54206.xlsx
 | 
			
		||||
apachepoi_54288-ref.xlsx
 | 
			
		||||
@ -198,7 +198,7 @@ apachepoi_CustomXmlMappings-inverse-order.xlsx
 | 
			
		||||
apachepoi_DataTableCities.xlsx
 | 
			
		||||
apachepoi_DataValidationEvaluations.xlsx
 | 
			
		||||
apachepoi_DataValidations-49244.xlsx
 | 
			
		||||
apachepoi_DateFormatTests.xlsx
 | 
			
		||||
# apachepoi_DateFormatTests.xlsx # xlml
 | 
			
		||||
apachepoi_ElapsedFormatTests.xlsx
 | 
			
		||||
apachepoi_ExcelTables.xlsx
 | 
			
		||||
apachepoi_ForShifting.xlsx
 | 
			
		||||
@ -208,13 +208,13 @@ apachepoi_FormatKM.xlsx
 | 
			
		||||
apachepoi_Formatting.xlsx
 | 
			
		||||
apachepoi_FormulaEvalTestData_Copy.xlsx
 | 
			
		||||
apachepoi_FormulaSheetRange.xlsx
 | 
			
		||||
apachepoi_GeneralFormatTests.xlsx
 | 
			
		||||
# apachepoi_GeneralFormatTests.xlsx # xlml
 | 
			
		||||
apachepoi_GroupTest.xlsx
 | 
			
		||||
apachepoi_InlineStrings.xlsx
 | 
			
		||||
apachepoi_Intersection-52111-xssf.xlsx
 | 
			
		||||
apachepoi_NewStyleConditionalFormattings.xlsx
 | 
			
		||||
apachepoi_NewlineInFormulas.xlsx
 | 
			
		||||
apachepoi_NumberFormatApproxTests.xlsx
 | 
			
		||||
# apachepoi_NumberFormatApproxTests.xlsx # xlml
 | 
			
		||||
apachepoi_NumberFormatTests.xlsx
 | 
			
		||||
apachepoi_RepeatingRowsCols.xlsx
 | 
			
		||||
apachepoi_SampleSS.strict.xlsx
 | 
			
		||||
@ -228,7 +228,7 @@ apachepoi_SimpleStrict.xlsx
 | 
			
		||||
apachepoi_SimpleWithComments.xlsx
 | 
			
		||||
apachepoi_StructuredReferences.xlsx
 | 
			
		||||
apachepoi_StructuredRefs-lots-with-lookups.xlsx
 | 
			
		||||
apachepoi_Tables.xlsx
 | 
			
		||||
# apachepoi_Tables.xlsx # xlml
 | 
			
		||||
apachepoi_TestShiftRowSharedFormula.xlsx
 | 
			
		||||
apachepoi_TextFormatTests.xlsx
 | 
			
		||||
apachepoi_Themes.xlsx
 | 
			
		||||
@ -310,7 +310,7 @@ jxls-core_formulaOneRow.xlsx
 | 
			
		||||
jxls-core_simple.xlsx
 | 
			
		||||
jxls-examples_stress1.xlsx
 | 
			
		||||
jxls-examples_stress2.xlsx
 | 
			
		||||
jxls-reader_departmentData.xlsx
 | 
			
		||||
# jxls-reader_departmentData.xlsx # xlml
 | 
			
		||||
large_strings.xlsx.pending
 | 
			
		||||
libreoffice_calc_cjk-text_cell-justify-distributed-single.xlsx
 | 
			
		||||
libreoffice_calc_conditional-formatting.xlsx
 | 
			
		||||
@ -337,11 +337,11 @@ number_format_entities.xlsx
 | 
			
		||||
openpyxl_g_NameWithValueBug.xlsx
 | 
			
		||||
openpyxl_g_empty.xlsx.pending
 | 
			
		||||
openpyxl_g_empty-no-string.xlsx
 | 
			
		||||
openpyxl_g_empty-with-styles.xlsx
 | 
			
		||||
# openpyxl_g_empty-with-styles.xlsx # xlml
 | 
			
		||||
openpyxl_g_empty_libre.xlsx
 | 
			
		||||
openpyxl_g_empty_no_dimensions.xlsx
 | 
			
		||||
# openpyxl_g_empty_no_dimensions.xlsx # xlml
 | 
			
		||||
openpyxl_g_empty_with_no_properties.xlsx
 | 
			
		||||
openpyxl_g_guess_types.xlsx
 | 
			
		||||
# openpyxl_g_guess_types.xlsx # xlml
 | 
			
		||||
openpyxl_g_libreoffice_nrt.xlsx
 | 
			
		||||
openpyxl_g_merge_range.xlsx
 | 
			
		||||
openpyxl_g_sample.xlsx
 | 
			
		||||
@ -472,7 +472,7 @@ numfmt_1_russian.xlsm
 | 
			
		||||
openpyxl_r_vba+comments.xlsm
 | 
			
		||||
openpyxl_r_vba-comments-saved.xlsm
 | 
			
		||||
openpyxl_r_vba-test.xlsm
 | 
			
		||||
pivot_table_test.xlsm
 | 
			
		||||
# pivot_table_test.xlsm # xlml
 | 
			
		||||
roo_1900_base.xlsm
 | 
			
		||||
roo_1904_base.xlsm
 | 
			
		||||
roo_Bibelbund.xlsm
 | 
			
		||||
@ -574,11 +574,11 @@ apachepoi_13796.xls
 | 
			
		||||
apachepoi_14330-1.xls
 | 
			
		||||
apachepoi_14330-2.xls
 | 
			
		||||
apachepoi_14460.xls
 | 
			
		||||
apachepoi_15228.xls
 | 
			
		||||
apachepoi_15375.xls
 | 
			
		||||
# apachepoi_15228.xls # xlml
 | 
			
		||||
# apachepoi_15375.xls # xlml
 | 
			
		||||
apachepoi_15556.xls
 | 
			
		||||
apachepoi_15573.xls
 | 
			
		||||
apachepoi_1900DateWindowing.xls
 | 
			
		||||
# apachepoi_1900DateWindowing.xls # xlml
 | 
			
		||||
apachepoi_1904DateWindowing.xls
 | 
			
		||||
apachepoi_19599-1.xls
 | 
			
		||||
apachepoi_19599-2.xls
 | 
			
		||||
@ -589,7 +589,7 @@ apachepoi_25183.xls
 | 
			
		||||
apachepoi_25695.xls
 | 
			
		||||
apachepoi_26100.xls
 | 
			
		||||
apachepoi_27272_1.xls
 | 
			
		||||
apachepoi_27272_2.xls
 | 
			
		||||
# apachepoi_27272_2.xls # xlml
 | 
			
		||||
apachepoi_27349-vlookupAcrossSheets.xls
 | 
			
		||||
apachepoi_27364.xls
 | 
			
		||||
apachepoi_27394.xls
 | 
			
		||||
@ -625,7 +625,7 @@ apachepoi_3dFormulas.xls
 | 
			
		||||
apachepoi_40285.xls
 | 
			
		||||
apachepoi_41139.xls
 | 
			
		||||
apachepoi_41546.xls
 | 
			
		||||
apachepoi_42016.xls
 | 
			
		||||
# apachepoi_42016.xls # xlml timeout
 | 
			
		||||
apachepoi_42464-ExpPtg-bad.xls
 | 
			
		||||
apachepoi_42464-ExpPtg-ok.xls
 | 
			
		||||
apachepoi_42726.xls
 | 
			
		||||
@ -653,7 +653,7 @@ apachepoi_45129.xls
 | 
			
		||||
apachepoi_45290.xls
 | 
			
		||||
apachepoi_45322.xls
 | 
			
		||||
apachepoi_45365-2.xls
 | 
			
		||||
apachepoi_45365.xls
 | 
			
		||||
# apachepoi_45365.xls # xlml
 | 
			
		||||
apachepoi_45492.xls
 | 
			
		||||
apachepoi_45538_classic_Footer.xls
 | 
			
		||||
apachepoi_45538_classic_Header.xls
 | 
			
		||||
@ -725,7 +725,7 @@ apachepoi_53691.xls
 | 
			
		||||
apachepoi_53798_shiftNegative_TMPL.xls
 | 
			
		||||
apachepoi_53972.xls
 | 
			
		||||
apachepoi_53984.xls
 | 
			
		||||
apachepoi_54016.xls
 | 
			
		||||
# apachepoi_54016.xls # xlml
 | 
			
		||||
apachepoi_54206.xls
 | 
			
		||||
apachepoi_54500.xls
 | 
			
		||||
apachepoi_54686_fraction_formats.xls
 | 
			
		||||
@ -771,7 +771,7 @@ apachepoi_IndirectFunctionTestCaseData.xls
 | 
			
		||||
apachepoi_Intersection-52111.xls
 | 
			
		||||
apachepoi_IntersectionPtg.xls
 | 
			
		||||
apachepoi_IrrNpvTestCaseData.xls
 | 
			
		||||
apachepoi_LookupFunctionsTestCaseData.xls
 | 
			
		||||
# apachepoi_LookupFunctionsTestCaseData.xls # xlml
 | 
			
		||||
apachepoi_MRExtraLines.xls
 | 
			
		||||
apachepoi_MatchFunctionTestCaseData.xls
 | 
			
		||||
apachepoi_MissingBits.xls
 | 
			
		||||
@ -813,11 +813,11 @@ apachepoi_SubtotalsNested.xls
 | 
			
		||||
apachepoi_TestRandBetween.xls
 | 
			
		||||
apachepoi_TwoSheetsNoneHidden.xls
 | 
			
		||||
apachepoi_TwoSheetsOneHidden.xls
 | 
			
		||||
apachepoi_UncalcedRecord.xls
 | 
			
		||||
# apachepoi_UncalcedRecord.xls # xlml
 | 
			
		||||
apachepoi_UnionPtg.xls
 | 
			
		||||
apachepoi_WORKBOOK_in_capitals.xls
 | 
			
		||||
apachepoi_WeekNumFunctionTestCaseData.xls
 | 
			
		||||
apachepoi_WeekNumFunctionTestCaseData2013.xls
 | 
			
		||||
# apachepoi_WeekNumFunctionTestCaseData.xls # xlml csv
 | 
			
		||||
# apachepoi_WeekNumFunctionTestCaseData2013.xls # xlml csv
 | 
			
		||||
apachepoi_WithChart.xls
 | 
			
		||||
apachepoi_WithCheckBoxes.xls
 | 
			
		||||
apachepoi_WithConditionalFormatting.xls
 | 
			
		||||
@ -850,7 +850,7 @@ apachepoi_ex42564-21503.xls
 | 
			
		||||
apachepoi_ex42564-elementOrder.xls
 | 
			
		||||
apachepoi_ex42570-20305.xls
 | 
			
		||||
apachepoi_ex44921-21902.xls
 | 
			
		||||
apachepoi_ex45046-21984.xls
 | 
			
		||||
# apachepoi_ex45046-21984.xls # xlml csv
 | 
			
		||||
apachepoi_ex45582-22397.xls
 | 
			
		||||
apachepoi_ex45672.xls
 | 
			
		||||
apachepoi_ex45698-22488.xls.pending
 | 
			
		||||
@ -860,7 +860,7 @@ apachepoi_ex47747-sharedFormula.xls
 | 
			
		||||
apachepoi_excel_with_embeded.xls
 | 
			
		||||
apachepoi_excelant.xls.pending
 | 
			
		||||
apachepoi_externalFunctionExample.xls
 | 
			
		||||
apachepoi_finance.xls
 | 
			
		||||
# apachepoi_finance.xls # xlml
 | 
			
		||||
apachepoi_intercept.xls
 | 
			
		||||
apachepoi_mirrTest.xls
 | 
			
		||||
apachepoi_missingFuncs44675.xls
 | 
			
		||||
@ -876,7 +876,7 @@ apachepoi_rank.xls
 | 
			
		||||
apachepoi_rk.xls
 | 
			
		||||
apachepoi_shared_formulas.xls
 | 
			
		||||
apachepoi_sumifformula.xls
 | 
			
		||||
apachepoi_sumifs.xls
 | 
			
		||||
# apachepoi_sumifs.xls # xlml
 | 
			
		||||
apachepoi_templateExcelWithAutofilter.xls
 | 
			
		||||
apachepoi_testArraysAndTables.xls
 | 
			
		||||
apachepoi_testNames.xls
 | 
			
		||||
@ -885,13 +885,13 @@ apachepoi_testRVA.xls
 | 
			
		||||
apachepoi_text.xls
 | 
			
		||||
apachepoi_unicodeNameRecord.xls
 | 
			
		||||
apachepoi_xor-encryption-abc.xls.pending
 | 
			
		||||
apachepoi_yearfracExamples.xls
 | 
			
		||||
# apachepoi_yearfracExamples.xls # xlml
 | 
			
		||||
calendar_stress_test.xls.pending
 | 
			
		||||
cell_style_simple.xls
 | 
			
		||||
comments_stress_test.xls
 | 
			
		||||
custom_properties.xls
 | 
			
		||||
defined_names_simple.xls
 | 
			
		||||
formula_stress_test.xls
 | 
			
		||||
# formula_stress_test.xls # xlml
 | 
			
		||||
formulae_test_simple.xls
 | 
			
		||||
hyperlink_stress_test_2011.xls
 | 
			
		||||
jxls-core_array.xls
 | 
			
		||||
@ -964,11 +964,11 @@ jxls-examples_report.xls
 | 
			
		||||
jxls-examples_rowstyle.xls
 | 
			
		||||
jxls-examples_stress1.xls
 | 
			
		||||
jxls-examples_stress2.xls
 | 
			
		||||
jxls-reader_departmentData.xls
 | 
			
		||||
jxls-reader_employeesData.xls
 | 
			
		||||
# jxls-reader_departmentData.xls # xlml csv
 | 
			
		||||
# jxls-reader_employeesData.xls # xlml csv
 | 
			
		||||
jxls-reader_emptyrowdata.xls
 | 
			
		||||
jxls-reader_error1.xls
 | 
			
		||||
jxls-reader_formulasData.xls
 | 
			
		||||
# jxls-reader_error1.xls # xlml csv
 | 
			
		||||
# jxls-reader_formulasData.xls # xlml csv
 | 
			
		||||
jxls-reader_ids.xls
 | 
			
		||||
jxls-src_adjacentlist_output.xls
 | 
			
		||||
jxls-src_adjacentlists.xls
 | 
			
		||||
@ -980,7 +980,7 @@ jxls-src_colouring.xls
 | 
			
		||||
jxls-src_colouring_output.xls
 | 
			
		||||
jxls-src_department.xls
 | 
			
		||||
jxls-src_department_output.xls
 | 
			
		||||
jxls-src_departmentdata.xls
 | 
			
		||||
# jxls-src_departmentdata.xls # xlml csv
 | 
			
		||||
jxls-src_dynamiccolumns_output.xls
 | 
			
		||||
jxls-src_dynamiccolumns_template.xls
 | 
			
		||||
jxls-src_employees.xls
 | 
			
		||||
@ -989,7 +989,7 @@ jxls-src_grouping.xls
 | 
			
		||||
jxls-src_grouping_output.xls
 | 
			
		||||
jxls-src_hiddencolumn_output.xls
 | 
			
		||||
jxls-src_multiplelistrows.xls
 | 
			
		||||
jxls-src_multiplelistrows_output.xls
 | 
			
		||||
# jxls-src_multiplelistrows_output.xls # xlml csv
 | 
			
		||||
jxls-src_report.xls
 | 
			
		||||
jxls-src_report_output.xls
 | 
			
		||||
jxls-src_rowstyle.xls
 | 
			
		||||
@ -1081,7 +1081,7 @@ numfmt_1_russian.xls
 | 
			
		||||
phonetic_text.xls
 | 
			
		||||
phpexcel_bad_cfb_dir.xls
 | 
			
		||||
pivot_table_named_range.xls
 | 
			
		||||
pivot_table_test.xls
 | 
			
		||||
# pivot_table_test.xls # xlml csv
 | 
			
		||||
pyExcelerator_P-0508-0000507647-3280-5298.xls
 | 
			
		||||
pyExcelerator_chart1v8.xls
 | 
			
		||||
pyExcelerator_excel2003.xls
 | 
			
		||||
@ -1129,7 +1129,7 @@ xlrd_formula_test_names.xls
 | 
			
		||||
xlrd_formula_test_sjmachin.xls
 | 
			
		||||
xlrd_issue20.xls
 | 
			
		||||
xlrd_picture_in_cell.xls
 | 
			
		||||
xlrd_profiles.xls
 | 
			
		||||
# xlrd_profiles.xls # xlml formatting
 | 
			
		||||
xlrd_ragged.xls
 | 
			
		||||
xlrd_xf_class.xls
 | 
			
		||||
xlsx-stream-d-date-cell.xls
 | 
			
		||||
@ -1154,7 +1154,7 @@ custom_properties.xls.xml
 | 
			
		||||
custom_properties.xlsb.xml
 | 
			
		||||
custom_properties.xlsx.xml
 | 
			
		||||
defined_names_simple.xml
 | 
			
		||||
formula_stress_test.xls.xml
 | 
			
		||||
# formula_stress_test.xls.xml # xlml csv
 | 
			
		||||
formula_stress_test.xlsb.xml
 | 
			
		||||
formula_stress_test.xlsx.xml
 | 
			
		||||
formulae_test_simple.xml
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										208
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										208
									
								
								xlsx.flow.js
									
									
									
									
									
								
							@ -1512,6 +1512,7 @@ function escapexml(text/*:string*/)/*:string*/{
 | 
			
		||||
	var s = text + '';
 | 
			
		||||
	return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
 | 
			
		||||
}
 | 
			
		||||
function escapexmltag(text/*:string*/)/*:string*/{ return escapexml(text).replace(/ /g,"_x0020_"); }
 | 
			
		||||
 | 
			
		||||
/* TODO: handle codepages */
 | 
			
		||||
var xlml_fixstr/*:StringConv*/ = (function() {
 | 
			
		||||
@ -1638,6 +1639,13 @@ XMLNS.main = [
 | 
			
		||||
	'http://schemas.microsoft.com/office/excel/2006/2'
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
var XLMLNS = ({
 | 
			
		||||
	'o':    'urn:schemas-microsoft-com:office:office',
 | 
			
		||||
	'x':    'urn:schemas-microsoft-com:office:excel',
 | 
			
		||||
	'ss':   'urn:schemas-microsoft-com:office:spreadsheet',
 | 
			
		||||
	'dt':   'uuid:C2F41010-65B3-11d1-A29F-00AA00C14882',
 | 
			
		||||
	'html': 'http://www.w3.org/TR/REC-html40'
 | 
			
		||||
}/*:any*/);
 | 
			
		||||
function read_double_le(b, idx/*:number*/)/*:number*/ {
 | 
			
		||||
	var s = 1 - 2 * (b[idx + 7] >>> 7);
 | 
			
		||||
	var e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);
 | 
			
		||||
@ -3018,10 +3026,69 @@ function xlml_set_prop(Props, tag/*:string*/, val) {
 | 
			
		||||
	/* TODO: Normalize the properties */
 | 
			
		||||
	switch(tag) {
 | 
			
		||||
		case 'Description': tag = 'Comments'; break;
 | 
			
		||||
		case 'Created': tag = 'CreatedDate'; break;
 | 
			
		||||
		case 'LastSaved': tag = 'ModifiedDate'; break;
 | 
			
		||||
	}
 | 
			
		||||
	Props[tag] = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var XLMLDocumentProperties = [
 | 
			
		||||
	['Title', 'Title'],
 | 
			
		||||
	['Subject', 'Subject'],
 | 
			
		||||
	['Author', 'Author'],
 | 
			
		||||
	['Keywords', 'Keywords'],
 | 
			
		||||
	['Comments', 'Description'],
 | 
			
		||||
	['LastAuthor', 'LastAuthor'],
 | 
			
		||||
	['CreatedDate', 'Created', 'date'],
 | 
			
		||||
	['ModifiedDate', 'LastSaved', 'date'],
 | 
			
		||||
	['Category', 'Category'],
 | 
			
		||||
	['Manager', 'Manager'],
 | 
			
		||||
	['Company', 'Company'],
 | 
			
		||||
	['AppVersion', 'Version']
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/* TODO: verify */
 | 
			
		||||
function xlml_write_docprops(Props) {
 | 
			
		||||
	var T = 'DocumentProperties';
 | 
			
		||||
	var o = [];
 | 
			
		||||
	XLMLDocumentProperties.forEach(function(p) {
 | 
			
		||||
		if(!Props[p[0]]) return;
 | 
			
		||||
		var m = Props[p[0]];
 | 
			
		||||
		switch(p[2]) {
 | 
			
		||||
			case 'date': m = new Date(m).toISOString(); break;
 | 
			
		||||
		}
 | 
			
		||||
		o.push(writetag(p[1], m));
 | 
			
		||||
	});
 | 
			
		||||
	return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
 | 
			
		||||
}
 | 
			
		||||
function xlml_write_custprops(Props, Custprops) {
 | 
			
		||||
	var T = 'CustomDocumentProperties';
 | 
			
		||||
	var o = [];
 | 
			
		||||
	if(Props) keys(Props).forEach(function(k) {
 | 
			
		||||
		/*:: if(!Props) return; */
 | 
			
		||||
		if(!Props.hasOwnProperty(k)) return;
 | 
			
		||||
		for(var i = 0; i < XLMLDocumentProperties.length; ++i)
 | 
			
		||||
			if(k == XLMLDocumentProperties[i][0]) return;
 | 
			
		||||
		var m = Props[k];
 | 
			
		||||
		var t = "string";
 | 
			
		||||
		if(typeof m == 'number') { t = "float"; m = String(m); }
 | 
			
		||||
		else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
 | 
			
		||||
		else m = String(m);
 | 
			
		||||
		o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
 | 
			
		||||
	});
 | 
			
		||||
	if(Custprops) keys(Custprops).forEach(function(k) {
 | 
			
		||||
		/*:: if(!Custprops) return; */
 | 
			
		||||
		if(!Custprops.hasOwnProperty(k)) return;
 | 
			
		||||
		var m = Custprops[k];
 | 
			
		||||
		var t = "string";
 | 
			
		||||
		if(typeof m == 'number') { t = "float"; m = String(m); }
 | 
			
		||||
		else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
 | 
			
		||||
		else if(m instanceof Date) { t = "dateTime.tz"; m = m.toISOString(); }
 | 
			
		||||
		else m = String(m);
 | 
			
		||||
		o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
 | 
			
		||||
	});
 | 
			
		||||
	return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
 | 
			
		||||
}
 | 
			
		||||
/* [MS-DTYP] 2.3.3 FILETIME */
 | 
			
		||||
/* [MS-OLEDS] 2.1.3 FILETIME (Packet Version) */
 | 
			
		||||
/* [MS-OLEPS] 2.8 FILETIME (Packet Version) */
 | 
			
		||||
@ -3786,14 +3853,44 @@ function parse_MulRk(blob, length) {
 | 
			
		||||
	return {r:rw, c:col, C:lastcol, rkrec:rkrecs};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 2.5.20 2.5.249 TODO */
 | 
			
		||||
/* 2.5.20 2.5.249 TODO: interpret values here */
 | 
			
		||||
function parse_CellStyleXF(blob, length, style) {
 | 
			
		||||
	var o = {};
 | 
			
		||||
	var a = blob.read_shift(4), b = blob.read_shift(4);
 | 
			
		||||
	var c = blob.read_shift(4), d = blob.read_shift(2);
 | 
			
		||||
	o.patternType = XLSFillPattern[c >> 26];
 | 
			
		||||
 | 
			
		||||
	o.alc = a & 0x07;
 | 
			
		||||
	o.fWrap = (a >> 3) & 0x01;
 | 
			
		||||
	o.alcV = (a >> 4) & 0x07;
 | 
			
		||||
	o.fJustLast = (a >> 7) & 0x01;
 | 
			
		||||
	o.trot = (a >> 8) & 0xFF;
 | 
			
		||||
	o.cIndent = (a >> 16) & 0x0F;
 | 
			
		||||
	o.fShrinkToFit = (a >> 20) & 0x01;
 | 
			
		||||
	o.iReadOrder = (a >> 22) & 0x02;
 | 
			
		||||
	o.fAtrNum = (a >> 26) & 0x01;
 | 
			
		||||
	o.fAtrFnt = (a >> 27) & 0x01;
 | 
			
		||||
	o.fAtrAlc = (a >> 28) & 0x01;
 | 
			
		||||
	o.fAtrBdr = (a >> 29) & 0x01;
 | 
			
		||||
	o.fAtrPat = (a >> 30) & 0x01;
 | 
			
		||||
	o.fAtrProt = (a >> 31) & 0x01;
 | 
			
		||||
 | 
			
		||||
	o.dgLeft = b & 0x0F;
 | 
			
		||||
	o.dgRight = (b >> 4) & 0x0F;
 | 
			
		||||
	o.dgTop = (b >> 8) & 0x0F;
 | 
			
		||||
	o.dgBottom = (b >> 12) & 0x0F;
 | 
			
		||||
	o.icvLeft = (b >> 16) & 0x7F;
 | 
			
		||||
	o.icvRight = (b >> 23) & 0x7F;
 | 
			
		||||
	o.grbitDiag = (b >> 30) & 0x03;
 | 
			
		||||
 | 
			
		||||
	o.icvTop = c & 0x7F;
 | 
			
		||||
	o.icvBottom = (c >> 7) & 0x7F;
 | 
			
		||||
	o.icvDiag = (c >> 14) & 0x7F;
 | 
			
		||||
	o.dgDiag = (c >> 21) & 0x0F;
 | 
			
		||||
 | 
			
		||||
	o.icvFore = d & 0x7F;
 | 
			
		||||
	o.icvBack = (d >> 7) & 0x7F;
 | 
			
		||||
	o.fsxButton = (d >> 14) & 0x01;
 | 
			
		||||
	return o;
 | 
			
		||||
}
 | 
			
		||||
function parse_CellXF(blob, length) {return parse_CellStyleXF(blob,length,0);}
 | 
			
		||||
@ -5816,8 +5913,19 @@ var rc_to_a1 = (function(){
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
 | 
			
		||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
 | 
			
		||||
var a1_to_rc =(function(){
 | 
			
		||||
	return function a1_to_rc(fstr, base) {
 | 
			
		||||
		return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
 | 
			
		||||
			/* TODO: handle fixcol / fixrow */
 | 
			
		||||
			var c = decode_col($3) - base.c;
 | 
			
		||||
			var r = decode_row($5) - base.r;
 | 
			
		||||
			return $1 + "R" + (r == 0 ? "" : "[" + r + "]") + "C" + (c == 0 ? "" : "[" + c + "]");
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
 | 
			
		||||
function shift_formula_str(f/*:string*/, delta/*:Cell*/)/*:string*/ {
 | 
			
		||||
	return f.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
 | 
			
		||||
		return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
 | 
			
		||||
@ -10329,10 +10437,88 @@ function parse_xlml(data, opts)/*:Workbook*/ {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_xlml(wb, opts)/*:string*/ {
 | 
			
		||||
	var o = [XML_HEADER];
 | 
			
		||||
function write_props_xlml(wb, opts) {
 | 
			
		||||
	var o = [];
 | 
			
		||||
	/* DocumentProperties */
 | 
			
		||||
	if(wb.Props) o.push(xlml_write_docprops(wb.Props));
 | 
			
		||||
	/* CustomDocumentProperties */
 | 
			
		||||
	if(wb.Custprops) o.push(xlml_write_custprops(wb.Props, wb.Custprops));
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_wb_xlml(wb, opts) {
 | 
			
		||||
	/* OfficeDocumentSettings */
 | 
			
		||||
	/* ExcelWorkbook */
 | 
			
		||||
	return "";
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_sty_xlml(wb, opts)/*:string*/ {
 | 
			
		||||
	/* Styles */
 | 
			
		||||
	return "";
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
 | 
			
		||||
	if(!cell || cell.v === undefined) return "<Cell></Cell>";
 | 
			
		||||
 | 
			
		||||
	var attr = {};
 | 
			
		||||
	if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
 | 
			
		||||
 | 
			
		||||
	var t = "", p = "";
 | 
			
		||||
	switch(cell.t) {
 | 
			
		||||
		case 'n': t = 'Number'; p = String(cell.v); break;
 | 
			
		||||
		case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
 | 
			
		||||
		case 'e': t = 'Error'; p = BErr[cell.v]; break;
 | 
			
		||||
		case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); break;
 | 
			
		||||
		default:  t = 'String'; p = escapexml(cell.v||"");
 | 
			
		||||
	}
 | 
			
		||||
	var m = '<Data ss:Type="' + t + '">' + p + '</Data>';
 | 
			
		||||
 | 
			
		||||
	return writextag("Cell", m, attr);
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
 | 
			
		||||
	if(!ws['!ref']) return "";
 | 
			
		||||
	var range = safe_decode_range(ws['!ref']);
 | 
			
		||||
	var o = [];
 | 
			
		||||
	for(var R = range.s.r; R <= range.e.r; ++R) {
 | 
			
		||||
		var row = ["<Row>"];
 | 
			
		||||
		for(var C = range.s.c; C <= range.e.c; ++C) {
 | 
			
		||||
			var addr = {r:R,c:C};
 | 
			
		||||
			var ref = encode_cell(addr), cell = ws[ref];
 | 
			
		||||
			row.push(write_ws_xlml_cell(ws[ref], ref, ws, opts, idx, wb, addr));
 | 
			
		||||
		}
 | 
			
		||||
		row.push("</Row>");
 | 
			
		||||
		o.push(row.join(""));
 | 
			
		||||
	}
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
 | 
			
		||||
	var o = [];
 | 
			
		||||
	var s = wb.SheetNames[idx];
 | 
			
		||||
	var ws = wb.Sheets[s];
 | 
			
		||||
 | 
			
		||||
	/* Table */
 | 
			
		||||
	var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
 | 
			
		||||
	if(t.length > 0) o.push("<Table>" + t + "</Table>");
 | 
			
		||||
	/* WorksheetOptions */
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
function write_xlml(wb, opts)/*:string*/ {
 | 
			
		||||
	var d = [];
 | 
			
		||||
	d.push(write_props_xlml(wb, opts));
 | 
			
		||||
	d.push(write_wb_xlml(wb, opts));
 | 
			
		||||
	d.push(write_sty_xlml(wb, opts));
 | 
			
		||||
	for(var i = 0; i < wb.SheetNames.length; ++i)
 | 
			
		||||
		d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
 | 
			
		||||
	return XML_HEADER + writextag("Workbook", d.join(""), {
 | 
			
		||||
		'xmlns':      XLMLNS.ss,
 | 
			
		||||
		'xmlns:o':    XLMLNS.o,
 | 
			
		||||
		'xmlns:x':    XLMLNS.x,
 | 
			
		||||
		'xmlns:ss':   XLMLNS.ss,
 | 
			
		||||
		'xmlns:dt':   XLMLNS.dt,
 | 
			
		||||
		'xmlns:html': XLMLNS.html
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
/* [MS-OLEDS] 2.3.8 CompObjStream */
 | 
			
		||||
function parse_compobj(obj) {
 | 
			
		||||
	var v = {};
 | 
			
		||||
@ -10644,9 +10830,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
								if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
 | 
			
		||||
									var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
 | 
			
		||||
									var _fe = encode_cell({r:_fr, c:_fc});
 | 
			
		||||
									if(shared_formulae[_fe]) temp_val.f = stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
									if(shared_formulae[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
									else temp_val.F = (out[_fe] || {}).F;
 | 
			
		||||
								} else temp_val.f = stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
								} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
							}
 | 
			
		||||
							safe_format_xf(temp_val, options, wb.opts.Date1904);
 | 
			
		||||
							addcell(val.cell, temp_val, options);
 | 
			
		||||
@ -10658,7 +10844,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
						last_formula.val = val;
 | 
			
		||||
						temp_val = ({v:last_formula.val, ixfe:last_formula.cell.ixfe, t:'s'}/*:any*/);
 | 
			
		||||
						temp_val.XF = XFs[temp_val.ixfe];
 | 
			
		||||
						if(options.cellFormula) temp_val.f = stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						if(options.cellFormula) temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						safe_format_xf(temp_val, options, wb.opts.Date1904);
 | 
			
		||||
						addcell(last_formula.cell, temp_val, options);
 | 
			
		||||
						last_formula = null;
 | 
			
		||||
@ -10669,7 +10855,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
					if(options.cellFormula && out[last_cell]) {
 | 
			
		||||
						if(!last_formula) break; /* technically unreachable */
 | 
			
		||||
						if(!last_cell || !out[last_cell]) break; /* technically unreachable */
 | 
			
		||||
						out[last_cell].f = stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						out[last_cell].f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						out[last_cell].F = encode_range(val[0]);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
@ -10680,7 +10866,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
 | 
			
		||||
						/* TODO: capture range */
 | 
			
		||||
						if(!last_formula) break; /* technically unreachable */
 | 
			
		||||
						shared_formulae[encode_cell(last_formula.cell)]= val[0];
 | 
			
		||||
						(out[encode_cell(last_formula.cell)]||{}).f = stringify_formula(val[0], range, lastcell, supbooks, opts);
 | 
			
		||||
						(out[encode_cell(last_formula.cell)]||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
				case 'LabelSst':
 | 
			
		||||
@ -13286,7 +13472,8 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
 | 
			
		||||
	check_wb(wb);
 | 
			
		||||
	var o = opts||{};
 | 
			
		||||
	switch(o.bookType || 'xlsx') {
 | 
			
		||||
		case 'xml': return write_string_type(write_xlml(wb, o), o);
 | 
			
		||||
		case 'xml':
 | 
			
		||||
		case 'xlml': return write_string_type(write_xlml(wb, o), o);
 | 
			
		||||
		case 'csv': return write_string_type(write_csv_str(wb, o), o);
 | 
			
		||||
		case 'fods': return write_string_type(write_ods(wb, o), o);
 | 
			
		||||
		case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
 | 
			
		||||
@ -13306,6 +13493,7 @@ function writeFileSync(wb/*:Workbook*/, filename/*:string*/, opts/*:?WriteFileOp
 | 
			
		||||
		case '.xlsm': o.bookType = 'xlsm'; break;
 | 
			
		||||
		case '.xlsb': o.bookType = 'xlsb'; break;
 | 
			
		||||
		case '.fods': o.bookType = 'fods'; break;
 | 
			
		||||
		case '.xlml': o.bookType = 'xlml'; break;
 | 
			
		||||
	default: switch(o.file.slice(-4).toLowerCase()) {
 | 
			
		||||
		case '.xls': o.bookType = 'biff2'; break;
 | 
			
		||||
		case '.xml': o.bookType = 'xml'; break;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										206
									
								
								xlsx.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										206
									
								
								xlsx.js
									
									
									
									
									
								
							@ -1465,6 +1465,7 @@ function escapexml(text){
 | 
			
		||||
	var s = text + '';
 | 
			
		||||
	return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
 | 
			
		||||
}
 | 
			
		||||
function escapexmltag(text){ return escapexml(text).replace(/ /g,"_x0020_"); }
 | 
			
		||||
 | 
			
		||||
/* TODO: handle codepages */
 | 
			
		||||
var xlml_fixstr = (function() {
 | 
			
		||||
@ -1591,6 +1592,13 @@ XMLNS.main = [
 | 
			
		||||
	'http://schemas.microsoft.com/office/excel/2006/2'
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
var XLMLNS = ({
 | 
			
		||||
	'o':    'urn:schemas-microsoft-com:office:office',
 | 
			
		||||
	'x':    'urn:schemas-microsoft-com:office:excel',
 | 
			
		||||
	'ss':   'urn:schemas-microsoft-com:office:spreadsheet',
 | 
			
		||||
	'dt':   'uuid:C2F41010-65B3-11d1-A29F-00AA00C14882',
 | 
			
		||||
	'html': 'http://www.w3.org/TR/REC-html40'
 | 
			
		||||
});
 | 
			
		||||
function read_double_le(b, idx) {
 | 
			
		||||
	var s = 1 - 2 * (b[idx + 7] >>> 7);
 | 
			
		||||
	var e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);
 | 
			
		||||
@ -2968,10 +2976,67 @@ function xlml_set_prop(Props, tag, val) {
 | 
			
		||||
	/* TODO: Normalize the properties */
 | 
			
		||||
	switch(tag) {
 | 
			
		||||
		case 'Description': tag = 'Comments'; break;
 | 
			
		||||
		case 'Created': tag = 'CreatedDate'; break;
 | 
			
		||||
		case 'LastSaved': tag = 'ModifiedDate'; break;
 | 
			
		||||
	}
 | 
			
		||||
	Props[tag] = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var XLMLDocumentProperties = [
 | 
			
		||||
	['Title', 'Title'],
 | 
			
		||||
	['Subject', 'Subject'],
 | 
			
		||||
	['Author', 'Author'],
 | 
			
		||||
	['Keywords', 'Keywords'],
 | 
			
		||||
	['Comments', 'Description'],
 | 
			
		||||
	['LastAuthor', 'LastAuthor'],
 | 
			
		||||
	['CreatedDate', 'Created', 'date'],
 | 
			
		||||
	['ModifiedDate', 'LastSaved', 'date'],
 | 
			
		||||
	['Category', 'Category'],
 | 
			
		||||
	['Manager', 'Manager'],
 | 
			
		||||
	['Company', 'Company'],
 | 
			
		||||
	['AppVersion', 'Version']
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/* TODO: verify */
 | 
			
		||||
function xlml_write_docprops(Props) {
 | 
			
		||||
	var T = 'DocumentProperties';
 | 
			
		||||
	var o = [];
 | 
			
		||||
	XLMLDocumentProperties.forEach(function(p) {
 | 
			
		||||
		if(!Props[p[0]]) return;
 | 
			
		||||
		var m = Props[p[0]];
 | 
			
		||||
		switch(p[2]) {
 | 
			
		||||
			case 'date': m = new Date(m).toISOString(); break;
 | 
			
		||||
		}
 | 
			
		||||
		o.push(writetag(p[1], m));
 | 
			
		||||
	});
 | 
			
		||||
	return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
 | 
			
		||||
}
 | 
			
		||||
function xlml_write_custprops(Props, Custprops) {
 | 
			
		||||
	var T = 'CustomDocumentProperties';
 | 
			
		||||
	var o = [];
 | 
			
		||||
	if(Props) keys(Props).forEach(function(k) {
 | 
			
		||||
if(!Props.hasOwnProperty(k)) return;
 | 
			
		||||
		for(var i = 0; i < XLMLDocumentProperties.length; ++i)
 | 
			
		||||
			if(k == XLMLDocumentProperties[i][0]) return;
 | 
			
		||||
		var m = Props[k];
 | 
			
		||||
		var t = "string";
 | 
			
		||||
		if(typeof m == 'number') { t = "float"; m = String(m); }
 | 
			
		||||
		else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
 | 
			
		||||
		else m = String(m);
 | 
			
		||||
		o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
 | 
			
		||||
	});
 | 
			
		||||
	if(Custprops) keys(Custprops).forEach(function(k) {
 | 
			
		||||
if(!Custprops.hasOwnProperty(k)) return;
 | 
			
		||||
		var m = Custprops[k];
 | 
			
		||||
		var t = "string";
 | 
			
		||||
		if(typeof m == 'number') { t = "float"; m = String(m); }
 | 
			
		||||
		else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
 | 
			
		||||
		else if(m instanceof Date) { t = "dateTime.tz"; m = m.toISOString(); }
 | 
			
		||||
		else m = String(m);
 | 
			
		||||
		o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
 | 
			
		||||
	});
 | 
			
		||||
	return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
 | 
			
		||||
}
 | 
			
		||||
/* [MS-DTYP] 2.3.3 FILETIME */
 | 
			
		||||
/* [MS-OLEDS] 2.1.3 FILETIME (Packet Version) */
 | 
			
		||||
/* [MS-OLEPS] 2.8 FILETIME (Packet Version) */
 | 
			
		||||
@ -3736,14 +3801,44 @@ function parse_MulRk(blob, length) {
 | 
			
		||||
	return {r:rw, c:col, C:lastcol, rkrec:rkrecs};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 2.5.20 2.5.249 TODO */
 | 
			
		||||
/* 2.5.20 2.5.249 TODO: interpret values here */
 | 
			
		||||
function parse_CellStyleXF(blob, length, style) {
 | 
			
		||||
	var o = {};
 | 
			
		||||
	var a = blob.read_shift(4), b = blob.read_shift(4);
 | 
			
		||||
	var c = blob.read_shift(4), d = blob.read_shift(2);
 | 
			
		||||
	o.patternType = XLSFillPattern[c >> 26];
 | 
			
		||||
 | 
			
		||||
	o.alc = a & 0x07;
 | 
			
		||||
	o.fWrap = (a >> 3) & 0x01;
 | 
			
		||||
	o.alcV = (a >> 4) & 0x07;
 | 
			
		||||
	o.fJustLast = (a >> 7) & 0x01;
 | 
			
		||||
	o.trot = (a >> 8) & 0xFF;
 | 
			
		||||
	o.cIndent = (a >> 16) & 0x0F;
 | 
			
		||||
	o.fShrinkToFit = (a >> 20) & 0x01;
 | 
			
		||||
	o.iReadOrder = (a >> 22) & 0x02;
 | 
			
		||||
	o.fAtrNum = (a >> 26) & 0x01;
 | 
			
		||||
	o.fAtrFnt = (a >> 27) & 0x01;
 | 
			
		||||
	o.fAtrAlc = (a >> 28) & 0x01;
 | 
			
		||||
	o.fAtrBdr = (a >> 29) & 0x01;
 | 
			
		||||
	o.fAtrPat = (a >> 30) & 0x01;
 | 
			
		||||
	o.fAtrProt = (a >> 31) & 0x01;
 | 
			
		||||
 | 
			
		||||
	o.dgLeft = b & 0x0F;
 | 
			
		||||
	o.dgRight = (b >> 4) & 0x0F;
 | 
			
		||||
	o.dgTop = (b >> 8) & 0x0F;
 | 
			
		||||
	o.dgBottom = (b >> 12) & 0x0F;
 | 
			
		||||
	o.icvLeft = (b >> 16) & 0x7F;
 | 
			
		||||
	o.icvRight = (b >> 23) & 0x7F;
 | 
			
		||||
	o.grbitDiag = (b >> 30) & 0x03;
 | 
			
		||||
 | 
			
		||||
	o.icvTop = c & 0x7F;
 | 
			
		||||
	o.icvBottom = (c >> 7) & 0x7F;
 | 
			
		||||
	o.icvDiag = (c >> 14) & 0x7F;
 | 
			
		||||
	o.dgDiag = (c >> 21) & 0x0F;
 | 
			
		||||
 | 
			
		||||
	o.icvFore = d & 0x7F;
 | 
			
		||||
	o.icvBack = (d >> 7) & 0x7F;
 | 
			
		||||
	o.fsxButton = (d >> 14) & 0x01;
 | 
			
		||||
	return o;
 | 
			
		||||
}
 | 
			
		||||
function parse_CellXF(blob, length) {return parse_CellStyleXF(blob,length,0);}
 | 
			
		||||
@ -5766,8 +5861,19 @@ var rc_to_a1 = (function(){
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
 | 
			
		||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
 | 
			
		||||
var a1_to_rc =(function(){
 | 
			
		||||
	return function a1_to_rc(fstr, base) {
 | 
			
		||||
		return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
 | 
			
		||||
			/* TODO: handle fixcol / fixrow */
 | 
			
		||||
			var c = decode_col($3) - base.c;
 | 
			
		||||
			var r = decode_row($5) - base.r;
 | 
			
		||||
			return $1 + "R" + (r == 0 ? "" : "[" + r + "]") + "C" + (c == 0 ? "" : "[" + c + "]");
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
 | 
			
		||||
function shift_formula_str(f, delta) {
 | 
			
		||||
	return f.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
 | 
			
		||||
		return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
 | 
			
		||||
@ -10275,10 +10381,88 @@ function parse_xlml(data, opts) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_xlml(wb, opts) {
 | 
			
		||||
	var o = [XML_HEADER];
 | 
			
		||||
function write_props_xlml(wb, opts) {
 | 
			
		||||
	var o = [];
 | 
			
		||||
	/* DocumentProperties */
 | 
			
		||||
	if(wb.Props) o.push(xlml_write_docprops(wb.Props));
 | 
			
		||||
	/* CustomDocumentProperties */
 | 
			
		||||
	if(wb.Custprops) o.push(xlml_write_custprops(wb.Props, wb.Custprops));
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_wb_xlml(wb, opts) {
 | 
			
		||||
	/* OfficeDocumentSettings */
 | 
			
		||||
	/* ExcelWorkbook */
 | 
			
		||||
	return "";
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_sty_xlml(wb, opts) {
 | 
			
		||||
	/* Styles */
 | 
			
		||||
	return "";
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
 | 
			
		||||
	if(!cell || cell.v === undefined) return "<Cell></Cell>";
 | 
			
		||||
 | 
			
		||||
	var attr = {};
 | 
			
		||||
	if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
 | 
			
		||||
 | 
			
		||||
	var t = "", p = "";
 | 
			
		||||
	switch(cell.t) {
 | 
			
		||||
		case 'n': t = 'Number'; p = String(cell.v); break;
 | 
			
		||||
		case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
 | 
			
		||||
		case 'e': t = 'Error'; p = BErr[cell.v]; break;
 | 
			
		||||
		case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); break;
 | 
			
		||||
		default:  t = 'String'; p = escapexml(cell.v||"");
 | 
			
		||||
	}
 | 
			
		||||
	var m = '<Data ss:Type="' + t + '">' + p + '</Data>';
 | 
			
		||||
 | 
			
		||||
	return writextag("Cell", m, attr);
 | 
			
		||||
}
 | 
			
		||||
/* TODO */
 | 
			
		||||
function write_ws_xlml_table(ws, opts, idx, wb) {
 | 
			
		||||
	if(!ws['!ref']) return "";
 | 
			
		||||
	var range = safe_decode_range(ws['!ref']);
 | 
			
		||||
	var o = [];
 | 
			
		||||
	for(var R = range.s.r; R <= range.e.r; ++R) {
 | 
			
		||||
		var row = ["<Row>"];
 | 
			
		||||
		for(var C = range.s.c; C <= range.e.c; ++C) {
 | 
			
		||||
			var addr = {r:R,c:C};
 | 
			
		||||
			var ref = encode_cell(addr), cell = ws[ref];
 | 
			
		||||
			row.push(write_ws_xlml_cell(ws[ref], ref, ws, opts, idx, wb, addr));
 | 
			
		||||
		}
 | 
			
		||||
		row.push("</Row>");
 | 
			
		||||
		o.push(row.join(""));
 | 
			
		||||
	}
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
function write_ws_xlml(idx, opts, wb) {
 | 
			
		||||
	var o = [];
 | 
			
		||||
	var s = wb.SheetNames[idx];
 | 
			
		||||
	var ws = wb.Sheets[s];
 | 
			
		||||
 | 
			
		||||
	/* Table */
 | 
			
		||||
	var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
 | 
			
		||||
	if(t.length > 0) o.push("<Table>" + t + "</Table>");
 | 
			
		||||
	/* WorksheetOptions */
 | 
			
		||||
	return o.join("");
 | 
			
		||||
}
 | 
			
		||||
function write_xlml(wb, opts) {
 | 
			
		||||
	var d = [];
 | 
			
		||||
	d.push(write_props_xlml(wb, opts));
 | 
			
		||||
	d.push(write_wb_xlml(wb, opts));
 | 
			
		||||
	d.push(write_sty_xlml(wb, opts));
 | 
			
		||||
	for(var i = 0; i < wb.SheetNames.length; ++i)
 | 
			
		||||
		d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
 | 
			
		||||
	return XML_HEADER + writextag("Workbook", d.join(""), {
 | 
			
		||||
		'xmlns':      XLMLNS.ss,
 | 
			
		||||
		'xmlns:o':    XLMLNS.o,
 | 
			
		||||
		'xmlns:x':    XLMLNS.x,
 | 
			
		||||
		'xmlns:ss':   XLMLNS.ss,
 | 
			
		||||
		'xmlns:dt':   XLMLNS.dt,
 | 
			
		||||
		'xmlns:html': XLMLNS.html
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
/* [MS-OLEDS] 2.3.8 CompObjStream */
 | 
			
		||||
function parse_compobj(obj) {
 | 
			
		||||
	var v = {};
 | 
			
		||||
@ -10590,9 +10774,9 @@ function parse_workbook(blob, options) {
 | 
			
		||||
								if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
 | 
			
		||||
									var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
 | 
			
		||||
									var _fe = encode_cell({r:_fr, c:_fc});
 | 
			
		||||
									if(shared_formulae[_fe]) temp_val.f = stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
									if(shared_formulae[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
									else temp_val.F = (out[_fe] || {}).F;
 | 
			
		||||
								} else temp_val.f = stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
								} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
 | 
			
		||||
							}
 | 
			
		||||
							safe_format_xf(temp_val, options, wb.opts.Date1904);
 | 
			
		||||
							addcell(val.cell, temp_val, options);
 | 
			
		||||
@ -10604,7 +10788,7 @@ function parse_workbook(blob, options) {
 | 
			
		||||
						last_formula.val = val;
 | 
			
		||||
						temp_val = ({v:last_formula.val, ixfe:last_formula.cell.ixfe, t:'s'});
 | 
			
		||||
						temp_val.XF = XFs[temp_val.ixfe];
 | 
			
		||||
						if(options.cellFormula) temp_val.f = stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						if(options.cellFormula) temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						safe_format_xf(temp_val, options, wb.opts.Date1904);
 | 
			
		||||
						addcell(last_formula.cell, temp_val, options);
 | 
			
		||||
						last_formula = null;
 | 
			
		||||
@ -10615,7 +10799,7 @@ function parse_workbook(blob, options) {
 | 
			
		||||
					if(options.cellFormula && out[last_cell]) {
 | 
			
		||||
						if(!last_formula) break; /* technically unreachable */
 | 
			
		||||
						if(!last_cell || !out[last_cell]) break; /* technically unreachable */
 | 
			
		||||
						out[last_cell].f = stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						out[last_cell].f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
 | 
			
		||||
						out[last_cell].F = encode_range(val[0]);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
@ -10626,7 +10810,7 @@ function parse_workbook(blob, options) {
 | 
			
		||||
						/* TODO: capture range */
 | 
			
		||||
						if(!last_formula) break; /* technically unreachable */
 | 
			
		||||
						shared_formulae[encode_cell(last_formula.cell)]= val[0];
 | 
			
		||||
						(out[encode_cell(last_formula.cell)]||{}).f = stringify_formula(val[0], range, lastcell, supbooks, opts);
 | 
			
		||||
						(out[encode_cell(last_formula.cell)]||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
 | 
			
		||||
					}
 | 
			
		||||
				} break;
 | 
			
		||||
				case 'LabelSst':
 | 
			
		||||
@ -13228,7 +13412,8 @@ function writeSync(wb, opts) {
 | 
			
		||||
	check_wb(wb);
 | 
			
		||||
	var o = opts||{};
 | 
			
		||||
	switch(o.bookType || 'xlsx') {
 | 
			
		||||
		case 'xml': return write_string_type(write_xlml(wb, o), o);
 | 
			
		||||
		case 'xml':
 | 
			
		||||
		case 'xlml': return write_string_type(write_xlml(wb, o), o);
 | 
			
		||||
		case 'csv': return write_string_type(write_csv_str(wb, o), o);
 | 
			
		||||
		case 'fods': return write_string_type(write_ods(wb, o), o);
 | 
			
		||||
		case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
 | 
			
		||||
@ -13248,6 +13433,7 @@ function writeFileSync(wb, filename, opts) {
 | 
			
		||||
		case '.xlsm': o.bookType = 'xlsm'; break;
 | 
			
		||||
		case '.xlsb': o.bookType = 'xlsb'; break;
 | 
			
		||||
		case '.fods': o.bookType = 'fods'; break;
 | 
			
		||||
		case '.xlml': o.bookType = 'xlml'; break;
 | 
			
		||||
	default: switch(o.file.slice(-4).toLowerCase()) {
 | 
			
		||||
		case '.xls': o.bookType = 'biff2'; break;
 | 
			
		||||
		case '.xml': o.bookType = 'xml'; break;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user