最近看園里有幾篇寫有關導出導入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"))); } }