ASP.NET MVC导出excel(数据量大,非常耗时的,异步导出)

简介:

要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指定目录,然后提供下载。导出的excel涉及到了多个sheet(工作簿),表格合并,格式设置等,所以采用了NPOI组件。

效果如下:

选中了多行,会导出多个工作簿sheet,一个汇总的,其他的就是明细数据。

下面是要几个封装好的类,从网上找的,然后修改了一下。这几个类很多方法都封装好了,十分利于复用。常见的excel格式都可以导出,如果有特别的需求,可以自己修改一下源码进行扩展。

GenerateSheet.cs

  View Code

GenerateExcel.cs

  View Code

ColumnsMapping.cs

  View Code

BaseGenerateSheet.cs

  View Code

以下这两个类,是我根据上面几个基础类自定义的一个导出类,基本上就配置一下表头,然后设置下正文表格样式。(哎呀,这个类代码我拷贝错了,不过使用方式基本类似,改天我修改下)

IdentityCardMonthPayOffSheet.cs

  View Code

IdentityCardMonthPayDetailSheet.cs

  View Code

IdentityCardMonthPay.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,如需转载请自行联系原作者

相关文章
|
5月前
|
开发框架 算法 .NET
一个简单高效低内存的.NET操作Excel开源框架 - MiniExcel
一个简单高效低内存的.NET操作Excel开源框架 - MiniExcel
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
38 0
|
1月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
95 5
|
8月前
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
114 0
|
9月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
67 0
|
9月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
113 0
|
9月前
|
SQL 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)
[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)
144 0
|
9月前
|
开发框架 缓存 JSON
ASP.NET Core MVC 从入门到精通之Filter
ASP.NET Core MVC 从入门到精通之Filter
120 0
|
5月前
|
缓存 开发框架 算法
.NET操作Excel高效低内存的开源框架 - MiniExcel
.NET操作Excel高效低内存的开源框架 - MiniExcel
53 0
.NET操作Excel高效低内存的开源框架 - MiniExcel
|
5月前
|
开发框架 自然语言处理 前端开发
基于ASP.NET MVC开发的、开源的个人博客系统
基于ASP.NET MVC开发的、开源的个人博客系统
51 0