Display Tag Lib Table進行分頁

Display Tag Lib是一個標籤庫,用來處理jsp網頁上的Table,功能很是強,能夠對的Table進行分頁、數據導出、分組、對列排序等等,反正我在作項目時須要的功能它都給我提供了,並且使用起來很是的方便。可以大大減小代碼量。     介個是Display Tag的官方網站http://displaytag.sourceforge.net。 首先固然是要下載它的jar包了,這裏能夠下載到最新的版本。將jar包放到WEB-INF的lib文件夾下。另外還須要兩個輔助包:apache的commons-lang和standard包,更多的輔助包能夠在這裏下載。css

    在web.xml下添加一個filter    html

<filter>        java

<filter-name>exportFilter</filter-name>        mysql

<filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class>    web

</filter>sql

    在jsp頁面作一個引用: <%@ taglib uri="http://displaytag.sf.net/el" prefix="display" %>數據庫

    首先咱們定義一個list  <% List test = new ArrayList( 6 );  test.add( "Test String 1" ); test.add( "Test String 2" );  test.add( "Test String 3" );  test.add( "Test String 4" ); test.add( "Test String 5" );  test.add( "Test String 6" ); request.setAttribute( "test", test ); %> 
    當咱們想在jsp頁面上顯示這個list時,咱們只須要寫一句話     <display:table />     display tag會自動生成一個tableapache

    若是list是從控制層拋出來的,name可以使用EL表達式表示     <display:table />session

    這是最簡單的display tag的使用,咱們能夠給它加上樣式等,也能夠定義顯示的列,下面的table顯示覆雜一些app

<display:table styleClass="list" cellspacing="0" cellpadding="0">

<display:column property="id" title="ID" />

<display:column property="name" />

<display:column property="email" />

<display:column property="description" title="Comments"/>

</display:table>

    若是想要給它加個連接也很簡單,下面的代碼給name加了鏈接,並附帶id參數,email也自動鏈接到mailto:XXX

<display:table styleClass="list" cellspacing="0" cellpadding="0">

<display:column property="id" title="ID" />

<display:column property="name" url="detail.jsp" paramId="id" paramProperty="id"/>

<display:column property="email" autolink="true"/>

<display:column property="description" title="Comments"/>

</display:table>

下面介紹幾個Display最經常使用的功能,更多功能請參考http://www.displaytag.org/index.jsp。 1. 分頁     若是想對代碼分頁,只需在display:table標籤中添加一項pagesize="每頁顯示行數",如 <display:table pagesize="10"/>

2. 對列排序     display tag可對列進行排序,就是點擊列名,對該列的數據進行排序。你只需對想要排序的列添加 sort="true" 就OK,以下面的代碼可對前三列進行排序。在display:table中添加defaultsort="列數",可默認對指定的列排序。

<display:table styleClass="list" cellspacing="0" cellpadding="0" defaultsort="1">

<display:column property="id" title="ID" sort="true"/>

<display:column property="name" url="detail.jsp" paramId="id" paramProperty="id" sort="true"/> <display:column property="email" autolink="true" sort="true"/>

<display:column property="description" title="Comments"/>

</display:table>  

若是table有分頁,Display Tag默認只對當前頁進行排序,若是想對整個list排序,能夠在display:table之間添加一段代碼: <display:setProperty value="list"/>


3. 導出數據     在display:table中添加export="true",看看會出現什麼!Display Tag默認會提供三種數據導出方式:CSV、Excel、XML 。     另外Display Tag還能夠導出爲PDF格式,在http://prdownloads.sourceforge.net/itext/下載一個輔助包iText.jar,copy到lib目錄下,而後在display:table之間添加一段代碼: <display:setProperty value="true"/>,大功告成。


