js解析Excel数据

最近做了一个小玩意,邮件群发器,为了让它更易于使用,打算做一个excel上传批量发送的功能,批量发送就不说了,后端直接循环就能达到效果,但是对于excel上传解析这个功能我开始纠结了,并不是说不能做,而是纠结要放在后端做还是放在前端做,之前我也有用php自己玩过excel导入的功能,但是我觉得总是把这些负担施加给服务器不太好,如果我们能放在前端通过js来解析,那么服务器压力会小很多,而且对用户更友好。

既然决定用js来解析excel,我就开始找资料了,因为之前没用js做过这个东西,但是我相信应该能找到我需要的东西,搜索的结果大部分都是说使用Excel.Application这个activex对象来实现,但是activex似乎只有在ie浏览器上面才能使用,但现在用ie的人我相信已经很少了,反正我是从来只用chrome。显然用这个是不行的。最后发现了两个有用的库:

js-xls

js-xlsx

兼容性

支持读取文件格式

Excel 2007+ XML Formats (XLSX/XLSM)

Excel 2007+ Binary Format (XLSB)

Excel 2003-2004 XML Format (XML “SpreadsheetML”)

Excel 97-2004 (XLS BIFF8)

Excel 5.0/95 (XLS BIFF5)

OpenDocument Spreadsheet (ODS)

支持写文件格式

XLSX

CSV (and general DSV)

JSON and JS objects (various styles)

github项目地址:https://github.com/SheetJS/js-xlsx

JS-XLS的安装是很简单的,在浏览器中使用该脚本文件,并使用脚本标记加载它:

<br>
&lt;!-- https://github.com/SheetJS/js-xls/blob/master/xls.js --&gt;<br>
&lt;script src="/path/to/xls.js"&gt;&lt;/script&gt;<br>

对于Node.js,只要通过NPM安装:

<br>
$ npm install xlsjs<br>
$ node<br>
&gt; require('xlsjs').readFile('excel_file.xls');<br>

对于JS-JS-XLSX安装和JS-XLS的基本相同。使用浏览器加载jszip.js和xlsx文件:

<br>
&lt;!-- https://github.com/SheetJS/js-xlsx/blob/master/jszip.js --&gt;<br>
&lt;script src="/path/to/jszip.js"&gt;&lt;/script&gt;<br>
&lt;!-- https://github.com/SheetJS/js-xlsx/blob/master/xlsx.js --&gt;<br>
&lt;script src="/path/to/xlsx.js"&gt;&lt;/script&gt;<br>

对于Node.js,只要通过NPM安装:

<br>
$ npm install xlsx<br>
$ node<br>
&gt; require('xlsx').readFile('excel_file.xlsx');<br>

在这里我选择了使用XLSX,毕竟他的兼容性更好。

案例代码:

<br>
&lt;!DOCTYPE html&gt;<br>
&lt;html lang="en"&gt;<br>
&lt;head&gt;<br>
	&lt;meta charset="UTF-8"&gt;<br>
	&lt;title&gt;excel解析&lt;/title&gt;</p>
<p>&lt;style type="text/css"&gt;<br>
		.main{<br>
			overflow: hidden;<br>
			margin: 0 0 20px;<br>
		}<br>
		#drop{<br>
			width: 300px;<br>
			height: 200px;<br>
			text-align: center;<br>
			line-height: 200px;<br>
			cursor: pointer;<br>
			border: 3px dashed #f5f5f5;<br>
			float: left;<br>
		}<br>
		#drop.active{<br>
			border-color: #f00;<br>
		}<br>
		#upload{<br>
			display: none;<br>
		}<br>
		#table{<br>
			margin-left: 20px;<br>
			float: left;<br>
		}<br>
		a{<br>
			font-size: 15px;<br>
			text-decoration: none;<br>
			color: #000;<br>
		}<br>
	&lt;/style&gt;</p>
<p>&lt;/head&gt;<br>
&lt;body&gt;</p>
<p>&lt;div class="main"&gt;</p>
<p>&lt;div id="drop"&gt;<br>
			点击此处或者将文件拖至此处上传<br>
			&lt;input type="file" id="upload" name=""&gt;<br>
		&lt;/div&gt;</p>
