您的位置:首页 > Web前端 > JavaScript

servlet+jsp实现分页查询+导出

2016-03-16 14:18 615 查看
为一个10年前的项目添加一些新功能,当时项目用的技术是servlet+jdk1.4,而且项目中并没有分页以及导出EXCEL功能,所以我加了这两个功能。首相我想的是,因为查询的数据要通过很多个表,其中有三个表的数据量特别大,而且都需要全表扫描,加了索引之后SQL执行速度依然不是很快,所以当时想用JS来控制分页,这样只需要与数据库进行一次交互,用JS分页我参考了一个例子

js demo:

// JavaScript Document
/**//**
* js分页类
*
* @param iAbsolute
*            每页显示记录数
* @param sTableId
*            分页表格属性ID值,为String
* @param sTBodyId
*            分页表格TBODY的属性ID值,为String,此项为要分页的主体内容
* @Version 1.0.0
* @author 辛现宝 2007-01-15 created var __variable__; private function
*         __method__(){};private
*/
window.document.onkeydown = disableRefresh;
function disableRefresh(evt) {
evt = (evt) ? evt : window.event
if (evt.keyCode) {
if (evt.keyCode == 116) {
//do something
page.firstPage();
}
}
};

function Page(iAbsolute, sTableId, sTBodyId) {
this.absolute = iAbsolute; // 每页最大记录数
this.tableId = sTableId;
this.tBodyId = sTBodyId;
this.rowCount = 0;// 记录数
this.pageCount = 0;// 页数
this.pageIndex = 0;// 页索引
this.__oTable__ = null;// 表格引用
this.__oTBody__ = null;// 要分页内容
this.__dataRows__ = 0;// 记录行引用
this.__oldTBody__ = null;
this.__init__(); // 初始化;
};
/**//*
* 初始化
*/
Page.prototype.__init__ = function() {
this.__oTable__ = document.getElementById(this.tableId);// 获取table引用
this.__oTBody__ = this.__oTable__.tBodies[this.tBodyId];// 获取tBody引用
this.__dataRows__ = this.__oTBody__.rows;
this.rowCount = this.__dataRows__.length;
try {
this.absolute = (this.absolute <= 0) || (this.absolute > this.rowCount) ? this.rowCount
: this.absolute;
this.pageCount = parseInt(this.rowCount % this.absolute == 0 ? this.rowCount
/ this.absolute
: this.rowCount / this.absolute + 1);
} catch (exception) {
}
this.__LoadPages__();
this.__updateTableRows__();
};
/**//*
* 下一页
*/
Page.prototype.nextPage = function() {
if (this.pageIndex + 1 < this.pageCount) {
this.pageIndex += 1;
this.__updateTableRows__();
}
document.getElementById("pageindex").innerHTML = this.pageIndex + 1;
document.getElementById("pageselect").value = this.pageIndex + 1;
};
/**//*
* 上一页
*/
Page.prototype.prePage = function() {
if (this.pageIndex >= 1) {
this.pageIndex -= 1;
this.__updateTableRows__();
}
document.getElementById("pageindex").innerHTML = this.pageIndex + 1;
document.getElementById("pageselect").value = this.pageIndex + 1;
};
/**//*
* 首页
*/
Page.prototype.firstPage = function() {
if (this.pageIndex != 0) {
this.pageIndex = 0;
this.__updateTableRows__();
}
document.getElementById("pageindex").innerHTML = this.pageIndex + 1;
document.getElementById("pageselect").value = this.pageIndex + 1;
};
/**//*
* 尾页
*/
Page.prototype.lastPage = function() {
if (this.pageIndex + 1 != this.pageCount) {
this.pageIndex = this.pageCount - 1;
this.__updateTableRows__();
}
document.getElementById("pageindex").innerHTML = this.pageCount;
document.getElementById("pageselect").value = this.pageIndex + 1;
};
/**//*
* 页定位方法
*/
Page.prototype.aimPage = function(iPageIndex) {
if (iPageIndex > this.pageCount - 1) {
this.pageIndex = this.pageCount - 1;
} else if (iPageIndex < 0) {
this.pageIndex = 0;
} else {
this.pageIndex = iPageIndex;
}
this.__updateTableRows__();
};
Page.prototype.changePage = function() {
var iPageIndex = document.getElementById("pageselect").value;
this.aimPage(iPageIndex - 1);
document.getElementById("pageindex").innerHTML = iPageIndex;
};

