2010年7月22日 星期四

asp.net_解決GridView匯出Excel的問題

距離上次寫資料匯出的功能已經好久好久,之前在匯出時是直接匯出Table,所以並沒有發生什麼問題,這次要匯出gridview到Excel就遇到了很多問題,逐一把他記載一下:

第一個錯誤:型別 'GridView' 的控制項 'gv' 必須置於有 runat=server 的表單標記之中。

如果去察看程式碼,會發現GridView明明就已經放在有runat=server的標記的標籤中,卻還是出現這樣的問題,網路上有一個通用的解法,但是沒有看到那篇文章特別有提到原因。

MSDN:Page.VerifyRenderingInServerForm為確認在 Run Time 時期呈現了所指定 ASP.NET 伺服器控制項的 HtmlForm 控制項。會回傳或使用用戶端指令碼的伺服器控制項,如果未放在 HtmlForm 伺服器控制項 (
) 標記之內,將無法運作。這些控制項可以呼叫這個方法來呈現清楚的錯誤訊息 (當它們未被封入 HtmlForm 控制項時)。(原始MSDN網頁)

意思就是你沒放在有runat="server"的標籤中啦!但是我放啦!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!你沒放!我放了!總之,他認為你沒放所以錯了!

解法:覆寫VerifyRenderingInServerForm,讓他不要去執行這一項驗證。

Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
'處理'GridView' 的控制項 'GridView' 必須置於有 runat=server 的表單標記之中
End Sub

第二個錯誤:RegisterForEventValidation 只能在 Render(); 期間呼叫。

這項網路上也有許多文章提出一個解法,大部分的人提出要在的標籤中,修改AutoEventWireup="true"並增加EnableEventValidation = "false";另一個人提出只需要增加EnableEventValidation = "false",並不需要將AutoEventWireup改為true。測試之後只需要增加EnableEventValidation = "false"屬性即可,但也有可能AutoEventWireup會解決另一個問題,還是先記錄下來吧!

第三個錯誤:檔名用中文時無法正確顯示。

解決方法就是利用HttpUtility.UrlEncode來進行轉碼動作。

Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", System.Web.HttpUtility.UrlEncode(FileName & ".xls", System.Text.Encoding.UTF8)))


第四個錯誤:若是輸出內容有亂碼,則可以將編碼指定為utf-8。

Response.Charset = "utf-8"
Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8")


最後將完整程式碼附在最後面:

Dim FileName As String = "人行道資料匯出"
Response.Clear()
Response.Write("")
Dim tw As StringWriter = New System.IO.StringWriter
Response.Write(tw.ToString())
Response.Buffer = True
'Response.AppendHeader("content-disposition", "attachment;filename=" & FileName & ".xls")
'Response.Charset = "utf-8"
Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8")
Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", System.Web.HttpUtility.UrlEncode(FileName & ".xls", System.Text.Encoding.UTF8)))
Response.ContentType = "application/vnd.ms-excel"
Me.EnableViewState = False
Dim oStringWriter As System.IO.StringWriter = New System.IO.StringWriter()
Dim oHtmlTextWriter As System.Web.UI.HtmlTextWriter = New System.Web.UI.HtmlTextWriter(oStringWriter)
Me.DataPanel.RenderControl(oHtmlTextWriter)'←要匯出的地方
Response.Write(oStringWriter.ToString())
Response.End()

有參考到的文章:
1.topcat姍舞之間的極度凝聚-解決GridView使用RenderControl取得HTML出現的問題
2.章立民研究室-讀者詢問將 GridView 內容匯出成 Excel 檔案問題
3.ASP.NET魔法學院-擴展GridView控制項-支援Excel及Word匯出
4.甘蔗築夢田-ASP.NET 匯出 Excel - 只能在 Render 期間呼叫 錯誤
5.藍色小舖

沒有留言:

張貼留言