導出EXCEL方法總結javascript
MVC導出數據到EXCEL的方法有不少種,常見的是:html
1.採用EXCEL COM組件來動態生成XLS文件並保存到服務器上,而後轉到該文件存放路徑便可;java
優勢:可設置豐富的EXCEL格式,缺點:須要依賴EXCEL組件,且EXCEL進程在服務器中沒法及時關閉,以及服務器上會存留大量的沒必要要的XLS文件;服務器
2.設置輸出頭爲:application/ms-excel,再輸出拼接的HTML TABLE數據;app
優勢:無需組件,可設置一些簡單的格式,缺點:拼接HTML TABLE過程較複雜,不夠直觀;ide
3.藉助第三方組件(如:NPOI)post
優勢及缺點均依賴於第三方組件的易用性上面,在此不做說明;ui
你們也能夠看我以前發表的一篇博文:我寫的一個ExcelHelper通用類,可用於讀取或生成數據this
實如今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格式內容,直接能夠在視圖中設計好就能夠了。