需求描述
實際應用中,我們可能需要導出表格內容,或者在頁面回發時根據用戶權限下載文件(注意,這里的導出與下載,都是在后臺進行的,和普通的一個鏈接下載文件不同)。
點擊按鈕導出表格
由于FineUI 默認支持AJAX,而導出與下載其實是一種破壞AJAX的操作,因為一般的導出代碼如下所示:
1 Response.ClearContent(); 2 Response.AddHeader("content-disposition", "attachment; filename=下載的文件.txt"); 3 Response.ContentType = "text/plain"; 4 Response.ContentEncoding = System.Text.Encoding.UTF8; 5 Response.Write("下載的文件內容"); 6 Response.End();
這里直接對Response對象進行操作,所以在導出和下載時要禁用AJAX。
比如通過按鈕導出表格內容,我們來看下導出按鈕的標簽定義:
1 <f:Button ID="Button1" EnableAjax="false" DisableControlBeforePostBack="false" 2 runat="server" Text="導出為Excel文件" OnClick="Button1_Click"> 3 </f:Button>
這里兩個參數要注意:
- EnableAjax:表明本次導出操作非AJAX,也就是說點擊此按鈕時頁面會刷新,但是頁面上其他的操作任然是AJAX的。
- DisableControlBeforePostBack:這個參數默認是true,就是在AJAX操作之前禁用按鈕,防止用戶操作過快多次點擊。這里非AJAX操作,自然要禁掉。
至于,表格的標簽以及導出的代碼,不是這篇文章的重點,就不再羅列,需要的網友可自行下載源代碼。
- 運行頁面截圖
- 下載的文件
選擇需要導出的列
有時我們僅僅需要導出表格中需要的列,最終實現效果如下所示:
- 在彈出窗口中選擇需要導出的列
- 點擊"導出"按鈕產生的文件
這里我們的關注點不是如何導出選中的列,而是在那個后臺消息處理中做這個導出?
實際上,當我們點擊彈出窗體的"導出" 按鈕時,事件處理是在Window的OnClose事件中進行的,如下所示:
1 protected void Window1_Close(object sender, FineUI.WindowCloseEventArgs e) 2 { 3 Response.ClearContent(); 4 Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls"); 5 Response.ContentType = "application/excel"; 6 Response.ContentEncoding = System.Text.Encoding.UTF8; 7 Response.Write(GetGridTableHtml(Grid1, e.CloseArgument.Split('#'))); 8 Response.End(); 9 }
同樣,由于這個過程直接操作了Response對象,會破壞FineUI默認的AJAX過程,所以關鍵點是要設置Window的EnableAjax=false,如下所示:
1 <f:Window ID="Window1" Title="選擇需要導出的列" Hidden="true" EnableIFrame="true" 2 EnableMaximize="true" Target="Top" EnableResize="true" runat="server" OnClose="Window1_Close" 3 IsModal="true" Width="450px" Height="250px" EnableAjax="false"> 4 </f:Window>
表格行內文件下載(LineButtonField)
先來看下最終實現的效果:
注意,在這個界面中,不同按鈕是否禁用AJAX不同:
- "選中了哪些行":啟用AJAX
- "按鈕"列:啟用AJAX
- "下載"列:禁用AJAX
如果是僅僅設置表格的 EnableAjax=false,雖然可能正常完成"下載"列的功能,但是"按鈕"列也會導致頁面刷新,這就不對。
解決辦法也很簡單,讓表格繼承PageManager或者Web.config的默認設置(EnableAjax=true),然后設置"下載"列的EnableAjax=false,如下所示:
1 <f:LinkButtonField HeaderText=" " Width="80px" CommandName="Action1" Text="按鈕" /> 2 <f:LinkButtonField HeaderText=" " EnableAjax="false" Width="80px" CommandName="Action2" Text="下載" />
再來看下后臺的事件處理:
protected void Grid1_RowCommand(object sender, FineUI.GridCommandEventArgs e) { object[] keys = Grid1.DataKeys[e.RowIndex]; string result = String.Format("你點擊了第 {0} 行,第 {1} 列,行命令是 {2}", e.RowIndex + 1, e.ColumnIndex + 1, e.CommandName) + "<br>" + String.Format("當前行數據 - 編號:{0},姓名:{1}", keys[0], keys[1]); if (e.CommandName == "Action1") { // AJAX回發 labResult.Text = result; } else if (e.CommandName == "Action2") { result = result.Replace("<br>", "\r\n"); // 非AJAX回發 Response.ClearContent(); Response.AddHeader("content-disposition", "attachment; filename=row_" + e.RowIndex + ".txt"); Response.ContentType = "text/plain"; Response.ContentEncoding = System.Text.Encoding.UTF8; Response.Write(result); Response.End(); } }
本章小結
本篇文章介紹了導出表格與下載文件的三個不同場景,大家要意識到這種對Response的直接操作,破壞了FineUI的默認AJAX處理,因此要禁用AJAX。
源代碼與在線示例
本系列所有文章的源代碼均可自行下載:http://fineui.codeplex.com/
在線示例:
- http://fineui.com/demo/#/demo/grid/grid_excel.aspx
- http://fineui.com/demo/#/demo/grid/grid_excel_selectcolumns.aspx
- http://fineui.com/demo/#/demo/grid/grid_rowcommand_download.aspx
第三個示例會增加到下個版本的FineUI(開源版)中,所以在線示例暫不可用,需要的同學請自行下載全部源代碼,本機運行。
如果本文對你有所啟發或者幫助,請猛擊“好文要頂”,支持原創,支持三石!
另附24張專業版高清大圖
《FineUI小技巧》系列文章目錄
文章列表