4. Display Tag的屬性設置     前面所說的display:setProperty 是一種改變Display Tag屬性的方法,可是在每一個jsp中都要寫太麻煩了。     Display Tag中設置了不少默認的屬性,它有一個專門的屬性文件,是在它的jar包中的displaytag/properties/TableTag.properties     想要改變它的默認屬性,咱們能夠在WEB-INF/classes下新建一個文件displaytag.properties,仿照TableTag.properties中屬性的格式設置須要修改的屬性。     TableTag.properties中的# messages中設置的是顯示在頁面上的提示信息。默認是英文的,咱們能夠把它改成中文的。不過這裏只能使用unicode,就是說中文字符必須轉換爲unicode碼,這個可使用jdk自帶的native2ascii.exe進行轉換。

  
6. displaytag的翻頁機制 這多是displaytag的侷限性了,它的翻頁機制是這樣的: 若是一個list中有10000個bean,按照它的機制,若是是第一頁(每頁n條),它會把前n條數據取出來,而後再把剩餘的10000-n條刪除,當你點擊頁面「2」的時候,它再從後臺繞一圈,把第二頁的數據,也就是把第n+1-2n條記錄取出來,把剩餘的刪除。這樣,它實現了翻頁,又防止了內存佔用過大。 可是,無論怎麼說,它仍是有一個取出全部條數的動做的,在極大數據量的狀況下,有可能形成內存溢出。


8. displaytag中decorator一例

import org.displaytag.decorator.TableDecorator;

import Java.util.HashMap;

import java.text.SimpleDateFormat; import java.util.Date;


public class BulletinListDecorator extends TableDecorator{  

private String bulletinId = null;

private String title = null;

private SimpleDateFormat sdf = null;

private int i = 0;


public BulletinListDecorator() {

    sdf = new SimpleDateFormat("yy-MM-dd"); }


public String getBulletinId(){

    i+=1;

    return ""+i;

}

public String getTitle(){

    bulletinId = (String)((HashMap) this.getCurrentRowObject()).get("bulletinId");

    title = (String)((HashMap) this.getCurrentRowObject()).get("title");

    return ""+title+""; }

public String getLastPubD(){

    return sdf.format((Date)((HashMap) this.getCurrentRowObject()).get("lastPubD"));

}

}    

<display:table  decorator="com.ztesoft.ds.application.web.bulletin.decorator.BulletinListDecorator">         <display:column property="bulletinId" titleKey="titlePage.seq" align="center" headerClass="ValueTd"/>         <display:column property="title" titleKey="titlePage.title" align="center" headerClass="ValueTd"/>         <display:column property="lastPubD" titleKey="titlePage.time" align="center"  headerClass="ValueTd"/>         <display:column property="className" titleKey="titlePage.class" align="center" headerClass="ValueTd"/>   <display:column property="clickNo" titleKey="titlePage.clickNo" align="center" headerClass="ValueTd"/>     </display:table>

其中bulletinList是一個ArrayList,titleKey指向了properties文件


補充:

一:

      在display:table中添加自定義的列用 display:column ,將其屬性media的值設置爲html便可,以下例子:

     <display:table name="list" pagesize="5" >

       <display:column title="刪除" media="html"> 

       <input type="button" value="刪除" />      

     </display:column>

</display:table>

二:

     在寫對應於bean裏面的列時,display:column 中property對應的值是bean裏面的屬性的名字,大小寫必須一致,例如:有個actionform類,有屬性 private String _Name; 則property的值也必須爲"_Name",不然提示找不到列。

 

*****************************************************************

轉:

displaytag 學習筆記總結(1)

6,列表的子集  <display:table name="mylist" offset="m" length="n"/>  offset 爲第一個數據在mylist中的序號。  length 爲顯示的記錄條數。

