最近工作中,需要制作一个报表,作用是对整体的任务完成情况进行统计和展示。发现Jquery确实非常好用和强大。
处理流程分析:
1.客户在页面选择查询日期,点击查询
2.调用pro_StatisticTableToTemp存储过程进行数据处理,处理结果放在一张临时表中
3.查询这张临时表,取出数据,然后处理成页面所需要的JSON格式
4.查询成功,JSON字符串返回到前台页面
5.使用JQuery对JSON进行解析,然后展示。
spring部分跳转代码
通过spring 跳转到showStatisticsResult.jsp
//查询出所有的机构信息,用于任务统计时条件筛选
List organList = commonDao.getObjectListByArguments("queryStatisticConOrgan", null);
//转换成JSON格式,传递给页面
Gson gsonOrg = new Gson();
String jsonOrganString = gsonOrg.toJson(organList);
request.setAttribute("jsonOrganString",jsonOrganString);
log.info("获取完任务统计中机构列表的JSON:"+jsonOrganString);
return new ModelAndView("showStatisticsResult");
内容展示页面 jsp
showStatisticsResult.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ page contentType="text/html; charset=utf-8"%>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", -10);
%>
<html>
<head>
<title>报表统计</title>
<base target="_self" />
<!-- 引用的一个外部样式表,来美化表格的样式 -->
<link
href="<%=request.getContextPath()%>/page/css/totaltablestyle_jy.css"
rel="stylesheet" type="text/css">
<!-- jquery的引用 -->
<script type="text/javascript"
src="/RiskScan/page/javascript/acc/jquery.js"></script>
<!-- jquery表格插件的引用 -->
<script language="javascript" type="text/javascript"
src="/RiskScan/webapp/page/javascript/acc/jquery.columnhover.pack.js"></script>
<script language="javascript" type="text/javascript"
src="/RiskScan/webapp/page/javascript/acc/jquery.columnhover.js"></script>
<!-- 引用日期选择控件 -->
<link
href="<%=request.getContextPath()%>/prompt/My97DatePicker/skin/WdatePicker.css"
rel="stylesheet" type="text/css">
<script language="javascript" type="text/javascript"
src="<%=request.getContextPath()%>/prompt/My97DatePicker/WdatePicker.js"></script>
<!-- 此页面用的JS代码,作用:验证表单、提交Ajax请求等 -->
<script language="javascript" type="text/javascript"
src="<%=request.getContextPath()%>/page/javascript/acc/StatisticsCheckFormAndCommit.js" charset=”utf-8″></script>
<!-- 悬浮提示的引用 -->
<link href="<%=request.getContextPath()%>/page/jqueryHoverTip/css/manhua_hoverTips.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="<%=request.getContextPath()%>/page/jqueryHoverTip/js/manhua_hoverTips.js"></script>
<script type="text/javascript">
//Jquery的全局事件
$(function() {
// 获取机构码下拉框信息,使用request取得属性值
var organStr = '<%=request.getAttribute("jsonOrganString")%>';
// alert(typeof(organStr)); 将弹出:String。是javascript中的字符串类型
//将JSON的字符串解析成JSON数据格式,由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式。
var objStr = eval("("+organStr+")");
//var objStr = (organStr);//(organStr);
//alert(eval("{}")); // return:undefined
//alert(eval("({})"));// return [object Object]
// 遍历json对象,构建select控件的选项
$.each(objStr, function(index, v) {
$("#selectOrgan").append(
"<option value='" + v.organId + "'>" + v.organName
+ "</option>");
});
// 鼠标悬浮提示的绑定
$("#searchButton").manhua_hoverTips( {
position : "t"
});// 改变了显示的位置参数,位置说明(以控件为参照物):上-b 右-l 下-t 左-r
// 设置表格内容初始化时为不可见
$("div#scrollDiv").css("display", "none");
// 绑定全局的Enter时间,默认查询
document.onkeydown = function(e) {
var ev = document.all ? window.event : e;
if (ev.keyCode == 13) {
// 点击查询
$("#searchButton").click();
}
};
});
</script>
</head>
<body>
<!-- 使用Ajax提交表单,所以,不再需要Form了 -->
<!-- <form name="StatisticsForm" id="StatisticsFormId" method="post"
action=<c:url value="/commitStatisticsData.sp"/>>-->
<div class="exa">
<h1>
会计标准化任务统计报表
</h1>
<!-- <pre style="text-align: left; padding-top: 8px;">-->
<div class="chooseConditionDiv">
<div class="conditionAlone">查询开始日期:<input class="Wdate" type="text" id="dateStartId" name="dateStart" οnclick="WdatePicker()" value="2013-10-03"></div>
<div class="conditionAlone">查询结束日期:<input class="Wdate" type="text" id="dateEndId" name="dateEnd" οnclick="WdatePicker()" value="2013-12-03"></div>
<div class="conditionAlone">查询机构:<select class="selectOrganWid" id="selectOrgan"/></div>
<div class="conditionAlone"><input type="button" id="searchButton" value="查 询" tips="点击此按钮或按下<br/>键盘Enter键查询" οnclick="return checkFormAjax()"/></div>
</div>
<!-- 包含表格的DIV容器 -->
<div id = "scrollDiv" class="scrollDiv">
<!-- 用于展示结果数据的表格 -->
<table id="tabletwo" class="scrollTable">
<thead>
<tr style="white-space: nowrap;" class="scrollColThead">
<!-- 首行标题 -->
<th class="scrollRowThead scrollCR">
机构码
</th>
<th colspan="2">
每日任务
</th>
<th colspan="3">
日终任务
</th>
<th colspan="2">
每周任务
</th>
<th colspan="2">
每旬任务
</th>
<th colspan="3">
每月任务
</th>
<th colspan="3">
每季任务
</th>
<th colspan="3">
半年定期任务
</th>
<th colspan="3">
每年任务
</th>
</tr>
<tr class="scrollColThead">
<th class="scrollRowThead scrollCR">
<!-- 注意内容的填充,什么都不填写会影响样式-->
</th>
<th>
已完成
</th>
<th>
未完成
</th>
<th>
已完成
</th>
<th>
未完成
</th>
<th>
迟报
</th>
<th>
已完成
</th>
<th>
未完成
</th>
<th>
已完成
</th>
<th>
未完成
</th>
<!-- 每月任务的完成情况,开始分为三部分 -->
<th>
已完成
</th>
<th>
未完成
</th>
<th>
迟报
</th>
<th>
已完成
</th>
<th>
未完成
</th>
<th>
迟报
</th>
<th>
已完成
</th>
<th>
未完成
</th>
<th>
迟报
</th>
<th>
已完成
</th>
<th>
未完成
</th>
<th>
迟报
</th>
</tr>
</thead>
<tbody id="showDatasTB">
<!-- tr 标签 -->
</tbody>
</table>
</div>
<!-- 这个Div用于空白填充和显示查询日期范围 -->
<div class="paddingTemp" id="paddingDiv"></div>
</div>
<!-- </form> -->
</body>
</html>
鼠标悬浮效果:
totaltablestyle_jy.css (部分代码)
/*重点:固定表头样式,实现类似于Excel的窗体冻结功能*/
.scrollRowThead {
position: relative;
left: expression(this.parentElement.parentElement .
parentElement.parentElement.scrollLeft);
z-index: 0;
}
/*重点:固定表头样式,实现类似于Excel的窗体冻结功能*/
.scrollColThead {
position: relative;
top: expression(this.parentElement.parentElement.parentElement.scrollTop)
;
z-index: 2;
}
/*行列交叉的地方*/
.scrollCR {
z-index: 3;
}
/*行头居中*/
.scrollColThead td,.scrollColThead th {
text-align: center;
}
/*行头列头背景*/
.scrollRowThead,.scrollColThead td,.scrollColThead th {
background-color: bisque;
}
/*表格的线*/
.scrolltable {
border-bottom: 1px solid gray;
border-right: 1px solid gray;
}
/*单元格的线等*/
.scrolltable td,.scrollTable th { /*border-left: 1px solid gray;
border-top: 1px solid gray;*/
border: 1px solid bisque;
padding: 5px;
}
/*这个是仅次于body的div 包围了所有元素*/
div.exa {
background-color: ivory; /**/ /*//background: 0; for ie*/
border: 0px solid gray;
padding: 0 10px;
}
/*这是筛选条件的区域*/
div.chooseConditionDiv {
background-color: LemonChiffon;
border: 1px solid gray;
padding: 2%;
marin-bottom: 0px;
/*width:100%;*/
}
/*单个条件控件的外围div*/
div.conditionAlone {
border: 0px solid red;
display: inline;
margin-right: 1%;
}
.selectOrganWid{
background-color: white;
}
div.paddingTemp {
height: 30px;
border: 0px solid green;
}
.scrollDiv {
height: 489px;
clear: both;
border: 0px solid #000000;
OVERFLOW: scroll;
width: 97%;
}
StatisticsCheckFormAndCommit.js
用于验证表单、提交Ajax请求以及生成报表。注意:编码格式为UTF-8,和JSP页面的编码格式是一致的,否则可能出现中文乱码问题。
// 表单验证+提交
function checkFormAjax() {
// 日期的非空验证
if (!$.trim($("#dateStartId").val())) {
alert("请选择开始日期");
return;
}
// 日期的非空验证
if (!$.trim($("#dateEndId").val())) {
alert("请选择结束日期");
return;
}
// 接下来,进行日期的大小比较
// 如:把 2013-11-13 格式,转换成 20131113 格式
var tempStart = $("#dateStartId").val().replace(/-/g, "/");
var theStartDate = new Date(tempStart);
var tempEnd = $("#dateEndId").val().replace(/-/g, "/");
var theEndDate = new Date(tempEnd);
// 获取select的value值
var theSelectedOrgan = $("#selectOrgan").val();
// 获取text的值
theSelectedOrgan = $("#selectOrgan").find("option:selected").text();
// 如果,开始日期大于结束日期
if (Date.parse(theStartDate) - Date.parse(theEndDate) > 0) {
window.alert("结束日期 小于 开始日期,请重新选择");
// 记得,先对原有的内容进行清空
$("div#paddingDiv").text("");
// 使用JQuery向指定Div写入内容
$("div#paddingDiv").append(
'查询日期: ' + tempStart + " — " + tempEnd + " 查询机构: "
+ theSelectedOrgan);
// 设置CSS属性:错误情况下,字体是红色的
$("div#paddingDiv").css("font-family", "微软雅黑").css("font-size", "18px")
.css("text-shadow", "1px 1px 1px #999999").css("color", "red");
return false;
} else {// 日期正确的情况
$("div#paddingDiv").text("");
// 使用JQuery向指定Div写入内容
$("div#paddingDiv").append(
'查询日期: ' + tempStart + " — " + tempEnd + " 查询机构: "
+ theSelectedOrgan);
// 设置样式
$("div#paddingDiv").css("font-family", "微软雅黑").css("font-size", "18px")
.css("text-shadow", "1px 1px 1px #999999").css("color", "black");
}
/**
* visibility属性用来确定元素是显示还是隐藏,这用visibility="visible|hidden"来表示,visible表示显示,hidden表示隐藏。
* 当visibility被设置为"hidden"的时候,元素虽然被隐藏了,但它仍然占据它原来所在的位置。
* display被设置:none,这时元素实际上就从页面中被移走,它下面所在的元素就会被自动跟上填充。元素被隐藏之后,就不能再接收到其它事件了
*/
// 显示时间范围的区域暂时隐藏 ,但是依旧占据空间
$("div#paddingDiv").css("visibility", "hidden");
// 使用JQuery 的Ajax提交表单
var dateStart = $("#dateStartId").val();
var dateEnd = $("#dateEndId").val();
var selectOrgan = $("#selectOrgan").val();
$.ajax( {
type : "POST",
url : "commitStatisticsData.sp",
data : {
dateStart : dateStart,
dateEnd : dateEnd,
selectOrgan : selectOrgan
},
success : function(data) {
// 需要先对子节点进行一次初始化
// 语法分析:$("p#demo") 选取所有 id="demo" 的 <p> 元素。
$("tbody#showDatasTB").empty();
// 暂时让表格所在的Div不可见
$("div#tableContainerId").hide();
// 迭代取到的json数据,拼接表格
$.each(data, function(k, v) {
// 展示、观察数据正误
// $("div#paddingDiv").append("编号:"+k+"\t机构码:"+v.jgm+"\t数量:"+v.mrrw.wcCount+"-"+v.mrrw.wwcCount);
// 进行数据展示
var tempTr = "<tr> <td id='jgmShowId' class='scrollRowThead'> "
+ v.jgm + " </td> <td id='mrwc'> " + v.mrrw.wcCount
+ " </td> <td id='mrwwc'> " + v.mrrw.wwcCount
+ " </td> <td id='rzrwwc'> " + v.rzrw.wcCount
+ " </td> <td id='rzrwwwc'> " + v.rzrw.wwcCount
+ " </td> <td id='rzrwcb'>" + v.rzrw.cbCount
+ "</td> <td id='mzwc'> " + v.mzrw.wcCount
+ " </td> <td id='mzwwc'> " + v.mzrw.wwcCount
+ " </td> <td id='mxwc'> " + v.mxrw.wcCount
+ " </td> <td id='mxwwc'> " + v.mxrw.wwcCount
+ " </td> <td id='mywc'> " + v.myrw.wcCount
+ " </td> <td id='mywwc'>" + v.myrw.wwcCount
+ " </td> <td id='mycb' tips='每月迟报数量'>"
+ v.myrw.cbCount + " </td> <td id='mjwc'> "
+ v.mjrw.wcCount + " </td> <td id='mjwwc'> "
+ v.mjrw.wwcCount
+ " </td> <td id='mjcb' tips='每季迟报数量'>"
+ v.mjrw.cbCount + " </td> <td id='bnwc'>"
+ v.bnrw.wcCount + "</td> <td id='bnwwc'>"
+ v.bnrw.wwcCount + "</td> <td id='bncb'>"
+ v.bnrw.cbCount + "</td> <td id='mnwc'>"
+ v.mnrw.wcCount + "</td> <td id='mnwwc'>"
+ v.mnrw.wwcCount + "</td> <td id='mncb'>"
+ v.mnrw.cbCount + "</td> </tr>";
// 添加入 tbody 中
$("tbody#showDatasTB").append(tempTr);
});
// 加载完成之后,对统计表格进行动画显示,如果加上动画,就没有滚动条了,注释掉
$("div#scrollDiv").css("display", "block");
//$("div#scrollDiv").slideDown(2000);
// 显示时间范围的区域显示出来
$("div#paddingDiv").css("visibility", "visible");
// 更改最后一个tr标签的css属性
$("tr:last").css( {
"background" : "khaki",
"text-align" : "center"
});
}
});
}
Spring MVC的配置:
处理Ajax Post请求
<!-- 工作量报表,提交表单:开始日期和结束日期的Action跳转 -->
<bean name="/commitStatisticsData.sp" class="com.peak.acc.action.TaskStatisticsConditionAction">
<property name="commonDao">
<ref bean="commonDao" />
</property>
</bean>
Java处理代码(部分):
public synchronized ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// 查询开始日期,并转换成存储过程需要的格式 yyyymmdd
String startDate = request.getParameter("dateStart").replace("-", "");
// 查询结束日期,并转换成存储过程需要的格式 yyyymmdd
String endDate = request.getParameter("dateEnd").replace("-", "");
// 查询机构
String organString = request.getParameter("selectOrgan").trim();
// 传递参数用的Map载体
HashMap paramMap = new HashMap();
paramMap.put("startDate", startDate);
paramMap.put("endDate", endDate);
// 调用存储过程,指定日期范围的数据录入
try {
// 调用存储过程,向临时统计表录入数据
commonDao
.getObjectByArguments("pro_StatisticTableToTemp", paramMap);
log.info("成功执行了存储过程:Prc_Acc_StatisticTableToTemp,开始日期:" + startDate
+ "\t结束日期:" + endDate);
} catch (Exception e) {
log.info("执行存储过程:Prc_Acc_StatisticTableToTemp时出现异常");
log.info(e.getCause().toString());
e.printStackTrace();
}
try {
// 接下来,取出数据,进行页面显示
List list = commonDao.getObjectListByArguments("queryStatisticsT",
null);
// 将数据库查询出来的列表集,转成页面展示需要的格式,单独放在一个方法里
List listShowInPage = exchangeToShowList(list, organString);
// 用google的gson框架把list转换成json格式的字符串
String listJsonStr = gson.toJson(listShowInPage);
log.info("一共查到了: " + list.size() + "条数据。" + "\njson格式数据如下:"
+ listJsonStr + "\n合并机构码之后加上条件筛选后展示到页面上的,共有:"
+ listShowInPage.size() + "条数据。");
// 设置响应为json,同时,设置编码格式
response.setContentType("application/json;charset=UTF-8");
response.getWriter().print(listJsonStr);
} catch (Exception e) {
log.info("------------------任务数量统计查询转换出现错误--------------------------");
e.printStackTrace();
}
// 展示
return null;
}
JSON 格式的数据(部分):
……
{"jgm":"XXXXXX","mrrw":{"wcCount":52,"wwcCount":71},"rzrw":{"wcCount":1,"wwcCount":0,"cbCount":0},"mzrw":{"wcCount":52,"wwcCount":0},"mxrw":{"wcCount":0,"wwcCount":0},"myrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"mjrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"bnrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"mnrw":{"wcCount":0,"wwcCount":0,"cbCount":0}},
{"jgm":"XXXXXX","mrrw":{"wcCount":82,"wwcCount":48},"rzrw":{"wcCount":1,"wwcCount":0,"cbCount":0},"mzrw":{"wcCount":21,"wwcCount":0},"mxrw":{"wcCount":9,"wwcCount":6},"myrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"mjrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"bnrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"mnrw":{"wcCount":0,"wwcCount":0,"cbCount":0}},
{"jgm":"总数统计","mrrw":{"wcCount":4659,"wwcCount":4703},"rzrw":{"wcCount":24,"wwcCount":19,"cbCount":3},"mzrw":{"wcCount":3764,"wwcCount":466},"mxrw":{"wcCount":645,"wwcCount":1679},"myrw":{"wcCount":95,"wwcCount":82,"cbCount":0},"mjrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"bnrw":{"wcCount":0,"wwcCount":0,"cbCount":0},"mnrw":{"wcCount":0,"wwcCount":0,"cbCount":0}}]
最终结果展示:
统计的总数: