本文主要講前端內容,后端涉及較少,可以認為是使用Java。
首先是excel文件上傳,這個較為簡單,可以html5的數據接口FormData()進行操作。具體代碼如下:
<!DOCTYPE html> <html> <head> </head> <body> <input type="file" id="_file" value=""/><p for="file">或點此選擇文件</p>
<button id = "file_button" >按鈕</button> </body> </html>
然后是對應的javascript
$("#button").click(function(){
var files = $('#_file').prop('files'); var data = new FormData(); data.append("upload",files[0]); //因為是只選擇一個文件,故而只取file[0]
$.ajax({
url: yourPath,
type: 'POST',
data: data,
cache: false,
dataType:'text',
processData: false,
contentType: false,
success: function(result) {
// Do something with the result
alert("成功");
},
error : function(result){
alert("失敗"+result.toString());
}
});
});
后端接收到文件之后,將其存儲成二進制數組,在數據庫中,比如postgresql,使用blob數據類型,然后在java中使用byte數組映射就可以了。
那么怎么從后端存儲的文件內容直接在頁面上excel呢?這里需要用到sheetJs,官網:http://sheetjs.com/,可以直接取其demo來用,
demo下載地址放在github上了:https://github.com/SheetJS/SheetJS.github.io。
在這里是直接使用它的一些代碼,主要說說思路。
下載后解壓是SheetJS.github.io-master文件夾,在而顯示生成excel的Js代碼主要在SheetJS.github.io-master\assets\js\dropsheet.js中。其中發下其最后是通過調用該文件中以下代碼
function handleDrop(e) { e.stopPropagation(); e.preventDefault(); if(pending) return opts.errors.pending(); var files = e.dataTransfer.files; var i,f; for (i = 0, f = files[i]; i != files.length; ++i) { var reader = new FileReader(); var name = f.name; reader.onload = function(e) { var data = e.target.result; var wb, arr; var readtype = {type: rABS ? 'binary' : 'base64' }; if(!rABS) { arr = fixdata(data); data = btoa(arr); } function doit() { try { if(useworker) { sheetjsw(data, process_wb, readtype); return; } wb = XLSX.read(data, readtype); process_wb(wb); } catch(e) { console.log(e); opts.errors.failed(e); } } if(e.target.result.length > 1e6) opts.errors.large(e.target.result.length, function(e) { if(e) doit(); }); else { doit(); } }; if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f); } }
說明:SheetJs這個demo中,解析excel使用的是js-xlsx這個庫,這個庫對excel的操作很多,解析只是一個方面,具體可以上github上看。而根據解析在html上繪制excel表格的是canvas-datagrid.js這個表格控件。
可以看到它是通過FileReader的readAsBinaryString方法讀取每個選中的文件,根據文件內容在html中繪制出excel表格,那么我們只要在這里自己從后端接收那個二進制數據,生成一個File對象,再跑同樣這段代碼就OK。
這個過程中碰到兩個問題:
一個就是后端的byte數組傳遞到前端很不方便,而且我在用ajax傳遞的時候,二進制數組參數會變成string型。
另一個就是javascript中無法直接新建一個File對象。。
首先第一個問題,二進制數組不能傳遞,那么就只能傳遞字符串了,但是不能直接轉字符串,那么有什么辦法呢?再上面的代碼看到,里面有一句
var readtype = {type: rABS ? 'binary' : 'base64' };
說明這個操作可以操作base64編碼的字符串,那就是轉成base64,這個需要引入apache的一個包,包名為commons-codec,再Maven中引用如下,
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency>
再調用其一個方法,
Base64.encodeBase64String(byteArray); //將byteArray轉為base64字符串
這樣就可以傳輸到前端了。
再說第二個問題,通過百度發現,javascript有一種數據類型Blob,而File正是基於這種Blob的。
一個Blob對象就是一個包含有只讀原始數據的類文件對象
但是Blob是可以初始化來生成的,