ASP.NET MVC导出excel(数据量大,非常耗时的,异步导出)
要在ASP.NET MVC站點上做excel導出功能,但是要導出的excel文件比較大,有幾十M,所以導出比較費時,為了不影響對界面的其它操作,我就采用異步的方式,后臺開辟一個線程將excel導出到指定目錄,然后提供下載。導出的excel涉及到了多個sheet(工作簿),表格合并,格式設置等,所以采用了NPOI組件。
效果如下:
選中了多行,會導出多個工作簿sheet,一個匯總的,其他的就是明細數據。
下面是要幾個封裝好的類,從網上找的,然后修改了一下。這幾個類很多方法都封裝好了,十分利于復用。常見的excel格式都可以導出,如果有特別的需求,可以自己修改一下源碼進行擴展。
GenerateSheet.cs
?View CodeGenerateExcel.cs
?View CodeColumnsMapping.cs
?View CodeBaseGenerateSheet.cs
?View Code以下這兩個類,是我根據上面幾個基礎類自定義的一個導出類,基本上就配置一下表頭,然后設置下正文表格樣式。(哎呀,這個類代碼我拷貝錯了,不過使用方式基本類似,改天我修改下)
IdentityCardMonthPayOffSheet.cs
?View CodeIdentityCardMonthPayDetailSheet.cs
?View CodeIdentityCardMonthPay.cs
?View Code #region 導出身份證月結表/// <summary>/// 導出月結表/// </summary>/// <param name="filter"></param>/// <returns></returns>public JsonResult ExportExcelIdentityCard(IdentityCardMonthPayFilter filter, string payOffMonthlist){string excelPath = this.Server.MapPath(string.Format(IdentityCardExcelDir + "身份證月結表_{0}.xlsx",DateTime.Now.ToString("yyyyMMddHHmmss")));MvcApplication._QueueIdentityCard.Enqueue(new IdentityCardMonthPayPara { ExcelPath = excelPath, Filter = filter,
PayOffMonthlist = payOffMonthlist });//MvcApplication.OutputIdentityCardExcel();var result = new { IsSuccess = true, Message = "成功" };return Json(result);}/// <summary>/// 已生成的月結表列表/// </summary>/// <returns></returns>public ActionResult LoadIdentityCardExcelList(){string myDir = Server.MapPath("~"+IdentityCardExcelDir);if (Directory.Exists(myDir) == false)//如果不存在就創建file文件夾 {Directory.CreateDirectory(myDir);}DirectoryInfo dirInfo = new DirectoryInfo(myDir);List<LinkEntity> list = LinkEntityExt.ForFileLength(dirInfo, IdentityCardExcelDir);return View("LoadExcelList", list);} #endregion
Global.asax.cs,在應用程序啟動時,監聽隊列,如果隊列里面有數據,則進行導出操作,這樣的話,即使操作人員離開了當前頁面,也不影響生產excel操作。而且使用隊列,可以防止并發產生的問題。
public static Queue<IdentityCardMonthPayPara> _QueueIdentityCard = new Queue<IdentityCardMonthPayPara>();protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
//BundleTable.EnableOptimizations = true;
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
RegisterContainer(ProjectBase.Data.IocContainer.Instance.Container);
log4net.Config.XmlConfigurator.Configure();
OutputIdentityCardExcel(); //這里進行注冊
}
/// <summary>/// 導出身份證月結表excel列表/// </summary>public static void OutputIdentityCardExcel(){IdentityCardMonthPayPara model = null;ThreadPool.QueueUserWorkItem(o =>{while (true){if (_QueueIdentityCard != null && _QueueIdentityCard.Count > 0){model = _QueueIdentityCard.Dequeue();if (model != null){IdentityCardMonthPay.ExportExcel(model.ExcelPath, model.Filter, model.PayOffMonthlist);}else{Thread.Sleep(6000);}}else{Thread.Sleep(6000);}}});}
?實時導出
實時導出有好幾種方式,我這里采用FileResult?來進行導出,使用FileResult導出要求服務器上面必須存在excel文件。在這里,如果沒有選中任何行,我就導出查詢到的所有數據,否則導出選中行的數據,由于數據不是很多,就采用實時導出的方式。
前臺js代碼:
//導出Excel function exportExcel(table) {var nTrs = table.fnGetNodes();//fnGetNodes獲取表格所有行,nTrs[i]表示第i行tr對象var row;var strdid = '';var selectCounts = 0;for (var i = 0; i < nTrs.length; i++) {if ($(nTrs[i])[0].cells[0].children[0].checked) {row = table.fnGetData(nTrs[i]);//fnGetData獲取一行的數據 selectCounts++;strdid += "" + row.ID + ",";}}strdid = strdid.length > 0 ? strdid.substring(0, strdid.length - 1) : strdid;if (selectCounts < 1) { //按照查詢結果進行導出window.location.href = '@Url.Action("ExportExcelByFilter", "Reconciliation")?' + "CusShortName=" + $("#CusShortName").val() +"&&LoadBillNum=" + $("#LoadBillNum").val() +"&&PostingTime=" + $("#PostingTime").val() + "&&PostingTimeTo=" + $("PostingTimeTo").val() +"&&ExceptionType="+$("#ExceptionType").val();}else { //導出選中行//window.location.href = '@Url.Action("ExportExcelBySelect", "Reconciliation")?' + "ListID=" + strdid; 地址欄太長會超出$.post('@Url.Action("ExportExcelBySelect", "Reconciliation")', { "ListID": strdid }, function (data) {window.location.href = data;});}}
控制器代碼
/// <summary>/// 導出選中的異常記錄/// </summary>/// <param name="ListID"></param>/// <returns></returns>public JsonResult ExportExcelBySelect(string ListID){string url = "/Downloads/WayBillException/運單異常記錄.xls";string excelUrl = Server.MapPath("~" + url);Core.Reconciliation.WayBillException.ExportExcel(excelUrl, ListID);return Json(url);}/// <summary>/// 導出查詢的異常記錄/// </summary>/// <param name="filter"></param>/// <returns></returns>public FileResult ExportExcelByFilter(WayBillExceptionFilter filter){filter.PageSize = int.MaxValue;string excelUrl = Server.MapPath("~/Downloads/WayBillException/運單異常記錄.xls");Core.Reconciliation.WayBillException.ExportExcel(filter,excelUrl);return File(excelUrl, "application/ms-excel", "運單異常記錄.xls");}?工作太忙了,無暇整理,還望見諒!以后抽空慢慢完善!至于園友提到完整Demo,這個比較費時,以后我會整理一個。涉及的東西比較多,諸如:Nhibernate3.3代碼映射、unity注入、倉儲模式、多層架構等等。之前有寫過前篇的一個系列,只是側重于UI和控制器交互這一塊,有興趣的朋友可以去瞧一下。地址:ASP.NET MVC搭建項目后臺UI框架—1、后臺主框架
本文轉自鄒瓊俊博客園博客,原文鏈接:http://www.cnblogs.com/jiekzou/p/4766701.html,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的ASP.NET MVC导出excel(数据量大,非常耗时的,异步导出)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2星|《深度模仿》:陷入锤子模式,案例太
- 下一篇: textmate开发一个blog