本文主要講前端內容,後端涉及較少,可以認為是使用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是可以初始化來生成的,