摘要

GridView 匯出 Excel 及 Word 文件是蠻常使用的需求,此篇文章將擴展 GridView 控制項提供匯出 Excel 及 Word 文件的方法。一般在 GridView 匯出的常見下列問題也會在此一併被解決。

GridView 匯出的常見問題:
問題1. GridView 使用 RenderControl 方法產生的錯誤。
問題2. GridView 分頁的問題。
問題3. 匯出檔案名稱產生亂碼的問題。
問題4. 匯出內容產生亂碼的問題。
 

解決 GridView 匯出問題

我們先針對 GridView 匯出的問題,逐一處理解決

問題1. GridView 使用 RenderControl 方法產生的錯誤。

此問題參考上篇「使用 BasePage 來解決 GridView 執行 RenderControl 產生的錯誤」來解決。

 

問題2. GridView 分頁的問題。

在執行匯出時,若 GridView 有使用分頁(AllowPaging=True),則採下列步驟處理。

Step1.取消分頁,即設定 GridView.AllowPaging=False。
Step2.GridView 執行 DataBind,使其重新繫結所有資料,再使用 RenderCotnrol 輸出 HTML 程式碼。
Step3.還原分頁,即設定 GridView.AllowPaging=True。
 

問題3. 匯出檔案名稱產生亂碼的問題。

針對此問題,只需將檔案名稱經 UrlEncode 編碼,即可解決中文檔名的問題。
HttpUtility.UrlEncode(FileName, Encoding)

 

問題4. 匯出內容產生亂碼的問題。

使用 Response 輸出 <meta http-equiv='Content-Type'; content='text/html';charset='utf-8'> 來解決內容亂碼的問題。

 

擴展 GridView 控制項

我們繼承 GridView 命名為 TBGridView,其中新增 Export、ExportExcel、ExportWord 等匯出方法。

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Drawing

Namespace WebControls
    < _
    Description("TBGridView 控制項"), _
    ToolboxData("<{0}:TBGridView runat=server></{0}:TBGridView>") _
    > _
    Public Class TBGridView
        Inherits GridView

        ''' <summary>
        ''' GridView 控制項匯出 Excel 文件。
        ''' </summary>
        Public Sub ExportExcel()
            Export(Encoding.UTF8, "gridview.xls", "application/ms-excel")
        End Sub

        ''' <summary>
        ''' GridView 控制項匯出 Word 文件。
        ''' </summary>
        Public Sub ExportWord()
            Export(Encoding.UTF8, "gridview.doc", "application/ms-word")
        End Sub

        ''' <summary>
        ''' GridView 控制項匯出。
        ''' </summary>
        ''' <param name="Encoding">編碼方式。</param>
        ''' <param name="FileName">檔案名稱。</param>
        ''' <param name="ContentType">內容類型標頭。</param> 
        Public Sub Export(ByVal Encoding As Encoding, ByVal FileName As String, ByVal ContentType As String)
            Dim oResponse As HttpResponse
            Dim oStringWriter As System.IO.StringWriter
            Dim oHtmlWriter As System.Web.UI.HtmlTextWriter
            Dim bAllowPaging As Boolean
            Dim sText As String
            Dim sFileName As String

            If TypeOf Me.Page Is TBBasePage Then
                DirectCast(Me.Page, TBBasePage).IsVerifyRender = False '頁面不需驗證控制項
            End If

            '檔案名稱需經 UrlEncode 編碼,解決中文檔名的問題
            sFileName = HttpUtility.UrlEncode(FileName, Encoding)

            oResponse = HttpContext.Current.Response
            oResponse.Clear()
            sText = "<meta http-equiv='Content-Type'; content='text/html';charset='{0}'>"
            sText = String.Format(sText, Encoding.WebName)
            oResponse.Write(sText)
            oResponse.AddHeader("content-disposition", "attachment;filename=" & sFileName)
            oResponse.ContentEncoding = Encoding
            oResponse.Charset = Encoding.WebName
            oResponse.ContentType = "application/ms-excel"

            ' If you want the option to open the Excel file without saving than
            ' comment out the line below
            ' oResponse.Cache.SetCacheability(HttpCacheability.NoCache)

            oStringWriter = New System.IO.StringWriter()
            oHtmlWriter = New System.Web.UI.HtmlTextWriter(oStringWriter)
            bAllowPaging = Me.AllowPaging
            If bAllowPaging Then
                Me.AllowPaging = False
                If Me.RequiresDataBinding Then
                    Me.DataBind()
                End If
            End If

            Me.RenderControl(oHtmlWriter)

            If bAllowPaging Then
                AllowPaging = bAllowPaging
            End If
            oResponse.Write(oStringWriter.ToString())
            oResponse.End()
        End Sub

    End Class
End Namespace

