您的位置:首页 > 其它

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

2016-07-13 11:37 302 查看
转了几篇文章。书名号里面的是我自己加上去的。

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.谢谢!!!

收藏于 2011-03-09
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: