欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

displaytag數據庫分頁方法及導出數據的問題處理

系統 2183 0

displaytag數據庫分頁方法及導出數據的問題處理

文章分類: Java編程

最近在使用 springside 配合 struts2 + spring2.5 + hibernate3 做項目,為了不重復發明輪子(其實是懶,而且項目時間有限),使用到了 displaytag 作為頁面顯示的組件。 displaytag 具有分頁顯示,導出報表,頁面排序等功能。與其相似的還有另外一個工具叫做 extremecomponent 。雖然 displaytag 功能很多,但是也有很多問題:第一就是他的默認分頁和排序是基于內存分頁的,這個在實際項目中是不太可行的,所以需要修改。第二就是他的導出報表的功能,他主要能導出 5 種格式 csv , xls xml , pdf , rtf (主要是 pdf excel ),其中默認的 pdf excel 導出都有亂碼問題。

?

本文主要是講述如何解決這 2 個問題。

displaytag 官網: http://displaytag.sourceforge.net/1.2/

基本的配置和使用你可以從官網上了解到,本文不做說明。

本文的解決方法一部分是來自于網絡其他文章。

好了首先是第一個分頁問題,我們要使 displaytag 能夠用數據庫分頁,而不僅僅是內存分頁。 displaytag 其實已經提供了 2 種方法讓你實現數據庫,在其官網中有介紹

http://displaytag.sourceforge.net/1.2/tut_externalSortAndPage.html

我使用的是第一種實現,實現 displaytag PaginatedList 接口:

?

Java代碼 復制代碼
  1. import ?java.util.List; ??
  2. ??
  3. import ?org.displaytag.pagination.PaginatedList; ??
  4. import ?org.displaytag.properties.SortOrderEnum; ??
  5. import ?org.springside.modules.orm.Page; ??
  6. ??
  7. /** ?
  8. ?*?實現displaytag的數據庫的分頁接口 ?
  9. ?*?并集成springside的Page類, ?
  10. ?*?這樣可以同時使用?springside的數據庫分頁功能及displaytag的分頁顯示功能 ?
  11. ?*?@author?tianjl ?
  12. ?* ?
  13. ?*?@param?<T> ?
  14. ?*/ ??
  15. public ? class ?DBPaginatedList<T>? extends ?Page<T>? implements ?PaginatedList?{ ??
  16. ??
  17. ???? private ?SortOrderEnum?sortDirection?=?SortOrderEnum.ASCENDING; ??
  18. ???? private ?String?sortCriterion; ??
  19. ??
  20. ???? //?--?構造函數?--// ??
  21. ???? public ?DBPaginatedList()?{ ??
  22. ???????? super (); ??
  23. ????} ??
  24. ??
  25. ???? public ?DBPaginatedList( int ?pageSize)?{ ??
  26. ???????? super (pageSize); ??
  27. ????} ??
  28. ??
  29. ???? public ? int ?getFullListSize()?{ ??
  30. ???????? return ?( int )?totalCount; ??
  31. ????} ??
  32. ??
  33. ???? public ?List<T>?getList()?{ ??
  34. ???????? return ?result; ??
  35. ????} ??
  36. ??
  37. ???? public ? int ?getObjectsPerPage()?{ ??
  38. ???????? return ?pageSize; ??
  39. ????} ??
  40. ??
  41. ???? public ? int ?getPageNumber()?{ ??
  42. ???????? return ?pageNo; ??
  43. ????} ??
  44. ??
  45. ???? public ? void ?setSortCriterion(String?fieldN)?{ ??
  46. ???????? this .sortCriterion?=?(fieldN?==? null ?||? "null" .equals(fieldN))??? "1" ??
  47. ????????????????:?fieldN; ??
  48. ????} ??
  49. ??
  50. ???? public ?String?getSortCriterion()?{ ??
  51. ???????? return ? this .sortCriterion; ??
  52. ????} ??
  53. ??
  54. ???? public ? void ?setSortDirection(String?dir)?{ ??
  55. ???????? if ?(dir?==? null ?||? "null" .equals(dir)?||? "asc" .equalsIgnoreCase(dir))?{ ??
  56. ????????????sortDirection?=?SortOrderEnum.ASCENDING; ??
  57. ????????}? else ?{ ??
  58. ????????????sortDirection?=?SortOrderEnum.DESCENDING; ??
  59. ????????} ??
  60. ????} ??
  61. ???? ??
  62. ???? public ? void ?setSortDirection(SortOrderEnum?sortDirection)?{ ??
  63. ???????? this .sortDirection?=?sortDirection; ??
  64. ????} ??
  65. ??
  66. ???? public ?String?getSortDirectionStr()?{ ??
  67. ???????? if ?(sortDirection?==?SortOrderEnum.ASCENDING) ??
  68. ???????????? return ? "ASC" ; ??
  69. ???????? else ??
  70. ???????????? return ? "DESC" ; ??
  71. ????} ??
  72. ??
  73. ???? public ?SortOrderEnum?getSortDirection()?{ ??
  74. ???????? return ?sortDirection; ??
  75. ????} ??
  76. ??
  77. ???? public ?String?getSearchId()?{ ??
  78. ???????? return ?Integer.toHexString(pageSize?*? 10000 ?+?pageNo); ??
  79. ????} ??
  80. ??
  81. }??
      import java.util.List;

import org.displaytag.pagination.PaginatedList;
import org.displaytag.properties.SortOrderEnum;
import org.springside.modules.orm.Page;

/**
 * 實現displaytag的數據庫的分頁接口
 * 并集成springside的Page類,
 * 這樣可以同時使用 springside的數據庫分頁功能及displaytag的分頁顯示功能
 * @author tianjl
 *
 * @param <T>
 */
public class DBPaginatedList<T> extends Page<T> implements PaginatedList {

	private SortOrderEnum sortDirection = SortOrderEnum.ASCENDING;
	private String sortCriterion;

	// -- 構造函數 --//
	public DBPaginatedList() {
		super();
	}

	public DBPaginatedList(int pageSize) {
		super(pageSize);
	}

	public int getFullListSize() {
		return (int) totalCount;
	}

	public List<T> getList() {
		return result;
	}

	public int getObjectsPerPage() {
		return pageSize;
	}

	public int getPageNumber() {
		return pageNo;
	}

	public void setSortCriterion(String fieldN) {
		this.sortCriterion = (fieldN == null || "null".equals(fieldN)) ? "1"
				: fieldN;
	}

	public String getSortCriterion() {
		return this.sortCriterion;
	}

	public void setSortDirection(String dir) {
		if (dir == null || "null".equals(dir) || "asc".equalsIgnoreCase(dir)) {
			sortDirection = SortOrderEnum.ASCENDING;
		} else {
			sortDirection = SortOrderEnum.DESCENDING;
		}
	}
	
	public void setSortDirection(SortOrderEnum sortDirection) {
		this.sortDirection = sortDirection;
	}

	public String getSortDirectionStr() {
		if (sortDirection == SortOrderEnum.ASCENDING)
			return "ASC";
		else
			return "DESC";
	}

	public SortOrderEnum getSortDirection() {
		return sortDirection;
	}

	public String getSearchId() {
		return Integer.toHexString(pageSize * 10000 + pageNo);
	}

}

    

?

?

這里要講一下, Page 類是 springside 提供的對分頁功能的封裝。這里你應該去掉繼承 Page 類,并配合你自己的數據庫分頁功能。在 Page 類中,有一個內部的 List 對象,存放著真實的結果集數據。 displaytag 在分析時,會判斷你傳給他的對象是否實現了 PaginatedList 接口,如果實現了,它會從該對象中調用 getList() 方法,獲取結果集。所以在你的使用中,你應該注意你的數據庫分頁代碼和 PaginatedList 接口的實現類的配合。

Java代碼 復制代碼
  1. public ? interface ?PaginatedList{ ??
  2. ???? /** ?
  3. ?????*?獲取分頁的結果集 ?
  4. ?????*/ ??
  5. ????List?getList(); ??
  6. ??
  7. ???? /** ?
  8. ?????*?獲取當前頁數 ?
  9. ?????*/ ??
  10. ???? int ?getPageNumber(); ??
  11. ??
  12. ???? /** ?
  13. ?????*?獲取每頁的個數 ?
  14. ?????*/ ??
  15. ???? int ?getObjectsPerPage(); ??
  16. ??
  17. ???? /** ?
  18. ?????*?獲取整個結果集的個數 ?
  19. ?????*/ ??
  20. ???? int ?getFullListSize(); ??
  21. ??
  22. ???? /** ?
  23. ?????*?獲取根據哪一列排序 ?
  24. ?????*/ ??
  25. ????String?getSortCriterion(); ??
  26. ??
  27. ???? /** ?
  28. ?????*?升序還是降序 ?
  29. ?????*/ ??
  30. ????SortOrderEnum?getSortDirection(); ??
  31. ??
  32. ???? /** ?
  33. ?????*?返回一個查詢的id ?
  34. ?????*/ ??
  35. ????String?getSearchId(); ??
  36. }??
      public interface PaginatedList{
    /**
	 * 獲取分頁的結果集
     */
    List getList();

    /**
	 * 獲取當前頁數
     */
    int getPageNumber();

    /**
	 * 獲取每頁的個數
     */
    int getObjectsPerPage();

    /**
	 * 獲取整個結果集的個數
     */
    int getFullListSize();

    /**
	 * 獲取根據哪一列排序
     */
    String getSortCriterion();

    /**
	 * 升序還是降序
     */
    SortOrderEnum getSortDirection();

    /**
	 * 返回一個查詢的id
     */
    String getSearchId();
}
    

