將 GridView 資料匯出成 Excel、Word

  • 21535
  • 0
  • .NET
  • 2013-08-27

最近 User 提出一個需求,要將查出的資料匯出成 Excel ,於是將之前寫的 Function 整理出來,儲存後的內容是 HTML,可以保存字型、顏色的格式設定。

最近 User 提出一個需求,要將查出的資料匯出成 Excel ,於是將之前寫的 Function 整理出來,儲存後的內容是 HTML,可以保存字型、顏色的格式設定。

 

先來看程式執行畫面:

 

 

 存檔後 Excel 開啟畫面:

 

 存檔後 Word 開啟畫面:

 

 Function 程式碼如下:

/// <summary>匯出成Excel</summary>
public static void ExportExcel(System.Web.UI.WebControls.GridView vGridView, string vFileName, Page vPage)
{
    ExportToOfficeFile(vGridView, vFileName + ".xls", vPage);
}

/// <summary>匯出成Word</summary>
public static void ExportWord(System.Web.UI.WebControls.GridView vGridView, string vFileName, Page vPage)
{
    ExportToOfficeFile(vGridView, vFileName + ".doc", vPage);
}

/// <summary>
/// 將GridView內容以HTML存成Excel、Word檔案,儲存後內容含格式資訊
/// 須設定頁面EnableEventValidation="false"
/// </summary>
/// <param name="vGridView">GridView物件名稱</param>
/// <param name="vFileName">存檔檔名</param>
/// <param name="vPage">來源Page頁面(ex:Page)</param>
/// <remarks>
/// 程式做法:
///   利用GridView自行Render出與網頁上格式相同的HTML,
///   配合application/vnd.xls MIME Type,讓資料可以直接在Excel、Word中重現
/// 註:
///   使用此 Function 須 using System.Web
/// </remarks>
private static void ExportToOfficeFile(System.Web.UI.WebControls.GridView vGridView, string vFileName, Page vPage)
{
    //關閉換頁跟排序
    //說明:若GridView無分頁功能、或有啟用分頁但只有1頁的資料時,則直接將資料Render出來
    //      若有啟用分頁功能且頁數有2頁以上,當DataSource為null時,則不進行轉換為Excel的動作
    if (vGridView.AllowPaging && vGridView.DataSource != null)
    {
        vGridView.AllowSorting = false;
        vGridView.AllowPaging = false;
        vGridView.DataBind();
    }

    if (vGridView.PageCount == 1)
    {
        //瀏覽器為IE時將檔名編碼,避免存檔後中文檔名會變亂碼
        string strFileName = string.Empty;
        if (HttpContext.Current.Request.Browser.Browser == "IE")
            strFileName = HttpUtility.UrlPathEncode(vFileName);
        else
            strFileName = vFileName;

        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.ContentType = "application/vnd.xls";
        HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + strFileName);
        HttpContext.Current.Response.AddHeader("mata", "http-equiv=Content-Type content=text/html;charset=big5");

        //註:若中文字會變亂碼,則替換下面的程式試試
        //HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("big5") 
        //HttpContext.Current.Response.Write("<meta http-equiv=Content-Type content=text/html;charset=utf-8>")
        //HttpContext.Current.Response.Write("<head><meta http-equiv=Content-Type content=text/html;charset=big5></head>")
        //HttpContext.Current.Response.Charset = "big5";

        System.IO.StringWriter sw = new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);

        //建立假HtmlForm避免以下錯誤:
        //Control 'GridView1' of type 'GridView' must be placed inside a form tag with runat=server
        //另一種做法是建立 override VerifyRenderingInServerForm function,在function內不寫程式碼
        //這樣就可以直接執行 GridView1.RenderControl(htw)
        System.Web.UI.HtmlControls.HtmlForm hf = new System.Web.UI.HtmlControls.HtmlForm();
        vPage.Controls.Add(hf);
        hf.Controls.Add(vGridView);
        hf.RenderControl(htw);

        HttpContext.Current.Response.Write(sw.ToString().Replace("<div>", "").Replace("</div>", ""));
        HttpContext.Current.Response.End();
    }
    else
    {
        throw new ArgumentException("無資料來源!GridView有分頁時," +
            "在呼叫SaveToOfficeFile函式前須重新繫結資料," +
            "請在呼叫此函式前再次給予資料來源!");
    }
}

 

要匯出時以下列方式進行呼叫即可:

ExportExcel(GridView1, "網站每日瀏覽次數", Page);

 

範例程式下載

 

註:在測試時,使用 Excel2007 開啟檔案時會出現如下的提示訊息,目前未查到不詢問的方法:

 

參考資料: