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

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

  1. java导出excel数据量大_解决大批量Excel导出OOM问题

    1.背景介绍:最近一直被OOM问题缠绕,原因是表单下载功能访问量比较大,数据量相当多,表单数据存储在mongodb,数据总量2亿多,每个实例总内存限制1.5G左右,线上部署了5个实例,但是最大承受时间 ...

  2. Winform中导出Excel数据量百万级的处理办法-导出为csv文件

    场景 Winform中通过NPOI导出Excel的三种方式(HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook)附代码下载: https://blog.csdn.net/B ...

  3. java dubbo服务导出excel数据量过大解决方案

    场景 公司项目有个以前的程序猿写的订单导出excel功能,后台管理界面先查询要导出的数据,然后点击导出按钮进行导出,原来的实现就是界面吧查询条件传到admim模块,admin通过dubbo远程调用or ...

  4. Navicat导出excel数据量过大解决方案

    Excel一张Sheet最多只能达到1048575行,在网上查询了一大堆都没能找到解决方法,其实解决这个问题很简单,换个导出格式导出即可(txt.csv) 注1:txt.csv理论上是可以无限存储的: ...

  5. 【译】Asp.Net 导出 Excel 数据的9种方案

    简介 Excel 的强大之处在于它不仅仅只能打开Excel格式的文档,它还能打开CSV格式.Tab格式.website table 等多钟格式的文档.它具备自动识别行号,字符,格式化数字等功能,例如: ...

  6. Matlab曲线图导出eps数据量太大占用很多存储空间

    Matlab曲线图导出eps数据量太大占用很多存储空间 我的Figure是从simulink里的scope里导出的,因为是采样率很高的时域波形,所以数据量很大.从Figure里导出eps向量格式的话, ...

  7. php导出excel数据使用csv替代xls格式

    为什么80%的码农都做不了架构师?>>>    php导出excel数据使用csv替代xls格式 一直以来需要将某些后台数据导出来以供运营人员查看,因为他们都用excel.所以最初的 ...

  8. 自定义注解导出excel数据

    自定义注解导出excel数据 利用自定义注解方式,对数据列表进行简单的导出操作.即在实体对象的属性域上添加导出标识的注解,在对实体进行导出时,利用自定义注解进行反射的方法,获取实体需要导出的属性及值. ...

  9. mysql给数据量大的表添加索引的办法

    有一个问题,一张表有3百万条记录,随着时间的增加,记录量会更多,此时查询速度很慢.在创建此表前没有未相应字段添加索引,所以此时需要为表添加索引.但是因为数据量大的原因,索引添加不成功,想了很多办法,终 ...

  10. 谷歌浏览器Chrome,TableExport.js 导出时数据量过大报网络错误的问题

    谷歌浏览器Chrome,TableExport.js 导出时数据量过大报网络错误的问题 之前项目里面遇到一个问题,谷歌浏览器下,数据量过大时报网络错误,下载失败,弄了很久都没找到解决的方法,偶然翻到一 ...

最新文章

  1. Linux系统轻量级监控工具monitorix和munin安装
  2. [na]tcpdump非常实用的抓包实例
  3. wordpress搭建个人博客
  4. MFC 单文档的全局变量
  5. (*长期更新)软考网络工程师学习笔记——Section 9 应用层
  6. [深度学习] 分布式Horovod介绍(四)
  7. akka的介绍_Akka笔记–演员介绍
  8. 在 idea 中为类和方法自动生成注释
  9. matlab 径向偏振光,径向偏振光的产生与应用..docx
  10. Redis进阶不得不了解的内存优化细节
  11. vs2010和matlab混合编程,VS2010与Matlab2010b混合编程
  12. Typora软件百度网盘下载地址
  13. admin.php生成地址,FastAdmin隐藏后台登录入口地址的方法
  14. win10开机一直转圈圈进不去系统怎么办
  15. 哈哈~ 开心死了 厚厚
  16. Python+Vue计算机毕业设计社团管理系统7qls9(源码+程序+LW+部署)
  17. 操作系统-思维导图整理
  18. 前端JS表格打印和导出
  19. JAVA程序员BUG集锦
  20. Java对身份证信息打码隐藏

热门文章

  1. UnicodeEncodeError: 'UCS-2' codec can't encode characters in position 8-8: Non-BMP character not sup
  2. Vue实现仿音乐播放器5-实现今日推荐访问百度音乐API获取数据
  3. mysql的show profile使用总结
  4. 需求用例分析之备选流
  5. 如何在 Flutter 和 Dart 中检查数字字符串
  6. 海史密斯适应型领导力
  7. python中的引用类型_Python 中的引用和类属性的初步理解
  8. java与jquery的选择器区别_JQuery选择器
  9. 你真的会写留言功能吗?
  10. C# winfrom 通过代码 删除TableLayoutPanel控件的一行或列