測試程式

在頁面放置一個 GridView 控制項繫結資料並設定分頁,另外放置二個按鈕分別做「匯出 Excel 文件」及「匯出 Word 文件」的動作。

image

匯出按鈕撰寫的程式碼如下

    Protected Sub btnExcportExcel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExcportExcel.Click
        GridView1.ExportExcel()
    End Sub

    Protected Sub btnExportWord_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportWord.Click
        GridView1.ExportWord()
    End Sub

匯出 Excel 文件的結果如下所示

image

匯出 Word 文件的結果如下所示

image

ASP.NET 魔法學院


DotBlogs Tags: GridView RenderControl ServerControl

Feedback

  • 大竹 2008/6/4 下午 02:32 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    Hi~Jeff:

    感謝你的教學
    不過在第TBGridView 61行中 oResponse.ContentType = "application/ms-excel" 應該是對應到ContentType才是吧!!
    ^^

  • jeff377 2008/6/4 下午 05:14 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to 大竹 :

    沒錯,那個地方應該是 ContentType 參數才對。

  • wawa 2008/6/13 下午 04:37 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    請問大竹大
    contentype的參數是什麼呢 那又該怎成怎樣

  • karro 2008/7/12 下午 12:51 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    請問有辦法把多個gridview分別匯到不同的sheet裡嗎
    或是多個gridview匯到同一張sheet,並以空一列格開
    用以上的方法

  • jeff377 2008/7/13 下午 06:59 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to karro :

    要達到你的需求只能使用 Excel 元件才有辨法。

  • Latte 2008/8/21 下午 03:17 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    請問...我是新手
    這是要建什麼檔才能用??
    裡面的TBBasePage又是什麼?

  • jeff377 2008/8/21 下午 08:29 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to Latte :
    文中有說明了,TBBasePage 你要參考「使用 BasePage 來解決 GridView 執行 RenderControl 產生的錯誤

  • danny760517 2008/8/30 下午 01:00 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    大大我想問一下,有沒有辦法從mysql抓資料並且丟到word指定的表格裡面,但不用gridview的方法

  • Eric 2008/11/21 下午 05:13 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    您好 我是寫C#
    請問寫完這一隻CLASS TBGridView
    GRIDVIEW怎麼去引用它呢??

  • jeff377 2008/11/21 下午 05:55 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to Eric :
    你要編譯成控制項組件,然後加入工具箱即可使用。你可以去參考「ASP.NET 控制項實作」系列文章中,第一篇就有談到如何建立控制項函式庫。

  • mattdo 2009/1/14 下午 01:20 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    請問有關內容編碼的問題
    是不是我也可以用
    Context.Response.ContentEncoding = System.Text.Encoding.UTF8

    這樣的方法來解決??

  • 黑熊 2009/3/27 上午 12:10 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    您好,想請問一下
    如果匯出的時候,不要匯出編輯及刪除這兩欄
    該怎麼做呢?

    試了好多方法都沒用><

    謝謝^^

  • jeff 2009/3/27 上午 09:56 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to 黑熊 :
    先將編輯/刪除的欄位先隱藏再匯出,作業結束後再設回顯示狀態即可。

  • 黑熊 2009/3/27 下午 02:51 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to jeff :
    我有這樣想過,但是我找不到參數

    editing or deleting= false??

  • jeff 2009/3/27 下午 05:01 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to 黑熊 :
    你應該是去載 GridView.Columns 中的 CommandField,直接將該 CommandField.Visible 設為 False 即可。

  • Jeremy 2009/8/21 上午 10:21 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出


    這邊提供另外一種作法,供各位參考
    http://mattberseth.com/blog/2007/04/export_gridview_to_excel_1.html

  • atowngit 2009/10/12 下午 10:00 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    請問:

    若想做個接口,比方說:先用一個 DataTable 物件將 GridView 的資料接出來,之後,在針對這個 Table 然後匯出 Excel 檔?

  • jack 2009/10/26 上午 11:13 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    你好 我是新手
    程式碼編譯出現
    'Namespace' 陳述式只可以發生在檔案或命名空間層級。
    請問要如何解決

  • hatelove 2009/10/26 上午 11:18 回覆

    # re: 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出

    to jack :

    先瞭解一下你是在哪一支程式底下撰寫這些code的?

    以上述的範例,NameSpace的問題,應該是因為您用錯檔案。

    這是自訂控制項,也就是用「類別庫」專案裡面,新增一個「類別檔」,繼承GridView修改的。

    您的例子應該不是這樣做...才會出現'Namespace' 陳述式只可以發生在檔案或命名空間層級。'的錯誤

標題 *
名稱 *
Email (將不會被顯示)
Url
回應
登入後使用進階評論
Please add 5 and 8 and type the answer here: