JAVA_SSM框架+MINIUI实现网页报表
来源:互联网 发布:剑网三炮姐脸型数据 编辑:程序博客网 时间:2024/06/01 03:59
最近两日新学了一下报表。
为了代码复用,也为了加深自己的流程印象。
将自己理解写在这里,仅供诸君参考。
如有错误,请见谅,并指出,谢谢。
1.对报表的理解:
报表含列,列有自己的Header,Field等配置参数,下面贴出MINI UI的API文档
2.实验流程
2.1报表模型
我这两天实现的表的格式基本上是
要添加自定义列在取表头时添加,要添加行在取数据时添加,注意字段对应。
对于C1基本上数据库里是没有列的(取不到field和header,数据需要取,此列基本上是描述列,静态的,一般只有一两列),作为C2.C3,由于是同一类(可以先写SQL取得列数据的集合,再写SQL利用前一集合取得的field循环获取对应的数据),所以数据库里一般有此列需要的数据。C4是汇总列。自己添加列后在前台做业务实现。
2.2逻辑实现
应该是如此的流程:
①获取列属性(C2,C3),表中没有的在业务层里加(C1,C4,在数据库里定义了列对象为自定义的COLUMN类型,再一层层加到LIST里返回一个LIST)
到前台JSON解析为:[{header:xx,field:xx,……},
{header:xx,field:xx,……},
{header:xx,field:xx,……}]
②获取列对应数据,依据列的Field在数据库中找寻,Field一定要相匹配
其中注意,前台用TreeGrid实现,其中TreeGrid的PARENTCODE属性为层级关系,也就是树的节点依据.
③其他实现的业务在BUSINESS和前台实现
3.代码如下:
3.1 Dao层
XML
select COLUMN_NAME as header, --列的名称 COLUMN_CODE as field, --列的字段,此值要与后面取出来的数据字段对应 '120' as width, --列的宽度 'center' as align, --列的 'center' as headerAlign, 'currency' as dataType, COLUMN_CODE as name from RPTCOLUMN t where t.report_code = 'RPT1'查询表数据:SELECT T1.ROW_CODE AS ROW_CODE, -- 树的行字段,前台可以通过此字段指定单元格所在行,PS:根据Field制定单元格所在列 T1.ORD AS ORD, -- ORD,暂时 T1.ITEM_DESC AS ITEM_DESC, -- 第一列表头数据 记得在SERVICE加表头与之对应 T1.PARENT_CODE AS PARENT_CODE, -- 所使用的层级描述,树的层级关系 <foreach collection="headers" index="index" item="item"> ,NVL(SUM(CASE WHEN T2.COLUMN_CODE= #{item.name} THEN T2.DATA END),0) AS "${item.field}" </foreach> --利用循环取得,要显示的表头字段,我设置中文的话显示有错误 最好不要用中文,这里为了方便取name为1,2 这里取得1,2的数据 。collection="headers"为接口定义中利用查询的表头作为参数 做数据的取得FROM RPTCOLUMN T1LEFT JOIN RPTDATA T2 ON T1.REPORT_CODE = 'RPT1'AND T1.ROW_CODE = T2.ROW_CODE WHERE T1.REPORT_CODE = 'RPT1'GROUP BY T1.ROW_CODE ,T1.ORD,T1.ITEM_DESC,T1.PARENT_CODE ORDER BY T1.ORD
接口
public interface Rpt1Mapper { List<Column> queryRpt1Header(HashMap<String,String> param); //表头 List<HashMap<String,String>> queryRpt1ListByHeader(@Param("headers") List<Column> headers,@Param("record") HashMap<String,String> record); //表数据}
3.2 BUSINESS层
接口
public interface ReportBusiness { List<Column> queryRpt1Header(HashMap<String,String> param); //表头 List<HashMap<String,String>> queryRpt1ListByHeader(HashMap<String,String> record); //表数据}
实现
@Component(value = "RSTReportBiz")public class ReportBusinessImpl implements ReportBusiness { @Autowired private Rpt1Mapper rpt1Mapper ; @Override public List<Column> queryRpt1Header(HashMap<String, String> param) { // 表头处理 List<Column> allCols =new ArrayList<Column>(); Column firstCol = new Column(); //设置返回List的集合中的数据 first firstCol.setHeader("C1"); firstCol.setAlign("left"); firstCol.setField("ITEM_DESC"); firstCol.setWidth("430"); firstCol.setHeaderAlign("center"); firstCol.setName("ITEM_DESC"); List<Column> cols = rptRpt1Mapper.queryRpt1Header(param); Column lastCol = new Column(); //设置返回List的集合中的数据 total lastCol.setHeader("TOTAL"); lastCol.setAlign("right"); lastCol.setField("TOTAL"); lastCol.setWidth("300"); lastCol.setHeaderAlign("center"); lastCol.setName("TOTAL"); if (cols == null || cols.size() == 0) { return null; } else { allCols.add(firstCol); //传入自己设置的Item first allCols.addAll(cols); //传入cols的Item allCols.add(lastCol); return allCols; } } @Override public List<HashMap<String, String>> queryRpt1ListByHeader(HashMap<String, String> record) { // 表数据处理 List<HashMap<String, String>> result =new ArrayList<HashMap<String, String>>(); HashMap<String, String> h1 =new HashMap<String, String>(); h1.put("ROW_CODE", "4"); //行数据的行数 h1.put("ORD", "17"); h1.put("ITEM_DESC", "第四行"); //第一列的值字段要对应 h1.put("PARENT_CODE", ""); //有层级关系再加,我这里没有 HashMap<String, String> h2 =new HashMap<String, String>(); h2.put("ROW_CODE", "5"); h2.put("ORD", "17"); h2.put("ITEM_DESC", "第五行"); h2.put("PARENT_CODE", ""); List<Column> columns = rptRpt1Mapper.queryRpt1Header(record); //先取出表头以传入queryRpt1ListByHeader,即Dao层XML里queryRpt1ListByHeader查询表数据中用到的循环 集合headers if (columns != null && columns.size() > 0) { result.addAll(rptRpt1Mapper.queryRpt1ListByHeader(columns, record)); //取出数据表中的数据 result.add(h1); //我所要加的行 result.add(h2); return result; } else { return null; } }}
3.3 Control层
@Controllerpublic class ReportController { @Autowired private ReportBusiness ReportBiz; @RequestMapping(value = "/showRpt1View") public String showRpt1View(){ return "alm/rptrst/Rpt1View"; } //表头 @RequestMapping(value = "/queryC001RstHeader") @ResponseBody public AjaxObj queryC001RstHeader(@RequestParam HashMap<String,String> record){ List<Column> columns = RSTReportBiz.queryC001RstHeader(record); return new AjaxObj(0,null,columns); } //报表数据 @RequestMapping(value = "/queryC001RstListByHeader") @ResponseBody public Pager<HashMap<String,String>> queryC001RstListByHeader(SystemContext systemContext,@RequestParam HashMap<String,String> record) { List<HashMap<String,String>> page = RSTReportBiz.queryC001RstListByHeader(record); return new Pager<HashMap<String,String>>(0, page); //Pager是一个封装的分页对象这里不需要分页,所以传入参数需要分页的总数total为0 }}
3.4前台页面
<body> <div class="description"> <h3>报表</h3> </div> <div class="mini-toolbar" style="padding: 0px; border: 0;background:#fff"> <div id="form1"> <table style="width: 100%;"> <tr> <td style="width: 100%;"></td> <td style="white-space: nowrap; text-align: right;padding-right:10px"> 报表日期:<input id="reportDt" name="reportDt" class="mini-combobox" style="width:110px" textField="TEXT" valueField="TEXT" valueFromSelect="true" url="<%=path %>/queryC001RstReportDtList" allowInput="true" dataField="data" onvaluechanged="onReportDtChanged" showNullItem="false" emptyText="请选择报表日期" NullItemText="请选择报表日期" /> 报表货币:<input id="currency" name="currency" class="mini-combobox" style="width:70px" textField="dictText" valueField="dictValue" url="<%=path %>/queryDicyEntryByDictCode?dictCode=1018" required="true" allowInput="false" dataField="data" showNullItem="false" emptyText="请选择报表货币" NullItemText="请选择报表货币" onvaluechanged="search"/> <a class="mini-button" iconCls="icon-search" onclick="search()">查询</a> <a class="mini-button" iconCls="icon-download" onclick="exportExcel()">导出</a> </td> </tr> </table> </div> </div> <div class="mini-fit" style="height: 100%; width: 100%"> <div id="treegrid1" class="mini-datagrid" style="width: 99%; height: 100%;" url="<%=path %>/queryRpt1ListByHeader" treeColumn="ITEM_DESC" idField="ROW_CODE" parentField="PARENT_CODE" resultAsTree="false" expandOnLoad="true" showTreeIcon="false" showExpandButtons='false' virtualScroll="true" autoLoad="false" dataField="datas" allowRowSelect="true" enableHotTrack="false" editNextOnEnterKey="true" allowCellEdit="true" allowCellSelect="true" cellEditAction="cellclick"> <div property="columns"></div> </div> </div><script type="text/javascript"> mini.parse(); var form = new mini.Form("#form1"); //这边表单传数据,但是我在SQL中没有演示 var grid = mini.get("treegrid1"); var reportDtCombo = mini.get("reportDt"); var currencyCombo = mini.get("currency"); reportDtCombo.select(0); currencyCombo.select(0); search(); function search(){ var formData = form.getData(); var url = path + '/queryRpt1Header'; myui.loadAjax(url,formData,function(o){ var data = o.data; var header = []; var j = 0; //下面是演示如何在JS中添加表头(列数据对象),跟在BUSINESS中实现的业务相同,不过我COLUMN中没有设置editor,即可编辑属性,添加此属性,实现效果相同.自己代码中后台BUSINESS没有添加表头在前台添加的,因为要求要可以编辑 header[j++]={"header":"C1",align:"left",field:"ITEM_DESC",name:"ITEM_DESC",width:"300",headerAlign:"left"}; for(var i = 0;i<data.length;i++){ header[j++] = {"header":data[i].header,align:"center",field:data[i].field,dataType:"currency",editor:{ type: "textbox",minWidth: "50"},width:"120",headerAlign:"center"}; } header[j++]={"header":"TOTAL",align:"right",field:"TOTAL",width:"150",headerAlign:"center",dataType:"currency"}; grid.setColumns(header); grid.on("load",function(){ grid.mergeColumns(["ITEM_DESC"]); }); grid.load(formData); },function(e){ alert(e.responseText); }); } function onReportDtChanged(){ var reportDt = reportDtCombo.getValue(); if(reportDt == null || reportDt.length <= 0){ reportDtCombo.select(0); } search(); } grid.on("drawcell", function (e) { var record = e.record, column = e.column, field = e.field, value = e.value; var val1; var val2; if(field == "TOTAL"){ val1=isNaN(record[1]) ? 0 : record[1]; //Field为1的数据 val2=isNaN(record[2]) ? 0 : record[2]; //Field为2的数据 var html = parseFloat(val1) + parseFloat(val2); //更新此行TOTAL的数据 e.cellHtml = formatCurrency(html); } }); grid.on("cellbeginedit", function(e) { //只有第四行的可以单元格可以编辑,而且只有Field为'1','2'的列可以编辑,也就是两个单元格列为C2,C3;行为第四行的单元格可以编辑 var editor = e.editor; var record = e.record; if(record.ROW_CODE=="4"){ }else{ e.cancel = true; } }); var fieldBool = true; grid.on("cellcommitedit", function(e) { var field = e.field; if (fieldBool) { fieldBool = false; var record = e.record; if(record.ROW_CODE == "4"){ var data1 = grid.findRow(function(row) { //第一行 if (row.ROW_CODE == "1") return true; }); var updateRow = grid.findRow(function(row) { //需要更新的行 if (row.ROW_CODE == "5") return true; }); if(field == "1"){ var val1 = isNaN(data1[1]) ? 0 : data1[1]; //第一行,Field为1的数据 我C2,C3列的Field分别为1和2 var val2 = isNaN(e.value) ? 0 : e.value; //取此单元格编辑的数据:e.value var val = parseFloat(val1) - parseFloat(val2); grid.updateRow(updateRow, { //调用更新行的方法 "1" : val }); } if(field == "2"){ //实现在Field为2的那一列的逻辑 var val1 = isNaN(data1[2]) ? 0 : data1[2]; var val2 = isNaN(e.value) ? 0 : e.value; var val = parseFloat(val1) - parseFloat(val2); grid.updateRow(updateRow, { "2" : val }); } } } fieldBool = true; });</script></body>
- JAVA_SSM框架+MINIUI实现网页报表
- Java_ssm框架基本配置
- java_SSM框架浅析
- 十分给力jquery插件miniui框架整合java实现各种图形报表管理系统
- MiniUi框架简单实例
- [学习笔记]JAVA_SSM框架简单的登录拦截器配置
- miniui框架的combobox标签
- Jquery miniUI实现三级联动
- miniui Treegrid的简单实现
- miniui实现多附件上传
- 用框架实现网页布局
- 【知识积累】jQuery MiniUI实现表单联动
- miniui实现表格中行的上下移动
- MiniUI快速入门教程(五)主框架布局
- webUI框架miniUI,easyUI,extJS,Bootstrap简介及简单部署
- javascript实现让网页逃不出框架
- 框架嵌套实现网页的分层
- div+ajax 实现网页框架布局
- javaScript 高级程序设计 第1章 javaScript简介
- MySQL的in查询效率太低的解决办法之一与其它优化示例
- View与SurfaceView的区别与联系
- 网站记录文章浏览数的做法
- Java NIO 核心组件学习笔记
- JAVA_SSM框架+MINIUI实现网页报表
- 图结构练习——最短路径
- HDU-4185-Oil Skimming [二分匹配]
- linux定时任务的设置 crontab 配置指南
- MyBatis Mapper 接口如何通过JDK动态代理来包装SqlSession 源码分析
- 判断网络
- ng-option
- web service 对外发布一个hello world接口(入门)
- LCS,LCIS,LIS模板