zoukankan      html  css  js  c++  java
  • ASP.NET MVC 拓展ViewResult实现word文档下载

     

    最近项目中有同事用到word文档导出功能,遇到了一些导出失败问题,帮其看了下解决问题的同事,看了下之前的代码发现几个问题:

    1. 代码编写不规范,word导出功能未收口
    2. 重复代码导出都是
    3. 实现逻辑比较复杂,不易于维护及使用

    在帮其解决问题后,写了下面这个ViewResult拓展,依赖Razor视图,能够直接转换页面为word文档,但是不支持外联样式表,样式可以定义在<head>头部

    废话不多说,直接上代码:

     

    public class WordFileResult : ViewResultBase

    {

    public string FileName { get; set; }

     

    public WordFileResult(object model, string viewName, string fileName)

    {

    ViewData = new ViewDataDictionary(model);

    ViewName = viewName;

    FileName = fileName;

    }

     

    public WordFileResult() : this(new ViewDataDictionary(), null, null)

    {

     

    }

     

    public WordFileResult(string fileName) : this(new ViewDataDictionary(), null, fileName)

    {

     

    }

     

    public WordFileResult(object model) : this(model, null, null)

    {

     

    }

     

    public WordFileResult(object model, string fileName) : this(model, null, fileName)

    {

     

    }

     

    protected override ViewEngineResult FindView(ControllerContext context)

    {

    context.HttpContext.Response.Charset = "utf-8";

    context.HttpContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");

    if (string.IsNullOrWhiteSpace(FileName))

    {

    FileName = ViewName;

    }

    context.HttpContext.Response.AppendHeader("Content-Disposition", string.Format("filename={0}.doc", FileName));

    context.HttpContext.Response.ContentType = "application/msword";

    ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, string.Empty);

    if (result.View != null)

    {

    return result;

    }

    return null;

    }

    }

     

     

    public static class ControllerExtensions

    {

    public static WordFileResult Word(this Controller controller, object model)

    {

    return new WordFileResult(model);

    }

     

    public static WordFileResult Word(this Controller controller, object model, string fileName)

    {

    return new WordFileResult(model, fileName);

    }

     

    public static WordFileResult Word(this Controller controller, string fileName)

    {

    return new WordFileResult(fileName);

    }

     

    public static WordFileResult Word(this Controller controller, object model, string viewName, string fileName)

    {

    return new WordFileResult(model, viewName, fileName);

    }

     

     

    }

     

    使用方式比较简单:

    1. 定义视图,使用Razor视图布局word内容,

    @using RazorWord.Models

    @model List<LoginViewModel>

    @{

    Layout = null;

    }

     

    <!DOCTYPE html>

     

    <html>

    <head>

    <meta name="viewport" content="width=device-width" />

    <title>Export</title>

    <style type="text/css">

    .table td,

    .table th {

    background-color: #fff !important;

    }

     

    .table {

    border-collapse: collapse !important;

    background-color: #ffffff;

    100%;

    margin-bottom: 20px;

    }

     

    .table thead > tr > th,

    .table tbody > tr > th,

    .table tfoot > tr > th,

    .table thead > tr > td,

    .table tbody > tr > td,

    .table tfoot > tr > td {

    padding: 8px;

    line-height: 1.428571429;

    vertical-align: top;

    border-top: 1px solid #dddddd;

    }

     

    .table thead > tr > th {

    vertical-align: bottom;

    border-bottom: 2px solid #dddddd;

    }

    </style>

    </head>

    <body>

    <div>

    <table class="table">

    <tr>

    <th>电子邮件</th>

    <th>密码</th>

    <th>是否记住密码</th>

    </tr>

    @foreach (LoginViewModel item in Model)

    {

    <tr>

    <td>@item.Email</td>

    <td>@item.Password]</td>

    <td>@(item.RememberMe ? "Y" : "N")</td>

    </tr>

    }

    </table>

    </div>

    </body>

    </html>

     

    1. 添加Action修改对应的Action方法返回值

     

    public ActionResult Export()

    {

    List<LoginViewModel> models = new List<LoginViewModel>();

    for (int i = 0; i < 20; i++)

    {

    models.Add(new LoginViewModel()

    {

    Email = $"{i}user@123.com",

    Password = new Random().Next(1, 10000).ToString(),

    RememberMe = i % 2 == 0 ? true : false

    });

    }

     

    return new WordFileResult(models, "下载文件名称");

    }

     

    public ActionResult Export1()

    {

    List<LoginViewModel> models = new List<LoginViewModel>();

    for (int i = 0; i < 20; i++)

    {

    models.Add(new LoginViewModel()

    {

    Email = $"{i}user@123.com",

    Password = new Random().Next(1, 10000).ToString(),

    RememberMe = i % 2 == 0 ? true : false

    });

    }

    return this.Word(models, "Export", "下载文件名称");

    }

     

     

    还有一种更方便的方式:使用ActionFilterAttribute过滤器

    直接上代码:

    public class WordDocumentAttribute : ActionFilterAttribute

    {

    public string FileName { get; set; }

    public override void OnResultExecuted(ResultExecutedContext filterContext)

    {

    var result = filterContext.Result as ViewResult;

    if (string.IsNullOrWhiteSpace(FileName))

    {

    FileName = result == null ? DateTime.Now.ToString("yyyy_MM_dd") : result.ViewName;

    }

    filterContext.HttpContext.Response.AppendHeader("Content-Disposition", string.Format("filename={0}.doc", FileName));

    filterContext.HttpContext.Response.ContentType = "application/msword";

    base.OnResultExecuted(filterContext);

    }

    }

    使用方式:在一个Action方法上面添加特性:WordDocumentAttribute

     

     

    [WordDocument(FileName = "下载文件名称")]

    public ActionResult Index()

    {

    return View();

    }

     

     

    搞定word导出功能,抛砖引玉,希望能够帮助到大家,也希望有更好实现方式的同学能够一起讨论!!!!!!

  • 相关阅读:
    深入了解抽象类和接口
    关于Hibernate查询对象调用set方法自动同步到数据库解决方案
    【鸽子的迷信(一)】python导入由excel文件改后缀变成的csv文件出现乱码错误(ParserError:Error tokenizing data. C error:)
    《计算机操作系统》CH1操作系统引论思维导图整理
    IntelliJ IDEA创建一个Maven项目
    C++实验三
    小练习
    C++实验二
    C++的ch1&ch2的整理
    C++实验一
  • 原文地址:https://www.cnblogs.com/AlvinLee/p/6137100.html
Copyright © 2011-2022 走看看