版權聲明:本文為部落客原創文章,未經部落客允許不得轉載
本文主要講前端内容,後端涉及較少,可以認為是使用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是可以初始化來生成的,
var blob = new Blob([base64Data], { type: "mime" })
然後就可以通過FileReader讀取了,再接下來隻需要按照demo的代碼調用就可以了。。。
reader.readAsBinaryString(blob);
...