?

?

這里請注意,你的數據庫分頁代碼和 displaytag 的分頁其實是 2 個不同的實現,也就是說,你在之后的使用中,要同時為你數據庫分頁的代碼設置分頁值,排序值,并且也要為 PaginatedList 接口的實現類設置分頁值及排序值。 當然你如果設計的好,能將 2 者柔和在一起,你可以只設置一次。我這里還是設置 2 次值的。 我這里寫了個工具類還是設置 2 次值的。他從request中獲取分頁參數,放到 PaginatedList 的實現類中,實際的數據庫分頁參數由struts2自動封裝到action中的Page對象中,其實這個類寫的有些多余,完全可以在 PaginatedList 的實現類內部解決問題,根本不需要引入HttpServletRequest 。

Java代碼 復制代碼
  1. /** ?
  2. ?*?分頁工具類 ?
  3. ?*? ?
  4. ?*?@author?tianjl ?
  5. ?*? ?
  6. ?*/ ??
  7. public ? class ?PaginationUtil?{ ??
  8. ??
  9. ???? /** ?
  10. ?????*?該方法用于displaytag的參數到springside的page的分頁參數做轉換 ?
  11. ?????*? ?
  12. ?????*?@param?request ?
  13. ?????*????????????(HttpServletRequest)?用于獲取請求參數 ?
  14. ?????*?@param?page ?
  15. ?????*????????????(DBPaginatedList)?springside的Page對象 ?
  16. ?????*/ ??
  17. ???? public ? static ? void ?pageInfoPopulate(HttpServletRequest?request, ??
  18. ????????????DBPaginatedList?page)?{ ??
  19. ???????? if ?(request?==? null ?||?page?==? null ) ??
  20. ???????????? return ; ??
  21. ???????? else ?{ ??
  22. ????????????String?pagestr?=?request.getParameter( "page" ); ??
  23. ????????????String?sort?=?request.getParameter( "sort" ); ??
  24. ????????????String?dir?=?request.getParameter( "dir" ) ??
  25. ???????????? if ?(!StringUtils.isBlank(pagestr))?{ ??
  26. ????????????????page.setPageNo(NumberUtils.toInt(pagestr)); ??
  27. ????????????} ??
  28. ???????????? if ?(!StringUtils.isBlank(sort))?{ ??
  29. ????????????????page.setOrderBy(sort); ??
  30. ????????????????page.setSortCriterion(sort); ??
  31. ????????????} ??
  32. ???????????? if ?(!StringUtils.isBlank(dir))?{ ??
  33. ???????????????? if ?(StringUtils.equals(Page.ASC,?dir))?{ ??
  34. ????????????????????page.setOrder(Page.ASC); ??
  35. ????????????????}? else ?{ ??
  36. ????????????????????page.setOrder(Page.DESC); ??
  37. ????????????????} ??
  38. ????????????????page.setSortDirection(dir); ??
  39. ????????????} ??
  40. ????????} ??
  41. ????} ??
  42. }??
      /**
 * 分頁工具類
 * 
 * @author tianjl
 * 
 */
public class PaginationUtil {

	/**
	 * 該方法用于displaytag的參數到springside的page的分頁參數做轉換
	 * 
	 * @param request
	 *            (HttpServletRequest) 用于獲取請求參數
	 * @param page
	 *            (DBPaginatedList) springside的Page對象
	 */
	public static void pageInfoPopulate(HttpServletRequest request,
			DBPaginatedList page) {
		if (request == null || page == null)
			return;
		else {
			String pagestr = request.getParameter("page");
			String sort = request.getParameter("sort");
			String dir = request.getParameter("dir")
			if (!StringUtils.isBlank(pagestr)) {
				page.setPageNo(NumberUtils.toInt(pagestr));
			}
			if (!StringUtils.isBlank(sort)) {
				page.setOrderBy(sort);
				page.setSortCriterion(sort);
			}
			if (!StringUtils.isBlank(dir)) {
				if (StringUtils.equals(Page.ASC, dir)) {
					page.setOrder(Page.ASC);
				} else {
					page.setOrder(Page.DESC);
				}
				page.setSortDirection(dir);
			}
		}
	}
}
    

