數據庫表格數據導出到excel方法總結

寫在前面

之前開發的時候需要實現excel表格文件的共享功能,並且是同一張大表格,不同的人只能看裏面的一部分數據。由於數據每天更新,且每次都要手動篩選出給不同的人看的數據。很是繁瑣。希望能有一個方便的方法來實現:維護這個數據大表的人只需要更新這張表,其他人就可以自己隨時獲取自己有權查看的那部分數據。

也許你有更好更簡單的方法來實現。歡迎留言我。作爲初學者寫這篇文字只是記錄一下我解決問題的過程。因爲這裏涉及到了Oracle數據庫的操作,javaEE、jsp的編寫,前臺HTML、javascript、DOM 的操作,等方面。方便今後忘了的時候自己翻閱。

下面是正文。

方案一、使用數據庫+plsqldev (.xlsx)

首先我想到的是將這個數據大表(一個.xlsx文件),轉換成數據表,存入數據庫中(我這裏使用的是Oracle(這不是重點)),然後創建view,並設置列名爲原 .xlsx 文件的列名。
維護數據的人只要在更新數據的時候使用 plsqldev 獨立版(無需安裝Oracle客戶端即可使用的版本),執行下面的sql:

select * from TABLENAME order by ID for update;
-- 這裏若不使用“order by ID”,有可能結果不是按照當初導入的順序呈現的。

將自己的excel文件複製粘貼到數據庫即可。然後想要查看的人查詢自己的view,並使用 plsqldev 的導出到 .xlsx 功能即可導出。

優點:簡單粗暴。使用者會使用 plsqldev 即可操作,而且實現了權限隔離,無法查看無權查看的數據的功能需求。

缺點:1.使用者不同的電腦環境 配置 plsqldev 時會出現各種情況,需要處理並且很棘手、2.用戶體驗差、3.使用時需要學習成本,學習如何使用 plsqldev 。

//無源碼

方案二、使用數據庫+jsp(.csv)

同樣是使用數據庫將表格數據遷移至數據庫裏,在服務器端使用 jsp 來實現 數據從數據庫導出到 .csv 的功能。在 jsp 設置參數判斷用戶的權限,來導出對應是view數據。並呈現給用戶。先說說這樣做的優缺點。

優點:實現了權限隔離,無法查看無權查看的數據的功能需求。簡單粗暴用戶只需一個鏈接即可下載到自己所需的 .csv 文件。

缺點:1.呈現的爲 .csv 文件,無發保存表格的樣式,體驗稍差。2.用戶需要自己調節樣式並另存爲 .xlsx 才能保存表格的樣式,然而畢竟會用戶不會操作,造成體驗差。

實現的源碼如下:

<%@page import="com.tltable.jdbc.tltableDAO"%>
<%@ page language="java" pageEncoding="UTF-8"%>

<%!String sql = "select * from TABLENAME order by u_uid";
    // 這只是個demo,做測試。
    //可以通過傳參實現執行不同的 sql 來查詢不同的 table (view)

    String[][] value = tltableDAO.selectToArray(sql);
     // tltableDAO.selectToArray 函數執行 sql 並將返回結果轉換爲數組的格式。

    String csvStr = this.ArrayToCsvstr(value);

    public String ArrayToCsvstr(String[][] value) {
        String csvstr = "";
        for (int j = 0; j < value.length; j++) {
            if (value[j] == null) {
                csvstr = "獲取值爲空。";
                break;
            }
            for (int i = 0; i < value[j].length; i++) {
                csvstr += value[j][i] + ",";
            }
            csvstr += "\n";
        }
        return csvstr;
    }
%>
<%
    response.setHeader("Content-type", "application/octet-stream;charset=GBK");
    //之前沒有加 charset=GBK ,默認的 UTF-8 下載下來用excel打開會是亂碼。
    response.setHeader("Content-Disposition", "attachment; filename=\"my-data.csv\"");//生成的csv名爲my-data.csv。也可以設置爲動態的文件名。
    //String data = request.getParameter("csv_text");
    out.println(csvStr);//把數據寫入到瀏覽器,以下載的方式
// 當然在輸出之前可以在 csvStr 前添加一行表數據的列名。增加用戶體驗。
%>

tltableDAO.selectToArray 代碼:

/**
     * 查詢數據庫,並轉化成 String[][]
     * 
     * @param sql
     * @param args
     * @return
     */
    public static String[][] selectToArray(String sql, Object... args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultset = null;
        String[][] aaa = null;
        try {
            connection = JDBCTools.getConnection();     
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }       
            resultset = preparedStatement.executeQuery();
            aaa = tltableDAO.getColumnValues(resultset);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.releaseDB(resultset, preparedStatement, connection);
        }

        return aaa;
    }
