forked from sheetjs/sheetjs
		
	- read and write support for Flat ODS files - read support for Uniform Office Spreadsheet (UOS) - IE6-8 cell regex split fix (fixes #350 #140 #268 h/t @Aymkdn @C0d3ine) - replace substr negative index with slices (fixes #351 h/t @Aymkdn) - ODS parsexmltag ignores ext overrides (fixes #548 h/t @lgodard) - csv can be written using write/writeFile with csv type - added `type` to README (fixes #432 h/t @tomkel)
		
			
				
	
	
		
			104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* BIFF2-4 single-sheet workbooks */
 | |
| function write_biff_rec(ba/*:BufArray*/, t/*:number*/, payload, length/*:?number*/) {
 | |
| 	var len = (length || (payload||[]).length);
 | |
| 	var o = ba.next(4 + len);
 | |
| 	o.write_shift(2, t);
 | |
| 	o.write_shift(2, len);
 | |
| 	if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload);
 | |
| }
 | |
| 
 | |
| function write_BOF(wb/*:Workbook*/, o) {
 | |
| 	if(o.bookType != 'biff2') throw "unsupported BIFF version";
 | |
| 	var out = new_buf(4);
 | |
| 	out.write_shift(2, 0x0002); // "unused"
 | |
| 	out.write_shift(2, 0x0010); // Sheet
 | |
| 	return out;
 | |
| }
 | |
| 
 | |
| function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) {
 | |
| 	if(!out) out = new_buf(7);
 | |
| 	out.write_shift(2, r);
 | |
| 	out.write_shift(2, c);
 | |
| 	out.write_shift(1, 0);
 | |
| 	out.write_shift(1, 0);
 | |
| 	out.write_shift(1, 0);
 | |
| 	return out;
 | |
| }
 | |
| 
 | |
| function write_BIFF2INT(r/*:number*/, c/*:number*/, val) {
 | |
| 	var out = new_buf(9);
 | |
| 	write_BIFF2Cell(out, r, c);
 | |
| 	out.write_shift(2, val);
 | |
| 	return out;
 | |
| }
 | |
| 
 | |
| function write_BIFF2NUMBER(r, c, val) {
 | |
| 	var out = new_buf(15);
 | |
| 	write_BIFF2Cell(out, r, c);
 | |
| 	out.write_shift(8, val, 'f');
 | |
| 	return out;
 | |
| }
 | |
| 
 | |
| function write_BIFF2BERR(r, c, val, t) {
 | |
| 	var out = new_buf(9);
 | |
| 	write_BIFF2Cell(out, r, c);
 | |
| 	if(t == 'e') { out.write_shift(1, val); out.write_shift(1, 1); }
 | |
| 	else { out.write_shift(1, val?1:0); out.write_shift(1, 0); }
 | |
| 	return out;
 | |
| }
 | |
| 
 | |
| /* TODO: codepage, large strings */
 | |
| function write_BIFF2LABEL(r, c, val) {
 | |
| 	var out = new_buf(8 + 2*val.length);
 | |
| 	write_BIFF2Cell(out, r, c);
 | |
| 	out.write_shift(1, val.length);
 | |
| 	out.write_shift(val.length, val, 'sbcs');
 | |
| 	return out.l < out.length ? out.slice(0, out.l) : out;
 | |
| }
 | |
| 
 | |
| function write_ws_biff_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
 | |
| 	switch(cell.t) {
 | |
| 		case 'n':
 | |
| 			if((cell.v == (cell.v|0)) && (cell.v >= 0) && (cell.v < 65536))
 | |
| 				write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, cell.v));
 | |
| 			else
 | |
| 				write_biff_rec(ba, 0x0003, write_BIFF2NUMBER(R,C, cell.v));
 | |
| 			break;
 | |
| 		case 'b': case 'e': write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t)); break;
 | |
| 		/* TODO: codepage, sst */
 | |
| 		case 's': case 'str':
 | |
| 			write_biff_rec(ba, 0x0004, write_BIFF2LABEL(R, C, cell.v));
 | |
| 			break;
 | |
| 		default: write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| function write_biff_ws(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
 | |
| 	var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
 | |
| 	for(var R = range.s.r; R <= range.e.r; ++R) {
 | |
| 		rr = encode_row(R);
 | |
| 		for(var C = range.s.c; C <= range.e.c; ++C) {
 | |
| 			if(R === range.s.r) cols[C] = encode_col(C);
 | |
| 			ref = cols[C] + rr;
 | |
| 			if(!ws[ref]) continue;
 | |
| 			/* write cell */
 | |
| 			write_ws_biff_cell(ba, ws[ref], R, C, opts);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /* Based on test files */
 | |
| function write_biff_buf(wb/*:Workbook*/, o/*:WriteOpts*/) {
 | |
| 	var ba = buf_array();
 | |
| 	var idx = 0;
 | |
| 	for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
 | |
| 	if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
 | |
| 	write_biff_rec(ba, 0x0009, write_BOF(wb, o));
 | |
| 	/* ... */
 | |
| 	write_biff_ws(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
 | |
| 	/* ... */
 | |
| 	write_biff_rec(ba, 0x000a);
 | |
| 	// TODO
 | |
| 	return ba.end();
 | |
| }
 |