?然后頁面中寫上displaytag的標簽:

Java代碼 復制代碼
  1. <display:table?id= "content" ?name= "pageList" ?requestURI= "/security/user.do" ? ??
  2. ????size= "totalCount" ?pagesize= "${pageList.pageSize?}" ?partialList= "true" > ??
  3. ????<display:column?property= "id" ?sortable= "true" ?style= "width:2%" /> ??
  4. ????<display:column?property= "name" ?title= "姓名" ?sortable= "true" ?/> ??
  5. ????<display:column?property= "loginName" ?title= "登錄名" ?sortable= "true" ?/> ??
  6. ????<display:column?property= "email" ?title= "郵箱" ?sortable= "true" ?/> ??
  7. </display:table>??
      <display:table id="content" name="pageList" requestURI="/security/user.do" 
	size="totalCount" pagesize="${pageList.pageSize }" partialList="true">
	<display:column property="id" sortable="true" style="width:2%"/>
	<display:column property="name" title="姓名" sortable="true" />
	<display:column property="loginName" title="登錄名" sortable="true" />
	<display:column property="email" title="郵箱" sortable="true" />
</display:table>
    

?

?

這里有幾個點要注意, size 屬性中必須指定一個總頁數,而且必須是 int 型的, springside Page 類的總頁數是 long 型的,所以我又自己定義了個 totalCount ,將值給 size 屬性。 partialList 屬性必須指定為 true ,這樣 displaytag 才會使用你的分頁。

到這里已經可以使 displaytag 使用你提供的數據庫分頁了。

然后,我們來解決導出數據的問題。導出數據是個很常用的功能,基本上是個系統都要這個功能。 displaytag 是提供了該功能的,但是問題太多。一個是當你讓 displaytag 使用了數據庫分頁后,只能導出當前頁的數據;另一個問題是導出數據中文亂碼的問題。

第一個問題需要修改源代碼,給與實際解決方案文章在此:

http://superwing.iteye.com/blog/427407

你需要在 org.displaytag.tags.TableTag.java 中,將 1065 以及 1066 兩行進行替換:

Java代碼 復制代碼
  1. PaginationHelper?paginationHelper?=? new ?PaginationHelper(pageNumber,?pagesize); ??
  2. this .tableIterator?=?paginationHelper.getIterator( this .list);???
      PaginationHelper paginationHelper = new PaginationHelper(pageNumber, pagesize);
this.tableIterator = paginationHelper.getIterator(this.list); 
    

?替換為:

Java代碼 復制代碼
  1. if (MediaTypeEnum.HTML.equals( this .currentMediaType)){ ??
  2. ????PaginationHelper?paginationHelper?=? new ?PaginationHelper(pageNumber,?pagesize); ??
  3. ???? this .tableIterator?=?paginationHelper.getIterator( this .list); ??
  4. } else ?{ ??
  5. ???? this .tableIterator?=?IteratorUtils.getIterator( this .list); ??
  6. }???
      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);
} 
    

?

在你的 action 種的代碼中,你需要知道用戶是否點擊了導出超鏈接,通過以下代碼可以獲取該值:

?

Java代碼 復制代碼
  1. String?exportValue?=?request.getParameter(TableTagParameters.PARAMETER_EXPORTING);??
      String exportValue = request.getParameter(TableTagParameters.PARAMETER_EXPORTING);
    

?

?

如果該值不為空,則表示用戶按了導出,否則就是沒有。你應該根據此值來選擇是查詢部分內容還是全部內容。比如:

Java代碼 復制代碼
  1. if ?(exportValue?==? null ?||?exportValue.equals( "" ))?{ ??
  2. ???? //非導出,根據查詢條件filters進行分頁查詢 ??
  3. ????pageList?=?securityEntityManager.searchUser(pageList,?filters); ??
  4. }? else ?{ ??
  5. ???? //導出,根據查詢條件filters查詢出所有結果集 ??
  6. ????List<User>?userList?=?securityEntityManager.getAllUser(pageList,?filters); ??
  7. ????pageList.setResult(userList); ??
  8. }??
      if (exportValue == null || exportValue.equals("")) {
	//非導出,根據查詢條件filters進行分頁查詢
	pageList = securityEntityManager.searchUser(pageList, filters);
} else {
	//導出,根據查詢條件filters查詢出所有結果集
	List<User> userList = securityEntityManager.getAllUser(pageList, filters);
	pageList.setResult(userList);
}
    
