導出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/[email protected]&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格式内容,直接可以在視圖中設計好就可以了。