7,自動設置連接  可以把此列的內容做爲連接,鏈接的url和內容一致。     固然必須格式有效的url,不然寫了也沒有鏈接。

 (   自認爲這個功能通常。   由於鏈接的內容和顯示的內容一般不同。   )  固然能夠在<display:column href="">在這裏給某列指定全部的連接爲同一個鏈接。  或者<display:column ><a href="">sdfs</a></display:column >二者效果是同樣的。

 !!!那麼,若是鏈接的url不是列內容,並且每行的連接都不相同,這個時候怎麼辦?   就好像廣告列表有商戶名稱,商戶名稱是一個鏈接,鏈接到商戶的具體信息頁面。   鏈接的url確定不一樣。如何處理?    如今還不知道,接着往下看。

8,使用裝飾類來轉換數據。  

 <display:table name="test" decorator="org.displaytag.sample.Wrapper" >  用來轉換數據內容的。通常用來格式化信息。  此類必繼承TableDecorator。  順便介紹一個格式化時間的包  org.apache.commons.lang.time.FastDateFormat;  格式化金錢的包  java.text.DecimalFormat;    思路就是覆蓋List中具體類型的getXXX方法。  this.getCurrentRowObject() 獲得當前行的數據。  this.getListIndex() 獲得當前行的序號。  以後就轉化爲List中存放的具體類型,以後獲得某列的數據。  返回格式化後的數據。

 !!!!另外我看到,裝飾類增長了一些getXXX方法,這些方法並無在ListObject中定義。  還不知道這樣作有什麼好處?     <display:column property="date" decorator="org.displaytag.sample.LongDateWrapper" />  這樣僅僅對一列數據進行格式化,須要繼承ColumnDecorator  須要實現:String decorate(Object columnValue)方法。此方法一樣接受一個Object參數,   此參數就是對象的某個具體屬性值,直接轉化爲對應類型,而後格式化,返回String。

9,創建動態連接。  兩種方式能夠創建動態連接。     第一種方式直接在頁面上使用   <display:column href="baseurl" paramId="paramid" />   http://baseurl/paramid=columnvalue   <display:column href="baseurl" paramId="paramid"  paramName=「name」 paramScope="scope"/>   http://baseurl/paramid=scope範圍內的名字爲name的值   <display:column href="baseurl" paramId="paramid"  paramProperty=「propertyname」/>   http://baseurl/paramid=名字爲propertyname的屬性值

 這種方式處理簡單的連接十分有效,可是連接參數值若是經過查詢數據庫等比較複雜的方式獲得的話,這種方式  就不適應了。這時候就必須使用第二種方法。

 第二種方法,在裝飾類中得到鏈接。   裝飾類多定義一些getXXX方法,那麼頁面上就可使用<display:column propety="XXX" ..>來使用裝飾類de   getXXX方法。好,這樣一來,在裝飾類的getXXX方法裏,獲得此行對象,這樣對象的各個屬性就都能獲得,   以後去查數據庫也好,去完成負責的判斷邏輯也好,都很容易實現,別忘了,而後拼裝起來,並寫成一個   <a href="....">這樣的字符串返回。   好,頁面直接一句話就可獲得此拼裝的《a》了。<display:column propety="XXX" ..>

 第二種方法比較好些,由於能夠顯得更靈活。想怎麼寫就怎麼寫。第一種方法就是簡單地實現。   10,翻頁。  1,怎麼獲得每行的序號?   <display:table id="xxx" ...>   使用<%=pageContext.getAttribute("xxx_rowNum")%>確定好用。    可是<c:out value="${row_rowNum}"/>這種方式就很差用。也不知道差哪了。

  翻頁很簡單。就是在<display:table  pagesize="m">這樣來指定每頁的數量就能夠了。   自動出現換頁的索引,上下頁等等東西。   實在是方便。可是問題就是一次傳下來不少東西,性能很差。等一會看看如何改良。

11,自動設置排序   <display:table name="sessionScope.stest" defaultsort="1" defaultorder="descending">   <display:column property="id" title="ID" sortable="true" headerClass="sortable" />   能夠設定默認時按照哪列排序,是升序仍是降序。本例設置第一列默認時降序。   每列都得對象都必須實現了Comparable接口才能被設置成sortable="true".   若是沒有實現Comparable,那麼必須寫一個裝飾類。   另外須要注意,    他只對當前頁面進行排序。而不是所有。在翻頁時特別須要注意。    要想實現所有的排序,那麼必須從新寫Action往網頁傳新的List了。