//這裏涉及的 JDBCTools.java 我想網上會有很多的。我就不貼出來了

方案三、使用數據庫+僞靜態HTML(.csv 或 .xlsx)

這個方案我認爲是最好的了。當然也是我花了很長時間纔想到的。基於方案一 方案二的弊端,本方案做了儘可能的兼容並提升了用戶體驗。

在方案二中我們可以將數據庫的數據轉換成數組,本方案則是將數組推送到 web 前端。這樣一來,可以實現

1、 以<table>的形式呈現出來

IE10+以及其他新版瀏覽器可以使用 handsontable 插件來實現大數據表格在 前端的完美呈現。 反正我覺得用戶不需要。就沒研究。感興趣的可自己去官網查看。handsontable官網

用戶可直接查看(我感覺沒必要)。且客戶端瀏覽器參差不齊,我公司基本使用的都是IE8。╮(╯▽╰)╭ IE8 太多效果沒法呈現。

2、 使用 JavaScript 配合使用 IE 的 ActiveXObject 調用 Excel 導出數據到 Excel

前提是電腦上安裝了 Office 的 excel 。源碼如下:

<a href="#" onclick="downloaddata_ie('testtable')">IE導出</a>
function downloaddata_ie(tableid) {
        var curTbl = document.getElementById(tableid);
        var oXL = new ActiveXObject("Excel.Application");//創建AX對象excel 
        var oWB = oXL.Workbooks.Add();//獲取workbook對象 
        var oSheet = oWB.ActiveSheet;//激活當前sheet 
        var Lenr = curTbl.rows.length;//取得表格行數 
        for (i = 0; i < Lenr; i++) {
            var Lenc = curTbl.rows(i).cells.length;//取得每行的列數 
            for (j = 0; j < Lenc; j++) {
                oSheet.Cells(i + 1, j + 1).value = curTbl.rows(i).cells(j).innerText;//賦值 
            }
        }
        oXL.Visible = true;//設置excel可見屬性 
    }

或者下面的代碼會自動在 excel 中彈出保存對話框,且使用的非賦值操作而是複製操作:

var idTmr;
function saveAsXlsx(tableid,filename) {// 整個表格拷貝到EXCEL中
    var curTbl = document.getElementById(tableid);
    var oXL = new ActiveXObject("Excel.Application");
    // 創建AX對象excel
    var oWB = oXL.Workbooks.Add();
    // 獲取workbook對象
    var xlsheet = oWB.Worksheets(1);
    // 激活當前sheet
    var sel = document.body.createTextRange();
    sel.moveToElementText(curTbl);
    // 把表格中的內容移到TextRange中
    sel.select();
    // 全選TextRange中內容
    sel.execCommand("Copy");
    // 複製TextRange中內容
    xlsheet.Paste();
    // 粘貼到活動的EXCEL中
    oXL.Visible = true;
    // 設置excel可見屬性

    try {
        var fname = oXL.Application.GetSaveAsFilename(filename+".xlsx",
                "Excel Spreadsheets (*.xlsx), *.xls11");
    } catch (e) {
        print("Nested catch caught " + e);
    } finally {
        oWB.SaveAs(fname);

        oWB.Close(savechanges = false);
        // xls.visible = false;
        oXL.Quit();
        oXL = null;
        // 結束excel進程,退出完成
        // window.setInterval("Cleanup();",1);
        idTmr = window.setInterval("Cleanup();", 1);

    }
}
function Cleanup() {
    window.clearInterval(idTmr);
    CollectGarbage();
}

3、 非 IE 瀏覽器 只能生成 .csv 文件供用戶下載

可以繼續使用 jsp 的方案,也可以使用 web 前端 的解決方案。

web 前端 解決方案 源碼:

<a href="#" download="aaa.csv" onclick="downloaddata_notie(this)">非IE導出</a>
    function downloaddata_notie(aLink) {
        var str = "1,2,3,4,5\n9,8,7,5";//demo數據 
        str = encodeURIComponent(str);//防止亂碼
        aLink.href = "data:text/csv;charset=utf-8,\ufeff" + str; 
        //  “\ufeff” 爲 BOM 頭
        aLink.click();
        return false;
    }

感謝您閱讀到這裏。其實寫這篇文章的時候我還沒有將這個功能實現,代碼都是做的demo。

先寫篇文章記錄下來,不然我真的會忘。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章