1. 程式人生 > >基於MVC4+EasyUI的Web開發框架經驗總結(10)--在Web介面上實現資料的匯入和匯出

基於MVC4+EasyUI的Web開發框架經驗總結(10)--在Web介面上實現資料的匯入和匯出

資料的匯入匯出,在很多系統裡面都比較常見,這個匯入匯出的操作,在Winform裡面比較容易實現,我曾經在之前的一篇文章《Winform開發框架之通用資料匯入匯出操作》介紹了在Winform裡面的通用匯入匯出模組的設計和開發過程,但在Web上我們應該如何實現呢?本文主要介紹利用MVC4+EasyUI的特點,並結合檔案上傳控制元件Uploadify 的使用,實現檔案上傳後馬上進行處理並顯示,然後確認後把資料寫入資料庫的過程。

我們知道,Web上對Excel的處理和Winform的有所差異,如果是在Web上處理,我們需要把Excel文件上傳到伺服器上,然後讀取檔案進行顯示,所以第一步是實現檔案的上傳操作,關於檔案上傳控制元件,具體可以參考我的文章《

基於MVC4+EasyUI的Web開發框架形成之旅--附件上傳元件uploadify的使用》。

1、匯入資料的介面效果展示

在Winform裡面,我們處理Excel資料匯入的介面如下所示。

在Web上的主介面如下所示。

匯入介面如下所示。

2、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處理程式碼如下所示。

        //顯示匯入介面
        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的程式碼如下所示。

        //實現對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);
        }

3、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開發框架經驗總結5--使用HTML編輯控件CKEditorCKFinder

err config 兩個 腳本 web開發 upload asp 正常 初始 http://www.cnblogs.com/wuhuacong/p/3780356.html Web開發上有很多HTML的編輯控件,如CKEditor、kindeditor等等,很多都做的很

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

在預設情況下,EasyUI的DataGrid好像都沒有具備自動寬度的適應功能,一般是指定畫素寬度的,但是使用的人員計算機的螢幕解析度可能不一樣,因此導致有些地方顯示太大或者太小,總是不能達到好的預期效果,如果DataGrid能夠根據視窗尺寸進行伸縮,效果應該好很多。本文主要介紹DataGrid控制元件實現自動

基於MVC4+EasyUI的Web開發框架經驗總結9--在Datagrid裡面實現外來鍵欄位的轉義操作

我們在使用EasyUI的時候,很多情況下需要使用到表格控制元件datagrid,這個控制元件控制元件非常強大,使用起來很簡潔,但是我在使用中,發現對於一個表裡面的外來鍵欄位進行轉義,並顯示引用表的一些名稱的操作,卻顯得比較難以實現,找了很多資料,基本上沒有找到對應的解決方案。本文主要介紹我對這種外來鍵欄位轉義

基於MVC4+EasyUI的Web開發框架經驗總結5--使用HTML編輯控制元件CKEditorCKFinder

Web開發上有很多HTML的編輯控制元件,如CKEditor、kindeditor等等,很多都做的很好,本文主要介紹在MVC介面裡面,CKEditor的配置和使用。CKEditor的前身是FCKEditor,隨著它的更新,上傳圖片的功能被分離出去了,現在如果需要實現上傳圖片,要麼自己寫程式碼或者採用其他上傳控

基於MVC4+EasyUI的Web開發框架經驗總結10--在Web介面實現資料匯入匯出

資料的匯入匯出,在很多系統裡面都比較常見,這個匯入匯出的操作,在Winform裡面比較容易實現,我曾經在之前的一篇文章《Winform開發框架之通用資料匯入匯出操作》介紹了在Winform裡面的通用匯入匯出模組的設計和開發過程,但在Web上我們應該如何實現呢?本文主要介紹利用MVC4+EasyUI的特點,並結

基於Metronic的Bootstrap開發框架經驗總結5--Bootstrap檔案傳外掛File Input的使用

Bootstrap檔案上傳外掛File Input是一個不錯的檔案上傳控制元件,但是搜尋使用到的案例不多,使用的時候,也是一步一個腳印一樣摸著石頭過河,這個控制元件在介面呈現上,叫我之前使用過的Uploadify 好看一些,功能也強大些,本文主要基於我自己的框架程式碼案例,介紹其中檔案上傳外掛File Inp

基於Metronic的Bootstrap開發框架經驗總結10--優化Bootstrap圖示管理

在基於Bootstrap開發的專案中,鮮豔顏色的按鈕,以及豐富的圖表是很吸引人的特點,為了將這個特點發揮到極致,可以利用Bootstrap圖示抽取到資料庫裡面,並在介面中進行管理和使用,這樣我們可以把這些圖示方便應用在各個頁面部件上,如選單模組,按鈕介面,表單輸入等多個場合進行使用。在前面隨筆《基於Metro

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