/**//*
* 执行分页时,更新显示表格内容
*/
Page.prototype.__updateTableRows__ = function() {
var iCurrentRowCount = this.absolute * this.pageIndex;
var iMoreRow = this.absolute + iCurrentRowCount > this.rowCount ? this.absolute
+ iCurrentRowCount - this.rowCount
: 0;
var tempRows = this.__cloneRows__();
// alert(tempRows === this.dataRows);
// alert(this.dataRows.length);
var removedTBody = this.__oTable__.removeChild(this.__oTBody__);
var newTBody = document.createElement("TBODY");
newTBody.setAttribute("id", this.tBodyId);

for ( var i = iCurrentRowCount; i < this.absolute + iCurrentRowCount
- iMoreRow; i++) {
newTBody.appendChild(tempRows[i]);
}
this.__oTable__.appendChild(newTBody);
/**//*
* this.dataRows为this.oTBody的一个引用, 移除this.oTBody那么this.dataRows引用将销失,
* code:this.dataRows = tempRows;恢复原始操作行集合.
*/
this.__dataRows__ = tempRows;
this.__oTBody__ = newTBody;
// alert(this.dataRows.length);
// alert(this.absolute+iCurrentRowCount);
// alert("tempRows:"+tempRows.length);

};
/**//*
* 克隆原始操作行集合
*/
Page.prototype.__cloneRows__ = function() {
var tempRows = [];
for ( var i = 0; i < this.__dataRows__.length; i++) {
/**//*
* code:this.dataRows[i].cloneNode(param), param = 1 or
* true:复制以指定节点发展出去的所有节点, param = 0 or false:只有指定的节点和它的属性被复制.
*/
tempRows[i] = this.__dataRows__[i].cloneNode(1);
}
return tempRows;
};
//add by youngt 13/05/23
Page.prototype.__LoadPages__ = function() {
//alert(this.pageCount);
document.getElementById("pageselect").options.length = 0;
for ( var i = 1; i <= this.pageCount; i++) {
document.getElementById("pageselect").options.add(new Option(i, i));
}
};
//add end


JSP demo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>无标题文档</title>

<script type="text/javascript" language="javascript">

window.onload = function() {

page = new Page(3, 'table1', 'group_one');

};

</script>

<script type="text/javascript" language="javascript" src="fenye.js">

</script>

</head>

<body>

<table id="table1" border="0" width="486">

<thead>

<tr style="background-color:#CCCCCC;">

<th style="cursor:pointer;">Last Name</th>

<th style="cursor:pointer;">First Name</th>

<th style="cursor:pointer;">Birthday</th>

<th style="cursor:pointer;">Siblings</th>

</tr>

</thead>

<tbody id="group_one">

<tr style="background-color:#f3f3f3">

<td>Smith</td>

<td>John</td>

<td>7/12/1978</td>

<td>2</td>

</tr>

<tr style="background-color:#B4D6FC">

<td>Johnson</td>

<td>Betty</td>

<td>10/15/1977</td>

<td>4</td>

</tr>

<tr style="background-color:#f3f3f3">

<td>Henderson</td>

<td>Nathan</td>

<td>2/25/1949</td>

<td>1</td>

</tr>

<tr style="background-color:#B4D6FC">

<td>Williams</td>

<td>James</td>

<td>7/8/1980</td>

<td>4</td>

</tr>

<tr style="background-color:#f3f3f3">

<td>Gilliam</td>

<td>Micheal</td>

<td>7/22/1949</td>

