最近项目中有同事用到word文档导出功能,遇到了一些导出失败问题,帮其看了下解决问题的同事,看了下之前的代码发现几个问题:
- 代码编写不规范,word导出功能未收口
- 重复代码导出都是
- 实现逻辑比较复杂,不易于维护及使用
在帮其解决问题后,写了下面这个ViewResult拓展,依赖Razor视图,能够直接转换页面为word文档,但是不支持外联样式表,样式可以定义在<head>头部
废话不多说,直接上代码:
public { public
public WordFileResult(object model, string viewName, string fileName) { ViewData = new ViewName = viewName; FileName = fileName; }
public WordFileResult() : this(new {
}
public WordFileResult(string fileName) : this(new {
}
public WordFileResult(object model) : this(model, null, null) {
}
public WordFileResult(object model, string fileName) : this(model, null, fileName) {
}
protected { 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 } }
public { public { return }
public { return }
public { return }
public { return }
} |
使用方式比较简单:
- 定义视图,使用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; width: 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> |
- 添加Action修改对应的Action方法返回值
public { List<LoginViewModel> models = new for (int i = 0; i < 20; i++) { models.Add(new { Email = $"{i}user@123.com", Password = new RememberMe = i % 2 == 0 ? true : false }); }
return }
public { List<LoginViewModel> models = new for (int i = 0; i < 20; i++) { models.Add(new { Email = $"{i}user@123.com", Password = new RememberMe = i % 2 == 0 ? true : false }); } return } |
还有一种更方便的方式:使用ActionFilterAttribute过滤器
直接上代码:
public { public public { var result = filterContext.Result as 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 { return View(); } |
搞定word导出功能,抛砖引玉,希望能够帮助到大家,也希望有更好实现方式的同学能够一起讨论!!!!!!