?

好,第一個導出問題解決完畢。

接下去是亂碼問題,我這里只說明 excel pdf 的處理。解決方法也是來自于網絡。

excel 的導出處理相對簡單,在你項目的 classpath 中加入 displaytag.properties 文件,加入以下代碼即可。

Java代碼 復制代碼
  1. export.excel. class =org.displaytag.export.excel.ExcelHssfView??
      export.excel.class=org.displaytag.export.excel.ExcelHssfView
    

? 注意該屬性表示使displaytag使用poi導出excel,所以你需要加入displaytag-export-poi-1.2.jar和poi的jar包,而且只能使用poi3.2版本的jar包,其他版本都會報錯說NoSuchMethod,但是我看poi源碼,明明是有該方法的,不知道什么原因。(我使用過poi3.5和poi3.0都報了該錯)

pdf的亂碼處理,需要下載iTextAsian.jar,然后加入你的classpath,再修改源代碼org.displaytag.export.PdfView的115行處:

Java代碼 復制代碼
  1. //將 ??
  2. smallFont?=?FontFactory.getFont(FontFactory.HELVETICA,? 7 ,?Font.NORMAL,? new ?Color( 0 ,? 0 ,? 0 )); ??
  3. //替換為: ??
  4. smallFont?=?FontFactory.getFont( "STSong-Light" , "UniGB-UCS2-H" ,?Font.DEFAULTSIZE);??
      //將
smallFont = FontFactory.getFont(FontFactory.HELVETICA, 7, Font.NORMAL, new Color(0, 0, 0));
//替換為:
smallFont = FontFactory.getFont("STSong-Light","UniGB-UCS2-H", Font.DEFAULTSIZE);
    

?這樣pdf亂碼也可以解決了。

最后再引申幾個我遇到的其他問題:

excel導出的內容標題看不清,這個需要修改源碼,找到org.displaytag.export.excel.ExcelHssfView的101到107行處是設置標題樣式的,主要是把102行:

Java代碼 復制代碼
  1. //將 ??
  2. headerStyle.setFillPattern(HSSFCellStyle.FINE_DOTS); ??
  3. //替換為: ??
  4. headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);??
      //將
headerStyle.setFillPattern(HSSFCellStyle.FINE_DOTS);
//替換為:
headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    

?這樣,導出的標題就不會看不清了。

另外一個問題,是因為displaytag和struts2一起使用導致的,由于displaytag生成的參數中帶“-”,而struts2中接受的參數中默認又不允許有“-”,控制臺會報錯,但是卻不影響使用。不過控制臺老報錯,看著也不爽。

http://hi.baidu.com/j2ee_cn/blog/item/688a03db5a48846cd1164e66.html

說修改xwork源碼可以解決該問題,我照做確實解決了,但是又出現了其他問題,struts2不會替我自動封裝參數到action的對象中了,所以我又改了回來。大家如果用的也是struts2可以試試,是不是有這樣的問題。

另一個方法是只要將,devMode設置為false就不會報這個錯了,這個的確可以解決該問題。

displaytag數據庫分頁方法及導出數據的問題處理


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲综合久久久久久中文字幕 | 国产精品一区二区在线观看 | www.天天操 | 国产亚洲精品高清在线 | 国产一区二区三区久久久久久久久 | 超碰在线观看97 | 九热 | 伊人欧美 | 欧美精品在线观看视频 | 欧美成在人线a免费视频 | 一级毛片视频免费 | 国产精品亚洲第一区二区三区 | 欧美一区二区三区免费视频 | 亚洲午夜网站 | 日本午夜高清视频 | 国产中文字幕一区 | 999热视频 | 亚洲国产精品视频一区 | 午夜精品一区二区三区在线视 | 国产大伊香蕉精品视频 | 韩国女主播青草在线观看 | 国产精品久久久久久久久久日本 | 精品久久久久久久久久 | 日本一区二区三区视频在线观看 | 亚洲国产日产韩国欧美综合 | 国产精品久久久久久久久久久久 | 色婷婷视频在线 | 日本午夜免费无码片三汲大片 | 婷婷视频在线观看 | 亚洲9777精品毛A片久久久 | 久久精品呦女 | 欧美激情二区三区 | 欧美精品99毛片免费高清观看 | 中文字幕国产精品 | 不卡一区| 一级黄色绿像片 | 男女www视频 | 色草在线 | 四虎黄色网址 | 一区二区在线 | 国产精品免费观看视频 |