12,如何分組   按照某列進行分組顯示。   這個功能真不錯。   <display:column property="city" title="CITY" group="1"/>   <display:column property="project" title="PROJECT" group="2"/>   這樣不只僅結果能夠分組,並且還能夠省略掉重複的數據,例如city列,project列都有   A ,B ,A,B 兩行那麼第二行這兩列就不顯示了。

  一樣只能對當前頁進行分組。

  注意:第一列必定要1,第二列必定是2,不然出NUllPoint 錯誤。

13,統計   好東西啊。能夠對分組進行統計,也能夠對全部行進行統計。   主要靠TableDecorator類finishRow()返回統計結果,放到頁面去顯示。

  TableDecorator類方法getDecoratedObject()獲得整個結果集。通常把它轉化成List,由於大多數狀況下結果   是存放在List中的。   public final String finishRow() {}當一行結束時執行此方法。因此用它來判斷是否須要計算城市統計,    抑或是所有統計。   至關於事件處理。返回的字符串也將在頁面上顯示。本例返回了<tr><td>...</td><tr>這樣的三份。   這樣就在表中嵌套進了三行。用來顯示統計是足夠了。

14,導出數據   很簡單。talbe裏設置export=「true」就好了。配置文件也要設置好export.xml = true , 這樣才能導出xml。   類推pdf、excel、html、csv。   每一個列能配置是否在某種格式中顯示,語法<display:column media="csv excel" 。。   不配置就在全部格式中都顯示。

  另外須要注意:    被包含的文件不能使用這個功能,非要使用,就的用過濾器。之後再深研究吧。

15,配置DisplayTag.   在應用的classpath路徑上拷貝一個TableTag.properties,並命名爲displaytag.properties.   這樣就默認取displaytag.properties裏的配置了。想漢化,很簡單。就須要把displaytag_zh.properties放到   classpath路徑下就能夠了。

  標題像漢化:由於默認是jstl的資源文件使用方式。因此得先學習jstl的   我知道了jstl.fmt如何使用資源文件。好了,jstl 首先必須用fmt:bunlle指定一個資源文件,而後才能   在他的body部分使用此資源文件,頗麻煩。

  而displaytag呢? 沒有這麼麻煩,若是與struts搭配使用,適用struts的資源文件固然最合理了。   你必須在displaytag.properties裏定義好一個   參數,#locale.provider=org.displaytag.localization.I18nJstlAdapter    locale.provider=org.displaytag.localization.I18nStrutsAdapter   就這麼簡單,就可以使用struts配置文件了。我今天居然看了一下午。哎,苦於沒有好點的資料啊。

  問題是:若是不合struts搭配使用。若是僅僅在jstl環境下,displaytag又該如何使用jstl的資源文件呢?   你必須象在jstl環境裏同樣使用<fmt:bundl>指定好資源文件,以後把displaytag標籤放到他的body   後,就可使用jstl的資源文件了!!!!(幸好我首先看了jstl使用資源文件的方法)

16,一個頁面兩個以上的表格.   很簡單,只須要每一個表格配置不一樣的id.

17,表格裏面還有表格.   很簡單.只要在外層表的   <dispaly:column>    ( 在這加<display:table ...>。。。    </display:table>便可)   </display:column>         18,表頭表尾   很簡單:<dispaly:caption><display:footer>想<display:column>同樣使用就好了.   主要注意一下: <display:footer>內容必須是<tr>.....</tr>

19,表格裏的值截斷,與顯示空白.  <display:column property="nullValue" nulls="false"/>    <display:column property="longDescription" maxLength="10" style="whitespace: nowrap;"/>  簡單得很.

