FineUI小技巧(3)表格匯出與檔案下載

三生石上(FineUI控制元件)發表於2014-06-24

需求描述

實際應用中,我們可能需要匯出表格內容,或者在頁面回發時根據使用者許可權下載檔案(注意,這裡的匯出與下載,都是在後臺進行的,和普通的一個連結下載檔案不同)。

點選按鈕匯出表格

由於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>

這裡兩個引數要注意:

  1. EnableAjax:表明本次匯出操作非AJAX,也就是說點選此按鈕時頁面會重新整理,但是頁面上其他的操作任然是AJAX的。
  2. DisableControlBeforePostBack:這個引數預設是true,就是在AJAX操作之前禁用按鈕,防止使用者操作過快多次點選。這裡非AJAX操作,自然要禁掉。

至於,表格的標籤以及匯出的程式碼,不是這篇文章的重點,就不再羅列,需要的網友可自行下載原始碼。

  1. 執行頁面截圖
  2. 下載的檔案

選擇需要匯出的列

有時我們僅僅需要匯出表格中需要的列,最終實現效果如下所示:

  1.  在彈出視窗中選擇需要匯出的列
  2. 點選"匯出"按鈕產生的檔案

這裡我們的關注點不是如何匯出選中的列,而是在那個後臺訊息處理中做這個匯出?

實際上,當我們點選彈出窗體的"匯出" 按鈕時,事件處理是在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不同:

  1. "選中了哪些行":啟用AJAX
  2. "按鈕"列:啟用AJAX
  3. "下載"列:禁用AJAX

如果是僅僅設定表格的 EnableAjax=false,雖然可能正常完成"下載"列的功能,但是"按鈕"列也會導致頁面重新整理,這就不對。

解決辦法也很簡單,讓表格繼承PageManager或者Web.config的預設設定(EnableAjax=true),然後設定"下載"列的EnableAjax=false,如下所示:

1 <f:LinkButtonField HeaderText="&nbsp;" Width="80px" CommandName="Action1" Text="按鈕" />
2 <f:LinkButtonField HeaderText="&nbsp;" 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/

線上示例:

  1. http://fineui.com/demo/#/demo/grid/grid_excel.aspx
  2. http://fineui.com/demo/#/demo/grid/grid_excel_selectcolumns.aspx
  3. http://fineui.com/demo/#/demo/grid/grid_rowcommand_download.aspx

第三個示例會增加到下個版本的FineUI(開源版)中,所以線上示例暫不可用,需要的同學請自行下載全部原始碼,本機執行。 

 

如果本文對你有所啟發或者幫助,請猛擊“好文要頂”,支援原創,支援三石!

 

另附24張專業版高畫質大圖

 

 

《FineUI小技巧》系列文章目錄

 

相關文章