1、何为 extremeTable,又一个开源taglib
      extremeTable,开源的jsp 自定义标签,以表格的形式显示数据,当前最新版本为 1.0.1-M1.
它是一个类似display tag,valueList 等开源产品.
homepage: http://extremecomponents.org/
download: http://sourceforge.net/projects/extremecomp/
开源产品作者:
Jeff Johnston ,现居住美国,圣路易斯.
                六年web应用软件开发经验,eXtremeComponents最初的创建者. 负责设计及大部分的编码。
其它还包括Paul Horn ,eXtremeTree的技术设计, 以及大部分的编码;
Dave Goodin,Brad Parks等.
主要特色
1、导出EXCEL以及pdf无需再另写jsp(这个基本与valuelist作比较,因为以前用valueList的时候每写一个table都要再写一个excel.jsp)
2、扩展性比较强,基本上想怎样改就怎样改,对jar影响比较少。
3、另外据官方声称有以下四点
Fast ( 本人曾小测一次,三千纪录情况下,效率基本与valuelist持平) 
Efficient 
Easy ( 得确很容易使用与理解加扩展) 
Reliable 
安装要求
1、Servlet 2.3 或更高
2、 JDK 1.3.1 或更高 
最小的Jars需求
1、commons-beanutils 1.6
2、commons-collections 3.0
3、 commons-lang 2.0
4、 commons-logging 1.0.4
5、 standard 1.0.2
PDF 导出要用到的包:
1、 avalon-framework 4.0
2、batik 1.5-fop-0.20-5
3、 fop 0.20.5
4、 xalan 2.5.1
5、 xercesImpl 2.6.1
6、 xml-apis 2.0.2
XLS 导出要用到的包:
1、 poi-2.5.1.jar
2、安装与测试
下载解压到的主要文件包括
[1]src源文件
[2]extremecomponents.jar以及其它所依赖的包
[3]tld文件
extremecomponents.tld
[4]一组默认样式及图片
extremecomponents.css
[5]用以校验安装的测试页面
test.jsp 
[6]doc文档,比较详细
快速配置安装
web app目录结构
/ROOT
     /WEB-INF/web.xml
        /tld/extremecomponents.tld
           /lib
           /classes/extremecomponents.properties 
                   [extremecomponents.properties文件可到source\org\extremecomponents\table\core\中得到]
      /images/*.jpg [一组默认样式及图片]
      /css/extremecomponents.css
      /test.jsp
      /index.jsp [用于学习以及扩展测试用代码请见下]
     
web.xml 配置
包括taglib uri 定义以及导出文件filter,由于只是手板功夫,这里就略过了,相关代码如下:
 <taglib>
<taglib>
 <taglib-uri>/tld/extremecomponents</taglib-uri>
<taglib-uri>/tld/extremecomponents</taglib-uri>
 <taglib-location>/WEB-INF/tld/extremecomponents.tld</taglib-location>
<taglib-location>/WEB-INF/tld/extremecomponents.tld</taglib-location>
 </taglib>
</taglib> 
 <filter>
<filter>
 <filter-name>eXtremeExport</filter-name>
<filter-name>eXtremeExport</filter-name>
 <filter-class>org.extremecomponents.table.filter.ExportFilter</filter-class>
<filter-class>org.extremecomponents.table.filter.ExportFilter</filter-class>
 </filter>
</filter>
 <filter-mapping>
<filter-mapping>
 <filter-name>eXtremeExport</filter-name>
<filter-name>eXtremeExport</filter-name>
 <url-pattern>/*</url-pattern>
<url-pattern>/*</url-pattern>
 </filter-mapping>
</filter-mapping>

 
配置好所有后,开tomcat,测试浏览http://your_web_app/test.jsp,看到
Congratulations!! You have successfully configured eXtremeTable!
恭喜你,这表示安装成功!
3、动手学习这个taglib
建index.jsp页面,修改代码如下
 <%@ page contentType="text/html;charset=GBK"%>
<%@ page contentType="text/html;charset=GBK"%>
 <%@ page import="java.util.*"%>
<%@ page import="java.util.*"%>
 <%@ taglib uri="/tld/extremecomponents" prefix="ec" %>
<%@ taglib uri="/tld/extremecomponents" prefix="ec" %>
 <!-- 在本页要用到jstl-->
<!-- 在本页要用到jstl-->
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 <!--使用include的方式-->
<!--使用include的方式-->
 <link rel="stylesheet" type="text/css" href="<c:url value="/extremecomponents.css"/>">
<link rel="stylesheet" type="text/css" href="<c:url value="/extremecomponents.css"/>">

 <%
<%
 List goodss = new ArrayList();
    List goodss = new ArrayList();
 for (int i = 1; i <= 10; i++)
    for (int i = 1; i <= 10; i++)

 
     {
{
 Map goods = new java.util.HashMap();
        Map goods = new java.util.HashMap();
 goods.put("code", "A00"+i);
        goods.put("code", "A00"+i);
 goods.put("name", "面包"+i);
        goods.put("name", "面包"+i);
 goods.put("status", "A:valid");
        goods.put("status", "A:valid");
 goods.put("born", new Date());
        goods.put("born", new Date());
 goodss.add(goods);
        goodss.add(goods);
 }
    }
 request.setAttribute("goodss", goodss);
    request.setAttribute("goodss", goodss);
 %>
%>
 <ec:table
<ec:table
 collection="goodss"
 collection="goodss"
 action="${pageContext.request.contextPath}/test.jsp"
    action="${pageContext.request.contextPath}/test.jsp"
 imagePath="${pageContext.request.contextPath}/images/*.gif"
    imagePath="${pageContext.request.contextPath}/images/*.gif"
 cellpadding="1"
    cellpadding="1"
 title="my bread">
    title="my bread">
 <ec:column property="code"/>
<ec:column property="code"/>
 <ec:column property="name"/>
<ec:column property="name"/>
 <ec:column property="status"/>
<ec:column property="status"/>
 <ec:column property="born" cell="date" format="yyyy-MM-dd"/>
<ec:column property="born" cell="date" format="yyyy-MM-dd"/>
 </ec:table>
</ec:table> 
效果如下:

[1] 1.0.1-M1 版支持国际化
修改web.xml文件增加
 <context-param>
<context-param>
 <param-name>extremecomponentsResourceBundleLocation</param-name>
   <param-name>extremecomponentsResourceBundleLocation</param-name>
 <param-value>com.itorgan.tags.extreme.extremetableResourceBundle</param-value>
   <param-value>com.itorgan.tags.extreme.extremetableResourceBundle</param-value>
 </context-param>
</context-param> 
意指到 com.itorgan.tags.extreme 下找 extremetableResourceBundle_[language]_[country].properties 文件
extremetableResourceBundle_en_US.properties代码如下
table.statusbar.resultsFound={0} results found, displaying {1} to {2} 
table.statusbar.noResultsFound=There were no results found.
table.toolbar.showAll=Show All
extremetableResourceBundle_zh_CN.properties如下.
table.statusbar.resultsFound={0} \u6761\u7EAA\u5F55\u7B26\u5408\u6761\u4EF6, \u73B0\u5728\u662F\u7B2C {1} \u81F3 {2} \u6761\u7EAA\u5F55
table.statusbar.noResultsFound=\u6CA1\u6709\u8981\u67E5\u8BE2\u7684\u7EAA\u5F55\u3002
table.toolbar.showAll=\u6240 \u6709
补充:中文 - > Unicode编码 可通过反编译class文件或用native2ascii命令得到 。
然后在table标签中增加locale属性即可切换
 <ec:table
<ec:table
 ………………
    ………………
 ………………
    ………………
 ………………
    ………………
 locale="en_US"
    locale="en_US"
 >
>

 <ec:table
<ec:table
 ………………
    ………………
 ………………
    ………………
 ………………
    ………………
 locale="zh_CN"
    locale="zh_CN"
 >
>

 
[2] 保留table的上一次状态
      是指,不管跳转到另一个后再返回,extremeTable会将之前的Filter,Sort参数保存到session中,以至返回看到的页面还是之前的状态.
实现操作方法:
修改extremecomponents.properties文件
table.useSessionFilterSortParam=foo
saveFilterSort="true" 注意:saveFilterSort="true"不能在properties文件中配置,只能在页面中设
新建一页面用于跳转的页面 1.jsp
代码为
 <a href="test.jsp?foo=true">Back</a>
<a href="test.jsp?foo=true">Back</a> 
[3] 样式修改
基本的HTML结构
 <div class="eXtremeTable" >
<div class="eXtremeTable" >
 <table border="0"  cellpadding="0"  cellspacing="0"  width="100%" >
<table border="0"  cellpadding="0"  cellspacing="0"  width="100%" >
 <tr>
    <tr>
 <td class="title" ><span><!--标题--></span></td>
        <td class="title" ><span><!--标题--></span></td>
 <td align="right" >
        <td align="right" >
 <table border="0"  cellpadding="0"  cellspacing="1"  class="toolbar" >
        <table border="0"  cellpadding="0"  cellspacing="1"  class="toolbar" >
 <tr>
            <tr>
 <form name="pres_toolbar"  action="/extremesite/public/demo/presidents.jsp" >
      <form name="pres_toolbar"  action="/extremesite/public/demo/presidents.jsp" >
 <!--工具栏,包括上一页,下一页以及导出-->
            <!--工具栏,包括上一页,下一页以及导出-->
 </tr>
            </tr>
 <tr>
            <tr> 
 </form>
      </form>
 </tr>
            </tr>
 </table>
        </table>
 </td>
        </td>
 </tr>
    </tr>
 </table>
</table>

 <table id="pres"  border="0"  cellspacing="2"  cellpadding="0"  width="100%"  class="tableRegion" >
<table id="pres"  border="0"  cellspacing="2"  cellpadding="0"  width="100%"  class="tableRegion" >
 <tr>
    <tr>
 <td colspan="6" >
        <td colspan="6" >
 <table border="0"  cellpadding="0"  cellspacing="0"  width="100%" >
        <table border="0"  cellpadding="0"  cellspacing="0"  width="100%" >
 <tr>
            <tr>
 <td class="statusBar" >43 results found, displaying 1 to 12 </td>
                <td class="statusBar" >43 results found, displaying 1 to 12 </td>
 <td class="filterButtons" ></td>
                <td class="filterButtons" ></td>
 </tr>
            </tr>
 </table>
        </table>
 </td>
        </td>
 </tr>
    </tr>        

 <form name="pres_filter"  action="/extremesite/public/demo/presidents.jsp" >
<form name="pres_filter"  action="/extremesite/public/demo/presidents.jsp" >
 <tr class="filter"  id="filter" >
    <tr class="filter"  id="filter" >
 <!--过滤条件的input框-->
        <!--过滤条件的input框-->
 </tr>
    </tr>
 </form>
</form>
 <tr>
    <tr>
 <!--tableHead-->
        <!--tableHead-->
 </tr>
    </tr>
 <tbody class="tableBody" >
    <tbody class="tableBody" >
 <tr>
    <tr>
 <!--column-->
        <!--column-->
 </tr>
    </tr>
 </tbody>
    </tbody>
 </table>
</table>
 </div>
</div>

 
extremeTable支持样式快速切换.可自定的样式包括column 的td以及table的一些属性,例如cellpadding等,
另本人发现,在properties中如下设置tableHeader的样式是不行的.不知道是否一个BUG
table.headerClass=itoTableHeader
table.headerSortClass=itoTableHeaderSort
只能继承一个HeaderCell
 public class HeaderCell extends org.extremecomponents.table.cell.HeaderCell
public class HeaderCell extends org.extremecomponents.table.cell.HeaderCell


 {
{
 public final static String TABLE_HEADER = "itoTableHeader";
    public final static String TABLE_HEADER = "itoTableHeader";
 public final static String TABLE_HEADER_SORT = "itoTableHeaderSort";
    public final static String TABLE_HEADER_SORT = "itoTableHeaderSort";
 }
} 
新的样式代码:
 <LINK REL="stylesheet" HREF="<c:url value="/style.css"/>" TYPE="text/css">
<LINK REL="stylesheet" HREF="<c:url value="/style.css"/>" TYPE="text/css">
 <ec:table
 collection="goodss"
    action="${pageContext.request.contextPath}/test.jsp"
    imagePath="${pageContext.request.contextPath}/images/*.gif"
    cellpadding="1"
    title="my bread"
    saveFilterSort="true"
    locale="zh_CN"
>
<ec:column property="code" title="编号" width="100" styleClass="GridTd"/>
<ec:column property="name" title="名称" width="200" styleClass="GridTd"/>
<ec:column property="status" title="状态" width="80" styleClass="GridTd"/>
<ec:column property="born" title="生产日期" width="100" cell="date" format="yyyy-MM-dd" styleClass="GridTd"/>
</ec:table> 
效果见下:
![ec[2].jpg](/images/blogjava_net/davidxu/ec[2].jpg)
[4] 实现 table width 自动累加
原来的extremeTable 宽度要自己set。不会自动能过下面的column累加。
本人作了个修改以达到自动累加,省得自己加写上去:
查看htmlView.java 两处地方 
toolbarPlacement
tableStart可见两处地方要修改的
[5] custom cell
在properties文件中我们可观察到:
 table.cell_=display
table.cell_=display
 table.cell_currency=org.extremecomponents.table.cell.NumberCell
table.cell_currency=org.extremecomponents.table.cell.NumberCell
 table.cell_number=org.extremecomponents.table.cell.NumberCell
table.cell_number=org.extremecomponents.table.cell.NumberCell
 table.cell_display=org.extremecomponents.table.cell.DisplayCell
table.cell_display=org.extremecomponents.table.cell.DisplayCell
 table.cell_date=org.extremecomponents.table.cell.DateCell
table.cell_date=org.extremecomponents.table.cell.DateCell 
当 column 默认使用org.extremecomponents.table.cell.DisplayCell

 public class DisplayCell extends BaseCell
public class DisplayCell extends BaseCell  {
{


 public String html()
    public String html()  {
{
 HtmlBuilder html = new HtmlBuilder();
        HtmlBuilder html = new HtmlBuilder();

 html.append(startTD());
        html.append(startTD());

 Object value = column.getValue();
        Object value = column.getValue();

 if (value != null && StringUtils.isNotEmpty(value.toString()))
        if (value != null && StringUtils.isNotEmpty(value.toString()))  {
{
 html.append(value);
            html.append(value);

 } else
        } else  {
{
 html.append(" ");
            html.append(" ");
 }
        }

 html.append(endTD());
        html.append(endTD());

 return html.toString();
        return html.toString();
 }
    }
 }
}

 
ec已其它cell
日期格式化: cell = " date " format = " yyyy-MM-dd " 
数字格式化: cell="currency" format="###,###,##0.00"
另外,extremeTable支持自定义cell
在这里我以一个简单的例子[以input框的形式出现] 说明如何实现这一方便的扩展
 public class DemoInput extends BaseCell
public class DemoInput extends BaseCell


 {
{
 public String html()
      public String html()

 
     {
{
 Integer rowNum = rowcount;
        Integer rowNum = rowcount;
 HtmlBuilder html = new HtmlBuilder();
        HtmlBuilder html = new HtmlBuilder();
 html.append(startTD());
        html.append(startTD());
 Object value = column.getValue();
        Object value = column.getValue();
 HtmlBuilder input = new HtmlBuilder();
        HtmlBuilder input = new HtmlBuilder();
 input.input("text");
        input.input("text");
 input.name(column.getProperty() + "_" + rowNum);
        input.name(column.getProperty() + "_" + rowNum);
 input.value(value.toString());
        input.value(value.toString());
 input.close();
        input.close();
 html.append(input.toString());
        html.append(input.toString());
 html.append(endTD());
        html.append(endTD());
 return html.toString();
        return html.toString();
 }
    }
 }
} 
properties文件增加
 table.cell_demoInput =org.extremecomponents.table.cell.DemoInput
table.cell_demoInput =org.extremecomponents.table.cell.DemoInput  
jsp代码
 <ec:column property="code" title="编号" width="100" cell="demoInput" styleClass="GridTd"/>
<ec:column property="code" title="编号" width="100" cell="demoInput" styleClass="GridTd"/> 
效果显示为
当然这只是一个简单的demo以说明如何自定义cell
如上面你可以简单的实现同样功能
 <ec:column property="code" title="编号" width="100" styleClass="GridTd">
<ec:column property="code" title="编号" width="100" styleClass="GridTd">
 <input type="text" value="${goodss.code}" name="code_${ROWCOUNT}">
<input type="text" value="${goodss.code}" name="code_${ROWCOUNT}">
 </ec:column>
</ec:column> 
[6]Extended Attributes
新版本支持Extended Attributes,方便了用户扩展,记得0.9版本时还要我修改N个地方,现在为table,column增加attribute方便多了.
为table增加一个height的属性
 public class TableTag extends org.extremecomponents.table.tag.TableTag
public class TableTag extends org.extremecomponents.table.tag.TableTag


 {
{
 //div 的高度
    //div 的高度
 private String height;
    private String height;

 public String getHeight()
    public String getHeight()

 
     {
{
 return height;
        return height;
 }
    }

 public void setHeight(String height)
    public void setHeight(String height)

 
     {
{
 this.height = height;
        this.height = height;
 }
    }

 public void addExtendedAttributes(Attributes attributes)
    public void addExtendedAttributes(Attributes attributes)

 
     {
{
 attributes.addAttribute("height", getHeight());
        attributes.addAttribute("height", getHeight());
 }
    }


 /**//**
    /**//**
 * set the new attribuer to null - by ito
     * set the new attribuer to null - by ito
 */
     */
 public void release()
    public void release()

 
     {
{
 super.release();
        super.release();
 height = null;
        height = null;
 }
    }
 }
} 
然后就可以通过
model.getTableHandler().getTable().getAttribute("height")取得这个值.可以方便扩展.
[7] 解决excel中文问题
继承XlsView.java

 private void body(BaseModel model, Column column, boolean isFirstColumn, boolean isLastColumn)
    private void body(BaseModel model, Column column, boolean isFirstColumn, boolean isLastColumn)  {
{
 //原来的代码略
      //原来的代码略
 hssfCell.setEncoding(HSSFCell.ENCODING_UTF_16); //解决中文乱码
        hssfCell.setEncoding(HSSFCell.ENCODING_UTF_16); //解决中文乱码
 //原来的代码略
//原来的代码略
 
        
 }
    }


 private void createHeader(BaseModel model)
    private void createHeader(BaseModel model)  {
{
 //原来的代码略
       //原来的代码略
 hssfCell.setEncoding(HSSFCell.ENCODING_UTF_16); //解决中文乱码
        hssfCell.setEncoding(HSSFCell.ENCODING_UTF_16); //解决中文乱码
 //原来的代码略
//原来的代码略
 
        
 }
   } 
[8] 解决pdf中文问题
帮POF注册中文字体,再修改export view即可解决
[9] Pagination
[10] 其它亮点
A sortable 与 exportable 属性 ,分别指可否排序,可否导出. 值为 false/true 
B 可以直接在<ec:column></e:column>中加html代码.
    并可用{collectionName.objectName}类似的语法取得当前object的成员变量值
C  ${ROWCOUNT}可取当前row num,是指以1开始计算 
D  ec另一亮点就帮我们写好了form ,如上代码:
      <ec:form name="mainform" action="goods.do"> </ec:form> 设置form name以及action 
参考文档
http://extremecomponents.org/extremesite/public/documentation.jsp