set 應用 get ember trim ase str zab ble http://www.cnblogs.com/wuhuacong/p/3669575.html 最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在用戶體驗和界面設計方面,和Winfor

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

ica new web開發 don ext images 如果 bob 獲取 http://www.cnblogs.com/wuhuacong/p/3840321.html 在很多Web界面中,我們都可以看到很多下拉列表的元素,有些是固定的,有些是動態的;有些是字典內容,

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

討論 off info code .cn viewer 存在 nco app http://www.cnblogs.com/wuhuacong/p/3871991.html 基於MVC4+EasyUI的Web開發框架經驗總結(8)--實現Office文檔的預覽

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

最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在使用者體驗和介面設計方面,和Winform開發框架保持一致,而在Web上,我主要採用EasyUI的前端介面處理技術,走MVC的技術路線,在重構完善過程中,很多細節花費不少時間進行研究和提煉,一步步走過來,也積累了不

基於MVC4+EasyUI的Web開發框架經驗總結3- 使用Json實體類構建選單資料

最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在使用者體驗和介面設計方面,和Winform開發框架保持一致,而在Web上,我主要採用EasyUI的前端介面處理技術,走MVC的技術路線,在重構完善過程中,很多細節花費不少時間進行研究和提煉,一步步走過來,也積累了不少經驗,本系列將主要介紹我在進一步

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

在我們做各種應用的時候,我們可能都會使用到圖表統計,以前接觸過一些不同的圖表控制元件,在無意中發現了圖表控制元件Highcharts,其強大的功能和豐富的互動效果,令人難以忘懷。本篇主要介紹在Web開發中使用圖表控制元件Highcharts,以及對其進行統一漢化等操作,讓我們的程式功能更加豐富,內容更加美觀。

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

最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在使用者體驗和介面設計方面,和Winform開發框架保持一致,而在Web上,我主要採用EasyUI的前端介面處理技術,走MVC的技術路線,在重構完善過程中,很多細節花費不少時間進行研究和提煉,一步步走過來,也積累了不少經驗,本系列將主要介紹我在進一步

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

為了提高客戶體驗和進行一些技術探索,現在正準備把我自己的客戶關係管理系統CRM在做一個Web的版本,因此對基於MVC的Web介面繼續進行一些研究和優化,力求在功能和介面上保持和Winform一致,本文主要介紹在我的CRM系統中用到的全國省份、城市、行政區三者的兩種效果,在Winform上實現沒問題,在Web上

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

在很多Web介面中,我們都可以看到很多下拉列表的元素,有些是固定的,有些是動態的;有些是字典內容,有些是其他表裡面的名稱欄位;有時候引用的是外來鍵ID,有時候引用的是名稱文字內容;正確快速使用下拉列表的處理,可以提高我們程式介面的美觀性和友好型,本文主要介紹在我的Web開發框架以及相關的擴充套件Web應用中用

基於MVC4+EasyUI的Web開發框架經驗總結14--自動生成圖示樣式檔案圖示的選擇操作

在很多Web系統中,一般都可能提供一些圖示的選擇,方便配置按鈕,選單等介面元素的圖示,從而是Web系統介面看起來更加美觀和協調。但是在系統中一般內建的圖示樣式相對比較有限,而且硬編碼寫到樣式表裡面,這樣給我們擴充套件使用有很多的不方便。基於這個原因,我想如果能夠獨立一個模組,自動根據圖示生成圖示CSS樣式檔案

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

在Web開發的時候,我們很多時候,需要引用很多CSS檔案、JS檔案,隨著使用更多的外掛或者獨立樣式檔案,可能我們的Web介面程式碼會越來越臃腫,看起來也很累贅,在MVC裡面提供了一個Bundle的物件,用來簡化頁面程式碼非常方便,本文主要介紹在我的MVC框架裡面,如何使用bundles來簡化頁面的程式碼的。

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

在部落格園很多文章裡面,曾經有一些介紹Office文件預覽檢視操作的,有些通過轉為PDF進行檢視,有些通過把它轉換為Flash進行檢視,但是過程都是曲線救國,真正能夠簡潔方便的實現Office文件的預覽的還是比較少,這裡的Office文件包括了Word、Excel、PPT文件。本文介紹兩種方式,一種方式是通過

基於MVC4+EasyUI的Web開發框架經驗總結12--利用Jquery處理資料互動的幾種方式

在基於MVC4+EasyUI的Web開發框架裡面,大量採用了Jquery的方法,對資料進行請求或者提交,方便頁面和伺服器後端進行資料的互動處理。本文主要介紹利用Jquery處理資料互動的幾種方式,包括獲取資料並顯示,插入新資料到伺服器,更新資料,刪除資料等操作。 1、利用Jquery獲取資料並顯示 為了順