2014-03-25 129 views
4

我有這個問題試圖返回一個Excel內聯響應。服務器無法在發送HTTP標頭後添加標頭c#excel inline

我搜索了所有通過幫助編碼頁面的答案,並找不到有效的東西。

我在下面做了一個簡單的例子。這個問題總是發生。

錯誤在這行:

Line 56:   Response.AddHeader("content-disposition", 

後面的代碼:

public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     PleaseWait(); 
     Call(); 
    } 

    protected void Call() 
    { 
     strSql = "SELECT * FROM ....... ; "; 

     SqlCommand cmd = new SqlCommand(strSql); 
     DataTable dt = GetData(cmd); 

     GridView GridView1 = new GridView(); 
     GridView1.AllowPaging = false; 
     GridView1.DataSource = dt; 
     GridView1.DataBind(); 

     Response.Clear(); 
     Response.Buffer = true; 
     Response.BufferOutput = true; 
     Response.ClearHeaders(); 

     Response.AddHeader("content-disposition", 
     "attachment;filename= "Output.xls"); 
     Response.Charset = ""; 
     Response.ContentType = "application/vnd.ms-excel"; 
     StringWriter sw = new StringWriter(); 
     HtmlTextWriter hw = new HtmlTextWriter(sw); 

     for (int i = 0; i < GridView1.Rows.Count; i++) 
     { 
      GridView1.Rows[i].Attributes.Add("class", "textmode"); 
     } 
     GridView1.RenderControl(hw); 

     string style = @"<style> .textmode { mso-number-format:\@; } </style>"; 
     Response.Write(style); 
     Response.Output.Write(sw.ToString()); 
     Response.Flush(); 
     Response.End(); 
    } 

    protected void PleaseWait() 
    { 
     this.Response.Write("<meta http-equiv=X-UA-Compatible content=IE=8>"); 
     this.Response.Write(@"<style type=text/css media=all>"); 
     this.Response.Write(@".loading"); 
     this.Response.Write(@"{"); 
     this.Response.Write(@"text-align: center;"); 
     this.Response.Write(@"padding-top: 30px;"); 
     this.Response.Write(@"border-width: 1px solid #000;"); 
     this.Response.Write(@"width: 300px;"); 
     this.Response.Write(@"height: 100px;"); 
     this.Response.Write(@"-ms-filter: alpha(opacity=90);"); 
     this.Response.Write(@"-ms-opacity: 0.90;"); 
     this.Response.Write(@"border-style: solid;"); 
     this.Response.Write(@"background-color: #FFFFFF;"); 
     this.Response.Write(@"position: absolute;"); 
     this.Response.Write(@"font-family: Trebuchet MS;"); 
     this.Response.Write(@"font-size: small;"); 
     this.Response.Write(@"position: absolute;"); 
     this.Response.Write(@"top: 0;"); 
     this.Response.Write(@"bottom: 0;"); 
     this.Response.Write(@"left: 0;"); 
     this.Response.Write(@"right: 0;"); 
     this.Response.Write(@"margin: auto;"); 
     this.Response.Write(@"display: block;"); 
     this.Response.Write(@"background: url('images/wait01.gif') no-repeat center;"); 
     this.Response.Write(@"}"); 
     this.Response.Write(@"</style>"); 

     this.Response.Write(@"<div id=mydiv class=loading>&nbsp;</div>"); 
     this.Response.Write(@"<script>mydiv.innerText = '';"); 
     this.Response.Write(@"</script>"); 
     this.Response.Write(@"<script language=javascript>;"); 
     this.Response.Write(@"var dots = 0;"); 
     this.Response.Write(@"var dotmax = 10;"); 
     this.Response.Write(@"function ShowWait()"); 
     this.Response.Write(@"{"); 
     this.Response.Write(@"var output;"); 
     this.Response.Write(@"output = 'Wait...';"); 
     this.Response.Write(@"dots++;"); 
     this.Response.Write(@"if(dots>=dotmax)dots=1;"); 
     this.Response.Write(@"for(var x = 0;"); 
     this.Response.Write(@"x < dots;x++)"); 
     this.Response.Write(@"{"); 
     this.Response.Write(@"output += '.';"); 
     this.Response.Write(@"}"); 
     this.Response.Write(@"mydiv.innerText = output;"); 
     this.Response.Write(@"}"); 
     this.Response.Write(@"function StartShowWait()"); 
     this.Response.Write(@"{"); 
     this.Response.Write(@"mydiv.style.visibility = 'visible'; "); 
     this.Response.Write(@"window.setInterval('ShowWait()',1500);"); 
     this.Response.Write(@"}"); 
     this.Response.Write(@"function HideWait()"); 
     this.Response.Write(@"{"); 
     this.Response.Write(@"mydiv.style.visibility = 'hidden';"); 
     this.Response.Write(@"window.clearInterval();"); 
     this.Response.Write(@"}"); 
     this.Response.Write(@"StartShowWait();"); 
     this.Response.Write(@"</script>"); 

     this.Response.Flush(); 
     Thread.Sleep(500); 
    } 

    private DataTable GetData(SqlCommand cmd) 
    { 
     DataTable dt = new DataTable(); 
     String strConnString = System.Configuration.ConfigurationManager. 
      ConnectionStrings["conn"].ConnectionString; 
     SqlConnection con = new SqlConnection(strConnString); 
     SqlDataAdapter sda = new SqlDataAdapter(); 
     cmd.CommandType = CommandType.Text; 
     cmd.Connection = con; 
     try 
     { 
      con.Open(); 
      sda.SelectCommand = cmd; 
      sda.Fill(dt); 
      return dt; 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
     finally 
     { 
      con.Close(); 
      sda.Dispose(); 
      con.Dispose(); 
     } 
    } 

    public override void VerifyRenderingInServerForm(Control control) 
    { 
    } 
} 

回答

5

呀,你不能這樣做。在您的PleaseWait方法中,您打電話給Response.Flush。這將發送當前緩衝的輸出以及HTTP標頭。 HTTP頭始終在其他響應數據之前發送,所以您運氣不佳。

通常的做法是建立一個單獨的PleaseWait頁面,它將定時重定向到實際文件(然後只發送文件數據和適當的頭文件)。

基本問題是HTTP是「單一請求,單個響應」。您試圖對單個請求返回兩個響應,而這純粹不可能通過純HTTP進行(可悲的是,有類似HTTP的協議允許這樣做,但它們並不真正支持瀏覽器 - 這對於性能,當你可以一次發送20個文件,而不是20個獨立的請求)。

+0

感謝您的幫助。 你有沒有創建一個單獨的PleaseWait頁面的例子,它將定時重定向到實際的文件? – Hamamelis

+0

@ user3370558那麼,你可以簡單地從「Please wait」頁面做一個'Response.Redirect'。你仍然需要將你的代碼分成兩個頁面或者根據例如。一個查詢字符串 - 'getData.aspx'可以顯示「Please wait」,並重定向到'getData.aspx?download = 1',這將運行'Call'而不是'PleaseWait'。 – Luaan

+0

謝謝,但在頁面getData.aspx我有同樣的問題和相同的錯誤...服務器不能追加HTTP標頭已發送後,在這一行第50行:Response.AddHeader(「content-disposition」, – Hamamelis

相關問題