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.謝謝!!!