65.9K
CodeProject 正在变化。 阅读更多。
Home

MVC 网格到 Excel 文件下载

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (14投票s)

2012年2月5日

CPOL

2分钟阅读

viewsIcon

144630

downloadIcon

8008

将ASP.NET MVC网格的结果转换为可下载的Excel文件


引言

本文介绍如何将ASP.NET MVC Web应用程序中表格或网格形式呈现的数据转换为可下载的Excel数据文件。






背景

我最近正在构建一个基于ASP.NET MVC 3的报表应用程序。其中一个功能是提供一个可下载的Excel文件,用于呈现为网格/表格的报表。与其重新创建一个完整的模块来完成此操作,我希望找到一种重用用于渲染视图的数据的方法,并尽可能减少代码量。

使用代码

我尝试将大部分实现封装在一个自定义ActionResult类(DownloadFileActionResult)中,因此您可以传递一个GridView对象形式的数据,并期望得到一个包含表格数据的可下载Excel文件。

您可以从下面的链接下载完整的代码。

如上所述,大部分实现都包含在DownloadFileActionResult类中。

首先,DownloadFileActionResult继承自抽象ActionResult类,构造函数接受两个参数:绑定的GridView对象和可下载Excel文件的名称。

ExecuteResult被重写,包含自定义实现,该实现创建一个响应,然后使用HtmlTextWriter和一个StringWriter将GridView的渲染管道传输到字符串。然后将此字符串流式传输回响应,以作为Excel文件交付。就这么简单。

public class DownloadFileActionResult : ActionResult
    {

        public GridView ExcelGridView { get; set; }
        public string fileName { get; set; }


        public DownloadFileActionResult(GridView gv, string pFileName)
        {
            ExcelGridView = gv;
            fileName = pFileName;
        }


        public override void ExecuteResult(ControllerContext context)
        {

           //Create a response stream to create and write the Excel file
            HttpContext curContext = HttpContext.Current;
            curContext.Response.Clear();
            curContext.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
            curContext.Response.Charset = "";
            curContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            curContext.Response.ContentType = "application/vnd.ms-excel";

            //Convert the rendering of the gridview to a string representation 
            StringWriter sw = new StringWriter();
            HtmlTextWriter htw = new HtmlTextWriter(sw);
            ExcelGridView.RenderControl(htw);
            
            //Open a memory stream that you can use to write back to the response
            byte[] byteArray = Encoding.ASCII.GetBytes(sw.ToString());
            MemoryStream s = new MemoryStream(byteArray);
            StreamReader sr = new StreamReader(s, Encoding.ASCII);

            //Write the stream back to the response
            curContext.Response.Write(sr.ReadToEnd());
            curContext.Response.End();

        }

    } 

在控制器的Action结果中,您需要创建GridView,将模型数据绑定到它,并将其存储在Session变量中,以便将模型数据与视图绑定。

 public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";
            CarModels cm = new CarModels();
            List<Cars> model = cm.getAllCars();

            GridView gv = new GridView();
            gv.DataSource = model;
            gv.DataBind();
            Session["Cars"] = gv;

            return View(model);
        }

在同一个控制器中,我们需要创建一个新的ActionResult,名为Download,以处理文件下载请求。

public ActionResult Download()
        {
            if (Session["Cars"] != null)
            {
                return new DownloadFileActionResult((GridView)Session["Cars"], "Cars.xls");
            }
            else 
            {
               //Some kind of a result that will indicate that the view has 
               //not been created yet. I would use a Javascript message to do so. 
            }
        }


在视图中,您放置以下下载链接

    @Html.ActionLink("Download File", "Download")

关注点

我希望本文能展示如何通过自定义实现来覆盖默认的ActionResult类,从而生成自定义响应。

我不完全满意将网格结果存储在Session变量中,并将努力提出一个更好的解决方案。

局限性

由于这只是作为Excel工作表呈现的HTML,因此您将无法使用大多数Excel功能。在我的例子中,客户想要的是数据的可下载版本,所以没问题。但是,如果您想创建一个真正的Excel文件,可以考虑使用XSLT将HTML输出转换为Excel文件。

参考

http://www.codeshelve.com/code/details/54/export-to-excel-in-asp-net-mvc

© . All rights reserved.