<td>1</td>

</tr>

<tr style="background-color:#f3f3f3">

<td>Smith</td>

<td>John</td>

<td>7/12/1978</td>

<td>2</td>

</tr>

<tr style="background-color:#B4D6FC">

<td>Johnson</td>

<td>Betty</td>

<td>10/15/1977</td>

<td>4</td>

</tr>

<tr style="background-color:#f3f3f3">

<td>Henderson</td>

<td>Nathan</td>

<td>2/25/1949</td>

<td>1</td>

</tr>

<tr style="background-color:#B4D6FC">

<td>Williams</td>

<td>James</td>

<td>7/8/1980</td>

<td>4</td>

</tr>

<tr style="background-color:#f3f3f3">

<td>Gilliam</td>

<td>Micheal</td>

<td>7/22/1949</td>

<td>1</td>

</tr>

</tbody>

</table>

<span id="s"></span>

<table>

<tr>

<td><a href="#" onclick="page.firstPage();">首页</a></td>

<td><a href="#" onclick="page.prePage();">上一页</a></td>

<td>第<span id="pageindex">1</span>页</td>

<td><a href="#" onclick="page.nextPage();">下一页</a></td>

<td><a href="#" onclick="page.lastPage();">尾页</a></td>

<td>第<select id="pageselect" onchange="page.changePage();"></select>页</td>

</tr>

</table>

</body>

</html>

后来实现了效果之后,发现数据量过多(10000+条)后用前台拼table这种方式会导致网页加载变得异常慢,所以就用后台分页的方法重做了一次分页功能

首先需要建一个page类,存放分页的信息
public class Pager {
private int pageIndex;//第几页
private int pageSize;//一页显示多少行
private int totalRecord;//总共多少条记录
private int totalPage;//总共多少页
private List datas;//存放数据

public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public List getDatas() {
return datas;
}
public void setDatas(List datas) {
this.datas = datas;
}

}

查询的时候将分页信息传入sql中:

int start = (pageIndex-1)*pageSize;

String sql = "select * from (SQL语言) a where rownum<=start+pageSize) where num>start

这样就查询出了分页的信息

在前台展示分页即可,前台需要定义一个int pageSize = 20;//每页显示多上行数据

int pageIndex = 1;//页数

这里只记录前台分页的代码块
<%if(pager!=null){%>

<table>
<tr>
<td>

<%
String url = "CMCCBoardBandHisQuery?OprType=CMCCBoardBandHisQuery";
url += "&accept_start_date="+accept_start_date+" 00:00:00";
url += "&accept_end_date="+ accept_end_date +" 23:59:59";
url += "&station_kind=" + station_kind;
url += "&pageSize=" + pageSize;
url += "&pageIndex=";
%>

第<%= pageIndex %>页,共<%= pager.getTotalPage() %>页
<%
if (pageIndex > 1){
%>
<a href="<%=url+1 %>">首页</a>
<a href="<%=url+(pageIndex-1) %>">上一页</a>
<%
}else {
%>
首页 上一页
<%}%>
<%
if (pageIndex < pager.getTotalPage()){
%>
<a href="<%=url+(pageIndex+1) %>">下一页</a>
<a href="<%=url+pager.getTotalPage() %>">尾页</a>
<%
}else {
%>
下一页 尾页
<%}%>

跳转至第
<label>
<select id="page" name="page" onchange="redirect();">
<%
for ( int i = 1; i <= pager.getTotalPage(); i++){
if (i == pageIndex){
%>
<!--当前页页码默认选中-->
<option selected value="<%= i%>"><%= i %></option>
<%
}else {
%>
<option value="<%= i %>"><%= i %></option>
<%
}
}%>
</select>
</label> 页
</td>

</tr>
</table>

<%} %>

这样就完成了分页效果,优点是前台一次性不用加载过多的table,网页加载速度变快,缺点是每次点上一页,下一页等都会完成一次与数据库的交互,大家依情况自己选择吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: