异步导出excel
最近看园里有几篇写有关导出导入excel的博客,我正好最近在项目中也有涉及想来一起分享一下,正好整理一下自己的思路。
一、异步的方式是通过iframe来实现,代码如下:
if ($('#downloadexcel').length <= 0) $('body').append("<iframe id=\"downloadexcel\" style=\"display:none\"></iframe>"); $('#downloadexcel').attr('src', url);
二、生成excel文件用的第三方组件NPOI,具体如何用园子里有很多关于这方面的资料,这里就不展开了。
三、这里主要介绍一下如何简化HttpResponse到前端生成excel,下面会贴出核心代码,希望给大家有所帮助。
- 声明一个excel返回实体,代码如下:
/// <summary> /// 表示返回的流数据。 /// </summary> [DataContract] public class ExcelResultMessage { #region [ Privates ] private MessageType type = MessageType.Info; private string description = string.Empty; #endregion #region [ Properteis ] /// <summary> /// 返回结果信息提示类型。 /// </summary> [DataMember(Order=1)] public MessageType Type { get { return this.type; } set { this.type = value; } } /// <summary> /// 返回结果信息提示。 /// </summary> [DataMember(Order=2)] public string Description { get { return this.description; } set { this.description = value; } } /// <summary> /// 返回结果数据。 /// </summary> [DataMember(Order=3)] public MemoryStream Data { get; set; } /// <summary> /// 文件名 /// </summary> [DataMember(Order = 4)] public string FileName { get; set; } #endregion }
- 声明一个excel数据容器,代码如下:
/// <summary> /// 表示返回的excel数据容器。 /// </summary> [DataContract] public class ExcelResult { #region [ Properteis ] /// <summary> /// 编码格式。 /// </summary> public Encoding ContentEncoding { get; set; } /// <summary> /// 内容类型。 /// </summary> public string ContentType { get; set; } /// <summary> /// 数据。 /// </summary> [DataMember] public ExcelResultMessage Message { get; set; } #endregion #region [ Methods ] /// <summary> /// 执行结果。 /// </summary> /// <param name="context"></param> public void ExecuteResult(HttpContext context) { if (context == null) { throw new ArgumentNullException("context"); } HttpResponse response = context.Response; response.ClearContent(); if (!String.IsNullOrEmpty(ContentType)) { response.ContentType = ContentType; } else { response.ContentType = "application/vnd.ms-excel"; } if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } response.Clear(); if (this.Message != null) { response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", this.Message.FileName)); response.BinaryWrite(this.Message.Data == null ? new byte[1] : this.Message.Data.GetBuffer()); response.End(); } } #endregion }
- 声明一个excel页面基类,代码如下:
/// <summary> /// excel页面基类。 /// </summary> public abstract class ExcelPageBase : PageBase { #region [ Privates ] #endregion #region [ Contructors ] /// <summary> /// /// </summary> public ExcelPageBase() : base() { } #endregion #region [ Properties ] /// <summary> /// excel数据结果。 /// </summary> protected ExcelResult ExcelResult { get; set; } #endregion #region [ Events ] /// <summary> /// 页面加载。 /// </summary> protected override void OnPreRender(EventArgs e) { SetNoCache(); this.ExcelResult = new ExcelResult(); GenerateExcelResult(this.ExcelResult); ExcelResult.ExecuteResult(this.Context); } /// <summary> /// 集成Json结果数据。 /// </summary> protected abstract void GenerateExcelResult(ExcelResult result); #endregion }
- 在实际导出excel中,只要实现这个excel页面基类,然后关注如何生成excel的MemoryStream就可以了,实例代码如下:
public partial class ExportFile : ExcelPage { protected override void GenerateExcelResult(ExcelResult result) { result.Message = new ExcelResultMessage(); SaleOrderResponse response = FinanceService.GetSaleOrderResponse(SaleModel.BuildSaleOrderQueryCondition(this.UserInfo), true); MemoryStream stream = SaleModel.ExportToExcel(response); result.Message.Data = stream; result.Message.FileName = HttpUtility.UrlEncode(string.Format("{0}{1}.xls", this.BuildContent("AuditSaleOrder"), DateTime.Now.ToString("yyyyMMddhhmmss"))); } }