<p>&lt;div id="table"&gt;&lt;/div&gt;</p>
<p>	&lt;/div&gt;</p>
<p>	&lt;a href="sample.xls" target="_blank"&gt;下载样表&lt;/a&gt;<br>
	&lt;script type="text/javascript" src="js/jszip.js"&gt;&lt;/script&gt;<br>
	&lt;script type="text/javascript" src="js/xlsx.js"&gt;&lt;/script&gt;<br>
	&lt;script type="text/javascript"&gt;<br>
		var drop = document.getElementById("drop"),<br>
			upload = document.getElementById("upload"),<br>
			tableC = document.getElementById("table");<br>
			X = XLSX,<br>
			rAbs = typeof FileReader !== "undefined" &amp;&amp; typeof FileReader.prototype !== "undefined" &amp;&amp; typeof FileReader.prototype.readAsBinaryString !== "undefined";<br>
		drop.addEventListener('click',handleClick,false);<br>
		drop.addEventListener('dragover',handleDragOver,false);<br>
		drop.addEventListener('dragleave',handleDragLeave,false);<br>
		drop.addEventListener('mouseout',handleDragLeave,false);<br>
		drop.addEventListener('drop',function(){<br>
			handleDrop(function(data){<br>
				makeTable(data);<br>
			})<br>
		},false);<br>
		upload.addEventListener('change',function(){<br>
			handleChange(function(data){<br>
				makeTable(data);<br>
			})<br>
		},false);<br>
		function clearTable(){<br>
			tableC.innerHTML = '';<br>
		}<br>
		function makeTable(data){<br>
			clearTable();<br>
			for(var index in data){ //遍历每个表<br>
				var table = document.createElement("table"),<br>
					tr = document.createElement("tr"),<br>
					td = document.createElement("td"),<br>
					keys = Object.keys(data[index][0]);<br>
				td.innerHTML = index + "数据";<br>
				td.colspan = keys.length;<br>
				tr.appendChild(td);<br>
				table.appendChild(tr);<br>
				tr = document.createElement("tr");<br>
				for(var i=0,len=keys.length;i&lt;len;i++){<br>
					td = document.createElement("td");<br>
					td.innerHTML = keys[i];<br>
					tr.appendChild(td);<br>
				}<br>
				table.appendChild(tr);<br>
				for(var i=0,len=data[index].length;i&lt;len;i++){ //循环表中每条数据<br>
					tr = document.createElement("tr")<br>
					var item = data[index][i];<br>
					for(var col in item){<br>
						td = document.createElement("td");<br>
						td.innerHTML = item[col];<br>
						tr.appendChild(td);<br>
					}<br>
					table.appendChild(tr);<br>
				}<br>
				tableC.appendChild(table);<br>
			}<br>
		}<br>
		function handleFile(files,callback){<br>
			var f = files[0],<br>
				reader = new FileReader(),<br>
				name = f.name;<br>
			reader.onload = function(){<br>
				var data = event.target.result,<br>
					wb;<br>
				if(rAbs){<br>
					wb = X.read(data,{type : 'binary'});<br>
				}else{<br>
					var arr = fixData(data);<br>
					wb = X.read(btoa(arr),{type : 'base64'});<br>
				}<br>
				callback &amp;&amp; callback(to_json(wb));<br>
			}<br>
			if(rAbs){<br>
				reader.readAsBinaryString(f)<br>
			}else{<br>
				reader.readAsArrayBuffer(f);<br>
			}<br>
			upload.value = '';<br>
		}<br>
		function fixdata(data) {<br>
			var o = "", l = 0, w = 10240;<br>
			for(; l&lt;data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w))); o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w))); return o; } function to_json(workbook) { var result = {}; workbook.SheetNames.forEach(function(sheetName) { var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]); if(roa.length &gt; 0){<br>
					result[sheetName] = roa;<br>
				}<br>
			});<br>
			return result;<br>
		}<br>
		function handleClick(){<br>
			upload.click();<br>
		}<br>
		function handleChange(callback){<br>
			if(upload.value){<br>
				handleFile(event.target.files,callback);<br>
			}<br>
		}<br>
		function handleDrop(callback){<br>
			event.preventDefault();<br>
			event.stopPropagation();<br>
			handleFile(event.dataTransfer.files,callback);<br>
		}<br>
		function handleDragOver(){<br>
			event.preventDefault();<br>
			event.stopPropagation();<br>
			drop.className = 'active';<br>
		}<br>
		function handleDragLeave(){<br>
			drop.className = '';<br>
		}<br>
	&lt;/script&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;<br>

在线Demo地址:http://demo.deanhan.cn/XLSX/

猛戳这里下载本文案例源码包
  • 支付宝二维码 支付宝
  • 微信二维码 微信
相关文章