基於MVC4+EasyUI的Web開發框架經驗總結(10)--在Web界面上實現數據的導入和導出

數據的導入導出,在不少系統裏面都比較常見,這個導入導出的操做,在Winform裏面比較容易實現,我曾經在以前的一篇文章《Winform開發框架之通用數據導入導出操做》介紹了在Winform裏面的通用導入導出模塊的設計和開發過程,但在Web上咱們應該如何實現呢?本文主要介紹利用MVC4+EasyUI的特色,並結合文件上傳控件Uploadify 的使用,實現文件上傳後立刻進行處理並顯示,而後確認後把數據寫入數據庫的過程。javascript

咱們知道,Web上對Excel的處理和Winform的有所差別,若是是在Web上處理,咱們須要把Excel文檔上傳到服務器上,而後讀取文件進行顯示,因此第一步是實現文件的上傳操做,關於文件上傳控件,具體能夠參考個人文章《基於MVC4+EasyUI的Web開發框架造成之旅--附件上傳組件uploadify的使用》。html

一、導入數據的界面效果展現

在Winform裏面,咱們處理Excel數據導入的界面以下所示。java

在Web上的主界面以下所示。node

導入界面以下所示。ajax

 

二、Web數據導入的處理邏輯和代碼

爲了實現Web上的數據導入導出操做,咱們須要增長兩個按鈕,一個是導入按鈕,一個是導出按鈕。數據庫

 <a href="javascript:void(0)" class="easyui-linkbutton" id="btnImport" iconcls="icon-excel" onclick="ShowImport()">導入</a>
 <a href="javascript:void(0)" class="easyui-linkbutton" id="btnExport" iconcls="icon-excel" onclick="ShowExport()">導出</a>

導入的JS處理代碼以下所示。json

        //顯示導入界面
        function ShowImport() {
            $.showWindow({
                title: '客戶聯繫人-Excel數據導入',
                useiframe: true,
                width: 1024,
                height: 700,
                content: 'url:/Contact/Import',
                buttons: [{
                    text: '取消',
                    iconCls: 'icon-cancel',
                    handler: function (win) {
                        win.close();
                    }
                }]
            });
        }

上面主要就是彈出一個窗口(上面的導入數據窗口),用來方便客戶選擇Excel文件並保存數據或者下載導入模板等操做的。服務器

