异步导出excel

最近看园里有几篇写有关导出导入excel的博客,我正好最近在项目中也有涉及想来一起分享一下,正好整理一下自己的思路。

一、异步的方式是通过iframe来实现,代码如下:

if ($('#downloadexcel').length <= 0)
            $('body').append("<iframe id=\"downloadexcel\" style=\"display:none\"></iframe>");
        $('#downloadexcel').attr('src', url);

二、生成excel文件用的第三方组件NPOI,具体如何用园子里有很多关于这方面的资料,这里就不展开了。

三、这里主要介绍一下如何简化HttpResponse到前端生成excel,下面会贴出核心代码,希望给大家有所帮助。

  1. 声明一个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
        }
    View Code

     

  2. 声明一个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
        }
    View Code

     

  3. 声明一个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
        }
    View Code

     

  4. 在实际导出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")));
            }
        }
    View Code

     

posted on 2013-11-12 17:14  4444  阅读(7293)  评论(1编辑  收藏  举报