forked from sheetjs/sheetjs
		
	DBF preserve field properties
- DBF write type N and roundtrip C length (fixes #1888 h/t@bandizsolt) - clean up xhr demo (fixes #2604 h/t @UP2022742) - clean up vue / nuxt demo
This commit is contained in:
		
							parent
							
								
									b3793e2ea7
								
							
						
					
					
						commit
						0b6ebc67da
					
				
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							| @ -70,7 +70,8 @@ init: ## Initial setup for development | ||||
| 	git submodule init | ||||
| 	git submodule update | ||||
| 	#git submodule foreach git pull origin master | ||||
| 	git submodule foreach make | ||||
| 	#git submodule foreach make | ||||
| 	git submodule foreach make all | ||||
| 	mkdir -p tmp | ||||
| 
 | ||||
| DISTHDR=misc/suppress_export.js | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /* vim: set ts=2: */ | ||||
| /*exported XLSX */ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, Deno:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
|  | ||||
| @ -204,7 +204,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ { | ||||
| 					out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400); | ||||
| 					break; | ||||
| 				case 'T': out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4)); break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4; break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4 + (dd.read_shift(4, 'i')/1e4)*Math.pow(2,32); break; | ||||
| 				case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break; | ||||
| 				case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; } | ||||
| 					/* falls through */ | ||||
| @ -218,13 +218,20 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ { | ||||
| 	} | ||||
| 	if(ft != 0x02) if(d.l < d.length && d[d.l++] != 0x1A) throw new Error("DBF EOF Marker missing " + (d.l-1) + " of " + d.length + " " + d[d.l-1].toString(16)); | ||||
| 	if(opts && opts.sheetRows) out = out.slice(0, opts.sheetRows); | ||||
| 	opts.DBF = fields; | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_sheet(buf, opts)/*:Worksheet*/ { | ||||
| 	var o = opts || {}; | ||||
| 	if(!o.dateNF) o.dateNF = "yyyymmdd"; | ||||
| 	return aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	var ws = aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	ws["!cols"] = o.DBF.map(function(field) { return { | ||||
| 		wch: field.len, | ||||
| 		DBF: field | ||||
| 	}}); | ||||
| 	delete o.DBF; | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_workbook(buf, opts)/*:Workbook*/ { | ||||
| @ -240,10 +247,11 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 	if(o.type == "string") throw new Error("Cannot write DBF to JS string"); | ||||
| 	var ba = buf_array(); | ||||
| 	var aoa/*:AOA*/ = sheet_to_json(ws, {header:1, raw:true, cellDates:true}); | ||||
| 	var headers = aoa[0], data = aoa.slice(1); | ||||
| 	var headers = aoa[0], data = aoa.slice(1), cols = ws["!cols"] || []; | ||||
| 	var i = 0, j = 0, hcnt = 0, rlen = 1; | ||||
| 	for(i = 0; i < headers.length; ++i) { | ||||
| 		if(i == null) continue; | ||||
| 		if(((cols[i]||{}).DBF||{}).name) { headers[i] = cols[i].DBF.name; ++hcnt; continue; } | ||||
| 		if(headers[i] == null) continue; | ||||
| 		++hcnt; | ||||
| 		if(typeof headers[i] === 'number') headers[i] = headers[i].toString(10); | ||||
| 		if(typeof headers[i] !== 'string') throw new Error("DBF Invalid column name " + headers[i] + " |" + (typeof headers[i]) + "|"); | ||||
| @ -252,13 +260,15 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 	} | ||||
| 	var range = safe_decode_range(ws['!ref']); | ||||
| 	var coltypes/*:Array<string>*/ = []; | ||||
| 	var colwidths/*:Array<number>*/ = []; | ||||
| 	var coldecimals/*:Array<number>*/ = []; | ||||
| 	for(i = 0; i <= range.e.c - range.s.c; ++i) { | ||||
| 		var guess = '', _guess = '', maxlen = 0; | ||||
| 		var col/*:Array<any>*/ = []; | ||||
| 		for(j=0; j < data.length; ++j) { | ||||
| 			if(data[j][i] != null) col.push(data[j][i]); | ||||
| 		} | ||||
| 		if(col.length == 0 || headers[i] == null) { coltypes[i] = '?'; continue; } | ||||
| 		var guess = '', _guess = ''; | ||||
| 		for(j = 0; j < col.length; ++j) { | ||||
| 			switch(typeof col[j]) { | ||||
| 				/* TODO: check if L2 compat is desired */ | ||||
| @ -268,10 +278,23 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 				case 'object': _guess = col[j] instanceof Date ? 'D' : 'C'; break; | ||||
| 				default: _guess = 'C'; | ||||
| 			} | ||||
| 			maxlen = Math.max(maxlen, String(col[j]).length); | ||||
| 			guess = guess && guess != _guess ? 'C' : _guess; | ||||
| 			if(guess == 'C') break; | ||||
| 			//if(guess == 'C') break;
 | ||||
| 		} | ||||
| 		rlen += _RLEN[guess] || 0; | ||||
| 		if(maxlen > 250) maxlen = 250; | ||||
| 		_guess = ((cols[i]||{}).DBF||{}).type; | ||||
| 		/* TODO: more fine grained control over DBF type resolution */ | ||||
| 		if(_guess == 'C') { | ||||
| 			if(cols[i].DBF.len > maxlen) maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		if(guess == 'B' && _guess == 'N') { | ||||
| 			guess = 'N'; | ||||
| 			coldecimals[i] = cols[i].DBF.dec; | ||||
| 			maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		colwidths[i] = guess == 'C' || _guess == 'N' ? maxlen : (_RLEN[guess] || 0); | ||||
| 		rlen += colwidths[i]; | ||||
| 		coltypes[i] = guess; | ||||
| 	} | ||||
| 
 | ||||
| @ -290,14 +313,14 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 		hf.write_shift(1, _f, "sbcs"); | ||||
| 		hf.write_shift(1, coltypes[i] == '?' ? 'C' : coltypes[i], "sbcs"); | ||||
| 		hf.write_shift(4, j); | ||||
| 		hf.write_shift(1, _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(1, colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, coldecimals[i] || 0); | ||||
| 		hf.write_shift(1, 0x02); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		j += _RLEN[coltypes[i]] || 0; | ||||
| 		j += (colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 	} | ||||
| 
 | ||||
| 	var hb = ba.next(264); | ||||
| @ -311,6 +334,12 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 			switch(coltypes[j]) { | ||||
| 				case 'L': rout.write_shift(1, data[i][j] == null ? 0x3F : data[i][j] ? 0x54 : 0x46); break; | ||||
| 				case 'B': rout.write_shift(8, data[i][j]||0, 'f'); break; | ||||
| 				case 'N': | ||||
| 					var _n = "0"; | ||||
| 					if(typeof data[i][j] == "number") _n = data[i][j].toFixed(coldecimals[j]||0); | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_n.length; ++hcnt) rout.write_shift(1, 0x20); | ||||
| 					rout.write_shift(1, _n, "sbcs"); | ||||
| 					break; | ||||
| 				case 'D': | ||||
| 					if(!data[i][j]) rout.write_shift(8, "00000000", "sbcs"); | ||||
| 					else { | ||||
| @ -319,9 +348,9 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 						rout.write_shift(2, ("00"+data[i][j].getDate()).slice(-2), "sbcs"); | ||||
| 					} break; | ||||
| 				case 'C': | ||||
| 					var _s = String(data[i][j]||""); | ||||
| 					var _s = String(data[i][j] != null ? data[i][j] : "").slice(0, colwidths[j]); | ||||
| 					rout.write_shift(1, _s, "sbcs"); | ||||
| 					for(hcnt=0; hcnt < 250-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 			} | ||||
| 		} | ||||
| 		// data
 | ||||
|  | ||||
| @ -442,13 +442,14 @@ var NUMBERS = !Object.defineProperty ? (void 0) :(function() { | ||||
|     return { Sheets: {}, SheetNames: [] }; | ||||
|   }; | ||||
|   var book_append_sheet = function(wb, ws, name) { | ||||
|     var i = 1; | ||||
|     if (!name) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf(name = "Sheet ".concat(i)) == -1) | ||||
|           break; | ||||
|       } | ||||
|     else if (wb.SheetNames.indexOf(name) > -1) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf("".concat(name, "_").concat(i)) == -1) { | ||||
|           name = "".concat(name, "_").concat(i); | ||||
|           break; | ||||
|  | ||||
| @ -64,7 +64,8 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) { | ||||
| 	var out/*:Array<any>*/ = []; | ||||
| 	var outi = 0, counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -76,8 +77,12 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) { vv = v + "_" + (++counter); CC = -1; } | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -79,7 +79,8 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 	var cols/*:Array<string>*/ = []; | ||||
| 	var counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -91,8 +92,12 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) vv = v + "_" + (++counter); | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
| @ -110,7 +115,7 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 		return stream.push(null); | ||||
| 	}; | ||||
| 	return stream; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| var __stream = { | ||||
| 	to_json: write_json_stream, | ||||
|  | ||||
| @ -4,9 +4,7 @@ vue: ## Simple server for vue | ||||
| 
 | ||||
| .PHONY: nuxt | ||||
| nuxt: ## nuxt.js demo
 | ||||
| 	mkdir -p node_modules | ||||
| 	cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx; fi; cd .. | ||||
| 	npm i nuxt vue | ||||
| 	npm i xlsx @nuxt/content | ||||
| 	npx nuxt | ||||
| 
 | ||||
| .PHONY: weex | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| # VueJS 2 | ||||
| # VueJS | ||||
| 
 | ||||
| The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped | ||||
| into web pages with script tags: | ||||
| @ -10,7 +10,11 @@ into web pages with script tags: | ||||
| The library can also be imported directly from single-file components with: | ||||
| 
 | ||||
| ```js | ||||
| import XLSX from 'xlsx'; | ||||
| // full import | ||||
| import * as XLSX from 'xlsx'; | ||||
| 
 | ||||
| // named imports | ||||
| import { read, utils, writeFileXLSX } from 'xlsx'; | ||||
| ``` | ||||
| 
 | ||||
| This demo directly generates HTML using `sheet_to_html` and adds an element to | ||||
| @ -93,19 +97,30 @@ fs.writeFileSync("sheetjs.xls", new Buffer(str, "base64")); | ||||
| 
 | ||||
| ## Other Demos | ||||
| 
 | ||||
| #### Server-Rendered VueJS Components with Nuxt.js | ||||
| ### Nuxt Content | ||||
| 
 | ||||
| The scripts should be treated as external resources in `nuxt.config.js`: | ||||
| `@nuxt/content` parser can be extended to support spreadsheet hot reload: | ||||
| 
 | ||||
| ```js | ||||
| module.exports = { | ||||
| 	head: { | ||||
| 		script: [ | ||||
| 			{ src: "https://unpkg.com/xlsx/dist/shim.min.js" }, | ||||
| 			{ src: "https://unpkg.com/xlsx/dist/xlsx.full.min.js" } | ||||
| 		] | ||||
| 	} | ||||
| }; | ||||
| // nuxt.config.js | ||||
| import { readFile, utils } from 'xlsx'; | ||||
| 
 | ||||
| const parseXLSX = (file, { path }) => { | ||||
|   const wb = readFile(path); | ||||
|   const o = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])})); | ||||
|   return { data: o }; | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|   content: { | ||||
|     extendParser: { | ||||
|       ".numbers": parseXLSX, | ||||
|       ".xlsx": parseXLSX, | ||||
|       ".xls": parseXLSX | ||||
|       // ... other extensions | ||||
|     } | ||||
|   } | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| [](https://github.com/SheetJS/js-xlsx) | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								demos/vue/content/sheetjs.numbers
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								demos/vue/content/sheetjs.numbers
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -27,7 +27,7 @@ | ||||
| </style> | ||||
| 
 | ||||
| <script> | ||||
| import XLSX from 'xlsx'; | ||||
| import * as XLSX from 'xlsx'; | ||||
| const modal = weex.requireModule('modal'); | ||||
| const stream = weex.requireModule('stream'); | ||||
| export default { | ||||
|  | ||||
| @ -1,10 +1,20 @@ | ||||
| module.exports = { | ||||
| 	head: { | ||||
| 		script: [ | ||||
| 			// { src: "https://unpkg.com/xlsx/dist/shim.min.js" }, // CDN
 | ||||
| 			// { src: "https://unpkg.com/xlsx/dist/xlsx.full.min.js" } // CDN
 | ||||
| 			{ src: "shim.js" }, // development
 | ||||
| 			{ src: "xlsx.full.min.js" } // development
 | ||||
| 		] | ||||
| 	} | ||||
| }; | ||||
| // nuxt.config.js
 | ||||
| import { readFile, utils } from 'xlsx'; | ||||
| 
 | ||||
| const parseXLSX = (file, { path }) => { | ||||
|   const wb = readFile(path); | ||||
|   const o = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])})); | ||||
|   return { data: o }; | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|   modules: [ '@nuxt/content' ], | ||||
|   content: { | ||||
|     extendParser: { | ||||
|       ".numbers": parseXLSX, | ||||
|       ".xlsx": parseXLSX, | ||||
|       ".xls": parseXLSX | ||||
|       // ...
 | ||||
|     } | ||||
|   }, | ||||
| } | ||||
|  | ||||
| @ -1 +1,7 @@ | ||||
| {} | ||||
| { | ||||
|   "dependencies": { | ||||
|     "@nuxt/content": "1.15.1", | ||||
|     "nuxt": "2.15.8", | ||||
|     "xlsx": "^0.18.3" | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,92 +1,24 @@ | ||||
| <!-- xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com --> | ||||
| <template> | ||||
| <div @drop="_drop" @dragenter="_suppress" @dragover="_suppress"> | ||||
| 	<div class="row"><div class="col-xs-12"> | ||||
| 		<form class="form-inline"> | ||||
| 			<div class="form-group"> | ||||
| 				<label for="file">Spreadsheet</label> | ||||
| 				<input type="file" class="form-control" id="file" :accept="SheetJSFT" @change="_change" /> | ||||
| 			</div> | ||||
| 		</form> | ||||
| 	</div></div> | ||||
| 	<div class="row"><div class="col-xs-12"> | ||||
| 		<button :disabled="data.length ? false : true" class="btn btn-success" @click="_export">Export</button> | ||||
| 	</div></div> | ||||
| 	<div class="row"><div class="col-xs-12"> | ||||
| 		<div class="table-responsive"> | ||||
| 			<table class="table table-striped"> | ||||
| 				<thead><tr> | ||||
| 					<th v-for="c in cols" :key="c.key">{{c.name}}</th> | ||||
| 				</tr></thead> | ||||
| 				<tbody> | ||||
| 					<tr v-for="(r, key) in data" :key="key"> | ||||
| 						<td v-for="c in cols" :key="c.key"> {{ r[c.key] }}</td> | ||||
| 					</tr> | ||||
| 				</tbody> | ||||
| 			</table> | ||||
| 		</div> | ||||
| 	</div></div> | ||||
| <div> | ||||
|   <div v-for="item in data.data" v-bind:key="item.name"> | ||||
|     <h2>{{ item.name }}</h2> | ||||
|     <table> | ||||
|       <tr v-for="row in item.data" v-bind:key="row.Index"> | ||||
|         <td>{{ row.Name }}</td> | ||||
|         <td>{{ row.Index }}</td> | ||||
|       </tr> | ||||
|     </table> | ||||
|   </div> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| const make_cols = refstr => Array(XLSX.utils.decode_range(refstr).e.c + 1).fill(0).map((x,i) => ({name:XLSX.utils.encode_col(i), key:i})); | ||||
| 
 | ||||
| const _SheetJSFT = [ | ||||
| 	"xlsx", "xlsb", "xlsm", "xls", "xml", "csv", "txt", "ods", "fods", "uos", "sylk", "dif", "dbf", "prn", "qpw", "123", "wb*", "wq*", "html", "htm" | ||||
| ].map(function(x) { return "." + x; }).join(","); | ||||
| export default { | ||||
| 	data() { | ||||
| 		return { | ||||
| 			data: ["SheetJS".split(""), "1234567".split("")], | ||||
| 			cols: [ | ||||
| 				{name:"A", key:0}, | ||||
| 				{name:"B", key:1}, | ||||
| 				{name:"C", key:2}, | ||||
| 				{name:"D", key:3}, | ||||
| 				{name:"E", key:4}, | ||||
| 				{name:"F", key:5}, | ||||
| 				{name:"G", key:6}, | ||||
| 			], | ||||
| 			SheetJSFT: _SheetJSFT | ||||
| 	}; }, | ||||
| 	methods: { | ||||
| 		_suppress(evt) { evt.stopPropagation(); evt.preventDefault(); }, | ||||
| 		_drop(evt) { | ||||
| 			evt.stopPropagation(); evt.preventDefault(); | ||||
| 			const files = evt.dataTransfer.files; | ||||
| 			if(files && files[0]) this._file(files[0]); | ||||
| 		}, | ||||
| 		_change(evt) { | ||||
| 			const files = evt.target.files; | ||||
| 			if(files && files[0]) this._file(files[0]); | ||||
| 		}, | ||||
| 		_export(evt) { | ||||
| 			/* convert state to workbook */ | ||||
| 			const ws = XLSX.utils.aoa_to_sheet(this.data); | ||||
| 			const wb = XLSX.utils.book_new(); | ||||
| 			XLSX.utils.book_append_sheet(wb, ws, "SheetJS"); | ||||
| 			/* generate file and send to client */ | ||||
| 			XLSX.writeFile(wb, "sheetjs.xlsx"); | ||||
| 		}, | ||||
| 		_file(file) { | ||||
| 			/* Boilerplate to set up FileReader */ | ||||
| 			const reader = new FileReader(); | ||||
| 			reader.onload = (e) => { | ||||
| 				/* Parse data */ | ||||
| 				const ab = e.target.result; | ||||
| 				const wb = XLSX.read(new Uint8Array(ab), {type:'array'}); | ||||
| 				/* Get first worksheet */ | ||||
| 				const wsname = wb.SheetNames[0]; | ||||
| 				const ws = wb.Sheets[wsname]; | ||||
| 				/* Convert array of arrays */ | ||||
| 				const data = XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| 				/* Update state */ | ||||
| 				this.data = data; | ||||
| 				this.cols = make_cols(ws['!ref']); | ||||
| 			}; | ||||
| 			reader.readAsArrayBuffer(file); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|   async asyncData ({$content}) { | ||||
|     return { | ||||
|       data: await $content('sheetjs').fetch() | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| @ -26,21 +26,33 @@ a { text-decoration: none } | ||||
| <script src="xlsx.full.min.js"></script> | ||||
| <script src="https://unpkg.com/axios/dist/axios.min.js"></script> | ||||
| <script> | ||||
| var demo = 'axios', book = 'xlsx'; | ||||
| var demo = 'axios', book = 'xlsx', orig = 'sheetjs.xlsx'; | ||||
| 
 | ||||
| if(!window.axios) throw new Error("This demo is not supported in your browser"); | ||||
| 
 | ||||
| function process_wb(wb) { | ||||
| 	console.log(wb); | ||||
| 	htmlout.innerHTML = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]], {editable:true}).replace("<table", '<table id="table" border="1"'); | ||||
| } | ||||
| 
 | ||||
| var url = "sheetjs.xlsx"; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + url + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + demo + '.' + book + '">Download new file</a>'; | ||||
| var path = 'files/' + demo + '.' + book; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>'; | ||||
| 
 | ||||
| axios(url, {responseType:'arraybuffer'}).then(function(res) { | ||||
| axios(orig, {responseType:'arraybuffer'}).then(function(res) { | ||||
| 		var data = new Uint8Array(res.data); | ||||
| 		var wb = XLSX.read(data, {type:"array"}); | ||||
| 		process_wb(wb); | ||||
| }).catch(function(e) { | ||||
| 	if(/404/.test(e.message) || e.response.status) { | ||||
| 		var ws = XLSX.utils.aoa_to_sheet([ | ||||
| 			["Fetch for " + orig + " failed :("], | ||||
| 			["Error Code",  e.response.status], | ||||
| 			["Error Text", e.message], | ||||
| 		]); | ||||
| 		ws["!merges"] = [XLSX.utils.decode_range("A1:B1")]; | ||||
| 		process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] }); | ||||
| 	} | ||||
| }); | ||||
| 
 | ||||
| document.getElementById('ulbutton').onclick = function() { | ||||
|  | ||||
| @ -25,27 +25,36 @@ a { text-decoration: none } | ||||
| </pre> | ||||
| <script src="xlsx.full.min.js"></script> | ||||
| <script> | ||||
| var demo = 'fetch', book = 'xlsx'; | ||||
| var demo = 'fetch', book = 'xlsx', orig = 'sheetjs.xlsx'; | ||||
| 
 | ||||
| if(!window.fetch) | ||||
| 	throw new Error("This demo is not supported in your browser"); | ||||
| if(!window.fetch) throw new Error("This demo is not supported in your browser"); | ||||
| 
 | ||||
| function process_wb(wb) { | ||||
| 	console.log(wb); | ||||
| 	htmlout.innerHTML = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]], {editable:true}).replace("<table", '<table id="table" border="1"'); | ||||
| } | ||||
| 
 | ||||
| var url = "sheetjs.xlsx"; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + url + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + demo + '.' + book + '">Download new file</a>'; | ||||
| var path = 'files/' + demo + '.' + book; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>'; | ||||
| 
 | ||||
| fetch(url).then(function(res) { | ||||
| 	if(!res.ok) throw new Error("fetch failed"); | ||||
| fetch(orig).then(function(res) { | ||||
| 	if(!res.ok) { var e = new Error(res.statusText); e.response = res; return Promise.reject(e);} | ||||
| 	return res.arrayBuffer(); | ||||
| }).then(function(ab) { | ||||
| 	var data = new Uint8Array(ab); | ||||
| 	var wb = XLSX.read(data, {type:"array"}); | ||||
| 	process_wb(wb); | ||||
| }).catch(function(e) { | ||||
| 	if(/404/.test(e.message) || e.response.status) { | ||||
| 		var ws = XLSX.utils.aoa_to_sheet([ | ||||
| 			["Fetch for " + orig + " failed :("], | ||||
| 			["Error Code",  e.response.status], | ||||
| 			["Error Text", e.message], | ||||
| 		]); | ||||
| 		ws["!merges"] = [XLSX.utils.decode_range("A1:B1")]; | ||||
| 		process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] }); | ||||
| 	} | ||||
| }); | ||||
| 
 | ||||
| document.getElementById('ulbutton').onclick = function() { | ||||
|  | ||||
| @ -4,8 +4,15 @@ | ||||
| var fs = require('fs'), path = require('path'); | ||||
| var express = require('express'), app = express(); | ||||
| var sprintf = require('printj').sprintf; | ||||
| var logit = require('../server/_logit'); | ||||
| var cors = require('../server/_cors'); | ||||
| 
 | ||||
| function logit(req, res, next) { | ||||
| 	console.log(sprintf("%s %s %d", req.method, req.url, res.statusCode)); | ||||
| 	next(); | ||||
| } | ||||
| function cors(req, res, next) { | ||||
| 	if(!res.headersSent) res.header('Access-Control-Allow-Origin', '*'); | ||||
| 	next(); | ||||
| } | ||||
| 
 | ||||
| var port = +process.argv[2] || +process.env.PORT || 7262; | ||||
| var basepath = process.cwd(); | ||||
| @ -13,8 +20,8 @@ var basepath = process.cwd(); | ||||
| var dir = path.join(__dirname, "files"); | ||||
| try { fs.mkdirSync(dir); } catch(e) {} | ||||
| 
 | ||||
| app.use(logit.mw); | ||||
| app.use(cors.mw); | ||||
| app.use(logit); | ||||
| app.use(cors); | ||||
| app.use(require('express-formidable')({uploadDir: dir})); | ||||
| app.post('/upload', function(req, res) { | ||||
| 	console.log(req.files); | ||||
|  | ||||
| @ -24,26 +24,38 @@ a { text-decoration: none } | ||||
| <div id="outfile"></div> | ||||
| </pre> | ||||
| <script src="xlsx.full.min.js"></script> | ||||
| <script src="https://unpkg.com/superagent/superagent.js"></script> | ||||
| <script src="https://unpkg.com/superagent@7.1.1/dist/superagent.min.js"></script> | ||||
| <script> | ||||
| var demo = 'superagent', book = 'xlsx'; | ||||
| var demo = 'superagent', book = 'xlsx', orig = 'sheetjs.xlsx'; | ||||
| 
 | ||||
| if(!window.superagent) throw new Error("This demo is not supported in your browser"); | ||||
| 
 | ||||
| function process_wb(wb) { | ||||
| 	console.log(wb); | ||||
| 	htmlout.innerHTML = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]], {editable:true}).replace("<table", '<table id="table" border="1"'); | ||||
| } | ||||
| 
 | ||||
| var url = "sheetjs.xlsx"; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + url + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + demo + '.' + book + '">Download new file</a>'; | ||||
| var path = 'files/' + demo + '.' + book; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>'; | ||||
| 
 | ||||
| superagent.get(url) | ||||
| 	.responseType('arraybuffer') | ||||
| 	.end(function(err, res) { | ||||
| superagent.get(orig).responseType('arraybuffer').end(function(e, res) { | ||||
| 	if(!e) { | ||||
| 		var data = new Uint8Array(res.body); | ||||
| 		var wb = XLSX.read(data, {type:"array"}); | ||||
| 		process_wb(wb); | ||||
| 	}); | ||||
| 		return; | ||||
| 	} | ||||
| 	if(/404/.test(e.message) || e.response.status) { | ||||
| 		var ws = XLSX.utils.aoa_to_sheet([ | ||||
| 			["Fetch for " + orig + " failed :("], | ||||
| 			["Error Code",  e.response.status], | ||||
| 			["Error Text", e.message], | ||||
| 		]); | ||||
| 		ws["!merges"] = [XLSX.utils.decode_range("A1:B1")]; | ||||
| 		process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] }); | ||||
| 	} | ||||
| }); | ||||
| 
 | ||||
| document.getElementById('ulbutton').onclick = function() { | ||||
| 	var wb = XLSX.utils.table_to_book(document.getElementById('htmlout')); | ||||
|  | ||||
| @ -25,28 +25,37 @@ a { text-decoration: none } | ||||
| </pre> | ||||
| <script src="xlsx.full.min.js"></script> | ||||
| <script> | ||||
| var demo = 'xhr', book = 'xlsx'; | ||||
| var demo = 'xhr', book = 'xlsx', orig = 'sheetjs.xlsx2'; | ||||
| 
 | ||||
| if(!window.XMLHttpRequest || typeof Uint8Array === 'undefined') | ||||
| 	throw new Error("This demo is not supported in your browser"); | ||||
| if(!window.XMLHttpRequest || typeof Uint8Array === 'undefined') throw new Error("This demo is not supported in your browser"); | ||||
| 
 | ||||
| function process_wb(wb) { | ||||
| 	console.log(wb); | ||||
| 	htmlout.innerHTML = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]], {editable:true}).replace("<table", '<table id="table" border="1"'); | ||||
| } | ||||
| 
 | ||||
| var url = "sheetjs.xlsx"; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + url + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + demo + '.' + book + '">Download new file</a>'; | ||||
| var path = 'files/' + demo + '.' + book; | ||||
| document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>'; | ||||
| document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>'; | ||||
| 
 | ||||
| { | ||||
| 	var req = new XMLHttpRequest(); | ||||
| 	req.open("GET", url, true); | ||||
| 	req.open("GET", orig, true); | ||||
| 	req.responseType = "arraybuffer"; | ||||
| 	req.onload = function(e) { | ||||
| 		var data = new Uint8Array(req.response); | ||||
| 		var wb = XLSX.read(data, {type:"array"}); | ||||
| 		process_wb(wb); | ||||
| 		if(req.status == 200) { | ||||
| 			var data = new Uint8Array(req.response); | ||||
| 			var wb = XLSX.read(data, {type:"array"}); | ||||
| 			process_wb(wb); | ||||
| 			return; | ||||
| 		} | ||||
| 		var ws = XLSX.utils.aoa_to_sheet([ | ||||
| 			["Fetch for " + orig + " failed :("], | ||||
| 			["Error Code",  req.status], | ||||
| 			["Error Text", req.statusText], | ||||
| 		]); | ||||
| 		ws["!merges"] = [XLSX.utils.decode_range("A1:B1")]; | ||||
| 		process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] }); | ||||
| 	}; | ||||
| 	req.send(); | ||||
| } | ||||
|  | ||||
| @ -442,13 +442,14 @@ var NUMBERS = !Object.defineProperty ? (void 0) :(function() { | ||||
|     return { Sheets: {}, SheetNames: [] }; | ||||
|   }; | ||||
|   var book_append_sheet = function(wb, ws, name) { | ||||
|     var i = 1; | ||||
|     if (!name) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf(name = "Sheet ".concat(i)) == -1) | ||||
|           break; | ||||
|       } | ||||
|     else if (wb.SheetNames.indexOf(name) > -1) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf("".concat(name, "_").concat(i)) == -1) { | ||||
|           name = "".concat(name, "_").concat(i); | ||||
|           break; | ||||
|  | ||||
| @ -17,9 +17,10 @@ var encode_cell = (c: CellAddress): string => `${encode_col(c.c)}${c.r+1}`; | ||||
| var encode_range = (r: Range): string => encode_cell(r.s) + ":" + encode_cell(r.e); | ||||
| var book_new = (): WorkBook => ({Sheets:{}, SheetNames:[]}); | ||||
| var book_append_sheet = (wb: WorkBook, ws: WorkSheet, name?: string): void => { | ||||
| 	if(!name) for(var i = 1; i < 9999; ++i) { | ||||
| 	var i = 1; | ||||
| 	if(!name) for(; i < 9999; ++i) { | ||||
| 		if(wb.SheetNames.indexOf(name = `Sheet ${i}`) == -1) break; | ||||
| 	} else if(wb.SheetNames.indexOf(name) > -1) for(var i = 1; i < 9999; ++i) { | ||||
| 	} else if(wb.SheetNames.indexOf(name) > -1) for(; i < 9999; ++i) { | ||||
| 		if(wb.SheetNames.indexOf(`${name}_${i}`) == -1) { name = `${name}_${i}`; break; } | ||||
| 	} | ||||
| 	wb.SheetNames.push(name); wb.Sheets[name] = ws; | ||||
|  | ||||
							
								
								
									
										14
									
								
								test.mjs
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										14
									
								
								test.mjs
									
									
									
										generated
									
									
									
								
							| @ -2271,6 +2271,20 @@ describe('HTML', function() { | ||||
| 			assert.equal(X.utils.sheet_to_csv(ws),  "A,B\n1,2\n3,4\n4,6"); | ||||
| 		}); | ||||
| 	}); | ||||
| 	describe('empty cell containing html element should increment cell index', function() { | ||||
| 		var html = "<table><tr><td>abc</td><td><b> </b></td><td>def</td></tr></table>"; | ||||
| 		var expectedCellCount = 3; | ||||
| 		it('HTML string', function() { | ||||
| 			var ws = X.read(html, {type:'string'}).Sheets.Sheet1; | ||||
| 			var range = X.utils.decode_range(ws['!ref']); | ||||
| 			assert.equal(range.e.c,expectedCellCount - 1); | ||||
| 		}); | ||||
| 		if(domtest) it('DOM', function() { | ||||
| 			var ws = X.utils.table_to_sheet(get_dom_element(html)); | ||||
| 			var range = X.utils.decode_range(ws['!ref']); | ||||
| 			assert.equal(range.e.c, expectedCellCount - 1); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('js -> file -> js', function() { | ||||
|  | ||||
							
								
								
									
										9
									
								
								test.ts
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										9
									
								
								test.ts
									
									
									
									
									
								
							| @ -2126,6 +2126,15 @@ Deno.test('HTML', async function(t) { | ||||
| 			assert.equal(X.utils.sheet_to_csv(ws),  "A,B\n1,2\n3,4\n4,6"); | ||||
| 		}); | ||||
| 	}); | ||||
| 	await t.step('empty cell containing html element should increment cell index', async function(t) { | ||||
| 		var html = "<table><tr><td>abc</td><td><b> </b></td><td>def</td></tr></table>"; | ||||
| 		var expectedCellCount = 3; | ||||
| 		await t.step('HTML string', async function() { | ||||
| 			var ws = X.read(html, {type:'string'}).Sheets.Sheet1; | ||||
| 			var range = X.utils.decode_range(ws['!ref']||"A1"); | ||||
| 			assert.equal(range.e.c,expectedCellCount - 1); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| Deno.test('js -> file -> js', async function(t) { | ||||
|  | ||||
							
								
								
									
										18
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										18
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -343,6 +343,21 @@ export interface WorkbookProperties { | ||||
|     CodeName?: string; | ||||
| } | ||||
| 
 | ||||
| /** DBF Field Header */ | ||||
| export interface DBFField { | ||||
|     /** Original Field Name */ | ||||
|     name?: string; | ||||
| 
 | ||||
|     /** Field Type */ | ||||
|     type?: string; | ||||
| 
 | ||||
|     /** Field Length */ | ||||
|     len?: number; | ||||
| 
 | ||||
|     /** Field Decimal Count */ | ||||
|     dec?: number; | ||||
| } | ||||
| 
 | ||||
| /** Column Properties Object */ | ||||
| export interface ColInfo { | ||||
|     /* --- visibility --- */ | ||||
| @ -366,6 +381,9 @@ export interface ColInfo { | ||||
| 
 | ||||
|     /** Excel's "Max Digit Width" unit, always integral */ | ||||
|     MDW?: number; | ||||
| 
 | ||||
|     /** DBF Field Header */ | ||||
|     DBF?: DBFField; | ||||
| } | ||||
| 
 | ||||
| /** Row Properties Object */ | ||||
|  | ||||
							
								
								
									
										86
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										86
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| /*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /* vim: set ts=2: */ | ||||
| /*exported XLSX */ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, Deno:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.18.3'; | ||||
| @ -7681,7 +7681,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ { | ||||
| 					out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400); | ||||
| 					break; | ||||
| 				case 'T': out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4)); break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4; break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4 + (dd.read_shift(4, 'i')/1e4)*Math.pow(2,32); break; | ||||
| 				case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break; | ||||
| 				case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; } | ||||
| 					/* falls through */ | ||||
| @ -7695,13 +7695,20 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ { | ||||
| 	} | ||||
| 	if(ft != 0x02) if(d.l < d.length && d[d.l++] != 0x1A) throw new Error("DBF EOF Marker missing " + (d.l-1) + " of " + d.length + " " + d[d.l-1].toString(16)); | ||||
| 	if(opts && opts.sheetRows) out = out.slice(0, opts.sheetRows); | ||||
| 	opts.DBF = fields; | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_sheet(buf, opts)/*:Worksheet*/ { | ||||
| 	var o = opts || {}; | ||||
| 	if(!o.dateNF) o.dateNF = "yyyymmdd"; | ||||
| 	return aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	var ws = aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	ws["!cols"] = o.DBF.map(function(field) { return { | ||||
| 		wch: field.len, | ||||
| 		DBF: field | ||||
| 	}}); | ||||
| 	delete o.DBF; | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_workbook(buf, opts)/*:Workbook*/ { | ||||
| @ -7717,10 +7724,11 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 	if(o.type == "string") throw new Error("Cannot write DBF to JS string"); | ||||
| 	var ba = buf_array(); | ||||
| 	var aoa/*:AOA*/ = sheet_to_json(ws, {header:1, raw:true, cellDates:true}); | ||||
| 	var headers = aoa[0], data = aoa.slice(1); | ||||
| 	var headers = aoa[0], data = aoa.slice(1), cols = ws["!cols"] || []; | ||||
| 	var i = 0, j = 0, hcnt = 0, rlen = 1; | ||||
| 	for(i = 0; i < headers.length; ++i) { | ||||
| 		if(i == null) continue; | ||||
| 		if(((cols[i]||{}).DBF||{}).name) { headers[i] = cols[i].DBF.name; ++hcnt; continue; } | ||||
| 		if(headers[i] == null) continue; | ||||
| 		++hcnt; | ||||
| 		if(typeof headers[i] === 'number') headers[i] = headers[i].toString(10); | ||||
| 		if(typeof headers[i] !== 'string') throw new Error("DBF Invalid column name " + headers[i] + " |" + (typeof headers[i]) + "|"); | ||||
| @ -7729,13 +7737,15 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 	} | ||||
| 	var range = safe_decode_range(ws['!ref']); | ||||
| 	var coltypes/*:Array<string>*/ = []; | ||||
| 	var colwidths/*:Array<number>*/ = []; | ||||
| 	var coldecimals/*:Array<number>*/ = []; | ||||
| 	for(i = 0; i <= range.e.c - range.s.c; ++i) { | ||||
| 		var guess = '', _guess = '', maxlen = 0; | ||||
| 		var col/*:Array<any>*/ = []; | ||||
| 		for(j=0; j < data.length; ++j) { | ||||
| 			if(data[j][i] != null) col.push(data[j][i]); | ||||
| 		} | ||||
| 		if(col.length == 0 || headers[i] == null) { coltypes[i] = '?'; continue; } | ||||
| 		var guess = '', _guess = ''; | ||||
| 		for(j = 0; j < col.length; ++j) { | ||||
| 			switch(typeof col[j]) { | ||||
| 				/* TODO: check if L2 compat is desired */ | ||||
| @ -7745,10 +7755,23 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 				case 'object': _guess = col[j] instanceof Date ? 'D' : 'C'; break; | ||||
| 				default: _guess = 'C'; | ||||
| 			} | ||||
| 			maxlen = Math.max(maxlen, String(col[j]).length); | ||||
| 			guess = guess && guess != _guess ? 'C' : _guess; | ||||
| 			if(guess == 'C') break; | ||||
| 			//if(guess == 'C') break;
 | ||||
| 		} | ||||
| 		rlen += _RLEN[guess] || 0; | ||||
| 		if(maxlen > 250) maxlen = 250; | ||||
| 		_guess = ((cols[i]||{}).DBF||{}).type; | ||||
| 		/* TODO: more fine grained control over DBF type resolution */ | ||||
| 		if(_guess == 'C') { | ||||
| 			if(cols[i].DBF.len > maxlen) maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		if(guess == 'B' && _guess == 'N') { | ||||
| 			guess = 'N'; | ||||
| 			coldecimals[i] = cols[i].DBF.dec; | ||||
| 			maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		colwidths[i] = guess == 'C' || _guess == 'N' ? maxlen : (_RLEN[guess] || 0); | ||||
| 		rlen += colwidths[i]; | ||||
| 		coltypes[i] = guess; | ||||
| 	} | ||||
| 
 | ||||
| @ -7767,14 +7790,14 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 		hf.write_shift(1, _f, "sbcs"); | ||||
| 		hf.write_shift(1, coltypes[i] == '?' ? 'C' : coltypes[i], "sbcs"); | ||||
| 		hf.write_shift(4, j); | ||||
| 		hf.write_shift(1, _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(1, colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, coldecimals[i] || 0); | ||||
| 		hf.write_shift(1, 0x02); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		j += _RLEN[coltypes[i]] || 0; | ||||
| 		j += (colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 	} | ||||
| 
 | ||||
| 	var hb = ba.next(264); | ||||
| @ -7788,6 +7811,12 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 			switch(coltypes[j]) { | ||||
| 				case 'L': rout.write_shift(1, data[i][j] == null ? 0x3F : data[i][j] ? 0x54 : 0x46); break; | ||||
| 				case 'B': rout.write_shift(8, data[i][j]||0, 'f'); break; | ||||
| 				case 'N': | ||||
| 					var _n = "0"; | ||||
| 					if(typeof data[i][j] == "number") _n = data[i][j].toFixed(coldecimals[j]||0); | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_n.length; ++hcnt) rout.write_shift(1, 0x20); | ||||
| 					rout.write_shift(1, _n, "sbcs"); | ||||
| 					break; | ||||
| 				case 'D': | ||||
| 					if(!data[i][j]) rout.write_shift(8, "00000000", "sbcs"); | ||||
| 					else { | ||||
| @ -7796,9 +7825,9 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 						rout.write_shift(2, ("00"+data[i][j].getDate()).slice(-2), "sbcs"); | ||||
| 					} break; | ||||
| 				case 'C': | ||||
| 					var _s = String(data[i][j]||""); | ||||
| 					var _s = String(data[i][j] != null ? data[i][j] : "").slice(0, colwidths[j]); | ||||
| 					rout.write_shift(1, _s, "sbcs"); | ||||
| 					for(hcnt=0; hcnt < 250-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 			} | ||||
| 		} | ||||
| 		// data
 | ||||
| @ -20973,7 +21002,7 @@ var HTML_ = (function() { | ||||
| 				m = htmldecode(m); | ||||
| 				if(range.s.r > R) range.s.r = R; if(range.e.r < R) range.e.r = R; | ||||
| 				if(range.s.c > C) range.s.c = C; if(range.e.c < C) range.e.c = C; | ||||
| 				if(!m.length) continue; | ||||
| 				if(!m.length) { C += CS; continue; } | ||||
| 				var o/*:Cell*/ = {t:'s', v:m}; | ||||
| 				if(opts.raw || !m.trim().length || _t == 's'){} | ||||
| 				else if(m === 'TRUE') o = {t:'b', v:true}; | ||||
| @ -22481,13 +22510,14 @@ var NUMBERS = !Object.defineProperty ? (void 0) :(function() { | ||||
|     return { Sheets: {}, SheetNames: [] }; | ||||
|   }; | ||||
|   var book_append_sheet = function(wb, ws, name) { | ||||
|     var i = 1; | ||||
|     if (!name) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf(name = "Sheet ".concat(i)) == -1) | ||||
|           break; | ||||
|       } | ||||
|     else if (wb.SheetNames.indexOf(name) > -1) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf("".concat(name, "_").concat(i)) == -1) { | ||||
|           name = "".concat(name, "_").concat(i); | ||||
|           break; | ||||
| @ -23698,7 +23728,8 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) { | ||||
| 	var out/*:Array<any>*/ = []; | ||||
| 	var outi = 0, counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -23710,8 +23741,12 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) { vv = v + "_" + (++counter); CC = -1; } | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
| @ -24102,7 +24137,8 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 	var cols/*:Array<string>*/ = []; | ||||
| 	var counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -24114,8 +24150,12 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) vv = v + "_" + (++counter); | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
| @ -24133,7 +24173,7 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 		return stream.push(null); | ||||
| 	}; | ||||
| 	return stream; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| var __stream = { | ||||
| 	to_json: write_json_stream, | ||||
|  | ||||
							
								
								
									
										86
									
								
								xlsx.js
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										86
									
								
								xlsx.js
									
									
									
										generated
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| /*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /* vim: set ts=2: */ | ||||
| /*exported XLSX */ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, Deno:false */ | ||||
| var XLSX = {}; | ||||
| function make_xlsx_lib(XLSX){ | ||||
| XLSX.version = '0.18.3'; | ||||
| @ -7584,7 +7584,7 @@ var fields = [], field = ({}); | ||||
| 					out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400); | ||||
| 					break; | ||||
| 				case 'T': out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4)); break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4; break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4 + (dd.read_shift(4, 'i')/1e4)*Math.pow(2,32); break; | ||||
| 				case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break; | ||||
| 				case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; } | ||||
| 					/* falls through */ | ||||
| @ -7598,13 +7598,20 @@ var fields = [], field = ({}); | ||||
| 	} | ||||
| 	if(ft != 0x02) if(d.l < d.length && d[d.l++] != 0x1A) throw new Error("DBF EOF Marker missing " + (d.l-1) + " of " + d.length + " " + d[d.l-1].toString(16)); | ||||
| 	if(opts && opts.sheetRows) out = out.slice(0, opts.sheetRows); | ||||
| 	opts.DBF = fields; | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_sheet(buf, opts) { | ||||
| 	var o = opts || {}; | ||||
| 	if(!o.dateNF) o.dateNF = "yyyymmdd"; | ||||
| 	return aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	var ws = aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	ws["!cols"] = o.DBF.map(function(field) { return { | ||||
| 		wch: field.len, | ||||
| 		DBF: field | ||||
| 	}}); | ||||
| 	delete o.DBF; | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_workbook(buf, opts) { | ||||
| @ -7620,10 +7627,11 @@ function sheet_to_dbf(ws, opts) { | ||||
| 	if(o.type == "string") throw new Error("Cannot write DBF to JS string"); | ||||
| 	var ba = buf_array(); | ||||
| 	var aoa = sheet_to_json(ws, {header:1, raw:true, cellDates:true}); | ||||
| 	var headers = aoa[0], data = aoa.slice(1); | ||||
| 	var headers = aoa[0], data = aoa.slice(1), cols = ws["!cols"] || []; | ||||
| 	var i = 0, j = 0, hcnt = 0, rlen = 1; | ||||
| 	for(i = 0; i < headers.length; ++i) { | ||||
| 		if(i == null) continue; | ||||
| 		if(((cols[i]||{}).DBF||{}).name) { headers[i] = cols[i].DBF.name; ++hcnt; continue; } | ||||
| 		if(headers[i] == null) continue; | ||||
| 		++hcnt; | ||||
| 		if(typeof headers[i] === 'number') headers[i] = headers[i].toString(10); | ||||
| 		if(typeof headers[i] !== 'string') throw new Error("DBF Invalid column name " + headers[i] + " |" + (typeof headers[i]) + "|"); | ||||
| @ -7632,13 +7640,15 @@ function sheet_to_dbf(ws, opts) { | ||||
| 	} | ||||
| 	var range = safe_decode_range(ws['!ref']); | ||||
| 	var coltypes = []; | ||||
| 	var colwidths = []; | ||||
| 	var coldecimals = []; | ||||
| 	for(i = 0; i <= range.e.c - range.s.c; ++i) { | ||||
| 		var guess = '', _guess = '', maxlen = 0; | ||||
| 		var col = []; | ||||
| 		for(j=0; j < data.length; ++j) { | ||||
| 			if(data[j][i] != null) col.push(data[j][i]); | ||||
| 		} | ||||
| 		if(col.length == 0 || headers[i] == null) { coltypes[i] = '?'; continue; } | ||||
| 		var guess = '', _guess = ''; | ||||
| 		for(j = 0; j < col.length; ++j) { | ||||
| 			switch(typeof col[j]) { | ||||
| 				/* TODO: check if L2 compat is desired */ | ||||
| @ -7648,10 +7658,23 @@ function sheet_to_dbf(ws, opts) { | ||||
| 				case 'object': _guess = col[j] instanceof Date ? 'D' : 'C'; break; | ||||
| 				default: _guess = 'C'; | ||||
| 			} | ||||
| 			maxlen = Math.max(maxlen, String(col[j]).length); | ||||
| 			guess = guess && guess != _guess ? 'C' : _guess; | ||||
| 			if(guess == 'C') break; | ||||
| 			//if(guess == 'C') break;
 | ||||
| 		} | ||||
| 		rlen += _RLEN[guess] || 0; | ||||
| 		if(maxlen > 250) maxlen = 250; | ||||
| 		_guess = ((cols[i]||{}).DBF||{}).type; | ||||
| 		/* TODO: more fine grained control over DBF type resolution */ | ||||
| 		if(_guess == 'C') { | ||||
| 			if(cols[i].DBF.len > maxlen) maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		if(guess == 'B' && _guess == 'N') { | ||||
| 			guess = 'N'; | ||||
| 			coldecimals[i] = cols[i].DBF.dec; | ||||
| 			maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		colwidths[i] = guess == 'C' || _guess == 'N' ? maxlen : (_RLEN[guess] || 0); | ||||
| 		rlen += colwidths[i]; | ||||
| 		coltypes[i] = guess; | ||||
| 	} | ||||
| 
 | ||||
| @ -7670,14 +7693,14 @@ function sheet_to_dbf(ws, opts) { | ||||
| 		hf.write_shift(1, _f, "sbcs"); | ||||
| 		hf.write_shift(1, coltypes[i] == '?' ? 'C' : coltypes[i], "sbcs"); | ||||
| 		hf.write_shift(4, j); | ||||
| 		hf.write_shift(1, _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(1, colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, coldecimals[i] || 0); | ||||
| 		hf.write_shift(1, 0x02); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		j += _RLEN[coltypes[i]] || 0; | ||||
| 		j += (colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 	} | ||||
| 
 | ||||
| 	var hb = ba.next(264); | ||||
| @ -7691,6 +7714,12 @@ function sheet_to_dbf(ws, opts) { | ||||
| 			switch(coltypes[j]) { | ||||
| 				case 'L': rout.write_shift(1, data[i][j] == null ? 0x3F : data[i][j] ? 0x54 : 0x46); break; | ||||
| 				case 'B': rout.write_shift(8, data[i][j]||0, 'f'); break; | ||||
| 				case 'N': | ||||
| 					var _n = "0"; | ||||
| 					if(typeof data[i][j] == "number") _n = data[i][j].toFixed(coldecimals[j]||0); | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_n.length; ++hcnt) rout.write_shift(1, 0x20); | ||||
| 					rout.write_shift(1, _n, "sbcs"); | ||||
| 					break; | ||||
| 				case 'D': | ||||
| 					if(!data[i][j]) rout.write_shift(8, "00000000", "sbcs"); | ||||
| 					else { | ||||
| @ -7699,9 +7728,9 @@ function sheet_to_dbf(ws, opts) { | ||||
| 						rout.write_shift(2, ("00"+data[i][j].getDate()).slice(-2), "sbcs"); | ||||
| 					} break; | ||||
| 				case 'C': | ||||
| 					var _s = String(data[i][j]||""); | ||||
| 					var _s = String(data[i][j] != null ? data[i][j] : "").slice(0, colwidths[j]); | ||||
| 					rout.write_shift(1, _s, "sbcs"); | ||||
| 					for(hcnt=0; hcnt < 250-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 			} | ||||
| 		} | ||||
| 		// data
 | ||||
| @ -20856,7 +20885,7 @@ var HTML_ = (function() { | ||||
| 				m = htmldecode(m); | ||||
| 				if(range.s.r > R) range.s.r = R; if(range.e.r < R) range.e.r = R; | ||||
| 				if(range.s.c > C) range.s.c = C; if(range.e.c < C) range.e.c = C; | ||||
| 				if(!m.length) continue; | ||||
| 				if(!m.length) { C += CS; continue; } | ||||
| 				var o = {t:'s', v:m}; | ||||
| 				if(opts.raw || !m.trim().length || _t == 's'){} | ||||
| 				else if(m === 'TRUE') o = {t:'b', v:true}; | ||||
| @ -22364,13 +22393,14 @@ var NUMBERS = !Object.defineProperty ? (void 0) :(function() { | ||||
|     return { Sheets: {}, SheetNames: [] }; | ||||
|   }; | ||||
|   var book_append_sheet = function(wb, ws, name) { | ||||
|     var i = 1; | ||||
|     if (!name) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf(name = "Sheet ".concat(i)) == -1) | ||||
|           break; | ||||
|       } | ||||
|     else if (wb.SheetNames.indexOf(name) > -1) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf("".concat(name, "_").concat(i)) == -1) { | ||||
|           name = "".concat(name, "_").concat(i); | ||||
|           break; | ||||
| @ -23570,7 +23600,8 @@ function sheet_to_json(sheet, opts) { | ||||
| 	var out = []; | ||||
| 	var outi = 0, counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -23582,8 +23613,12 @@ function sheet_to_json(sheet, opts) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) { vv = v + "_" + (++counter); CC = -1; } | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
| @ -23974,7 +24009,8 @@ function write_json_stream(sheet, opts) { | ||||
| 	var cols = []; | ||||
| 	var counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -23986,8 +24022,12 @@ function write_json_stream(sheet, opts) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) vv = v + "_" + (++counter); | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
| @ -24005,7 +24045,7 @@ function write_json_stream(sheet, opts) { | ||||
| 		return stream.push(null); | ||||
| 	}; | ||||
| 	return stream; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| var __stream = { | ||||
| 	to_json: write_json_stream, | ||||
|  | ||||
							
								
								
									
										84
									
								
								xlsx.mjs
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										84
									
								
								xlsx.mjs
									
									
									
										generated
									
									
									
								
							| @ -7678,7 +7678,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ { | ||||
| 					out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400); | ||||
| 					break; | ||||
| 				case 'T': out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4)); break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4; break; | ||||
| 				case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4 + (dd.read_shift(4, 'i')/1e4)*Math.pow(2,32); break; | ||||
| 				case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break; | ||||
| 				case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; } | ||||
| 					/* falls through */ | ||||
| @ -7692,13 +7692,20 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ { | ||||
| 	} | ||||
| 	if(ft != 0x02) if(d.l < d.length && d[d.l++] != 0x1A) throw new Error("DBF EOF Marker missing " + (d.l-1) + " of " + d.length + " " + d[d.l-1].toString(16)); | ||||
| 	if(opts && opts.sheetRows) out = out.slice(0, opts.sheetRows); | ||||
| 	opts.DBF = fields; | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_sheet(buf, opts)/*:Worksheet*/ { | ||||
| 	var o = opts || {}; | ||||
| 	if(!o.dateNF) o.dateNF = "yyyymmdd"; | ||||
| 	return aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	var ws = aoa_to_sheet(dbf_to_aoa(buf, o), o); | ||||
| 	ws["!cols"] = o.DBF.map(function(field) { return { | ||||
| 		wch: field.len, | ||||
| 		DBF: field | ||||
| 	}}); | ||||
| 	delete o.DBF; | ||||
| 	return ws; | ||||
| } | ||||
| 
 | ||||
| function dbf_to_workbook(buf, opts)/*:Workbook*/ { | ||||
| @ -7714,10 +7721,11 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 	if(o.type == "string") throw new Error("Cannot write DBF to JS string"); | ||||
| 	var ba = buf_array(); | ||||
| 	var aoa/*:AOA*/ = sheet_to_json(ws, {header:1, raw:true, cellDates:true}); | ||||
| 	var headers = aoa[0], data = aoa.slice(1); | ||||
| 	var headers = aoa[0], data = aoa.slice(1), cols = ws["!cols"] || []; | ||||
| 	var i = 0, j = 0, hcnt = 0, rlen = 1; | ||||
| 	for(i = 0; i < headers.length; ++i) { | ||||
| 		if(i == null) continue; | ||||
| 		if(((cols[i]||{}).DBF||{}).name) { headers[i] = cols[i].DBF.name; ++hcnt; continue; } | ||||
| 		if(headers[i] == null) continue; | ||||
| 		++hcnt; | ||||
| 		if(typeof headers[i] === 'number') headers[i] = headers[i].toString(10); | ||||
| 		if(typeof headers[i] !== 'string') throw new Error("DBF Invalid column name " + headers[i] + " |" + (typeof headers[i]) + "|"); | ||||
| @ -7726,13 +7734,15 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 	} | ||||
| 	var range = safe_decode_range(ws['!ref']); | ||||
| 	var coltypes/*:Array<string>*/ = []; | ||||
| 	var colwidths/*:Array<number>*/ = []; | ||||
| 	var coldecimals/*:Array<number>*/ = []; | ||||
| 	for(i = 0; i <= range.e.c - range.s.c; ++i) { | ||||
| 		var guess = '', _guess = '', maxlen = 0; | ||||
| 		var col/*:Array<any>*/ = []; | ||||
| 		for(j=0; j < data.length; ++j) { | ||||
| 			if(data[j][i] != null) col.push(data[j][i]); | ||||
| 		} | ||||
| 		if(col.length == 0 || headers[i] == null) { coltypes[i] = '?'; continue; } | ||||
| 		var guess = '', _guess = ''; | ||||
| 		for(j = 0; j < col.length; ++j) { | ||||
| 			switch(typeof col[j]) { | ||||
| 				/* TODO: check if L2 compat is desired */ | ||||
| @ -7742,10 +7752,23 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 				case 'object': _guess = col[j] instanceof Date ? 'D' : 'C'; break; | ||||
| 				default: _guess = 'C'; | ||||
| 			} | ||||
| 			maxlen = Math.max(maxlen, String(col[j]).length); | ||||
| 			guess = guess && guess != _guess ? 'C' : _guess; | ||||
| 			if(guess == 'C') break; | ||||
| 			//if(guess == 'C') break;
 | ||||
| 		} | ||||
| 		rlen += _RLEN[guess] || 0; | ||||
| 		if(maxlen > 250) maxlen = 250; | ||||
| 		_guess = ((cols[i]||{}).DBF||{}).type; | ||||
| 		/* TODO: more fine grained control over DBF type resolution */ | ||||
| 		if(_guess == 'C') { | ||||
| 			if(cols[i].DBF.len > maxlen) maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		if(guess == 'B' && _guess == 'N') { | ||||
| 			guess = 'N'; | ||||
| 			coldecimals[i] = cols[i].DBF.dec; | ||||
| 			maxlen = cols[i].DBF.len; | ||||
| 		} | ||||
| 		colwidths[i] = guess == 'C' || _guess == 'N' ? maxlen : (_RLEN[guess] || 0); | ||||
| 		rlen += colwidths[i]; | ||||
| 		coltypes[i] = guess; | ||||
| 	} | ||||
| 
 | ||||
| @ -7764,14 +7787,14 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 		hf.write_shift(1, _f, "sbcs"); | ||||
| 		hf.write_shift(1, coltypes[i] == '?' ? 'C' : coltypes[i], "sbcs"); | ||||
| 		hf.write_shift(4, j); | ||||
| 		hf.write_shift(1, _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(1, colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 		hf.write_shift(1, coldecimals[i] || 0); | ||||
| 		hf.write_shift(1, 0x02); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(1, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		hf.write_shift(4, 0); | ||||
| 		j += _RLEN[coltypes[i]] || 0; | ||||
| 		j += (colwidths[i] || _RLEN[coltypes[i]] || 0); | ||||
| 	} | ||||
| 
 | ||||
| 	var hb = ba.next(264); | ||||
| @ -7785,6 +7808,12 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 			switch(coltypes[j]) { | ||||
| 				case 'L': rout.write_shift(1, data[i][j] == null ? 0x3F : data[i][j] ? 0x54 : 0x46); break; | ||||
| 				case 'B': rout.write_shift(8, data[i][j]||0, 'f'); break; | ||||
| 				case 'N': | ||||
| 					var _n = "0"; | ||||
| 					if(typeof data[i][j] == "number") _n = data[i][j].toFixed(coldecimals[j]||0); | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_n.length; ++hcnt) rout.write_shift(1, 0x20); | ||||
| 					rout.write_shift(1, _n, "sbcs"); | ||||
| 					break; | ||||
| 				case 'D': | ||||
| 					if(!data[i][j]) rout.write_shift(8, "00000000", "sbcs"); | ||||
| 					else { | ||||
| @ -7793,9 +7822,9 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) { | ||||
| 						rout.write_shift(2, ("00"+data[i][j].getDate()).slice(-2), "sbcs"); | ||||
| 					} break; | ||||
| 				case 'C': | ||||
| 					var _s = String(data[i][j]||""); | ||||
| 					var _s = String(data[i][j] != null ? data[i][j] : "").slice(0, colwidths[j]); | ||||
| 					rout.write_shift(1, _s, "sbcs"); | ||||
| 					for(hcnt=0; hcnt < 250-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 					for(hcnt=0; hcnt < colwidths[j]-_s.length; ++hcnt) rout.write_shift(1, 0x20); break; | ||||
| 			} | ||||
| 		} | ||||
| 		// data
 | ||||
| @ -20970,7 +20999,7 @@ var HTML_ = (function() { | ||||
| 				m = htmldecode(m); | ||||
| 				if(range.s.r > R) range.s.r = R; if(range.e.r < R) range.e.r = R; | ||||
| 				if(range.s.c > C) range.s.c = C; if(range.e.c < C) range.e.c = C; | ||||
| 				if(!m.length) continue; | ||||
| 				if(!m.length) { C += CS; continue; } | ||||
| 				var o/*:Cell*/ = {t:'s', v:m}; | ||||
| 				if(opts.raw || !m.trim().length || _t == 's'){} | ||||
| 				else if(m === 'TRUE') o = {t:'b', v:true}; | ||||
| @ -22478,13 +22507,14 @@ var NUMBERS = !Object.defineProperty ? (void 0) :(function() { | ||||
|     return { Sheets: {}, SheetNames: [] }; | ||||
|   }; | ||||
|   var book_append_sheet = function(wb, ws, name) { | ||||
|     var i = 1; | ||||
|     if (!name) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf(name = "Sheet ".concat(i)) == -1) | ||||
|           break; | ||||
|       } | ||||
|     else if (wb.SheetNames.indexOf(name) > -1) | ||||
|       for (var i = 1; i < 9999; ++i) { | ||||
|       for (; i < 9999; ++i) { | ||||
|         if (wb.SheetNames.indexOf("".concat(name, "_").concat(i)) == -1) { | ||||
|           name = "".concat(name, "_").concat(i); | ||||
|           break; | ||||
| @ -23695,7 +23725,8 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) { | ||||
| 	var out/*:Array<any>*/ = []; | ||||
| 	var outi = 0, counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -23707,8 +23738,12 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) { vv = v + "_" + (++counter); CC = -1; } | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
| @ -24099,7 +24134,8 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 	var cols/*:Array<string>*/ = []; | ||||
| 	var counter = 0; | ||||
| 	var dense = Array.isArray(sheet); | ||||
| 	var R = r.s.r, C = 0, CC = 0; | ||||
| 	var R = r.s.r, C = 0; | ||||
| 	var header_cnt = {}; | ||||
| 	if(dense && !sheet[R]) sheet[R] = []; | ||||
| 	for(C = r.s.c; C <= r.e.c; ++C) { | ||||
| 		cols[C] = encode_col(C); | ||||
| @ -24111,8 +24147,12 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 			default: | ||||
| 				if(val == null) val = {w: "__EMPTY", t: "s"}; | ||||
| 				vv = v = format_cell(val, null, o); | ||||
| 				counter = 0; | ||||
| 				for(CC = 0; CC < hdr.length; ++CC) if(hdr[CC] == vv) vv = v + "_" + (++counter); | ||||
| 				counter = header_cnt[v] || 0; | ||||
| 				if(!counter) header_cnt[v] = 1; | ||||
| 				else { | ||||
| 					do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter; | ||||
| 					header_cnt[vv] = 1; | ||||
| 				} | ||||
| 				hdr[C] = vv; | ||||
| 		} | ||||
| 	} | ||||
| @ -24130,7 +24170,7 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) { | ||||
| 		return stream.push(null); | ||||
| 	}; | ||||
| 	return stream; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| var __stream = { | ||||
| 	to_json: write_json_stream, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user