??xml version="1.0" encoding="utf-8" standalone="yes"?>
DisplayTag是一个非常好用的表格昄标签Q适合MVC模式Q其主页在http://displaytag.sourceforge.net/
一、最单的情况Q未使用<display:column/>标签
<%request.setAttribute( "test", new ReportList(6) );%>
<display:table name="test" />
标签遍历List里的每一个对象,q将对象里的所有属性显C出来。一般用于开发的时候检查对象数据的完整性?
二、?lt;display:column/>标签的情?
<display:table name="test">
<display:column property="id" title="ID" />
<display:column property="name" />
<display:column property="email" />
<display:column property="status" />
<display:column property="description" title="Comments"/>
</display:table>
property对应List里对象的属性(用getXXX()Ҏ取得Q,title则对应表D头里的列名。定义列有两U方式:
A?lt;display:column property="email" />
使用<display:column/>标签里的property属性来定义
B?lt;display:column title="email">email@it.com</display:column>
?lt;display:column/>标签体里增加内容Q可以是帔RQ也可以用其他标{{?
两种方式比较Q用property属性来定义更加快速和利于排序?
三、表格显C样式的定义
A、在<display:table/>?lt;display:column/>标签里指定标准的html属性,烦琐
B、修Ҏ式表
<display:table name="test" class="mars">
<display:column property="id" title="ID" class="idcol"/>
<display:column property="name" />
<display:column property="email" />
<display:column property="status" class="tableCellError" />
<display:column property="description" title="Comments"/>
</display:table>
通过class属性来指定所要应用的样式。可以在光认样式表里(./css/screen.cssQ直接修?
四、标{֏得数据的数据?
有四U范?
pageScope
requestScope (默认) <display:table name="test2" >
sessionScope <display:table name="sessionScope.holder.list" > 注意Q这里要指定范围Q非默认
applicationScope
五、通过增加id属性创建隐含的对象
<display:table name="test" id="testit">
<display:column property="id" title="ID" />
<display:column property="name" />
<display:column title="static value">static</display:column>
<display:column title="row number (testit_rowNum)"><%=pageContext.getAttribute("testit_rowNum")%></display:column>
<display:column title="((ListObject)testit).getMoney()"><%=((ListObject)pageContext.getAttribute("testit")).getMoney()%></display:column>
</display:table>
注意到在<display:table/>里增加了id属性,q时在page context里创Z一个隐含对象,指向List里的当前对象Q?
可以通过(ListObject)pageContext.getAttribute("id")来捕莯个对象。同时还创徏了一个id_rowNum对象Q同P?
通过pageContext.getAttribute("testit_rowNum")来捕P它仅仅代表当前行的行数?
有了q两个隐含对象,可以通过其他标签来访问,例如Jstl:
<display:table id="row" name="mylist">
<display:column title="row number" >
<c:out value="${row_rowNum}"/>
</display:column>
<display:column title="name" >
<c:out value="${row.first_name}"/>
<c:out value="${row.last_name}"/>
</display:column>
</display:table>
六、显C部分数?
昄开始五条数据:通过讑֮length属?
<display:table name="test" length="5">
<display:column property="id" title="ID" />
<display:column property="email" />
<display:column property="status" />
</display:table>
昄W三到第八条数据Q通过讑֮offset和length属?
<display:table name="test" offset="3" length="5">
<display:column property="id" title="ID" />
<display:column property="email" />
<display:column property="status" />
</display:table>
七、对email和url地址的直接连?
<display:table name="test" >
<display:column property="id" title="ID" />
<display:column property="email" autolink="true" />
<display:column property="url" autolink="true" />
</display:table>
如果要显C的对象里包含email和url地址Q则可以在display:column里直接设定autolink="true"来直接连?
八、用装饰模式{换数据显C(写自q decorator Q?
A、对整个表格应用decorator
<display:table name="test" decorator="org.displaytag.sample.Wrapper" >
<display:column property="id" title="ID" />
<display:column property="email" />
<display:column property="status" />
<display:column property="date" />
<display:column property="money" />
</display:table>
org.displaytag.sample.Wrapper卌己写的decoratorQ它要承TableDecoratorc,看看它的一个方法:
public String getMoney()
{
return this.moneyFormat.format(((ListObject) this.getCurrentRowObject()).getMoney());
}
很明显,它通过父类的getCurrentRowObject()Ҏ获得当前对象Q然后对其getMoney()Ҏq行‘Ҏ’
B、对单独的column应用decorator
<display:table name="test">
<display:column property="id" title="ID" />
<display:column property="email" />
<display:column property="status" />
<display:column property="date" decorator="org.displaytag.sample.LongDateWrapper" />
</display:table>
org.displaytag.sample.LongDateWrapper要实现ColumnDecorator接口Q它的方法:
public final String decorate(Object columnValue)
{
Date date = (Date) columnValue;
return this.dateFormat.format(date);
}
昄Q它获得不了当前对象Q因为它实现的是接口Q,仅仅是获得该对象的columnValueQ然?#8216;Ҏ’
九、创建动态连?
有两U方法创建动态连接:
A、在<display:column/>里通过增加href、paramId、paramName、paramScope、paramProperty属?
href 基本的URL 地址
paramId 加在URL 地址后的参数名称
paramName 数据bean的名Uͼ一般ؓnullQ即使用当前List里的对象Q?
paramScope 数据bean的范_一般ؓnull
paramProperty 数据bean的属性名Uͼ用来填充URL 地址后的参数?
<display:table name="sessionScope.details">
<display:column property="id" title="ID" href="details.jsp" paramId="id" />
<display:column property="email" href="details.jsp" paramId="action" paramName="testparam" paramScope="request" />
<display:column property="status" href="details.jsp" paramId="id" paramProperty="id" />
</display:table>
q种Ҏ便直接,但缺Ҏ无法产生cMdetails.jsp?id=xx&action=xx的复合URL
B、应用decorator 创徏动态连接:
<display:table name="sessionScope.details" decorator="org.displaytag.sample.Wrapper" >
<display:column property="link1" title="ID" />
<display:column property="email" />
<display:column property="link2" title="Actions" />
</display:table>
org.displaytag.sample.Wrapper里的ҎQ?
public String getLink1()
{
ListObject lObject= (ListObject)getCurrentRowObject();
int lIndex= getListIndex();
return "<a href=\"details.jsp?index=" + lIndex + "\">" + lObject.getId() + "</a>";
}
public String getLink2()
{
ListObject lObject= (ListObject)getCurrentRowObject();
int lId= lObject.getId();
return "<a href=\"details.jsp?id=" + lId
+ "&action=view\">View</a> | "
+ "<a href=\"details.jsp?id=" + lId
+ "&action=edit\">Edit</a> | "
+ "<a href=\"details.jsp?id=" + lId
+ "&action=delete\">Delete</a>";
}
十、分?
实现分页非常的简单,增加一个pagesize属性指定一ơ想昄的行数即?
<display:table name="sessionScope.test" pagesize="10">
<display:column property="id" title="ID" />
<display:column property="name" />
<display:column property="email" />
<display:column property="status" />
</display:table>
十一、排?
排序实现也是很简单,在需要排序的column里增加sortable="true"属性,headerClass="sortable"仅仅?
指定昄的样式。column里的属性对象要实现Comparable接口Q如果没有的话可以应用decorator
defaultsort="1" 默认W一个column排序
defaultorder="descending" 默认递减排序
<display:table name="sessionScope.stest" defaultsort="1" defaultorder="descending">
<display:column property="id" title="ID" sortable="true" headerClass="sortable" />
<display:column property="name" sortable="true" headerClass="sortable"/>
<display:column property="email" />
<display:column property="status" sortable="true" headerClass="sortable"/>
</display:table>
注意的是Q当同时存在分页时如果不指定sort=list,则排序仅仅针对的是当前页面,而不是整个List都进行排?
十二、column 分组
分组只是需要在column里增加group属?
<display:table name="test" class="simple">
<display:column property="city" title="CITY" group="1"/>
<display:column property="project" title="PROJECT" group="2"/>
<display:column property="amount" title="HOURS"/>
<display:column property="task" title="TASK"/>
</display:table>
十三、导出数据到其他格式Q页面溢出filter??Q?
?lt;display:table/>里设定export="true"
?lt;display:column/>里设定media="csv excel xml pdf" 军_该字D在导出到其他格式时被包不包含,不设定则都包?
<display:setProperty name="export.csv" value="false" />
军_该种格式能不能在面中导?
<display:table name="test" export="true" id="currentRowObject">
<display:column property="id" title="ID"/>
<display:column property="email" />
<display:column property="status" />
<display:column property="longDescription" media="csv excel xml pdf" title="Not On HTML"/>
<display:column media="csv excel" title="URL" property="url"/>
<display:setProperty name="export.pdf" value="true" />
<display:setProperty name="export.csv" value="false" />
</display:table>
十四、配|属性,覆盖默认
两种ҎQ?
A、在E序classpath下新?span class="hilite1">displaytag.properties文g
B、对于单个表|应用<display:setProperty>标签
具体可配|的属性:http://displaytag.sourceforge.net/configuration.html
十五、一个完整的例子
<display:table name="test" export="true" sort="list" pagesize="8">
<display:column property="city" title="CITY" group="1" sortable="true" headerClass="sortable"/>
<display:column property="project" title="PROJECT" group="2" sortable="true" headerClass="sortable"/>
<display:column property="amount" title="HOURS"/>
<display:column property="task" title="TASK"/>
</display:table>
sort="list" Ҏ个listq行排序
导出数据到其他格式时Qgroup无效
]]>
对他的实现方式有点好奇,遂查看一下这个导出功能的链接Q乖乖,那是相当z啊Q就是把我这个页面的全部参数d到URL里,然后附加上了几个奇怪数字组成的参数Q估计就是DisplayTag用来识别我要做导出操作的了。从q个链接来看Q做导出操作时还是要到我q个Action去进行逻辑处理Q但我这个Action输出的内容可是一个完整的HTMLQ而不是Excel啊,他是怎么实现的呢Q带着个大大的问号Q开始去挖源代码。顺便提一下,m2eclipse实方便Q不但帮我管理了目的依赖,q能帮我把源代码拽下来关联到相应的jarQ所以我直接在项目依赖里面找到displaytag.jarQ就可以查看源代码了?br />
代码其实很简单,其实是利用了ServletRsponse的缓存机Ӟ当我们调用response.getWriter().print()ҎӞ打印的内Ҏ不会立即发送到客户端的Q在发送到客户端之前,q可以对其进行操作,哈哈Q有Ҏ白了吧?DisplayTag是利用了这个原理,在TableTagq个cMQ导出ExcelӞServletResponseq没有提交到客户端,先执行了一下response.reset()和pageContext.getOut().clearBuffer()Q这样就把前面jsp里面输出的所有内定w清除掉了~然后再用response.setContentType()重新讄文gcdQ输格内容,完事了再q回Tag.SKIP_PAGEQ这样JSP里面剩下的内容也不会再输ZQ客L得到的就完全是在DisplayTag控制下的内容了,牛吧Q?br />
其实q个response.reset以前也见q,读servlet API文档时也看过Ҏ的解释,但如果不是今天看q个Display的源代码Q还真不会想到这样子来应用,看来q就是理论和实践的差距呀Q!Q?br />
PS:上面q种ҎQ只适用于输出文本内宏VDisplayTag自带的Excel导出工具其实是输出了一个csv文gQ把扩展名改成xls了而已。如果要输出真正的xls文g莯PDFq样的二q制文gQ用上面的Ҏ在某些中间g上就会有问题了。因为原则上response.getOutputStreamҎ是只能被调用一ơ的Q这在进入jsp处理时就被调用了Q而输出PDF文gq样二进制流时又必须使用q个ҎQ那出错了。DisplayTag很y妙的提供了一个FilterQ对标准的ServletRepsonse做了一个包?Wrap)Q在执行Export导出Ӟ如果是jsp{其他请求执行的response.getOutputStreamQ就q回自己的一个缓存的OutputStreamQ而不是真正去调用容器的这个方法。直到执行ExportӞ才去调用容器的方法,保证q个response.getOutputStream只执行一ơ?br />
DisplayTag的地址Qhttp://displaytag.sourceforge.net/1.2/index.htmlQ很单,很强大,强烈推荐Q可以少写N多表格和分页标签
]]>
打开q个文gQ复制一份ƈ作相应修改保存到classes目录下,可以对View中的表格昄形式做相应的讄
Java代码
basic.empty.showtable=false #讄当数据ؓI时Q是不是昄表格 true表示昄表格
basic.show.header=true #讄当数据ؓI时Q显C的表格是否有表?true表示昄
# page | list 讄排序的数据量 相当于jsp面中display标签中的page属?nbsp;
sort.amount=page
export.amount=list #导出的数据量
export.decorated=true
paging.banner.group_size=8 #前台昄的最多页?8 表示最多显C??nbsp;
paging.banner.placement=top #前台昄?上一?下一?文字的位|?top表示上面 bottom表示下面
css.tr.even=even #偶数行的css标识 是偶数行的cssc?下面几个也是讄相应的css class
css.tr.odd=odd
css.th.sorted=sorted
css.th.ascending=order1
css.th.descending=order2
css.table=
css.th.sortable=sortable
# factory classes for extensions
factory.requestHelper=org.displaytag.util.DefaultRequestHelperFactory
# factory class for decorators
factory.decorator=org.displaytag.decorator.DefaultDecoratorFactory
# locale provider (Jstl provider by default)
locale.provider=org.displaytag.localization.I18nJstlAdapter
# locale.resolver (nothing by default, simply use locale from request)
#locale.resolver=
export.types=csv excel xml pdf
export.csv.class=org.displaytag.export.CsvView
export.excel.class=org.displaytag.export.ExcelView
export.xml.class=org.displaytag.export.XmlView
export.pdf.class=org.displaytag.export.PdfView
#export.***讄为true表示昄q种导出方式 falseZ采用
export.csv=true
export.csv.label=<span class="export csv">CSV </span>
export.csv.include_header=false
export.csv.filename=
export.excel=true
export.excel.label=<span class="export excel">Excel </span>
export.excel.include_header=true
export.excel.filename=
export.xml=true
export.xml.label=<span class="export xml">XML </span>
export.xml.filename=
export.pdf=false
export.pdf.label=<span class="export pdf">PDF </span>
export.pdf.include_header=true
export.pdf.filename=
export.rtf=false
export.rtf.label=<span class="export rtf">RTF </span>
export.rtf.include_header=true
export.rtf.filename=
# messages
#相应的显CZ?包括I数据时候显C的 下两个显C的位置不一?一个是在table?nbsp; 一个是在下?nbsp;
basic.msg.empty_list=Nothing found to display.
basic.msg.empty_list_row=<tr class="empty"><td colspan="{0}">Nothing found to display.</td></tr>
error.msg.invalid_page=invalid page
export.banner=<div class="exportlinks">Export options: {0}</div>#导出处的提示文字
export.banner.sepchar= | #导出处的提示文字分隔W?nbsp;
paging.banner.item_name=item
paging.banner.items_name=items
paging.banner.no_items_found=<span class="pagebanner">No {0} found.</span>
paging.banner.one_item_found=<span class="pagebanner">One {0} found.</span>
paging.banner.all_items_found=<span class="pagebanner">{0} {1} found, displaying all {2}.</span>
paging.banner.some_items_found=<span class="pagebanner">{0} {1} found, displaying {2} to {3}.</span>
paging.banner.full=<span class="pagelinks">[<a href="{1}">First</a>/<a href="{2}">Prev</a>] {0} [<a href="{3}">Next</a>/<a href="{4}">Last</a>]</span>
paging.banner.first=<span class="pagelinks">[First/Prev] {0} [<a href="{3}">Next</a>/<a href="{4}">Last</a>]</span>
paging.banner.last=<span class="pagelinks">[<a href="{1}">First</a>/<a href="{2}">Prev</a>] {0} [Next/Last]</span>
paging.banner.onepage=<span class="pagelinks">{0}</span>
paging.banner.page.selected=<strong>{0}</strong>
paging.banner.page.link=<a href="{1}" title="Go to page {0}">{0}</a>
paging.banner.page.separator=, \
# external sort and pagination
pagination.sort.param=sort
pagination.sortdirection.param=dir
pagination.pagenumber.param=page
pagination.searchid.param=searchid
pagination.sort.asc.value=asc
pagination.sort.desc.value=desc
pagination.sort.skippagenumber=true
# unused
save.excel.banner=<a href="{0}" rel="external">save ({1} bytes)</a>
save.excel.filename=export.xls
basic.empty.showtable=false #讄当数据ؓI时Q是不是昄表格 true表示昄表格
basic.show.header=true #讄当数据ؓI时Q显C的表格是否有表?true表示昄
# page | list 讄排序的数据量 相当于jsp面中display标签中的page属?br />
sort.amount=page
export.amount=list #导出的数据量
export.decorated=true
paging.banner.group_size=8 #前台昄的最多页?8 表示最多显C??br />
paging.banner.placement=top #前台昄?上一?下一?文字的位|?top表示上面 bottom表示下面
css.tr.even=even #偶数行的css标识 是偶数行的cssc?下面几个也是讄相应的css class
css.tr.odd=odd
css.th.sorted=sorted
css.th.ascending=order1
css.th.descending=order2
css.table=
css.th.sortable=sortable
# factory classes for extensions
factory.requestHelper=org.displaytag.util.DefaultRequestHelperFactory
# factory class for decorators
factory.decorator=org.displaytag.decorator.DefaultDecoratorFactory
# locale provider (Jstl provider by default)
locale.provider=org.displaytag.localization.I18nJstlAdapter
# locale.resolver (nothing by default, simply use locale from request)
#locale.resolver=
export.types=csv excel xml pdf
export.csv.class=org.displaytag.export.CsvView
export.excel.class=org.displaytag.export.ExcelView
export.xml.class=org.displaytag.export.XmlView
export.pdf.class=org.displaytag.export.PdfView
#export.***讄为true表示昄q种导出方式 falseZ采用
export.csv=true
export.csv.label=<span csv">CSV </span>
export.csv.include_header=false
export.csv.filename=
export.excel=true
export.excel.label=<span excel">Excel </span>
export.excel.include_header=true
export.excel.filename=
export.xml=true
export.xml.label=<span xml">XML </span>
export.xml.filename=
export.pdf=false
export.pdf.label=<span pdf">PDF </span>
export.pdf.include_header=true
export.pdf.filename=
export.rtf=false
export.rtf.label=<span rtf">RTF </span>
export.rtf.include_header=true
export.rtf.filename=
# messages
#相应的显CZ?包括I数据时候显C的 下两个显C的位置不一?一个是在table?nbsp; 一个是在下?br />
basic.msg.empty_list=Nothing found to display.
basic.msg.empty_list_row=<tr ><td colspan="{0}">Nothing found to display.</td></tr>
error.msg.invalid_page=invalid page
export.banner=<div >Export options: {0}</div>#导出处的提示文字
export.banner.sepchar= | #导出处的提示文字分隔W?br />
paging.banner.item_name=item
paging.banner.items_name=items
paging.banner.no_items_found=<span >No {0} found.</span>
paging.banner.one_item_found=<span >One {0} found.</span>
paging.banner.all_items_found=<span >{0} {1} found, displaying all {2}.</span>
paging.banner.some_items_found=<span >{0} {1} found, displaying {2} to {3}.</span>
paging.banner.full=<span >[<a href="{1}">First</a>/<a href="{2}">Prev</a>] {0} [<a href="{3}">Next</a>/<a href="{4}">Last</a>]</span>
paging.banner.first=<span >[First/Prev] {0} [<a href="{3}">Next</a>/<a href="{4}">Last</a>]</span>
paging.banner.last=<span >[<a href="{1}">First</a>/<a href="{2}">Prev</a>] {0} [Next/Last]</span>
paging.banner.onepage=<span >{0}</span>
paging.banner.page.selected=<strong>{0}</strong>
paging.banner.page.link=<a href="{1}" title="Go to page {0}">{0}</a>
paging.banner.page.separator=, \
# external sort and pagination
pagination.sort.param=sort
pagination.sortdirection.param=dir
pagination.pagenumber.param=page
pagination.searchid.param=searchid
pagination.sort.asc.value=asc
pagination.sort.desc.value=desc
pagination.sort.skippagenumber=true
# unused
save.excel.banner=<a href="{0}" rel="external">save ({1} bytes)</a>
save.excel.filename=export.xls
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/ZHOUJIAOSHOU/archive/2009/06/17/4277400.aspx
下面介绍几个Display最常用的功能,更多功能请参?a >http://displaytag.homeip.net/displaytag-examples-1.1/?br />
1. 分页
如果惛_代码分页Q只需在display:table标签中添加一pagesize="每页昄行数"Q如
<display:table name="test" pagesize="10"/>
2. 对列排序
display tag可对列进行排序,是点击列名Q对该列的数据进行排序。你只需Ҏ要排序的列添?sort="true" OKQ如下面的代码可对前三列q行排序。在display:table中添加defaultsort="列数"Q可默认Ҏ定的列排序?br />
<display:table name="test" styleClass="list" cellspacing="0" cellpadding="0" defaultsort="1">
<display:column property="id" title="ID" class="idcol" 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排序Q可以在display:table之间d一D代码:
<display:setProperty name="sort.amount" value="list"/>
3. 导出数据
在display:table中添加export="true"Q看看会出现什么!Display Tag默认会提供三U数据导出方式:CSV、Excel、XML ?br />
另外Display Tagq可以导ZؓPDF格式Q在http://prdownloads.sourceforge.net/itext/下蝲一个辅助包iText.jarQcopy到lib目录下,然后在display:table之间d一D代码:
<display:setProperty name="export.pdf" value="true"/>Q大功告成?/p>
4. Display Tag的属性设|?br />
前面所说的display:setProperty 是一U改变Display Tag属性的ҎQ但是在每个jsp中都要写太麻烦了?br />
Display Tag中设|了很多默认的属性,它有一个专门的属性文Ӟ是在它的jar包中的displaytag/properties/TableTag.properties
惌改变它的默认属性,我们可以在WEB-INFclasses下新Z个文件displaytag.propertiesQ仿照TableTag.properties中属性的格式讄需要修改的属性?br />
TableTag.properties中的# messages中设|的是显C在面上的提示信息。默认是英文的,我们可以把它改ؓ中文的。不q这里只能用unicodeQ就是说中文字符必须转换为unicode码,q个可以使用jdk自带的native2ascii.exeq行转换?/p>
5. 其它功能
DisplayTagq有一些很实用的小功能Q这里提两个。一个是Ҏ据的FormatQ这?.1版本d的新功能Q可以用标{方式格式化时间、数字、字W串。比如日期,在需要格式化的column标签中添加format=""Q第一个参Cؓ格式化的数据序号Q第二个参数是数据类型,数字为numberQ第三个参数为数据格式?br />
另外一个功能是对table数据的合计功能。在table标签中添?decorator="org.displaytag.decorator.TotalTableDecorator"Q然后在惌q行合计的数据列的column标签中添?total="true"Q该列就可以被计L了。但q个功能有个~点Q不能用在有分页的时候,它只能合计第一늚数据?br />
DisplayTag的不?br />
初次使用DisplayTag的h可能会觉得惊喜,但是用久了会发现很多问题Q最大的问题是对中文的支持不好,比如如果查询条g中有中文Q就无法页Q无法对中文排序Q将中文导出为指定文件时出现q{等。这些问题有时候会让h很郁P有时候逼得你要M改它的源代码。下面是对以上几个问题的解决ҎQ?br />
1. 对于中文无法页、排序,最单的办法是修改Tomcat下的server.xml文g。找到HTTP的Connector标签Q在里面d一URIEncoding="..."Q引号里面的内容取决于你的页面编码,比如可以是GBKQUTF8{。这样上面两个问题就可以解决了?br />
2. 导出为文Ӟ其实q个功能除了中文支持外还有很多其它问题,比如它会Html标签一起导出、只导出昄的内容,但如果对tableq行了decoratorQdecorator后的内容无法导出。如果想要将中文正确导出Q需要修改DisplayTag源代码?br />
下蝲相同版本的源代码Q在org.displaytag.export.ExcelView.java文g中找到getMimeType()ҎQ将此方法修改ؓ return "application/vnd.ms-excel;charset=GB2312";Q修改后导出数据的速度会慢很多Q不q将吧?br />
3. 新版的DisplayTag1.1d了对一ơ取部分数据的支持,相关的标{括partialList和sizeQ需要设|partialList="true"和size的大。具体怎么用偶q没研究?/p>