將excel檔案內容儲存到資料庫,並可以實時在前端檢視(不必生成檔案)

zzzzMing發表於2018-02-06

本文主要講前端內容,後端涉及較少,可以認為是使用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);
 

 

...

相關文章