2014年2月12日 星期三

[ASP.NET C#] 將 GridView 資料匯出成 Excel、Word

Reference:http://www.dotblogs.com.tw/walter/archive/2010/05/04/export-gridview-to-excel.aspx

將 GridView 資料匯出成 Excel、Word

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

先來看程式執行畫面:
 

 存檔後 Excel 開啟畫面:

 存檔後 Word 開啟畫面:

 Function 程式碼如下:
01/// <summary>匯出成Excel</summary>
02public static void ExportExcel(System.Web.UI.WebControls.GridView vGridView, string vFileName, Page vPage)
03{
04    ExportToOfficeFile(vGridView, vFileName + ".xls", vPage);
05}
06 
07/// <summary>匯出成Word</summary>
08public static void ExportWord(System.Web.UI.WebControls.GridView vGridView, string vFileName, Page vPage)
09{
10    ExportToOfficeFile(vGridView, vFileName + ".doc", vPage);
11}
12 
13/// <summary>
14/// 將GridView內容以HTML存成Excel、Word檔案,儲存後內容含格式資訊
15/// 須設定頁面EnableEventValidation="false"
16/// </summary>
17/// <param name="vGridView">GridView物件名稱</param>
18/// <param name="vFileName">存檔檔名</param>
19/// <param name="vPage">來源Page頁面(ex:Page)</param>
20/// <remarks>
21/// 程式做法:
22///   利用GridView自行Render出與網頁上格式相同的HTML,
23///   配合application/vnd.xls MIME Type,讓資料可以直接在Excel、Word中重現
24/// 註:
25///   使用此 Function 須 using System.Web
26/// </remarks>
27private static void ExportToOfficeFile(System.Web.UI.WebControls.GridView vGridView, string vFileName, Page vPage)
28{
29    //關閉換頁跟排序
30    //說明:若GridView無分頁功能、或有啟用分頁但只有1頁的資料時,則直接將資料Render出來
31    //      若有啟用分頁功能且頁數有2頁以上,當DataSource為null時,則不進行轉換為Excel的動作
32    if (vGridView.AllowPaging && vGridView.DataSource != null)
33    {
34        vGridView.AllowSorting = false;
35        vGridView.AllowPaging = false;
36        vGridView.DataBind();
37    }
38 
39    if (vGridView.PageCount == 1)
40    {
41        //瀏覽器為IE時將檔名編碼,避免存檔後中文檔名會變亂碼
42        string strFileName = string.Empty;
43        if (HttpContext.Current.Request.Browser.Browser == "IE")
44            strFileName = HttpUtility.UrlPathEncode(vFileName);
45        else
46            strFileName = vFileName;
47 
48        HttpContext.Current.Response.Clear();
49        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
50        HttpContext.Current.Response.ContentType = "application/vnd.xls";
51        HttpContext.Current.Response.AddHeader("content-disposition""attachment;filename=" + strFileName);
52        HttpContext.Current.Response.AddHeader("mata""http-equiv=Content-Type content=text/html;charset=big5");
53 
54        //註:若中文字會變亂碼,則替換下面的程式試試
55        //HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("big5")
56        //HttpContext.Current.Response.Write("<meta http-equiv=Content-Type content=text/html;charset=utf-8>")
57        //HttpContext.Current.Response.Write("<head><meta http-equiv=Content-Type content=text/html;charset=big5></head>")
58        //HttpContext.Current.Response.Charset = "big5";
59 
60        System.IO.StringWriter sw = new System.IO.StringWriter();
61        System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);
62 
63        //建立假HtmlForm避免以下錯誤:
64        //Control 'GridView1' of type 'GridView' must be placed inside a form tag with runat=server
65        //另一種做法是建立 override VerifyRenderingInServerForm function,在function內不寫程式碼
66        //這樣就可以直接執行 GridView1.RenderControl(htw)
67        System.Web.UI.HtmlControls.HtmlForm hf = new System.Web.UI.HtmlControls.HtmlForm();
68        vPage.Controls.Add(hf);
69        hf.Controls.Add(vGridView);
70        hf.RenderControl(htw);
71 
72        HttpContext.Current.Response.Write(sw.ToString().Replace("<div>""").Replace("</div>"""));
73        HttpContext.Current.Response.End();
74    }
75    else
76    {
77        throw new ArgumentException("無資料來源!GridView有分頁時," +
78            "在呼叫SaveToOfficeFile函式前須重新繫結資料," +
79            "請在呼叫此函式前再次給予資料來源!");
80    }
81}

要匯出時以下列方式進行呼叫即可:
ExportExcel(GridView1, "網站每日瀏覽次數", Page);


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


沒有留言:

張貼留言