DisplayTag外部(External paging)分页如何导出全部数据?????

来源:互联网 发布:python 把日期格式化 编辑:程序博客网 时间:2024/06/04 18:11

转了几篇文章。书名号里面的是我自己加上去的。

 


DisplayTag外部(External)分页如何导出全部数据

2010-06-25 11:13
http://wallimn.javaeye.com/blog/421465

最近大量使用了displayTag标签,真是很好用,各种功能设计得很体贴、很实用,效率也不错。导出、分页、排序都很方便,外

观设计也很便于修改。 
  对于大数据量的分页与排序,一般推荐使用外部(External)排序分页(详细介绍请看我翻译的官方文档:

http://wallimn.javaeye.com/blog/327753),也就是使用分页查询的SQL语句,利用数据库直接处理好分页与排序,服务器端

servlet只处理当前页的数据。详细方法请见我的博客: 
  http://wallimn.javaeye.com/blog/327742
  http://wallimn.javaeye.com/blog/327741
  但是,当使用这种方式的时候,导出为Excel等数据的时候,无法导出全部数据。在不使用外部方式的时候,在属性文件里设

置一个参数(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 
一下是他的博客地址

http://zuiyanwangyue.javaeye.com/

真的非常感谢他.因为本人还是学生...代码量不多.看了源代码3天了,还是一点头绪都没有. 
今天收到zuiyanwangyue发来的消息.尝试改了一下源代码.结果行了.在这里再一次感谢zuiyanwangyue.谢谢!!!

 

 

 


 

0 0
原创粉丝点击