zoukankan      html  css  js  c++  java
  • MVC导出数据到EXCEL新方法:将视图或分部视图转换为HTML后再直接返回FileResult

    导出EXCEL方法总结

    MVC导出数据到EXCEL的方法有很多种,常见的是:

    1.采用EXCEL COM组件来动态生成XLS文件并保存到服务器上,然后转到该文件存放路径即可;

    优点:可设置丰富的EXCEL格式,缺点:需要依赖EXCEL组件,且EXCEL进程在服务器中无法及时关闭,以及服务器上会存留大量的不必要的XLS文件;

    2.设置输出头为:application/ms-excel,再输出拼接的HTML TABLE数据;

    优点:无需组件,可设置一些简单的格式,缺点:拼接HTML TABLE过程较复杂,不够直观;

    3.借助第三方组件(如:NPOI)

    优点及缺点均依赖于第三方组件的易用性上面,在此不作说明;

    大家也可以看我之前发表的一篇博文:我写的一个ExcelHelper通用类,可用于读取或生成数据

    实现在MVC下新的导出EXCEL方法

    这里给大家分享一个在MVC下的新方法:将视图或分部视图转换为HTML后再直接返回FileResult即可轻松实现导出EXCEL功能,下面直接上代码。

    首先看一下分部视图(IndexDataList)的内容:

    @model IEnumerable<CCPS.Models.Data.CustomerCommentInfo>
    @using PagedList.Mvc;
    
    <table>
        <thead>
            <tr>
                <th>意见ID</th>
                <th>组 织</th>
                <th>车牌</th>
                <th>车型</th>
                <th>皇家版</th>
                <th>客户</th>
                <th>客户电话</th>
                <th>责任部门</th>
                <th>责任班组</th>
                <th>业务顾问</th>
                <th>意见类型</th>
                <th>状态</th>
                <th>录入员</th>
                <th>录入时间</th>
            </tr>
        </thead>
        <tbody id="list-table-body">
            @foreach (var item in Model)
            {
                string className = "";
                if (item.Status == "已审核未处理")
                {
                    className = "uncl_yellow";
                    if (item.AuditDatetime != null && DateTime.Now > ((DateTime)item.AuditDatetime).AddHours(24))
                    {
                        className = "uncl_red";
                    }
                }
                <tr class="@className" data-adt="@item.AuditDatetime">
                    <td><a href="http://oa.pfcn.com/flow/fl_ui_main.aspx?ID=@item.Id&flow_id=147" target="_blank">@item.Id</a></td>
                    <td>@item.OrgName</td>
                    <td>@item.PlateNo</td>
                    <td>@item.Model</td>
                    <td>@item.IsRoyalVer</td>
                    <td>@item.CustomerName</td>
                    <td>@item.CustomerPhoneNo</td>
                    <td>@item.RelevantDept</td>
                    <td>@item.RelevantGroup</td>
                    <td>@item.Consultant</td>
                    <td>@item.Type</td>
                    <td>@item.Status</td>
                    <td>@item.CreateBy</td>
                    <td>@string.Format("{0:g}", item.CreateDatetime)</td>
                </tr>
            }
        </tbody>
    </table>
    @if(true!=ViewBag.NoPaging)
    { 
    <div class="pager">
        @Html.PagedListPager(Model as PagedList.IPagedList<CCPS.Models.Data.CustomerCommentInfo>, page => string.Format("javascript:turnPage({0});", page), PagedListRenderOptions.ClassicPlusFirstAndLast)
    </div>
    }
    

    我这里的分部视图不仅仅只是为了导出EXCEL用,在搭配主视图显示数据时照样可以可以用,所以我这里有是否分页判断,如果导出EXCEL,那肯定就不需要分页了。

    下面是实现将视图、分部视图生成HTML的方法,代码如下:

            [NonAction]
            protected string RenderViewToString(Controller controller, string viewName, string masterName)
            {
                IView view = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, masterName).View;
                using (StringWriter writer = new StringWriter())
                {
                    ViewContext viewContext = new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
                    viewContext.View.Render(viewContext, writer);
                    return writer.ToString();
                }
            }
    
            [NonAction]
            protected string RenderPartialViewToString(Controller controller, string partialViewName)
            {
                IView view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName).View;
                using (StringWriter writer = new StringWriter())
                {
                    ViewContext viewContext = new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
                    viewContext.View.Render(viewContext, writer);
                    return writer.ToString();
                }
            }
    

    这两个方法是按照其视图呈现的步骤与原理来实现的,一般步骤是:找到视图-->实例化视图上下文-->呈现视图到输出容器

    最后就是定义一个导出EXCEL的Action方法,并返回FileResult,这样就完成了导出EXCEL功能,代码如下:

            public ActionResult Export(DataFilter<CustomerCommentInfo>[] filters)
            {
                var resultList = DataProvider.GetCustomerCommentInfos(filters).OrderBy(t => t.CreateDatetime);
                ViewBag.NoPaging = true;
                ViewData.Model = resultList;
                string viewHtml = RenderPartialViewToString(this, "IndexDataList");
                return File(System.Text.Encoding.UTF8.GetBytes(viewHtml), "application/ms-excel", string.Format("ccpi_{0}.xls", Guid.NewGuid()));
            }
    

    是不是很简单呢?想要导出什么样的EXCEL格式内容,直接可以在视图中设计好就可以了。

  • 相关阅读:
    设计模式之四(抽象工厂模式第二回合)
    C# try catch finally
    设计模式之三(工厂方法模式)
    C# XML与Json之间的相互转换
    Google免费的SVN服务器管理VS2010代码
    设计模式之四(抽象工厂模式第一回合)
    MVC项目开发中那些用到的知识点(Jquery ajax提交Json后台处理)
    设计模式之四(抽象工厂模式第三回合)
    设计模式之二(简单工厂模式)
    Jquery的$命名冲突
  • 原文地址:https://www.cnblogs.com/zuowj/p/4846076.html
Copyright © 2011-2022 走看看