數據的導入導出,在不少系統裏面都比較常見,這個導入導出的操做,在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上的數據導入導出操做,咱們須要增長兩個按鈕,一個是導入按鈕,一個是導出按鈕。數據庫
<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); }
剛纔介紹了數據的導入操做,數據的導出操做相對簡單一些,它的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開發框架造成之旅--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處理數據交互的幾種方式