1. 程式人生 > >DisplayTag外部(External paging)分頁如何匯出全部資料?????

DisplayTag外部(External paging)分頁如何匯出全部資料?????

轉了幾篇文章。書名號裡面的是我自己加上去的。


DisplayTag外部(External)分頁如何匯出全部資料

最近大量使用了displayTag標籤,真是很好用,各種功能設計得很體貼、很實用,效率也不錯。匯出、分頁、排序都很方便,外

觀設計也很便於修改。 
  對於大資料量的分頁與排序,一般推薦使用外部(External)排序分頁(詳細介紹請看我翻譯的官方文件:

置一個引數(export.amount),或者在標籤中設定一個引數,就可以實現全部資料的匯出。 
  這個問題該如何解決呢? 
  其實當使用外部分頁的時候,由於此時List中只有當前頁的資料,正常來講是無法匯出全部資料。問題的關鍵就是如何讓後

臺的servlet知道使用者的請求是匯出資料。注意到,在匯出的時候,DisplayTag標籤會使用一個位址列引數來傳遞匯出的型別,這

個引數的名稱很怪,是個數字與字母的組合。查閱了一下文件及原始碼,發現這實際上displayTag定義的一個常量:

TableTagParameters.PARAMETER_EXPORTING。任何時候傳遞匯出型別的時候都使用這個引數名。這樣我們就可以在伺服器端通過

判斷這個引數的有無,來知道使用者的請求是分頁展示資料,還是匯出資料。若是匯出,那麼可以將分頁SQL語句特殊處理一下,將

全部資料返回。然後displayTag就自動將其全部匯出為使用者指定的型別了。 
  以上說明了解決DisplayTag外部(External)分頁如何匯出全部資料的大致思路,希望對使用過這個標籤遇到這個問題網友有

所幫助。

2009-07-16 
注: 
如果還不行,可以試著將每頁的記錄數設定為全部記錄的總數。
 

《《《《《《《《《《《《《《《《《《《《
我做做好事,給個例子哈,看大家那麼辛苦~~~~~~


這是我用struts2做的外部分頁action類(起名叫做StandardPageAction)中的execute方法,大家管中窺豹:

public String execute()  {
        try{
         StandardDAO dao=new StandardDAO();
         final int pageSize = 15;////這裡確定頁大小。在實際應用時,頁大小最好在此處確定。
        // 獲取當前頁碼,displaytag通過引數"page"傳遞這個值
        int pageNumber;
        if (request.getParameter("page") != null
                && !"".equals(request.getParameter("page"))) {
            pageNumber = Integer.parseInt(request.getParameter("page"));
        } else {
            pageNumber = 1;
        }
        StandardPageList pageList  = new StandardPageList();

        //Test:中文資料,即豬;Test1:數字資料,即1;
        hql1 = "from Test"; //注意:這裡使用的Test,即類名,而非資料庫名test。面向物件!!!!!!!!!
        
        //由於是使用外部分頁,所以在這裡考慮匯出全部資料的處理。判斷請求是否含有“匯出”引數。
        Object p = request.getParameter(TableTagParameters.PARAMETER_EXPORTING);
        List pages = null;
        if(p!=null){//匯出資料時,匯出所有資料。
            pages = dao.getAllData(hql1);
        }
        else //非匯出資料時,按照外部分頁的要求,僅提取一頁的資料用於顯示。
            pages = dao.getData(pageNumber,pageSize,hql1);//hql1需通過外部使用setter設值,可參照上面的hql語句。。

。。
        // 設定當前頁碼
        pageList.setPageNumber(pageNumber);
        // 設定當前頁列表
        pageList.setList(pages);
        // 設定page size
        pageList.setObjectsPerPage(pageSize);
        // 設定總頁數
        hql2 = "select count(*) from Test";//注意:這裡使用的Test,即類名,而非資料庫名test。面向物件!!!!!!

!!!
        pageList.setFullListSize(dao.getDataSize(hql2));//hql2需通過外部使用setter設值,可參照上面的hql語句。。。


        //設定pageList給頁面中的displaytag的table標籤以顯示結果。
        request.setAttribute("pageList", pageList);
        }catch(NullPointerException ex){
            System.out.println("注意:你沒給hql1、hql2賦值!!!!!!!!!!!!");
        }
        return SUCCESS;
    }


這兩個類都是要自己去實現的,沒辦法,外部分頁大部分都是這樣子去做的:
StandardDAO//負責執行hql語句。
StandardPageList//實現了PaginatedList介面


另外提醒一下,上面的hql1、hql2語句嘛,本來賦值不應在action裡面直接賦值的,最好是由外部setter來注入值(=。= 夠專業

吧~~~~~~~~)。我這裡因為是測試,所以貪方便了。沒辦法啦,這幾天一直在弄displaytag,研究完畢,測試完畢後就能大範圍

應用到我的專案裡了。

大家仔細看完最近發的博文就知道了。

話說大家要有自己的想法,不要只知道copy、paste,大家要多寫寫博文,多多交流,多為後來人指路~~~~~~

這裡是“開源的世界”open source~~~~~~~

》》》》》》》》》》》》》》》》》》》》》

《《《《《《《《《《《《《《《《《《《《《

後記:後來由於相關的專案需要,所以又加上了一些東西,比如設計了一個tableDecorator(實現了

org.displaytag.decorator.TableDecorator),還有前面提到的hql1、hql2需要在外部設定值的問題。。。所以進行了一些嘗試

。。。起初我想用一個新的action:NewAction,從它那裡設定hql1、hql2,然後跳轉到StandardPageAction。。。但是實踐證明

這樣並不成功。。。

在思考中,想到了一個方法,就是“繼承”,用NewAction繼承StandardPageAction,然後直接使用NewAction,這樣就不需要分

幾步跳轉了。。。能夠有效地實現效果。。。同理,由於不同的需要,也可以設計各種NewTableDecorator來達到不同的顯示效果

。我把這種處理方案稱之為“定製”設計。(注:TableDecorator可以用來給生成的列表新增一些自定義的列,比如用於增刪改

查的連結)


當然,後來我還想了一下,我可以把引數傳到action中的例項變數去,網上也有相應的方法。這樣就能達到一個action,多次復

用,從而可以有不同效果的目的。但是後來想了一下,擔心過於機械化了,而且引數可能會太多,所以終究沒有采納。。。

》》》》》》》》》》》》》》》》》》》》》》


關於使用displaytag匯出時的若干問題
問題:當export="list" 時不能到全部匯出.

解決方法:

修改TableTag.java

doExport()

在   boolean exportFullList = this.properties.getExportFullList();

後新增以下程式碼: 

if (exportFullList) {
   this.tableModel.setRowListPage(this.tableModel.getRowListFull());
 }

出現亂碼的地方有三個地方,當匯出中文列表名,中文表格資料和匯出檔名時,會產生亂碼現象。

解決方法:

更改配置檔案displaytag.properties,使用displaytag-export-poi.jar包。更改

export.excel.class=org.displaytag.export.ExcelView   為  export.excel.class=org.displaytag.excel.ExcelHssfView,這

樣可以解決中文表格資料的問題。對於中文列表名亂碼的問題,必須更改org.displaytag.excel.ExcelHssfView原始碼。具體如

下:

原來:

                  HSSFCell cell = xlsRow.createCell((short) colNum++);
                    cell.setCellValue(columnHeader);
                    cell.setCellStyle(headerStyle);
                    cell.setEncoding(HSSFCell.ENCODING_UTF_16);

改為:

               HSSFCell cell = xlsRow.createCell((short) colNum++);
               cell.setEncoding(HSSFCell.ENCODING_UTF_16);
              cell.setCellValue(columnHeader);
                    cell.setCellStyle(headerStyle);
   匯出檔名:

TableTag.java

原來:

if (StringUtils.isNotEmpty(filename))
        {
            response.setHeader("Content-Disposition", //$NON-NLS-1$
                "attachment; filename=\"" + filename + "\""); //$NON-NLS-1$ //$NON-NLS-2$
        }

改為:

if (StringUtils.isNotEmpty(filename)) {
   response
     .setHeader(
       "Content-Disposition", //$NON-NLS-1$
       "attachment; filename=" + new String(filename.getBytes("gb2312"), ("ISO8859-1"))); //$NON-NLS-1$ //$NON-

NLS-2$
  }


2009-07-16
關於displaytag external paging 第二種分頁方法匯出所有資料的問題
首先要感謝zuiyanwangyue提供給我的解決方法!!! 
我是採用了displaytag提供的第二種分頁方法

// 頁數的引數名 
String pageIndexName = new ParamEncoder(Constants.ABSENCE_LIST) 
.encodeParameterName(TableTagParameters.PARAMETER_PAGE); 
// 每頁顯示的條數 
int pageSize = 15; 
// 當前頁 
int pageIndex = GenericValidator.isBlankOrNull(request.getParameter(pageIndexName)) ? 0 : (Integer.parseInt

(request.getParameter(pageIndexName)) - 1);

// 統計總記錄數 
int resultSize = (Integer) absMgr.getPypDepartmentAbsByTimesCount(condition[0], condition[1], condition[2]).get

(0); 
//獲取匯出的狀態如果不為空.說明點選了匯出按鈕 
String exportValue = request.getParameter(TableTagParameters.PARAMETER_EXPORTING); 
if (exportValue == null || exportValue.equals("")) { 
// 取得當前分頁資料 
studentAbsList = absMgr.getPypDepartmentAbsByTimesSql(pageIndex, pageSize, condition[0], condition[1], condition

[2]); 
}else { 
//獲取所有資料 
studentAbsList = absMgr.fastGetDepAbs(condition); 
}

//缺勤資訊 
request.setAttribute(Constants.ABSENCE_LIST, studentAbsList);


我覺得你說的問題可能和Displaytag的設計初衷有關,如果是一個特殊的列表,亦即table標籤中的partialList="true",那麼

Table標籤的處理類在進行初始化引數時(見TableTag的initParameters()方法),會做出相應的處理使得在頁面上看到的資料和導

出的資料條數是一樣的,它並沒有區別對待不同的媒體型別。

見TableTag的1065以及1066兩行: 
PaginationHelper paginationHelper = new PaginationHelper(pageNumber, pagesize); 
this.tableIterator = paginationHelper.getIterator(this.list);

如果想要Displaytag適合你的要求恐怕就要修改Displaytag的原始碼了,增加以下判斷: 
//檢查當前的媒體型別 
            if(MediaTypeEnum.HTML.equals(this.currentMediaType)){ 
            PaginationHelper paginationHelper = new PaginationHelper(pageNumber, pagesize); 
                this.tableIterator = paginationHelper.getIterator(this.list); 
            }else { 
            this.tableIterator = IteratorUtils.getIterator(this.list); 
            } 
即如果是在頁面上顯示則進行分頁,否則的話就遍歷整個列表。 
這樣就應該滿足你的要求了。

幫我解決此問題的人是zuiyanwangyue 
一下是他的部落格地址

真的非常感謝他.因為本人還是學生...程式碼量不多.看了原始碼3天了,還是一點頭緒都沒有. 
今天收到zuiyanwangyue發來的訊息.嘗試改了一下原始碼.結果行了.在這裡再一次感謝zuiyanwangyue.謝謝!!!