为什么要开发一个报表管理系统:
- 用户报表可能很多,需要统一管理。
- 很多报表的查询条件中的查询条件组成项是一样的,没必要每个查询都写雷同的代码。
- 希望能动态设置查询条件
设计思路:
1、查询条件元素进行元数据管理
2、报表查询条件元数据管理
3、动态拼接查询条件区域
4、我们报表部分集成birt,因此还需要集成调用birt报表的url字符串。
我们向birt报表服务传递 哪些内容:
客户端类型 clientType: 0表示c#端调用,1表示web调用;
单位类型:agetype(这个名字起得有点无语?) 0 是财政单位?1 是执收单位,这是为了控制查询数据范围。
查询类型:querytype:0是普通单位、1 是大厅单位 ;2是上级单位,这是为了控制查询方式,其实也是为了控制查询范围。
统计类型 tongjitype:
数据显示范围交给birt报表服务本身去控制吧。
拼接birt参数的时候,得根据相关业务条件去拼接。
动态报表有2部分动态内容构成:
- 一个是动态构建查询条件
- 一个是动态构建报表
先上报表管理界面:
报表查询条件(参数)可配置:
报表查询参数可配置的:
如下图:
(查询条件/参数是动态配置)
- 预定义参数类型:我们先在数据库当中预定义参数类型,后期有时间,改为界面可操作。
2、参数管理:
3、特定报表绑定指定的参数
实现思路及代码:
1、参数、及报表参数(对参数的的引用)存放在数据库当中。
2、查询报表的时候,根据数据库当中参数,动态生成显示界面查询条件区域。
$.ajax({
url : url, //查询所有参数
async : false,
type : "GET",
success : function(data) {
console.log("*************************************************************");
console.log(data);
var object = jQuery.parseJSON(data);
var sty = object.sty;
var params = object.params; //报表参数集合
var ars = object.columnpara;
if(ars!=undefined && ars!=""){
serArr2Local(ars);
}
//添加table
var row = sty.row_num,
column = sty.columnNum,
html = "";
if(row!=0&&column!=0){
//加载
html += "<table style='width:95%;'>";
for(var i=0;i<row;i++){
html += "<tr style='heigth: 140px'>";
for(var j=0;j<column;j++){
html+= "<td id='td_"+i+"_"+j+"' nowrap></td>";
}
html += "</tr>";
}
html += "</table>";
}
$("#search_div").html(html);
paraIndex = sty.date2cell;
$.each(paraIndex, function(idx, obj){
if(obj.width!="")
$("#td_"+obj.row+"_"+obj.column).attr("width",obj.width+"px");
if(obj.para==null){
$("#td_"+obj.row+"_"+obj.column).remove();
}else{
//合并的单元格
if(obj.colspan!=null){
$("#td_"+obj.row+"_"+obj.column).attr("colspan",obj.colspan);
}
if(obj.rowspan!=null){
$("#td_"+obj.row+"_"+obj.column).attr("rowspan",obj.rowspan);
}
}
});
$.each(params, function(idx, obj) {
var item = new Object();
item.name = obj.name;
item.type = obj.type;
item.event = obj.event;
item.disname=obj.displayname;
item.ismust=obj.ismust;
item.id=obj.id;
if(clientType==1&&obj.displayname=="主管部门"){
//单位端不需要主管部门筛选条件
//NODE.params.splice(item);
return true;
}
else if (obj.type == 'tree') {
createTree(obj);
} else if(obj.type=='radiotree'){
if(clientType==1){ //单位端
if(NODE.link=="nontaxComplete.rptdesign"){
obj.displayname="收费类别";
}
console.log("-----------------------------------");
console.log(obj);
console.log("==================================");
createRadioTree_unit(obj);
}else{
createRadioTree(obj);
}
//var dataSet = updateData(obj.data);
mapData.put(obj.name, obj.data);
} else if (obj.type == 'select') {
if(clientType==1&&obj.displayname=="统计类型"){
obj.data.splice(6,1);
}
if(clientType==1&&NODE.link=="nontaxComplete.rptdesign"){
obj.data.splice(3,2);
obj.data.splice(0,1);
}
createSelect(obj);
} else if (obj.type == 'checkbox') {
createCheckbox(obj);
} else if (obj.type == 'radio') {
createReadio(obj);
} else if (obj.type == 'text') {
createText(obj);
} else if (obj.type == 'date') {
createDate(obj);
} else if (obj.type == 'number') {
createNumber(obj);
} else if (obj.type == 'layer'){
creatLayer(obj);
mapData.put(obj.name, obj.data);
} else if(obj.type == 'dateRange'){
createDateRange(obj);
}else if(obj.type == 'date_YM'){
createDate_YM(obj);
}else if(obj.type == 'date_YYYYMMDD'){
createDate_YYYYMMDD(obj);
}
NODE.params.push(item);
});
//需要初始隐藏的参数
if($("#agetype")){
$('#agebegin_div').hide();
$('#ageend_div').hide();
}
if($("#frequency")){
$('#frequencybegin_div').hide();
$('#frequencyend_div').hide();
}
var html = "";
if(params.length>0){
//alert(isWeb);
if(isWeb=='1'){
html= "<div><input type='button' id='btnSearch' value='查找' class='btn' onclick='search()'></div><div><input type='button' class='btn' id='Export' value='导出' onclick='Export()'></div><div><input type='button' class='btn' id='Print' value='打印' onclick='Print()'></div><div><input type='button' class='btn' id='Reset' value='重置' onclick='Reset()'></div>";
}else{
//html= "<div><input type='button' id='btnSearch' style='display:none' value='查找' class='btn' onclick='search()'></div><div><input type='button' class='btn' style='display:none' id='Export' value='导出' onclick='Export()'></div><div><input type='button' class='btn' style='display:none' id='Print' value='打印' onclick='Print()'></div><div><input type='button' class='btn' style='display:none' id='Reset' value='重置' onclick='Reset()'></div>";
}
}else{
search();
}
$("#search_div").append(html);
$('#loading1').remove();
$('#loading2').remove();
}
});
相对完成的方法如下:
function initSearchDiv(event, treeId, treeNode, clickFlag) {
$("<div id='loading1' class=\"datagrid-mask\"></div>").css({display:"block",width:"100%",height:$(window).height()}).appendTo("body");
$("<div id='loading2' class=\"datagrid-mask-msg\"></div>").html("查询条件构建中...").appendTo("body").css({display:"block",left:($(document.body).outerWidth(true) - 190) / 2,top:($(window).height() - 45) / 2});
document.getElementById("ifr").src = "report_ts.html";
$("#search_div").html("");
var url ="";
if(deptid!=null&&deptid!=""){
url = "ParameterServer?method=paramInit&reportId="
+ report_id+"&clientType="+clientType+"&isOffice="+ isoffice +"&deptId="+deptid+"&year="+year+"&admdivcode="+admdivcode+ "&date=" + new Date()+"&queryType="+queryType+"&reportType="+reportType;
//执收单位端点击一个报表没关闭再点击第二个报表 ,reportType无法传过来
if(queryType=="1"&&clientType=="1"&&reportType==null){
url = url.replace("reportType=null","reportType=0");
}
if(queryType=="0"&&clientType=="1"&&reportType==null){
url = url.replace("reportType=null","reportType=1");
}
}else{
url = "ParameterServer?method=paramInit&reportId="
+ report_id + "&date=" + new Date();
}
NODE.params = new Array();
NODE.link = report_name;
NODE.reportid = report_id;
if (NODE.link != "" && NODE.link != null) {
var pas = new Array();
$.ajax({
url : url, //查询所有参数
async : false,
type : "GET",
success : function(data) {
console.log("*************************************************************");
console.log(data);
var object = jQuery.parseJSON(data);
var sty = object.sty;
var params = object.params; //报表参数集合
var ars = object.columnpara;
if(ars!=undefined && ars!=""){
serArr2Local(ars);
}
//添加table
var row = sty.row_num,
column = sty.columnNum,
html = "";
if(row!=0&&column!=0){
//加载
html += "<table style='width:95%;'>";
for(var i=0;i<row;i++){
html += "<tr style='heigth: 140px'>";
for(var j=0;j<column;j++){
html+= "<td id='td_"+i+"_"+j+"' nowrap></td>";
}
html += "</tr>";
}
html += "</table>";
}
$("#search_div").html(html);
paraIndex = sty.date2cell;
$.each(paraIndex, function(idx, obj){
if(obj.width!="")
$("#td_"+obj.row+"_"+obj.column).attr("width",obj.width+"px");
if(obj.para==null){
$("#td_"+obj.row+"_"+obj.column).remove();
}else{
//合并的单元格
if(obj.colspan!=null){
$("#td_"+obj.row+"_"+obj.column).attr("colspan",obj.colspan);
}
if(obj.rowspan!=null){
$("#td_"+obj.row+"_"+obj.column).attr("rowspan",obj.rowspan);
}
}
});
$.each(params, function(idx, obj) {
var item = new Object();
item.name = obj.name;
item.type = obj.type;
item.event = obj.event;
item.disname=obj.displayname;
item.ismust=obj.ismust;
item.id=obj.id;
if(clientType==1&&obj.displayname=="主管部门"){
//单位端不需要主管部门筛选条件
//NODE.params.splice(item);
return true;
}
else if (obj.type == 'tree') {
createTree(obj);
} else if(obj.type=='radiotree'){
if(clientType==1){ //单位端
if(NODE.link=="nontaxComplete.rptdesign"){
obj.displayname="收费类别";
}
console.log("-----------------------------------");
console.log(obj);
console.log("==================================");
createRadioTree_unit(obj);
}else{
createRadioTree(obj);
}
//var dataSet = updateData(obj.data);
mapData.put(obj.name, obj.data);
} else if (obj.type == 'select') {
if(clientType==1&&obj.displayname=="统计类型"){
obj.data.splice(6,1);
}
if(clientType==1&&NODE.link=="nontaxComplete.rptdesign"){
obj.data.splice(3,2);
obj.data.splice(0,1);
}
createSelect(obj);
} else if (obj.type == 'checkbox') {
createCheckbox(obj);
} else if (obj.type == 'radio') {
createReadio(obj);
} else if (obj.type == 'text') {
createText(obj);
} else if (obj.type == 'date') {
createDate(obj);
} else if (obj.type == 'number') {
createNumber(obj);
} else if (obj.type == 'layer'){
creatLayer(obj);
mapData.put(obj.name, obj.data);
} else if(obj.type == 'dateRange'){
createDateRange(obj);
}else if(obj.type == 'date_YM'){
createDate_YM(obj);
}else if(obj.type == 'date_YYYYMMDD'){
createDate_YYYYMMDD(obj);
}
NODE.params.push(item);
});
//需要初始隐藏的参数
if($("#agetype")){
$('#agebegin_div').hide();
$('#ageend_div').hide();
}
if($("#frequency")){
$('#frequencybegin_div').hide();
$('#frequencyend_div').hide();
}
var html = "";
if(params.length>0){
//alert(isWeb);
//页面追加 查找、打印、导出按钮 最重要的当然是查找按钮
if(isWeb=='1'){
html= "<div><input type='button' id='btnSearch' value='查找' class='btn' onclick='search()'></div><div><input type='button' class='btn' id='Export' value='导出' onclick='Export()'></div><div><input type='button' class='btn' id='Print' value='打印' onclick='Print()'></div><div><input type='button' class='btn' id='Reset' value='重置' onclick='Reset()'></div>";
}else{
//html= "<div><input type='button' id='btnSearch' style='display:none' value='查找' class='btn' onclick='search()'></div><div><input type='button' class='btn' style='display:none' id='Export' value='导出' onclick='Export()'></div><div><input type='button' class='btn' style='display:none' id='Print' value='打印' onclick='Print()'></div><div><input type='button' class='btn' style='display:none' id='Reset' value='重置' onclick='Reset()'></div>";
}
}else{
search();
}
$("#search_div").append(html);
$('#loading1').remove();
$('#loading2').remove();
}
});
}else{
$('#loading1').remove();
$('#loading2').remove();
}
$("#search_div").show();
}
创建具体查询条件的dom元素代码如下:
//创建下拉树(多选)
function createTree(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div id='"+obj.name+"_div'>";
html += obj.displayname ;
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
// html += "<select id='"+obj.name+"' class='easyui-combotree' style='"+obj.style+" border:1px solid red;' multiple='true' required='true'></select>";
html += "<select id='"+obj.name+"' class='easyui-combotree' style='border:1px solid red;' multiple='true' required='true'></select>";
html += "</div>";
// $("#search_table tr:last td:last").append(html);
appendhtml(html,obj);
$.parser.parse(); // 动态创建easyui元素后需要重新渲染
$('#'+obj.name).combotree('loadData', obj.data); //加载数据
$("#"+obj.name).combotree({multiple:true}); //设置为多选
}
function getFontCss(treeId, treeNode) {
return (!!treeNode.highlight) ? {color:"#FF6666", "font-weight":"bold"} : {color:"#333", "font-weight":"normal"};
}
//创建下拉树 (单选)
function createRadioTree(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div style='' id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
// html += "<span>"+obj.displayname+"</span>"
// + "<input type='hidden' id='"+obj.name+"' name='"+obj.name+"' /><input class='input' type='input' style='"+obj.style+"' id='"+obj.name+"1' onclick=radiotree('"+obj.name+"') readonly >";
html += "<span>"+obj.displayname+"</span> "
+ "<input type='hidden' id='"+obj.name+"' name='"+obj.name+"' /><input class='input' type='input' style='' id='"+obj.name+"1' onclick=layertree('"+obj.name+"') readonly >";
appendhtml(html,obj);
if(obj.event){
$("#"+obj.name).bind("input propertychange",
(new Function("return "+obj.event))()
);
}
}
//创建下拉树 (单选) 只读,
function createRadioTree_unit(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div style='' id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
if(obj.name=='agencyId'){
html += "<span>"+obj.displayname+"</span> "
+ "<input type='hidden' id='"+obj.name+"' name='"+obj.name+"' /><input class='input' type='input' style='' id='"+obj.name+"1' disabled='disabled' >";
}/* if(obj.name=='countName'){
html += "<span>"+obj.displayname+"</span> "
+ "<input type='hidden' id='"+obj.name+"' name='"+obj.name+"' /><input class='input' type='input' style='' id='"+obj.name+"1' disabled='disabled' >";
} */else{
html += "<span>"+obj.displayname+"</span>"
+ "<input type='hidden' id='"+obj.name+"' name='"+obj.name+"' /><input class='input' type='input' style='"+obj.style+"' id='"+obj.name+"1' onclick=layertree('"+obj.name+"') readonly >";
if(obj.event){
$("#"+obj.name).bind("input propertychange",
(new Function("return "+obj.event))()
);
}
}
appendhtml(html,obj);
}
function layertree(ids){
var dataSet = mapData.get(ids);
var title_des = null;
//var html ="<div class='layer '><ul id='"+id+"_UI' class='ztree' cellpadding='0' cellspacing='0' border='0' class='display'></ul></div>";
var title_des = "";
var code_des ="";
var name_des = "";
input_id = ids;
if(ids.indexOf("agencyId")>=0||ids.indexOf("agencyName")>=0){
title_des = "执收单位选择";
code_des = "单位编码";
name_des = "单位名称";
}else if(ids.indexOf("nontaxId")>=0||ids.indexOf("nontaxName")>=0){
title_des = "收费项目选择";
code_des = "项目编码";
name_des = "项目名称";
}else if(ids.indexOf("typeName")>=0){
title_des = "收费类别选择";
code_des = "收费编码";
name_des = "收费名称";
}else if(ids.indexOf("fundNature")>=0){
title_des = "资金性质选择";
code_des = "资金性质编码";
name_des = "资金性质名称";
}else if(ids.indexOf("billId")>=0){
title_des = "票据选择";
code_des = "票据编码";
name_des = "票据名称";
}else if(ids.indexOf("countName")>=0){
if(countType==2){
title_des = "收费类别选择";
code_des = "收费编码";
name_des = "收费名称";
}else if(countType==3){
title_des = "收费项目选择";
code_des = "项目编码";
name_des = "项目名称";
}else if(countType == 4){
title_des = "预算科目选择";
code_des = "科目编码";
name_des = "科目名称";
}else if(countType == 5){
title_des = "行政区划选择";
code_des = "区划编码";
name_des = "区划名称";
}else{
if(clientType=='1'){return}
title_des = "执收单位选择";
code_des = "单位编码";
name_des = "单位名称";
}
}else if(ids.indexOf("storeId")>=0){
title_des = "仓库选择";
code_des = "仓库编码";
name_des = "仓库名称";
}else if(ids.indexOf("bankId")>=0){
title_des = "银行选择";
code_des = "银行编码";
name_des = "银行名称";
}else if(ids.indexOf("bankbranchId")>=0){
title_des = "银行网点选择";
code_des = "网点编码";
name_des = "网点名称";
}else if(ids.indexOf("subId")>=0){
title_des = "预算科目选择";
code_des = "科目编码";
name_des = "科目名称";
}else if(ids.indexOf("deptId") >= 0){
title_des = "主管部门选择";
code_des = "部门编码";
name_des = "部门名称";
}else if(ids.indexOf("sflb") >= 0){
title_des = "收费类别选择";
code_des = "类别代码";
name_des = "类别名称";
}else if(ids.indexOf("columnsManage") >= 0){
//zNodes = dataSet;
title_des = "编辑列";
code_des = "";
name_des = "";
$("#showColumn").jqxWindow("setTitle", "<strong>" + title_des+"</strong>");
$("#showColumn").jqxWindow('open');
$("#btEnter2").jqxButton({ width: 60, height: 25 });
$("#btCancel2").jqxButton({ width: 60, height: 25 });
$("#btnReset").jqxButton({ width: 60, height: 25 });
//单击选中行,选中数据
//$("#btEnter2").click(function(){
/* alert("是编辑列的回车键!");
return; */
//把zNodes传到后端保存
//updateDataSource(ids,zNodes);
// updateColumnPara(NODE.reportid);
//});
$("#btCancel2").click(function(){
$("#showColumn").jqxWindow('close');
});
showColunmModal(zNodes);//zNodes是数据源,在columnsModel.js文件中定义的,需要从后端传到前端
}
if(ids.indexOf("columnsManage") >= 0){
return;
}
//var data = jQuery.parseJSON(data);
$("#layer1").jqxWindow("setTitle", "<strong>" + title_des+"</strong>");
$("#layer1").jqxWindow('open');
var source =
{
dataType: "json",
dataFields: [
{ name: 'id', type: 'string' },
{ name: 'code', type: 'string' },
{ name: 'name', type: 'string' },
{ name: 'pid', type: 'string' }
],
hierarchy:
{
keyDataField: { name: 'id' },
parentDataField: { name: 'pid' }
},
id: 'id',
localData: dataSet
};
var dataAdapter = new $.jqx.dataAdapter(source);
$("#treegrid").jqxTreeGrid(
{
width: 594,
height: 368,
filterable: true,
sortable:true,
theme: 'energyblue',
source: dataAdapter,
ready: function () {
//$("#treegrid").jqxTreeGrid("expandAll");
//$("#treegrid").jqxTreeGrid('expandRow','2');
},
columns: [
{ text: code_des, dataField: 'code', width: 180 },
{ text: name_des, dataField: 'name' }
]
});
$("#treegrid").jqxTreeGrid('clearFilters');
//$("#treegrid").jqxTreeGrid('expandRow', '0010');
$('#treegrid').on('rowDoubleClick', function (event){
$("#layer1").jqxWindow('close');
var row = args.row;
var key = args.key;
$("#"+input_id).val(key);
$("#"+input_id+"1").val(row.code+" "+row.name);
$("#"+input_id).trigger("input");
});
var row ;
var key ;
$('#treegrid').on('rowSelect', function (event){
row = args.row;
key = args.key;
});
$("#btEnter").jqxButton({ width: 60, height: 25 });
$("#btCancel").jqxButton({ width: 60, height: 25 });
//单击选中行,选中数据
$("#btEnter").click(function(){
if(row!=""&&key!=""){
$("#"+input_id).val(key);
$("#"+input_id+"1").val(row.code+" "+row.name);
$("#"+input_id).trigger("input");
$("#layer1").jqxWindow('close'); }
})
$("#btCancel").click(function(){
$("#layer1").jqxWindow('close');
})
//$.fn.zTree.init($("#"+id+"_UI"), setting, dataSet);
$('#treegrid').on('filter', function (event){
//debugger;
//$("#treegrid").jqxTreeGrid('refresh');
$("#treegrid").jqxTreeGrid('clearSelection');
if(dataSet!=null){
var input = $("input[type='text']").val();
if(input != null&&input != ""){
if(!isNaN(input)){
for(var o in dataSet){
if(dataSet[o].code==input){
var id = dataSet[o].id;
$("#treegrid").jqxTreeGrid('selectRow', dataSet[o].id);
break;
}
}
for(var ii=1;ii<=input.length;ii++){
for(var o in dataSet){
if(dataSet[o].code==input.substr(0,ii)){
$("#treegrid").jqxTreeGrid("expandRow", dataSet[o].id);
}
}
}
}else{
for(var o in dataSet){
if(dataSet[o].name==input){
var id = dataSet[o].id;
$("#treegrid").jqxTreeGrid('selectRow', dataSet[o].id);
break;
}
}
for(var o in dataSet){
//debugger;
if(dataSet[o].name!=null){
if(dataSet[o].name.indexOf(input)>=0||dataSet[o].pid=="-1"){
$("#treegrid").jqxTreeGrid("expandRow", dataSet[o].id);
if(dataSet[o].pid!="-1"){
$("#treegrid").jqxTreeGrid("expandRow", dataSet[o].pid);
}
}
}
}
}
}
}
});
$("div[role='combobox']").change(function(){
$("#treegrid").jqxTreeGrid('clearFilters');
});
$("input[type='text']").keyup(function(){
if($("input[type='text']").val().length==0){
$("#treegrid").jqxTreeGrid('clearFilters');
}
});
$('#layer1').on('close', function (event) { dataSet = null });
}
//保存列排序参数到数据库
function updateDataSource(paraId, objData){//参数id,参数数据来源
var ds = JSON.stringify(objData);
$.ajax({
url : "ReportParameServer?method=updateDataSource&date=" + new Date(),
async : false,
type : "POST",
data : {"id":paraId, "ds":ds},
success : function(data) {
if(data=="true"){
zNodes = objData;
alert("调整成功!");
}else{
alert("调整失败!");
}
}
});
}
function updateData(dataSet){
$.each(dataSet, function(i, data) {
//data.name="["+data.code+"]"+data.name;
//不想要中括号
data.name=data.name;
});
return dataSet;
}
//获取当前时间
function curDateTime(day){
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth()+1;
var date = d.getDate();
if(day!=null){
date = day;
}
var curDateTime= year;
if(month>9)
curDateTime = curDateTime +"-"+month;
else
curDateTime = curDateTime +"-0"+month;
if(date>9)
curDateTime = curDateTime +"-"+date;
else
curDateTime = curDateTime +"-0"+date;
return curDateTime;
}
//获取当前时间
function curYM(day){
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth()+1;
var date = d.getDate();
if(day!=null){
date = day;
}
var curDateTime= year;
if(month>9)
curDateTime = curDateTime +"-"+month;
else
curDateTime = curDateTime +"-0"+month;
return curDateTime;
}
//获取当前时间 格式为YYYYMMDD
function curYYYYMMDD(){
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth()+1;
var day = d.getDate();
var curDateTime= year;
if(month>9)
curDateTime = curDateTime +""+month;
else
curDateTime = curDateTime +"0"+month;
if(day>9)
curDateTime = curDateTime +""+day;
else
curDateTime = curDateTime +"0"+day;
return curDateTime;
}
//创建下拉框
function createSelect(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+= obj.displayname +" ";
// html += "<select style='height:20px;"+obj.style+"' id="+obj.name+">";
html += "<select style='height:20px;' id="+obj.name+">";
var ii = 0;
$.each(obj.data, function(idx, item) {
var value="";
if(!item.id){
value=-999;
}else{
value=item.id;
}
html += "<option value="+value+">" + item.name + "</option>";
if(ii<1)
{
if(item.name != "请选择" && obj.displayname != "筛选")
{
conditions += " " + obj.displayname + ":" + item.name;
}
ii ++;
}
});
html += "</select></div>";
appendhtml(html,obj);
// $("#search_div").append(html);
if(obj.event){
$('#'+obj.name).change(
(new Function("return "+obj.event))()
);
}
}
//创建复选框
function createCheckbox(obj) {
var width=getWidth(obj);
var style;
if(obj.style){
style=obj.style+" width:"+width+"px";
}else{
style="width:"+width+"px";
}
// var html = "<div id='"+obj.name+"'_div style='"+style+"'>" ;
var html = "<div id='"+obj.name+"'_div >" ;
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+= obj.displayname ;
$.each( obj.data, function(idx, item) {
// html += "<input type='checkbox' name='"+obj.name+"' value='"+item.id+"'>" + item.name;
html += "<input type='checkbox' name='"+obj.name+"' value='"+item.id+"'>" + item.name;
});
html+=" </div>";
// $("#search_div").append(html);
appendhtml(html,obj);
// $("#search_table tr:last td:last").append(html);
}
//创建单选框
function createReadio(obj) {
var width=getWidth(obj);
var style;
if(obj.style){
style=obj.style+" width:"+width+"px";
}else{
style="width:"+width+"px";
}
// var html = "<div id='"+obj.name+"'_div style='"+style+"'>";
var html = "<div id='"+obj.name+"'_div >";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+=obj.displayname ;
var ii =0;
$ .each(obj.data , function(idx, item) {
if (idx == 0) {
if(obj.displayname=="政务中心"){
html += "<input type='radio' name='"+obj.name+"' value='"+item.id+"'>" + "<label>"+ item.name +"</label>";
}else{
html += "<input type='radio' name='"+obj.name+"' checked=true value='"+item.id+"'>" + "<label>"+ item.name +"</label>";
}
} else {
html += "<input type='radio' name='"+obj.name+"' value='"+item.id+"'>" + "<label>"+ item.name +"</label>";
}
if(ii<1 && obj.displayname !="政务中心")
{
conditions += " " + obj.displayname + ":" + item.name;
ii ++;
}
});
html+="</div>";
// $("#search_div").append(html);
appendhtml(html,obj);
// $("#search_table tr:last td:last").append(html);
if(obj.event){
$("input[name=\"" + obj.name + "\"]").each(function() {
$(this).click((new Function("return "+obj.event))());
});
}
}
//创建文本框
function createText(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+=obj.displayname +" "
+ "<input class='input' type='input' style='"+obj.style+"' id='"+obj.name+"' name='"+obj.name+"' ></div>";
// $("#search_table tr:last td:last").append(html);
// $("#search_div").append(html);
appendhtml(html,obj);
}
//创建弹出层(为input绑定事件)
var input_id = "";
function creatLayer(obj) {
var data = JSON.stringify(obj.data);
//debugger;
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
// html += "<span>"+obj.displayname+"</span>"
// + "<input type='hidden' id='"+obj.name+"' name='"+obj.name+"' /><input class='input' type='input' style='"+obj.style+"' id='"+obj.name+"1' onclick=layer('"+obj.name+"') readonly >";
html += "<span>"+obj.displayname+"</span> "
+ "<input type='hidden' id='"+obj.name+"' name='"+obj.name+"' /><input class='input' type='input' id='"+obj.name+"1' onclick=layertree('"+obj.name+"') readonly >";
appendhtml(html,obj);
// $("#search_table tr:last td:last").append(html);
if(obj.event){
$("#"+obj.name+"1").bind("propertychange",
(new Function("return "+obj.event))()
);
}
}
//创建日期输入框
function createDate(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+="<span id='"+obj.name+"_span'>"+obj.displayname +"</span> "
+ "<input class='Wdate' type='input' id='"
+ obj.name
+ "' name='"
+ obj.name
+ "' onFocus=\"WdatePicker({dateFmt:'yyyy-MM-dd',alwaysUseStartDate:true})\" ></div>";
// $("#search_div").append(html);
appendhtml(html,obj);
if(obj.name.indexOf("start") >=0){
if(obj.defaultVal==minDateVal){
//$("#"+obj.name).val(curDateTime(1));
}else{
$("#"+obj.name).val(curDateTime(1));
conditions += " "+obj.displayname + ":" + curDateTime(1);
}
}else{
if(obj.defaultVal==maxDateVal){
}else{
$("#"+obj.name).val(curDateTime());
conditions += " "+ obj.displayname + ":" + curDateTime();
}
}
}
//创建日期_年月输入框
function createDate_YM(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+="<span id='"+obj.name+"_span'>"+obj.displayname +"</span> "
+ "<input class='Wdate' type='input' id='"
+ obj.name
+ "' name='"
+ obj.name
+ "' onFocus=\"WdatePicker({dateFmt:'yyyy-MM',alwaysUseStartDate:true})\" ></div>";
// $("#search_div").append(html);
appendhtml(html,obj);
$("#"+obj.name).val(curYM());
/* if(obj.name.indexOf("start") >=0){
if(obj.defaultVal==minDateVal){
//$("#"+obj.name).val(curDateTime(1));
}else{
$("#"+obj.name).val(createDate_YM());
//conditions += " "+obj.displayname + ":" + createDate_YM();
}
}else{
if(obj.defaultVal==maxDateVal){
}else{
$("#"+obj.name).val(createDate_YM());
//conditions += " "+ obj.displayname + " " + createDate_YM();
}
} */
}
//创建日期_年月日输入框
function createDate_YYYYMMDD(obj) {
var width=getWidth(obj);
var html = "<div id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+="<span id='"+obj.name+"_span'>"+obj.displayname +"</span> "
+ "<input class='Wdate' type='input' id='"
+ obj.name
+ "' name='"
+ obj.name
+ "' onFocus=\"WdatePicker({dateFmt:'yyyyMMdd',alwaysUseStartDate:true})\" ></div>";
// $("#search_div").append(html);
appendhtml(html,obj);
$("#"+obj.name).val(curYYYYMMDD());
}
//创建数字输入框
function createNumber(obj) {
var width=getWidth(obj);
// var html = "<div style='width:"+width+"px;' id='"+obj.name+"_div'>";
var html = "<div id='"+obj.name+"_div'>";
if(obj.ismust=="Y"){
html+="<font size='3' color='red'>*</font>";
}
html+=obj.displayname +" "
+ "<input type='input' class='input' id='"
+ obj.name
+ "' name='"
+ obj.name
+ "' onpropertychange='_isNumber(this)' oninput='_isNumber(this)'></div>";
// $("#search_div").append(html);
appendhtml(html,obj);
}
3、每个创建的元素,如何追加到查询区域当中呢:
看下面的js函数:
function appendhtml(html,obj){
if(paraIndex!=null&¶Index!=""){
for(var i = 0;i<paraIndex.length;i++){
if(paraIndex[i].para==obj.id){
$("#td_"+paraIndex[i].row+"_"+paraIndex[i].column).html(html);
var width = $("#td_"+paraIndex[i].row+"_"+paraIndex[i].column).width()-getTitleWidth(obj.displayname);
//var width = obj.width-getTitleWidth(obj.name);
if( width != null && width > 0){
$("#" + obj.name).width(width);
$("#" + obj.name+"1").width(width);
}
}
}
}else{ //如果没有定义样式,则直接追加到search_div当中
$("#search_div").append(html);
}
}
如果是web页面,将在页面中,追加三个按钮:
具体代码看什么onclick方法中相关代码,这个方法名称当初真心取得有问题,容易让人产生误解。
4、把查询条件向报表中传递
具体我们看看查找按钮的代码:其思路为:根据dom元素类型,拼接查询条件,把条件追加到ifram的url当中去。如果增加了查询条件类型(参数类型),这个方法需要配套修改。为了在报表中,显示出查询条件(主要为了打印、导出时,纸面上有条件),拼接了condition变量,存放条件,针对日期显示,单独搞两个textVal变量。这些都是辅助性质的。
function search() {
var sdate = "",edate = "";
var sdate_c = "",edate_c = "";
conditions = "";
var url = "";
var flag = 0;
url += "&usercode=" + NODE.usercode;
$.each(NODE.params, function(idx, obj) {
var name = obj.name;
var type = obj.type;
var disname = obj.disname;
var ismust=obj.ismust;
var textVal = $("#" + name + "1").val();
if (type == "checkbox") {
var str = chk(name);
if (str.length<1) {
if(ismust=="Y"){ //必填
asyncbox.error(disname + ' 为必填项!','提示');
flag++;
return false;
}
} else {
url += "&" + name + "=" + str;
conditions +=" " + disname + ":"+ textVal ;
}
}else if (type == "radio") {
var str = $("input[name=" + name + "]:checked").val();
textVal = $("input[name=" + name + "]:checked").next().text();
if (!str) {
if(ismust=="Y"){ //必填
asyncbox.error(disname + ' 为必填项!','提示');
flag++;
return false;
}
} else {
url += "&" + name + "=" + str;
conditions +=" " + disname + ":"+ textVal ;
}
}else if (type == "select") {
var str = $("#" + name).val();
//textVal = $("#" + name).text();
textVal = $("#" + name).find("option:selected").text();
if (!str) {
if(ismust=="Y"){ //必填
asyncbox.error(disname + ' 为必填项!','提示');
flag++;
return false;
}
} else if(str&&str!=-999){
url += "&" + name + "=" + str;
if(textVal != "请选择")
{
conditions +=" " + disname + ":"+ textVal ;
}
}
}else if (type == "text" || type == "date" || type == "number"|| type == "date_YM") {
var val = $("#" + name).val();
if(NODE.link =='NontaxCompleteCondition.rptdesign'||NODE.link == "nontaxComplete.rptdesign"){
if(name.indexOf("start") >= 0)
{
sdate_c = $("#" + name).val();
}
else if(name.indexOf("end") >= 0)
{
edate_c = $("#" + name).val();
}
}
if(type == "date")
{
textVal = val;
}
if(type == "date_YM")
{
textVal = val;
}
if (!val) {
if(ismust=="Y"){ //必填
asyncbox.error(disname + ' 为必填项!','提示');
flag++;
return false;
}
if(name.indexOf("tYear")>=0){
url += "&" + name + "=" + year;
}
} else {
if(type == "date")
{
if(disname != "至")
{
conditions +=" " + disname + ":"+ textVal ;
}
else
{
conditions +=" " + disname + " "+ textVal ;
}
}
else if(type == "date_YM")
{
if(disname != "至")
{
conditions +=" " + disname + ":"+ textVal ;
}
else
{
conditions +=" " + disname + " "+ textVal ;
}
}
else if(type == "text")
{
conditions +=" " + disname + " "+ val ;
}
url += "&" + name + "=" + val;
}
}else if(type == "layer"){
var val = $("#" + name).val();
if (!val) {
if(ismust=="Y"){ //必填
asyncbox.error(disname + ' 为必填项!','提示');
flag++;
return false;
}
if(NODE.link=='NontaxCompleteCondition.rptdesign'){
if(name.indexOf("countName") >= 0 ){
if($("#censusType").val()=='BasChargeAgency'){
url += "&ageType=1&" + name + "=" + deptid;
}else{
url += "&agencyId=" + deptid;
}
}
}else{
if(name.indexOf("agencyId")>=0||name.indexOf("agencyName")>=0){
url += "&ageType=1&" + name + "=" + deptid;
}
}
if(name.indexOf("billId")>=0){
url += "&" + name + "=";
}
} else {
if(NODE.link=='NontaxCompleteCondition.rptdesign'){
if($("#censusType").val()!='BasChargeAgency'){
url += "&agencyId=" + deptid;
}
}
conditions +=" " + disname + ":"+ textVal ;
url += "&" + name + "=" + val;
}
}else if (type == "tree") {
var val = $("#" + name).combotree('getValues');
var params = "";
if (val[0]=="") {
if(ismust=="Y"){ //必填
asyncbox.error(disname + ' 为必填项!','提示');
flag++;
return false;
}
} else {
for (i = 0; i < val.length; i++) {
if (val.length == 1) {
params += val[i];
} else if (i == 0) {
params += val[i] + "',";
} else if (i == val.length - 1) {
params += "'" + val[i];
} else {
params += "'" + val[i] + "',";
}
}
conditions +=" " + disname + ":"+ textVal ;
url += "&" + name + "=" + params;
}
}else if (type == "radiotree") {
var val = $("#" + name).val();
var dname = $("#" + name).prev().text();
if (!val) {
if(ismust=="Y"){ //必填
asyncbox.error(disname + ' 为必填项!','提示');
flag++;
return false;
}
if(NODE.link=='NontaxCompleteCondition.rptdesign'){
if($("#censusType").val()=='BasChargeAgency'){
url += "&ageType=1&" ;
//+ name + "=" + deptid
}else{
url += "&agencyId=" + deptid;
}
}else{
if(name.indexOf("agencyId")>=0||name.indexOf("agencyName")>=0){
//url += "&ageType=1&" + name + "=" + deptid;
url += "&ageType=1";
}
}
} else {
if(name.indexOf("agencyId")>=0||name.indexOf("agencyName")>=0){
url += "&ageType=0";
}
if(NODE.link=='NontaxCompleteCondition.rptdesign')
{
conditions +=" " + dname + ":"+ textVal ;
}
else
{
conditions +=" " + disname + ":"+ textVal ;
}
// var t = $('#' + name).val(); // 得到树对象
// var node = t.tree('getSelected'); // 得到选择的节点
// var level = node.attributes; //深度
// var nodeid = node.id; //节点ID
// var nodename = node.text; //节点名称
// url += "&" + name + "=" + nodeid + "&"+name+"level=" + level
// + "&"+name+"nodename=" + nodename;
}
url += "&" + name + "=" + val;
}
});
if(NODE.link == "NontaxCompleteCondition.rptdesign"||NODE.link == "nontaxComplete.rptdesign")
{
if(sdate_c == null|| sdate_c == "" || edate_c == null|| edate_c== "")
{
alert("起始时间为必填项!");
return;
}
else if(sdate_c != null && sdate_c != "" && edate_c != null && edate_c != "")
{
var startDate_c= sdate_c.split("-");
var endDate_c= edate_c.split("-");
var sYear =startDate_c[0];
var eYear =endDate_c[0];
if(sYear != eYear)
{
alert("查询的时间必须在同一个年度!");
return;
}
}
}
var a=new Array();
if($("#org").length>0){
a=$("#org").combotree('getValues');
}
var b=$("input[name=statisticstype]:checked").val();;
if(b=='2'&&a[0]==""){
asyncbox.error('按机构统计时“组织机构必填”!','提示');
flag++;
return false;
}
if (flag == 0) {
var ifr_url = "";
if(NODE.link.indexOf("jsp") > 0){
ifr_url=NODE.link;
}else{
var clientType = GetQueryString("clientType");
if(url.search('tongjiType')!=-1){
ifr_url="frameset?__report=report/" + NODE.link
+ "&report_id=" + report_id
+ "&__parameterpage=false&isoffice="+isoffice+"&admdivcode=" + admdivcode
+ "&year=" + year + "&clientType=" + clientType + url + "&conditions=" + conditions+"&token="+token;
}else{
ifr_url="frameset?__report=report/" + NODE.link
+ "&report_id=" + report_id
+ "&__parameterpage=false&isoffice="+isoffice+"&tongjiType=1&admdivcode=" + admdivcode
+ "&year=" + year + "&clientType=" + clientType + url + "&conditions=" + conditions+"&token="+token;;
}
if(clientType=='0'){
ifr_url +="&officeId=" + deptid;
}
if(NODE.link=='day_collecting_bank.rptdesign'){
if(ifr_url.search('agencyId')==-1){
ifr_url += "&agencyId=" + deptid;
}
}
}
if(clientType=='0'){
ifr_url += "&officeId=" + deptid;
if(ifr_url.indexOf("storeId")<0){
// ifr_url+="&storeId="+deptid;
}
}else{
if(ifr_url.indexOf("agencyId")<0){
ifr_url+="&agencyId="+deptid;
}
}
if(ifr_url.indexOf("queryType")<0){
ifr_url+="&queryType="+queryType;
}
//alert(conditions);
ifr_url+="&hallid="+deptid+"&dept="+deptid;
//获得自定义列顺序参数
var coloptstr = getCurrentColumnPara();
if(coloptstr!=""){
ifr_url += "&colopt="+coloptstr;
}
ifr_url = encodeURI(ifr_url);
document.getElementById("ifr").src = ifr_url;
}
}
这段代码当中:conditions 是为了拼接查询条件,传递到报表当中,供报表中显示查询条件用。
报表我们用birt,birt中,同样要设对应的查询参数。
(birt 当中 对应的参数,名字要和条件名字一致)
ps:dept 在一个子系统中,传的就是单位guid? 主业务系统传的的agencyId
报表本身准备完毕后,就是如何挂到另外一个应用当中:
1、我们用report_test.jsp 做入口
2、进入这个页面的时候,要传递单位id参数
3、要把参数传递到iframe当中。
传递参数的代码:
$(function() {
var height = $(window).height();
initLayer();
//调用初始化查询条件区的方法...
initSearchDiv();
......
var ifr_url = "";
var startbilldateVal='2010-01-01';
var endbilldateVal='2030-01-01';
if(report_name.indexOf("jsp") > 0){
ifr_url=report_name;
}else{ //构建调用birt报表的url字符串
var clientType = GetQueryString("clientType");
ifr_url="frameset?__report=report/" + report_name
+ "&report_id=" + report_id
+ "&__parameterpage=false&admdivcode=" + admdivcode + "&year=" + year
+ //其他需要传递的参数
....
}
$.ajax({
url : "ParameterServer?method=getAgency&id="+deptid+"&report_id="+report_id,
async : false,
async : false,
type : "GET",
success : function(data) {
var params = jQuery.parseJSON(data);
$.each(params, function(idx, obj) {
$("#agencyId").val(deptid);
$("#agencyId1").val(obj.code+" "+obj.name);
if(clientType=='1'){
$("#countName").val('');
$("#countName1").val('');
}else{
$("#countName").val(deptid);
$("#countName1").val(obj.code+" "+obj.name);
}
conditions += " 收费单位:"+ obj.code+" "+obj.name;
})
}
});
//if(NODE.link=='fina_income_detail.rptdesign')
//{
// conditions += " 缴款书状态:已收款";
//}
//alert(conditions);
ifr_url +="&conditions=" + conditions;
ifr_url +="&hallid=" + deptid +"&userId="+userId+"&dept="+deptid;
//获得自定义列顺序参数
var coloptstr = getCurrentColumnPara();
if(coloptstr!=""){
ifr_url += "&colopt="+coloptstr;
}
ifr_url = encodeURI(ifr_url);
document.getElementById("ifr").src = ifr_url;
$("#ifr").height(document.body.clientHeight-$("#search_div").height()-10);
});
其实,就是拼iframe的url, 把参数带入url
一个ie兼容性问题的解决:
console.log 在ie下有问题,而且不报错!去掉console.log 就好
遗留问题:
- 上传birt报表文件要分文件夹存放,现在在一个reports目录下,文件太多。
- 多数据源的应用,开了头,没完善。
- 报表向导只做了原型,没有产品化落地。
- 自定义
单独弄一个报表设计器,争取拜托birt报表设计器?
报表管理数据库结构:
数据库当中必须记录用户设置的列相关参数:
-- Create table
create table COLUMNPARAMETER
(
ID VARCHAR2(32) default sys_guid() not null,
REPORTID VARCHAR2(32) not null,
REPORTURL VARCHAR2(2000),
PARASARR VARCHAR2(4000),
ORDERPARAS VARCHAR2(2000),
CPARASARR CLOB,
DEFAULTCPARASARR CLOB
)
tablespace HBFS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64
minextents 1
maxextents unlimited
);
-- Add comments to the table
comment on table COLUMNPARAMETER
is '报表列参数表';
-- Add comments to the columns
comment on column COLUMNPARAMETER.REPORTID
is '报表id';
comment on column COLUMNPARAMETER.REPORTURL
is '参数链接';
comment on column COLUMNPARAMETER.PARASARR
is '参数数组字符串';
comment on column COLUMNPARAMETER.ORDERPARAS
is '排序参数';
comment on column COLUMNPARAMETER.CPARASARR
is '大参数数组字符串';
comment on column COLUMNPARAMETER.DEFAULTCPARASARR
is '默认大参数数组字符串';
由于我厂参数是配置的:
需要增加几个参数:
columnsManage 指定列的顺序、是否隐藏、列的宽度
关于指定列排序:
我们需要增加二个参数:按哪一列排序、是升序还是降序:
(指定按列排序的表字段)
(指定的列是升序还是降序)
相应的birt报表文件中,dataset对象的beforeopen方法中增加如下代码
if(screen!=""&&screen!=null&&screen!="null"){
if(seach!=""&&seach!=null&&seach!="null"){
this.queryText = "select * from (" + this.queryText +") where "+ seach +" like'%" + screen +"%'" ;
//添加排序参数:
if(col!=null && col!="" &&col!="null"&sort!=null &&sort!="" &&sort!="null"){
this.queryText ="select * from ("+this.queryText+") order by "+col+" "+sort;
}
}
}
这个代码的主要作用是:根据接受的指定的列名、升降序,拼sql,使得执行该sql查询语句后,结果是排序过的。
绑定参数与报表的关系:
参数设置了,报表文件中根据传入的参数进行了处理,还需要把2者关联起来,我厂做了一个报表服务,关联报表及参数间关系:
绑定了参数,还需要指定参数在页面上布局的位置:
设置表头背景图片宽度等的位置:
发布报表的步骤:
1、设计好报表
2、上传报表
3、配置参数
关于birt报表参数传递:
一个是在reprort_test.jsp页面中,确定相关参数初始值,一个是birt本身提供默认值,
哪个方法更优?搞不清,我们先按相关参数初始值。
ps:不是参数说明:
clientType :表示是否是财政 还是 单位,clientType=0 // 表示是财政 clientType=1 // 表示是单位
ifoffice 就是启用了科室分管 ;officeId 科室的guid?