ok,差很少到了關鍵的時候了。!!!!!

============================================= 關鍵: 20,如何分頁.    由於displaytag的分頁機制須要一次把全部紀錄都傳到裏面.因此對紀錄不少的項目並不合適.若是還非得用  displaytag那隻好放棄他的一些功能了.比較理智的方法是僅僅讓displaytag得到一頁的list.這樣就不用displaytag  的分頁index,而使用本身的,或者寫customertag,或者使用jsppager tag.

 有不少人質疑這種方法,由於這使得displaytag的光芒至少減小了一半以上,由於他的不少功能所以而沒法使用,  例如排序功能,能夠針對全部list進行全局排序,若是每次只傳給一頁的數據,全局排序就和當頁排序沒有區別了.  displaytag的全局排序功能宣佈廢掉了.

 <display:table name="mylist" offset="m" length="n"/>這樣的功能基本上也沒有什麼用處。

 那麼還使用它幹什麼呢? displaytag即便廢掉了一些武功仍然有它的優勢.例如  1,支持表格的嵌套.  2,支持css這樣就能寫少許地代碼使得程序更簡潔.只好定義好一套css,就能全局範圍內使用了.  3,另外還支持截斷長的字符串,這樣就不用在頁面使用本身的方法了.   4,可以實現比較複雜的邏輯從而產生動態連接。這也勉強因此個好處吧。  5,能輕鬆地使用struts的資源文件。使得它能夠很好的國際化。  6,可以過濾空值。

 缺點:   1,分組就使用不了了,統計也沒法使用了。只統計當前頁是沒有意義的。  2,排序也變成當前頁排序了。沒多少意思。  3,導出也變成當前頁導出了,沒多少意思了。

其它功能
    DisplayTag還有一些很實用的小功能,這裏提兩個。一個是對數據的Format,這是1.1版本添加的新功能,可使用標籤的方式格式化時間、數字、字符串。好比日期,在須要格式化的column標籤中添加format="",第一個參數爲格式化的數據序號,第二個參數是數據類型,數字爲 number,第三個參數爲數據格式。
    另一個功能是對table數據的合計功能。在table標籤中添加 decorator="org.displaytag.decorator.TotalTableDecorator",而後在想要進行合計的數據列的 column標籤中添加 total="true",該列就能夠被計算總數了。但這個功能有個缺點,不能用在有分頁的時候,它只能合計第一頁的數據。

DisplayTag的不足    初次使用DisplayTag的人可能會以爲驚喜,可是用久了會發現不少問題,最大的問題是對中文的支持很差,好比若是查詢條件中有中文,就沒法翻頁,沒法對中文排序,將中文導出爲指定文件時出現亂碼等等。這些問題有時候會讓人很鬱悶,有時候逼得你要去修改它的源代碼。下面是對以上幾個問題的解決方法:    1. 對於中文沒法翻頁、排序,最簡單的辦法是修改Tomcat下的server.xml文件。找到HTTP的Connector標籤,在裏面添加一項 URIEncoding="...",引號裏面的內容取決於你的頁面編碼,好比能夠是GBK,UTF8等。這樣上面兩個問題就能夠解決了。    2. 導出爲文件:其實這個功能除了中文支持外還有不少其它問題,好比它會將Html標籤一塊兒導出、只導出顯示的內容,但若是對table進行了 decorator,decorator後的內容沒法導出。若是想要將中文正確導出,須要修改DisplayTag源代碼。    下載相同版本的源代碼,在org.displaytag.export.ExcelView.java文件中找到getMimeType()方法,將此方法修改成 return "application/vnd.ms-excel;charset=GB2312";,修改後導出數據的速度會慢不少,不過將就吧。    3. 新版的DisplayTag1.1添加了對一次取部分數據的支持,相關的標籤包括partialList和size,須要設置partialList="true"和size的大小。具體怎麼用偶還沒研究。

相關文章
相關標籤/搜索