而後在Import.cshtml的視圖代碼裏面,咱們須要初始化Datagrid和相關的界面元素,初始化DataGrid的代碼以下所示。app

        //實現對DataGird控件的綁定操做
        function InitGrid() {
            var guid = $("#AttachGUID").val();
            $('#grid').datagrid({   //定位到Table標籤,Table標籤的ID是grid
                url: '/Contact/GetExcelData?guid=' + guid,   //指向後臺的Action來獲取當前用戶的信息的Json格式的數據
                title: '客戶聯繫人-Excel數據導入',
                iconCls: 'icon-view',
                height: 400,
                width: function () { return document.body.clientWidth * 0.9 },//自動寬度

                ..................

上面紅色部分的內容,就是咱們在文件順利上傳到服務器上的時候,根據一個guid的參數初始化DataGrid的列表數據。框架

下面是附件上傳控件uploadify的初始化腳本代碼,其中紅色部分注意一下,咱們須要上傳的是一個文件,而且不容許多選,限定上傳文件的類型爲xls。

文件上傳完成後,首先調用CheckExcelColumns控制器函數來檢查是否匹配導入模板的字段,若是匹配經過,加載Excel並展現數據到Datagrid裏面,不然提示用戶按模板格式錄入數據。

    <script type="text/javascript">
        $(function () {
            //添加界面的附件管理
            $('#file_upload').uploadify({
                'swf': '/Content/JQueryTools/uploadify/uploadify.swf',  //FLash文件路徑
                'buttonText': '瀏  覽',                                 //按鈕文本
                'uploader': '/FileUpload/Upload',                       //處理ASHX頁面
                'queueID': 'fileQueue',                        //隊列的ID
                'queueSizeLimit': 1,                          //隊列最多可上傳文件數量,默認爲999
                'auto': false,                                 //選擇文件後是否自動上傳,默認爲true
                'multi': false,                                 //是否爲多選,默認爲true
                'removeCompleted': true,                       //是否完成後移除序列,默認爲true
                'fileSizeLimit': '10MB',                       //單個文件大小,0爲無限制,可接受KB,MB,GB等單位的字符串值
                'fileTypeDesc': 'Excel Files',                 //文件描述
                'fileTypeExts': '*.xls',  //上傳的文件後綴過濾器
                'onQueueComplete': function (event, data) {    //全部隊列完成後事件
                    var guid = $("#AttachGUID").val();
                    ViewUpFiles(guid, "div_files");

                    //提示用戶Excel格式是否正常,若是正常加載數據
                    $.ajax({
                        url: '/Contact/CheckExcelColumns?guid=' + guid,
                        type: 'get',
                        dataType:'json',
                        success: function (data) {
                            if (data.Success) {                                
                                InitGrid(); //從新刷新表格數據
                                $.messager.alert("提示", "文件已上傳,數據加載完畢!");
                            }
                            else {
                                $.messager.alert("提示", "上傳的Excel文件檢查不經過。請根據頁面右上角的Excel模板格式進行數據錄入。");
                            }
                        }
                    });                    
                },
                'onUploadStart': function (file) {
                    InitUpFile();//上傳文件前 ,重置GUID,每次不一樣
                    $("#file_upload").uploadify("settings", 'formData', { 'folder': '數據導入文件', 'guid': $("#AttachGUID").val() }); //動態傳參數
                },
                'onUploadError': function (event, queueId, fileObj, errorObj) {
                    //alert(errorObj.type + ":" + errorObj.info);
                }
            });
        });

 

爲了有效處理數據的導入,咱們須要嚴格保證導入的數據是和模板的字段是匹配的,不然處理容易出錯,也沒有任何意義。爲了實現這個目的,框架裏面提供方法對字段進行檢查,主要是確保Excel裏面包含了完整的字段便可。

        /// <summary>
        /// 檢查Excel文件的字段是否包含了必須的字段
        /// </summary>
        /// <param name="guid">附件的GUID</param>
        /// <returns></returns>
        public ActionResult CheckExcelColumns(string guid)
        {
            CommonResult result = new CommonResult();

            try
            {
                DataTable dt = ConvertExcelFileToTable(guid);
                if (dt != null)
                {
                    //檢查列表是否包含必須的字段
                    result.Success = DataTableHelper.ContainAllColumns(dt, columnString);
                }
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                result.ErrorMessage = ex.Message;
            }

            return ToJsonContent(result);
        }

 

而在InitGrid的初始化中的這個GetExcelData的控制器方法以下所示。主要的邏輯就是獲取到Excel,並把Excel裏面的數據轉換爲DataTable,最後初始化爲實體類列表,並返回給調用頁面就能夠了。

       /// <summary>
        /// 獲取服務器上的Excel文件,並把它轉換爲實體列表返回給客戶端
        /// </summary>
        /// <param name="guid">附件的GUID</param>
        /// <returns></returns>
        public ActionResult GetExcelData(string guid)
        {
            if (string.IsNullOrEmpty(guid))
            {
                return null;
            }

            List<ContactInfo> list = new List<ContactInfo>();
            DataTable table = ConvertExcelFileToTable(guid);
            if (table != null)
            {
                #region 數據轉換
                int i = 1;
                foreach (DataRow dr in table.Rows)
                {
                    string customerName = dr["客戶名稱"].ToString();
                    if (string.IsNullOrEmpty(customerName))
                    {
                        continue;//客戶名稱爲空,記錄跳過
                    }

                    CustomerInfo customerInfo = BLLFactory<Customer>.Instance.FindByName(customerName);
                    if (customerInfo == null)
                    {
                        continue;//客戶名稱不存在,記錄跳過
                    }

                    ContactInfo info = new ContactInfo();
                    info.Customer_ID = customerInfo.ID;//客戶ID
                    info.HandNo = dr["編號"].ToString();
                    info.Name = dr["姓名"].ToString();
                     ..............................//增長一個特殊字段的轉義
                    info.Data1 = BLLFactory<Customer>.Instance.GetCustomerName(info.Customer_ID);

                    list.Add(info);
                }
                #endregion
            }
            var result = new { total = list.Count, rows = list };
            return JsonDate(result);
        }

 

三、Web上數據的導出操做 

剛纔介紹了數據的導入操做,數據的導出操做相對簡單一些,它的JS函數操做以下所示。

        //導出Excel數據
        var exportCondition;
        function ShowExport() {
            var url = "/Contact/Export";
            $.ajax({
                type: "POST",
                url: url,
                data: exportCondition,
                success: function (filePath) {
                    var downUrl = '/FileUpload/DownloadFile?file=' + filePath;
                    window.location = downUrl;
                }
            });
        }

雖然數據的導出比較簡單一點,可是因爲咱們須要使用POST方式對數據條件進行提交,所以不像普通的方式下載文件Window.Open(url)就能夠實現文件下載了。若是POST方式提交了參數,那麼返回的數據即便是文件流,也沒法進行有效的下載。

從上面的腳本咱們能夠看到,裏面的exportCondition就是咱們須要提交到服務器的條件,服務器根據這個條件進行檢索數據,並返回一個Excel文件就能夠了。

因爲使用ajax這種POST方式沒法直接下載文件流,所以,咱們須要先根據條件,在服務器上生成文件,返回一個文件路徑,再次經過DownloadFile方法進行文件的下載才能夠。

所以這個傳遞的條件也是很重要的,在查詢操做的時候,咱們能夠把對應的條件傳遞給它。

        //綁定搜索按鈕的的點擊事件
        function BindSearchEvent() {
            //按條件進行查詢數據,首先咱們獲得數據的值
            $("#btnSearch").click(function () {
                //獲得用戶輸入的參數
                //取值有幾種方式:$("#id").combobox('getValue'), $("#id").datebox('getValue'), $("#id").val(),combotree('getValue')
                //字段增長WHC_前綴字符,避免傳遞如URL這樣的Request關鍵字衝突
                var queryData = {
                     WHC_Name: $("#txtName").val(),
                     WHC_OfficePhone: $("#txtOfficePhone").val(),
                     WHC_Mobile: $("#txtMobile").val(),
                     WHC_Address: $("#txtAddress").val(),
                     WHC_Email: $("#txtEmail").val(),
                     WHC_Note: $("#txtNote").val()
                  }
                //將值傳遞給DataGrid
                InitGrid(queryData);

                //傳遞給導出操做
 exportCondition = queryData; return false;
            });
        }

在咱們選定某個樹的節點的時候,咱們也能夠傳遞自定義的條件給它。

        //根據消息分組加載指定列表
        function loadByGroupTree(node) {
            //賦值給特殊字段,公司和部門查詢的時候選擇其中一個
            var queryParams = $('#grid').datagrid('options').queryParams;
            var condition = "{ id: \"" + node.id +"\", groupname:\"" + node.text +"\", userid:\"" + @Session["UserId"] + "\" }";
            queryParams.CustomedCondition = condition;//提供給datagrid的條件
 exportCondition = { CustomedCondition: condition };//提供給導出的條件

            $("#grid").datagrid("reload");
            $('#grid').datagrid('uncheckAll');
        }

後臺的Export控制器方法主要的邏輯以下所示。

最終是返回一個生成好的文件地址。

最後給一個方法直接下載文件就能夠了。

        /// <summary>
        /// 根據路徑下載文件,主要用於生成的文件的下載
        /// </summary>
        /// <param name="filePath">文件路徑</param>
        /// <returns></returns>
        public ActionResult DownloadFile(string file)
        {
            string realPath = Server.MapPath(file);
            string saveFileName = FileUtil.GetFileName(realPath);

            Response.WriteFile(realPath);
            Response.Charset = "GB2312";
            Response.ContentEncoding = Encoding.GetEncoding("GB2312");
            Response.ContentType = "application/ms-excel/msword";
            Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(saveFileName));
            Response.Flush();
            Response.End();

            return new FileStreamResult(Response.OutputStream, "application/ms-excel/msword");
        }

導出的Excel界面效果以下所示。

因爲篇幅的緣由,這個導入導出的操做就介紹到這裏,但願有問題你們共同探討。

 

基於MVC4+EasyUI的Web開發框架的系列文章:

基於MVC4+EasyUI的Web開發框架造成之旅--整體介紹

基於MVC4+EasyUI的Web開發框架造成之旅--MVC控制器的設計

基於MVC4+EasyUI的Web開發框架造成之旅--界面控件的使用

基於MVC4+EasyUI的Web開發框架造成之旅--附件上傳組件uploadify的使用

基於MVC4+EasyUI的Web開發框架造成之旅--框架整體界面介紹

基於MVC4+EasyUI的Web開發框架造成之旅--基類控制器CRUD的操做

基於MVC4+EasyUI的Web開發框架造成之旅--權限控制

基於MVC4+EasyUI的Web開發框架經驗總結(1)-利用jQuery Tags Input 插件顯示選擇記錄

基於MVC4+EasyUI的Web開發框架經驗總結(2)- 使用EasyUI的樹控件構建Web界面

基於MVC4+EasyUI的Web開發框架經驗總結(3)- 使用Json實體類構建菜單數據

基於MVC4+EasyUI的Web開發框架經驗總結(4)--使用圖表控件Highcharts

基於MVC4+EasyUI的Web開發框架經驗總結(5)--使用HTML編輯控件CKEditor和CKFinder

基於MVC4+EasyUI的Web開發框架經驗總結(6)--在頁面中應用下拉列表的處理

基於MVC4+EasyUI的Web開發框架經驗總結(7)--實現省份、城市、行政區三者聯動

基於MVC4+EasyUI的Web開發框架經驗總結(8)--實現Office文檔的預覽

基於MVC4+EasyUI的Web開發框架經驗總結(9)--在Datagrid裏面實現外鍵字段的轉義操做

基於MVC4+EasyUI的Web開發框架經驗總結(10)--在Web界面上實現數據的導入和導出

基於MVC4+EasyUI的Web開發框架經驗總結(11)--使用Bundles處理簡化頁面代碼

基於MVC4+EasyUI的Web開發框架經驗總結(12)--利用Jquery處理數據交互的幾種方式

基於MVC4+EasyUI的Web開發框架經驗總結(13)--DataGrid控件實現自動適應寬帶高度

基於MVC4+EasyUI的Web開發框架經驗總結(14)--自動生成圖標樣式文件和圖標的選擇操做

相關文章
相關標籤/搜索