ASP.NET中GridView數據導出EXCEL小結
時間:2010-12-13 11:26來源:未知 作者:admin 點擊:480次我要投稿 高質量的ASP.NET空間,完美支持1.0/2.0/3.5/4.0/MVC等
本周按業務部門的要求,做一個客戶拜訪登記管理的小程序(B/S模式),在這里面用到了GridView來顯示根據條件查詢到的數據,但業務部門同時要求數據要導出為EXCEL方面使用,在網上查找了很多資料,匯總并根據自己的實際情況編寫使用,效果不錯,現記下以備忘并與大家分享。(開發環境:Windows 2003/VS 2005/SQL SERVER 2005)
導出為EXCEL的代碼網上有很多,分析后選擇了最簡單的直接用流方法導出,文件類型為XLS文件,但實際上是一個文本文件(HTML格式),這樣的優點是1、服務器本身不需要安裝OFFICE組件,有很好的通用性;2、導出文件為直接生成直接下載,不需要預先保存在服務器上,對空間大小沒有需求;3、控制簡單,代碼容易理解。缺點是有一些EXCEL特有的功能可能無法實現吧。
先將代碼貼出,再一步步的講一下當時遇到的問題和處理方法吧:
GridView導出到EXCEL
Protected Sub btn_export_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_export.Click
Response.Clear()
Response.Buffer = True
Response.Charset = "utf-8"
Dim FileName As String
If Session("branch_no") = "" Then
lbl_inputlist.Text = "登錄已超時,請重新登錄后再導出!"
Exit Sub
End If
FileName = Session("branch_no") & "_" & DateTime.Now.ToString("yyyyMMddHHmmssfff") & ".xls"
'FileName = Session("branch_no") & Path.GetRandomFileName() & ".xls"
Response.AddHeader("Content-Disposition", "attachment;filename=" & FileName)
Response.ContentType = "application/ms-excel"
Dim strWriter As New StringWriter()
Dim htw As New HtmlTextWriter(strWriter)
GV_list.BackColor = System.Drawing.Color.White
GV_list.ForeColor = System.Drawing.Color.Black
GV_list.BorderWidth = 1
GV_list.RowStyle.BackColor = System.Drawing.Color.White
GV_list.RowStyle.ForeColor = System.Drawing.Color.Black
GV_list.AlternatingRowStyle.BackColor = System.Drawing.Color.White
GV_list.BorderStyle = BorderStyle.Solid
GV_list.BorderWidth = 1
GV_list.AlternatingRowStyle.ForeColor = System.Drawing.Color.Black
GV_list.HeaderStyle.BackColor = Drawing.Color.White
GV_list.HeaderStyle.ForeColor = Drawing.Color.Black
GV_list.AllowPaging = False
GV_list.AllowSorting = False
GV_list.DataBind()
GV_list.RenderControl(htw)
Response.Write(strWriter.ToString)
Response.End()
GV_list.AllowPaging = True
GV_list.DataBind()
End Sub
Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
End Sub
Protected Sub GV_list_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GV_list.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Cells(0).Attributes.Add("style", "vnd.ms-excel.numberformat:@;")
e.Row.Cells(4).Attributes.Add("style", "vnd.ms-excel.numberformat:@;")
e.Row.Cells(5).Attributes.Add("style", "vnd.ms-excel.numberformat:@;")
End If
End Sub
遇到的問題:
一、將網上找到的代碼放到相應的地方后,直接運行,程序中斷在“GV_list.RenderControl(htw)”處,提示“類型“GridView”的控件“GV_list”必須放在具有 runat=server 的窗體標記內。”,查看了半天也沒有找到原因,再次上網搜索,得到結果,在代碼中要加上一個阻止系統自動調用檢查的過程才能避免這種情況,將過程加上后,果然正常。分析后認為出現問題的原理是這樣的,當點擊導出按鈕時,因為已將返回的文件類型改成了EXCEL文件而非標準的ASPX返回文件(Response.ContentType = "application/ms-excel"),調用VerifyRenderingInServerForm方法進行檢查的時候,控件當然不可能在任何一個Form的runat=server中了,因此報錯,加上這個空過程后正常。
Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
'空過程
End Sub
二、導出的EXCEL表,打開后會根據GridView的設定,有不同的前景色和背景色,不利于查看、打印。分析GirdView的各參數,將表格、行、列及表頭標題行的顏色全部設為黑白的,解決了這個問題。
導出外觀
'表格外觀(前景色、背景色)
GV_list.BackColor = System.Drawing.Color.White
GV_list.ForeColor = System.Drawing.Color.Black
'表格線
GV_list.BorderWidth = 1
'數據行外觀
GV_list.RowStyle.BackColor = System.Drawing.Color.White
GV_list.RowStyle.ForeColor = System.Drawing.Color.Black
'數據交替行外觀
GV_list.AlternatingRowStyle.BackColor = System.Drawing.Color.White
GV_list.AlternatingRowStyle.ForeColor = System.Drawing.Color.Black
'控件外觀
GV_list.BorderStyle = BorderStyle.Solid
GV_list.BorderWidth = 1
'表頭標題行外觀
GV_list.HeaderStyle.BackColor = Drawing.Color.White
GV_list.HeaderStyle.ForeColor = Drawing.Color.Black
三、數據較多時,GridView設定了分頁查看及排序,但在導出時,只導出第一頁的內容及頁碼鏈接,標題行還帶有排序鏈接,實際上在需要導出數據的時候,我們需要的是一次獲得所有數據,EXCEL也有自己的排序等功能,只需要導出一個純粹的數據就可以了,因此,需要將分頁及排序功能屏蔽。
'屏蔽分頁
GV_list.AllowPaging = False
'屏蔽排序
GV_list.AllowSorting = False
四、一開始,我的導出文件的文件名是固定的,后來發現在實際使用過程中,如果一個操作人員做了多次導出操作的話,如果不小心可能會將原來的導出文件覆蓋,因此就使用當前時間加操作機構號的方式來得到一個唯一文件名,防止這種情況發生,在實際使用中,還可以再加上報表的名稱。
微軟自己也為這種情況提供了一個方法,獲取一個隨機的文件名(Path.GetRandomFileName()),但我感覺這種方法可能用于生成臨時文件更好一些,而下載文件的話,用日期時間做文件名最好。
獲取隨機文件名
Dim FileName As String
FileName = Session("branch_no") & "_" & DateTime.Now.ToString("yyyyMMddHHmmssfff") & ".xls"
'下面這種方法用來獲取臨時文件名比較合適
'FileName = Session("branch_no") & Path.GetRandomFileName() & ".xls"
Response.AddHeader("Content-Disposition", "attachment;filename=" & FileName)
五、在導出后,發現在生成的文件中,大于11位的數字都被EXCEL顯示成了科學計數法,如果是校驗位不為X的18位身份證號碼的話,最后三位還會被設為“0”,手機號雖然可以正確顯示,但如果是座機的話,區號的第一位0也會被自動抹掉,使用起來十分的不方便。
以前在使用一些程序時也遇到過這種情況,當時開發人員的處理辦法是在這些字段前面或最后加一個空格、下劃線或者單引號等等,但這樣也會造成不便,比如在EXCEL表中對這些數據對比、排序、操作時也會有問題,如果將空格或下劃線刪除,又會馬上變為科學計數法,十分不方便。
感謝互聯網,呵呵,馬上找到了合適的辦法,在導出時就指定了該列為文本格式,這樣的話,用EXCEL打開文件也就是正常的了。
在下面的代碼中,我的0、4、5列分別是工號(14位數字)、身份證號碼、聯系電話,已被指定為文本格式,在實際使用中,可根據自己的數據情況進行修改,但要記住第一列是Cells(0),以此類推。
指定文本格式
Protected Sub GV_list_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GV_list.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Cells(0).Attributes.Add("style", "vnd.ms-excel.numberformat:@;")
e.Row.Cells(4).Attributes.Add("style", "vnd.ms-excel.numberformat:@;")
e.Row.Cells(5).Attributes.Add("style", "vnd.ms-excel.numberformat:@;")
End If
End Sub
如果數據量很大,而你又是一個注重細節的人(在乎文件大小和數據流量的人)的話,也可以定義一個style為文本格式,然后將相應的列指定為此style,下面就是一個例子,而且我對日期格式也進行了指定,這樣的話日期看起來也好看一些。
style方式
'下面的代碼是在導出事件中的
GV_list.RenderControl(htw)
'將css代碼加在此處
response.Write("<style> .text { vnd.ms-excel.numberformat:@; } .cndate {vnd.ms-excel.numberformat:yyyy年m月d日} </style>")
Response.Write(strWriter.ToString)
'下面是一個單獨的過程
Protected Sub GV_list_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GV_list.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Cells(0).Attributes.Add("class", "text")
e.Row.Cells(4).Attributes.Add("class", "text")
e.Row.Cells(5).Attributes.Add("class", "text")
e.Row.Cells(6).Attributes.Add("class", "cndate")
End If
End Sub
邊學邊做,花了半天的時間,將整個GridView導出數據到EXCEL的功能了解了一個大概,現匯總一下和大家一起分享,因為這次的數據基本可以肯定沒有超過六萬條的可能,就沒有考慮OFFICE2003無法打開的情況,而且如果數據超過了最大允許條數,因為生成并下載的實際上文本格式,也可以直接使用OFFICE2007來打開操作,關于多個工作表導出及導出為“真正”的EXCEL文件的。