• 创建返回Excel的自定义ActionResult


    该篇文章是Stephen Walther博客中的文章,个人觉得不错就翻译了一下。但由于个人英语水平有限,还望各位海量。如果想看原文,请点击ASP.NET MVC Tip #2 - Create a custom Action Result that returns Microsoft Excel Documents查看原文

    在这篇条目中,我会展示给大家创建一个能够返回Asp.net MVCController Action的自定的Action Result。这个action result从一个Linq to SQL查询获取数据并创建一个Microsoft Excel的文件。

    在一个MVC的应用程序中,一个Controller控制器的操作返回一个Action result。特别的这些操作返回值是来源于基础的ActionResult类就像下面这些:

    · ViewResult

    · EmptyResult

    · RedirectResult

    · RedirectToRouteResult

    · JsonResult

    · ContentResult

    例如,你使用ViewResult向浏览器返回一个特别的View,使用一个ContentResult向浏览器返回文本内容。

    但是如果你要向浏览器返回一些象image,PDF,或者Microsoft Excel的其他类型的内容该怎么办?在该种情况下,你只能创建一个自己的action result。这个条目中,我会给大家展示怎样创建一个返回Microsoft Excel文件的action result

    列表一是ExcelResult的代码:

      1 using System;
      2 using System.Web.Mvc;
      3 using System.Data.Linq;
      4 using System.Collections;
      5 using System.IO;
      6 using System.Web.UI.WebControls;
      7 using System.Linq;
      8 using System.Web;
      9 using System.Web.UI;
     10 using System.Drawing;
     11 
     12 
     13 namespace Tip2
     14 {
     15     public class ExcelResult : ActionResult
     16     {
     17         private DataContext _dataContext;
     18         private string _fileName;
     19         private IQueryable _rows;
     20         private string[] _headers = null;
     21 
     22         private TableStyle _tableStyle;
     23         private TableItemStyle _headerStyle;
     24         private TableItemStyle _itemStyle;
     25 
     26         public string FileName
     27         {
     28             get { return _fileName; }
     29         }
     30 
     31         public IQueryable Rows
     32         {
     33             get { return _rows; }
     34         }
     35 
     36 
     37         public ExcelResult(DataContext dataContext, IQueryable rows, string fileName)
     38             :this(dataContext, rows, fileName, nullnullnullnull)
     39         {
     40         }
     41 
     42         public ExcelResult(DataContext dataContext, string fileName, IQueryable rows, string[] headers)
     43             : this(dataContext, rows, fileName, headers, nullnullnull)
     44         {
     45         }
     46 
     47         public ExcelResult(DataContext dataContext, IQueryable rows, string fileName, string[] headers, TableStyle tableStyle, TableItemStyle headerStyle, TableItemStyle itemStyle)
     48         {
     49             _dataContext = dataContext;
     50             _rows = rows;
     51             _fileName = fileName;
     52             _headers = headers;
     53             _tableStyle = tableStyle;
     54             _headerStyle = headerStyle;
     55             _itemStyle = itemStyle;
     56 
     57             // provide defaults
     58             if (_tableStyle == null)
     59             {
     60                 _tableStyle = new TableStyle();
     61                 _tableStyle.BorderStyle = BorderStyle.Solid;
     62                 _tableStyle.BorderColor = Color.Black;
     63                 _tableStyle.BorderWidth = Unit.Parse("2px");
     64             }
     65             if (_headerStyle == null)
     66             {
     67                 _headerStyle = new TableItemStyle();
     68                 _headerStyle.BackColor = Color.LightGray;
     69             }
     70         }
     71 
     72         public override void ExecuteResult(ControllerContext context)
     73         {
     74             // Create HtmlTextWriter
     75             StringWriter sw = new StringWriter();
     76             HtmlTextWriter tw = new HtmlTextWriter(sw);
     77 
     78             // Build HTML Table from Items
     79             if (_tableStyle != null)
     80                 _tableStyle.AddAttributesToRender(tw);
     81             tw.RenderBeginTag(HtmlTextWriterTag.Table);
     82 
     83             // Generate headers from table
     84             if (_headers == null)
     85             {
     86                 _headers = _dataContext.Mapping.GetMetaType(_rows.ElementType).PersistentDataMembers.Select(m => m.Name).ToArray();
     87             }
     88 
     89 
     90             // Create Header Row
     91             tw.RenderBeginTag(HtmlTextWriterTag.Thead);
     92             foreach (String header in _headers)
     93             {
     94                 if (_headerStyle != null)
     95                     _headerStyle.AddAttributesToRender(tw);
     96                 tw.RenderBeginTag(HtmlTextWriterTag.Th);
     97                 tw.Write(header);
     98                 tw.RenderEndTag();
     99             }
    100             tw.RenderEndTag();
    101 
    102             
    103 
    104             // Create Data Rows
    105             tw.RenderBeginTag(HtmlTextWriterTag.Tbody);
    106             foreach (Object row in _rows)
    107             {
    108                 tw.RenderBeginTag(HtmlTextWriterTag.Tr);
    109                 foreach (string header in _headers)
    110                 {
    111                     string strValue = row.GetType().GetProperty(header).GetValue(row, null).ToString();
    112                     strValue = ReplaceSpecialCharacters(strValue);
    113                     if (_itemStyle != null)
    114                         _itemStyle.AddAttributesToRender(tw);
    115                     tw.RenderBeginTag(HtmlTextWriterTag.Td);
    116                     tw.Write( HttpUtility.HtmlEncode(strValue));
    117                     tw.RenderEndTag();
    118                 }
    119                 tw.RenderEndTag();
    120             }
    121             tw.RenderEndTag(); // tbody
    122 
    123             tw.RenderEndTag(); // table
    124             WriteFile(_fileName, "application/ms-excel", sw.ToString());            
    125         }
    126 
    127 
    128         private static string ReplaceSpecialCharacters(string value)
    129         {
    130             value = value.Replace("""'");
    131             value = value.Replace("""\"");
    132             value = value.Replace("""\"");
    133             value = value.Replace("""-");
    134             value = value.Replace("""");
    135             return value;
    136         }
    137 
    138         private static void WriteFile(string fileName, string contentType, string content)
    139         {
    140             HttpContext context = HttpContext.Current;
    141             context.Response.Clear();
    142             context.Response.AddHeader("content-disposition""attachment;filename=" + fileName);
    143             context.Response.Charset = "";
    144             context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    145             context.Response.ContentType = contentType;
    146             context.Response.Write(content);
    147             context.Response.End();
    148         }
    149     }
    150 }
    151 

    每个action result必须继承基础的ActionResult类。列表一中的ExcelResult类事实上也是继承基础的ActionResult类。基础的ActionResult类的Execute()方法是你必须要重写的。Excute()方法是产生action result返回的内容。

    在列表一中,Excute()方法被用来从Linq to SQL的数据产生一个Excel文件。Excute()方法调用WriteFile()方法来向浏览器写包含正确MIME类型的以完成的Excel文件。

    通常的,你不会直接从控制器(controller)返回一个action result。你使用Controller类中的方法来代替:

    · View()

    · Redirect()

    · RedirectToAction()

    · RedirectToRoute()

    · Json()

    · Content()

    例如,如果你想要从Controller的操作中返回一个view,你不用返回一个ViewResult,而是用View()方法代替。View()方法实例化一个ViewResult并想浏览器返回一个新的ViewResult

    应用于Controller由三个扩展方法组成的类的代码在类表二中。这些扩展方法向Controller类中添加名叫Excel()的方法。Excel()方法返回ExcelResult

     1 using System;
     2 using System.Web.Mvc;
     3 using System.Data.Linq;
     4 using System.Collections;
     5 using System.Web.UI.WebControls;
     6 using System.Linq;
     7 
     8 namespace Tip2
     9 {
    10     public static class ExcelControllerExtensions
    11     {
    12         public static ActionResult Excel
    13         (
    14             this Controller controller,
    15             DataContext dataContext,
    16             IQueryable rows,
    17             string fileName
    18         )
    19         {
    20             return new ExcelResult(dataContext, rows, fileName, nullnullnullnull);
    21         }
    22 
    23         public static ActionResult Excel
    24         (
    25             this Controller controller,
    26             DataContext dataContext,
    27             IQueryable rows,
    28             string fileName,
    29             string[] headers
    30         )
    31         {
    32             return new ExcelResult(dataContext, rows, fileName, headers, nullnullnull);
    33         }
    34 
    35         public static ActionResult Excel
    36         (
    37             this Controller controller, 
    38             DataContext dataContext,
    39             IQueryable rows, 
    40             string fileName, 
    41             string[] headers, 
    42             TableStyle tableStyle, 
    43             TableItemStyle headerStyle,
    44             TableItemStyle itemStyle
    45         )
    46         {
    47             return new ExcelResult(dataContext, rows, fileName, headers, tableStyle, headerStyle, itemStyle);
    48         }
    49 
    50     }
    51 }

        在列表三中的Controller代码向你阐明怎样在一个Controller使用Excel()扩展方法。这个控制器Controller包含三个名为GenerateExcel1()GenerateExcel2()GenerateExcel3()方法。这个三个控制器操作方法返回一个从Movies数据表获取数据的Excel文件。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Data.Linq;
     5 using System.Data.Linq.Mapping;
     6 using System.Web.UI.WebControls;
     7 using System.Web;
     8 using System.Web.Mvc;
     9 using Tip2.Models;
    10 using Tip2;
    11 
    12 namespace Tip2.Controllers
    13 {
    14     public class HomeController : Controller
    15     {
    16 
    17         private MovieDataContext db = new MovieDataContext();
    18 
    19         public ActionResult Index()
    20         {
    21             return View();
    22         }
    23 
    24         /// <summary>
    25         /// Generates Excel document using headers grabbed from property names
    26         /// </summary>
    27         public ActionResult GenerateExcel1()
    28         {
    29             return this.Excel(db, db.Movies, "data.xls");            
    30         }
    31 
    32         /// <summary>
    33         /// Generates Excel document using supplied headers
    34         /// </summary>
    35         public ActionResult GenerateExcel2()
    36         {
    37             var rows = from m in db.Movies select new {Title=m.Title, Director=m.Director};
    38             return this.Excel(db, rows, "data.xls"new[] { "Title""Director" });
    39         }
    40 
    41         /// <summary>
    42         /// Generates Excel document using supplied headers and using supplied styles
    43         /// </summary>
    44         public ActionResult GenerateExcel3()
    45         {
    46             var rows = from m in db.Movies select new { Title = m.Title, Director = m.Director };
    47             var headerStyle = new TableItemStyle();
    48             headerStyle.BackColor = System.Drawing.Color.Orange;
    49             return this.Excel(db, rows, "data.xls"new[] { "Title""Director" }, null, headerStyle, null);
    50         }
    51     }
    52 }
    53 

        最后,在Index.aspx View展示怎样调用GenerateExcel()控制器操作并创建Excel文件。注意三个连接指向三个不同的GenerateExcel版本。

     

     1     <h1>Generate Microsoft Excel Document</h1>
     2     
     3     
     4     <ul>
     5         <li>
     6         <href="/Home/GenerateExcel1">Generate</a> - Generates an Excel document by using the entity property names for column headings and the default
     7         formatting.        
     8         </li>
     9         <li>
    10         <href="/Home/GenerateExcel2">Generate</a> - Generates an Excel document by using supplied header names and default formatting.        
    11         </li>
    12         <li>
    13         <href="/Home/GenerateExcel3">Generate</a> - Generates an Excel document by using supplied header names and supplied formatting.        
    14         </li>
    15 
    16     </ul>

  • 相关阅读:
    SpringBoot自定义错误页面,SpringBoot 404、500错误提示页面
    SpringBoot切换Tomcat容器,SpringBoot使用Jetty容器
    SpringBoot 国际化配置,SpringBoot Locale 国际化
    SpringBoot Logback配置,SpringBoot日志配置
    SpringBoot thymeleaf使用方法,thymeleaf模板迭代
    SpringBoot thymeleaf模板页面没提示,SpringBoot thymeleaf模板插件安装
    JSP判断闰年
    JSP求和计算
    JSP指令
    jsp新建项目
  • 原文地址:https://www.cnblogs.com/stalwart/p/1766093.html
Copyright © 2020-2023  润新知