• ASP.NET MVC导出excel


    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

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

    WayBillExceptionSheet.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、后台主框架

    感触:工作中项目里通常使用了一种或几种框架,而每一种框架都是一系列设计模式的集合,想要一下子全部说明白,真的需要时间,有些东西更是难以用文字表述,只能自己慢慢领悟。

     

  • 相关阅读:
    DIJ最短路
    快速输入/输出
    Codeforces Round #610 (Div. 2).K for the Price of One (Hard Version)
    Codeforces Round #625 (Div. 1, based on Technocup 2020 Final Round).B. Navigation System
    Codeforces Round #612 (Div. 2)C. Garland
    Codeforces Round #621 (Div. 1 + Div. 2).D. Cow and Fields
    73.Python中ORM聚合函数详解:Count
    72.Python中ORM聚合函数详解:Avg,aggregate,annotate
    17. Getting to the essence of things
    55.ORM外键:引用同app下的不同模型,引用不同app下的模型,引用模型自身使用详解
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4769826.html
Copyright © 2020-2023  润新知