精华内容
下载资源
问答
  • Web自定义报表前后端代码-使用dataTable插件实现自定义报表统计
    千次阅读
    2020-03-29 10:40:09

    自定义报表查询

    所谓的自定义报表,即提供与功能相关的所有字段全部列出,让用户根据以实际工作需求获取适当的字段信息,达到简化用户工作的效果。

    经多家客户提供的报表需求来看,可分为“汇总统计”和“明细统计”两种,然后再由指定字段排序。

    汇总统计:可按字段进行数量的汇总或金额的汇总。
    明细统计:即将所有信息数据全部展现。
    指定排序:用户可自定义指定字段,指定排序方式进行展现。

    目前初步已完成的工作开发方案:

    前端处理方式:

    • **自定义查询条件:**将相关的查询字段列出,供用户选择查询。
    • **自定义返回字段:**使用复选框供用户选择。
      html页面渲染处理方式
    <div class="col-sm-12">
    	<div class="checkbox checkbox-info checkbox-inline">
    		<input id="custom-column-companyproductid" class="custom-column-checkbox" type="checkbox" value="companyproductid">
    		<label for="custom-column-companyproductid">耗材唯一码</label>
    	</div>
    </div>
    <div class="col-sm-12">
    	<div class="checkbox checkbox-info checkbox-inline">
    		<input id="custom-column-uniquecode" class="custom-column-checkbox" type="checkbox" value="uniquecode">
    		<label for="custom-column-uniquecode">产品唯一码</label>
    	</div>
    </div>
    <div class="col-sm-12">
    	<div class="checkbox checkbox-info checkbox-inline">
    		<input id="custom-column-productname" class="custom-column-checkbox" type="checkbox" value="productname">
    		<label for="custom-column-productname">耗材名称</label>
    	</div>
    </div>
    

    JQUERY代码加载查询条件方式

    var queryBean=new Object();//查询Bean
    //获取查询条件
    $("#custom-query-condition-accordion .custom-query-attribute").each(function(){
    	var $Node=$(this);
    	var attribute=$Node.attr("attribute");//属性名称【字段名称】
    	var value=$Node.val();//属性值
    	queryBean[attribute]=value;
    });
    //特殊字段需要另外编写
    queryBean.productname=$(".custom-productname").find("option:selected").attr("productname");//耗材名称
    queryBean.productnorms=$(".custom-productnorms").find("option:selected").attr("productnorms");//耗材规格
    queryBean.productstyles=$(".custom-productstyles").find("option:selected").attr("productstyles");//耗材型号
    

    JQUERY代码加载用户所选的要显示的字段信息

    //获取自定义显示字段
    var showColumnBean=new Object();//显示字段Bean
    var columnTextBean=new Object();//字段中文注释Bean
    //查询条件数量
    var resultCheckCounts=$("#custom-result-condition-collapseOne").find(".custom-column-checkbox:checked").length;
    $("#custom-result-condition-collapseOne .custom-column-checkbox").each(function(){
    	var $checkbox=$(this);
    	var attribute=$checkbox.val();//属性名称【字段名称】
    	var text=$.trim($checkbox.next().html());//表头
    	if(resultCheckCounts<=0)
    	{
    		showColumnBean[attribute]=true;//默认显示所有
    	}
    	else
    	{
    		var checked=$checkbox.is(":checked");//是否需要显示
    		showColumnBean[attribute]=checked;//是否显示
    	}
    	columnTextBean[attribute]=text;//中文信息
    });
    

    JQUERY动态表格初始化处理方式:

    function initialMappingCityformProductTable(aoColumns)
    {
    	$('#city_platform_maping_product').DataTable({
    		"oLanguage": {
    			"sLengthMenu": "每页显示 _MENU_条",
    			"sZeroRecords": "没有找到符合条件的数据",
    			"sProcessing": "<img src=’./loading.gif’ />",
    			"sInfo": "当前第 _START_ - _END_ 条 共计 _TOTAL_ 条",
    			"sInfoEmpty": "没有记录",
    			"sInfoFiltered": "(从 _MAX_ 条记录中过滤)",
    			"sSearch": "搜索:", 
    			"sCopy": "复制",
    			"oPaginate": {
    				"sFirst": "首页",
    				"sPrevious": "前一页",
    				"sNext": "后一页",
    				"sLast": "尾页"
    			}
    		},
    		dom: '<"html5buttons"B>lTfgitp',
    		bRetrieve: true,
    		"paging": false,
    		"scrollX": true,
    		"scrollY": "500px",
    		"aoColumnDefs": [ { "bSortable": false, "aTargets": [ 0 ] }],
    		buttons:
    		[
    			{extend: 'copy',"text": "复制"},
    	    	{extend: 'csv',"text": "导出CSV"},
    	    	{extend: 'excel', title: '市平台材料对照信息',"text": "导出EXCEL"},
    	    ],
            "scrollX": true,
            "aoColumns":aoColumns
    	});
    }
    

    JQUERY动态表格头部处理方式

    function bindTableHead(paramBean)
    {
    	var showColumnBean=paramBean.showColumnBean;//需要显示的列
    	var columnTextBean=paramBean.columnTextBean;//列名称注释
    	if(showColumnBean==null||JSON.stringify(showColumnBean)=='{}'
    		||columnTextBean==null||JSON.stringify(columnTextBean)=='{}')
    	{
    		return false;
    	}
    	var aoColumns=new Array();
    	var tableHead='<tr>';
    	for(var attribute in showColumnBean)//遍历需要显示的字段
    	{
    		if(showColumnBean[attribute])
    		{
    			var column=new Object();//表格列
    			column.mData=attribute;
    			aoColumns.push(column);
    			tableHead+='<th>'+columnTextBean[attribute]+'</th>';
    		}
    	}
    	tableHead+='</tr>';
    	//表格
    	var table='<table style="width:100%" class="table table-striped table-bordered table-hover dataTables-example" id="city_platform_maping_product">';
    	table+='<thead>';
    	table+=tableHead;
    	table+='</thead>';
    	table+='<tbody>';
    	table+='</tbody>';
    	table+='</table>';
    	$("#city_platform_maping_product_div").html(table);
    	return aoColumns;
    }
    

    JQUERY异步查询结果处理

    var requestParam=new Object();//请求参数
    requestParam.queryBean=queryBean;//查询Bean
    requestParam.showColumnBean=showColumnBean;//显示字段Bean
    $.ajax({
    	url:"../cloudProduct/get_MappingCityPlatformProductByInfo.do",
    	data:JSON.stringify(requestParam),
    	dataType:"json",
    	type:"post",
    	contentType:"application/json;charset=utf-8",
    	success:function(data)
    	{
    		var dataJson=eval(data);
    		if(dataJson.success_Info=='success')
    		{
    			$("#customColumnModal").modal('hide');//关闭弹框
    			var paramBean=new Object();
    			paramBean.showColumnBean=showColumnBean;
    			paramBean.columnTextBean=columnTextBean;
    			//拼接表头,必须先拼接表格头部,再初始化表格
    			var aoColumns=product_CityPlatform_Mapping_Initial.bindTableHead(paramBean);
    			//初始化表格
    			product_CityPlatform_Mapping_Initial
    				.initialMappingCityformProductTable(aoColumns);
    			var mappingCityPlatformList=dataJson.mappingCityPlatformList;//后台返回到的数据
    			if(mappingCityPlatformList!=undefined&&mappingCityPlatformList.length>0)
    			{
    				//添加列,必须先初始化表格,再添加数据
    				$('#city_platform_maping_product').dataTable()
    					.fnAddData(mappingCityPlatformList);
    			}
    			swal.close();
    		}
    		else
    		{
    			swal({
        			title: "查询失败!",
        			text:dataJson.wrong_Info,
      				timer:2000,
      				type:"error",
      				showConfirmButton: false
      			});
    		}
    	},
    	error:function(data)
    	{
    		console.log('请求失败:'+data);
    	}
    });
    

    后台处理方式:

    • 自定义查询条件: 使用传统的sql拼接查询条件,入参方式使用阿里巴巴 fastJSON:com.alibaba.fastjson.JSONObject可灵活处理数据。封装了sql拼接代码,节省点dao层工作开发时间
    • 自定义返回字段: 将返回字段以key:value键值对形式保存,便于动态拼接。</font> **<font color='balc'>java后台SQL拼接查询条件处理方式示例
    JSONObject columns = new JSONObject();// 字段容器
    columns.put("status","case b.status WHEN 1 THEN '停用' ELSE '正常' END status");
    columns.put("ismapping", "case b.ismapping WHEN 1 THEN '是' ELSE '否' END ismapping");
    columns.put("iscloud", "CASE b.iscloud WHEN 1 THEN '是' ELSE '否' END iscloud");
    columns.put("third", "CASE b.third WHEN 1 THEN '是' ELSE '否' END third");
    columns.put("isplatform","CASE b.isplatform WHEN 1 THEN '是' ELSE '否' END isplatform");
    Session session = this.getSessionFactory().getCurrentSession();
    Transaction t = session.beginTransaction();
    StringBuffer hql = new StringBuffer();
    hql.append("SELECT ");
    paramBean.put("columns", columns);
    JSONObject appendSql = CommonFun.appendCustomSqlResultColumnInfo(paramBean);// SQL拼接
    hql.append(appendSql.getString("appendSql"));// 执行拼接
    hql.append(" FROM ");
    hql.append("t_publica           f, ");
    hql.append("t_publicb           e, ");
    hql.append("t_pro               d, ");
    hql.append("t_linproduct        c, ");
    hql.append("t_category          h, ");
    hql.append("t_company           b, ");
    hql.append("t_promappingplatform ph, ");
    hql.append("t_platform          g");
    hql.append("WHERE b.linkproductid = c.linkproductid ");
    hql.append("AND c.productid = d.productid ");
    hql.append("AND d.factorynumber = e.factorynumber ");
    hql.append("AND b.companynamenumber = f.companynamenumber ");
    hql.append("AND h.categoryid=b.categoryid ");
    hql.append("AND b.companyproductid = ph.companyproductid ");
    hql.append("AND ph.productcityplatformid=g.productcityplatformid ");
    JSONObject queryBean = new JSONObject();
    if (paramBean.containsKey("queryBean") && paramBean.get("queryBean") != null)
    {
         queryBean = paramBean.getJSONObject("queryBean");// 查询条件Bean
    }
    hql.append(bindJsonQueryCondition(queryBean, "b", "isbilling", true, "number"));
    hql.append(bindJsonQueryCondition(queryBean, "b", "ismappinghis", true, "number"));
    hql.append(bindJsonQueryCondition(queryBean, "b", "islimit", true, "number"));
    hql.append(bindJsonQueryCondition(queryBean, "b", "isnumber", true, "number"));
    hql.append(bindJsonQueryCondition(queryBean, "b", "biddingmethod", "varchar"));
    hql.append(bindJsonQueryCondition(queryBean, "b", "isconsignment", true, "number"));
    hql.append(bindJsonQueryCondition(queryBean, "b", "isgaozhi", true, "number"));
    hql.append(bindJsonQueryCondition(queryBean, "b", "factorynumber", "varchar"));
    // 时间区间
    hql.append(bindQueryConditionBetween(queryBean,"ph","operationtime","operationtime_s","operationtime_e",true,"oracle"));
    hql.append("ORDER BY b.supplyprice,d.productname ");
    SQLQuery sqlQuery = session.createSQLQuery(hql.toString());
    // 字段拼接
    List<String> scalarColumns_String = new ArrayList<String>();// String数据类型
    List<String> scalarColumns_Decimal = new ArrayList<String>();// BigDecimal数据类型
    List<String> scalarColumns_Integer = new ArrayList<String>();// Integer数据类型
    List<String> scalarColumns_Long = new ArrayList<String>();// Long数据类型
    // String
    scalarColumns_String.add("hospitalstatus");
    scalarColumns_String.add("ismappinghis");
    scalarColumns_String.add("ismappingcloud");
    scalarColumns_String.add("ismappingthirdparty");
    scalarColumns_String.add("ismappingcityplatform");
    scalarColumns_String.add("isbilling");
    // BigDecimal
    scalarColumns_Decimal.add("supplyprice");
    scalarColumns_Decimal.add("priceincreasel");
    scalarColumns_Decimal.add("retailprice");
    scalarColumns_Decimal.add("packingcount");
    // Integer
    scalarColumns_Integer.add("linkproductid");
    // Long
    scalarColumns_Long.add("productmappingcityplatformid");
    scalarColumns_Long.add("productcityplatformid");
    paramBean.put("scalarColumns_String", scalarColumns_String);
    paramBean.put("scalarColumns_Decimal", scalarColumns_Decimal);
    CommonFun.bindCustomSqlResultColumnInfo(paramBean, sqlQuery);
    @ SuppressWarnings("unchecked")
    List <ProductMappingCityPlatformInfoBean> list = sqlQuery.setResultTransformer (Transformers.aliasToBean (ProductMappingCityPlatformInfoBean.class)).list ();
    t.commit ();
    return list;
    

    java后台SQL拼接CommonFun公共处理方法代码

    /**
     * 拼接自定义SQL返回字段
     * @author zhuteng
     * @time 2019-09-28
     * @param jsonObject
     * @return
     * @throws Exception
     */
    public static JSONObject appendCustomSqlResultColumnInfo (JSONObject paramBean) throws Exception
    {
    	if ( ! paramBean.containsKey ("columns") || paramBean.get ("columns") == null)
    	{
    		throw new Exception ("自定义Dao未定义指定的字段!");
    	}
    	JSONObject columns = paramBean.getJSONObject ("columns");
    	Iterator <String> columnArray = columns.keys ();// SQL字段遍历
    	if ( ! columnArray.hasNext ()) throw new Exception ("自定义Dao未定义指定的字段!");
    	// 开始拼接
    	StringBuffer hql = new StringBuffer ();
    	boolean isFirstCondition = false;// 是否存在自定义字段
    	if (paramBean.containsKey ("showColumnBean") && paramBean.get ("showColumnBean") != null)
    	{
    		JSONObject showColumnBean = paramBean.getJSONObject ("showColumnBean");// 需要查询的字段
    		if (showColumnBean.keys ().hasNext ())
    		{
    			isFirstCondition = true;
    		}
    	}
    	//自定义字段和默认查询做了两部分处理,主要是为了节省处理性能
    	if (isFirstCondition)// 自定义查询,字段拼接
    	{
    		isFirstCondition = false;// 标志位初始化
    		JSONObject showColumnBean = paramBean.getJSONObject ("showColumnBean");// 需要查询的字段
    		while (columnArray.hasNext ())
    		{
    			String column = columnArray.next ();// 字段名
    			if ("countunit".equals (column))
    			{
    				System.out.println ();
    			}
    			// 是否获取字段,不匹配则不处理
    			if(!showColumnBean.containsKey(column)||!showColumnBean.getBoolean(column))continue;
    			String str = isFirstCondition ? "," : "";// 判断是否拼接段位符
    			hql.append (str).append (columns.getString (column));
    			isFirstCondition = true;// 更新标识位
    		}
    	}
    	else
    	// 默认查询
    	{
    		while (columnArray.hasNext ())
    		{
    			String column = columnArray.next ();// 字段名
    			String str = (isFirstCondition) ? "," : "";// 判断是否拼接段位符
    			hql.append (str).append (columns.getString (column));
    			isFirstCondition = true;// 更新标识位
    		}
    	}
    	JSONObject resultInfo = new JSONObject ();
    	resultInfo.put ("appendSql" , hql.toString ());
    	return resultInfo;
    }
    
    /**
     * 处理自定义SQL返回字段
     * 
     * @author zhuteng
     * @time 2019-09-28
     * @param jsonObject
     * @return
     * @throws Exception
     */
    public static void bindCustomSqlResultColumnInfo (JSONObject paramBean , SQLQuery sqlQuery) throws Exception
    {
    	List <String> scalarColumns_String = new ArrayList <String> ();// String数据类型
    	List <String> scalarColumns_Decimal = new ArrayList <String> ();// BigDecimal数据类型
    	List <String> scalarColumns_Integer = new ArrayList <String> ();// Integer数据类型
    	List <String> scalarColumns_Long = new ArrayList <String> ();// Long数据类型
    	List <String> scalarColumns_Timestamp = new ArrayList <String> ();// TimeStamp数据类型
    	boolean isExistRsultColumns=false;
    	if(paramBean.containsKey("scalarColumns_String")
    		&&paramBean.get("scalarColumns_String")!=null)
    	{
    		JSONArray array = paramBean.getJSONArray ("scalarColumns_String");
    		if (array.size () > 0) isExistRsultColumns = true;// 设置为已设置查询返回字段
    		for (int i = 0 ; i < array.size () ; i ++ )
    		{
    			scalarColumns_String.add (array.getString (i));
    		}
    	}
    	if (paramBean.containsKey ("scalarColumns_Decimal") 
    		&& paramBean.get ("scalarColumns_Decimal") != null)
    	{
    		JSONArray array = paramBean.getJSONArray ("scalarColumns_Decimal");
    		if (array.size () > 0) isExistRsultColumns = true;// 设置为已设置查询返回字段
    		for (int i = 0 ; i < array.size () ; i ++ )
    		{
    			scalarColumns_Decimal.add (array.getString (i));
    		}
    	}
    	if (paramBean.containsKey ("scalarColumns_Integer") 
    		&& paramBean.get ("scalarColumns_Integer") != null)
    	{
    		JSONArray array = paramBean.getJSONArray ("scalarColumns_Integer");
    		if (array.size () > 0) isExistRsultColumns = true;// 设置为已设置查询返回字段
    		for (int i = 0 ; i < array.size () ; i ++ )
    		{
    			scalarColumns_Integer.add (array.getString (i));
    		}
    	}
    	if (paramBean.containsKey ("scalarColumns_Long") 
    		&& paramBean.get ("scalarColumns_Long") != null)
    	{
    		JSONArray array = paramBean.getJSONArray ("scalarColumns_Long");
    		if (array.size () > 0) isExistRsultColumns = true;// 设置为已设置查询返回字段
    		for (int i = 0 ; i < array.size () ; i ++ )
    		{
    			scalarColumns_Long.add (array.getString (i));
    		}
    	}
    	if (paramBean.containsKey ("scalarColumns_Timestamp") 
    		&& paramBean.get ("scalarColumns_Timestamp") != null)
    	{
    		JSONArray array = paramBean.getJSONArray ("scalarColumns_Timestamp");
    		if (array.size () > 0) isExistRsultColumns = true;// 设置为已设置查询返回字段
    		for (int i = 0 ; i < array.size () ; i ++ )
    		{
    			scalarColumns_Timestamp.add (array.getString (i));
    		}
    	}
    	// 若未设置自定义返回字段,则不允许查询
    	if ( ! isExistRsultColumns) throw new Exception ("未定义返回字段!");
    	// 开始处理
    	boolean isFirstCondition = false;
    	if ( ! paramBean.containsKey ("columns") || paramBean.get ("columns") == null)
    	{
    		throw new Exception ("自定义Dao未定义指定的字段!");
    	}
    	JSONObject columns = paramBean.getJSONObject ("columns");
    	Iterator <String> columnArray = columns.keys ();// SQL字段遍历
    	// 字段拼接
    	if (paramBean.containsKey ("showColumnBean") && paramBean.get ("showColumnBean") != null)
    	{
    		JSONObject showColumnBean = paramBean.getJSONObject ("showColumnBean");// 需要查询的字段
    		if (showColumnBean.keys ().hasNext ())
    		{
    			isFirstCondition = true;
    		}
    	}
    	// 自定义查询,字段拼接,做了两部分处理,主要是为了节省处理性能
    	if (isFirstCondition)
    	{
    		// 需要查询的字段
    		JSONObject showColumnBean = paramBean.getJSONObject ("showColumnBean");
    		while (columnArray.hasNext ())
    		{
    			String column = columnArray.next ();// 字段名
    			// 是否获取字段,不匹配则不处理
    			if (!showColumnBean.containsKey(column)||!showColumnBean.getBoolean(column))continue;
    			if (scalarColumns_String.contains (column))
    			{
    				sqlQuery.addScalar (column , Hibernate.STRING);
    			}
    			else if (scalarColumns_Decimal.contains (column))
    			{
    				sqlQuery.addScalar (column , Hibernate.BIG_DECIMAL);
    			}
    			else if (scalarColumns_Integer.contains (column))
    			{
    				sqlQuery.addScalar (column , Hibernate.INTEGER);
    			}
    			else if (scalarColumns_Long.contains (column))
    			{
    				sqlQuery.addScalar (column , Hibernate.LONG);
    			}
    			else if (scalarColumns_Timestamp.contains (column))
    			{
    				sqlQuery.addScalar (column , Hibernate.TIMESTAMP);
    			}
    		}
    	}
    	else
    	// 未设定自定义字段查询
    	{
    		for (String column : scalarColumns_String)
    		{
    			sqlQuery.addScalar (column , Hibernate.STRING);
    		}
    		for (String column : scalarColumns_Decimal)
    		{
    			sqlQuery.addScalar (column , Hibernate.BIG_DECIMAL);
    		}
    		for (String column : scalarColumns_Integer)
    		{
    			sqlQuery.addScalar (column , Hibernate.INTEGER);
    		}
    		for (String column : scalarColumns_Long)
    		{
    			sqlQuery.addScalar (column , Hibernate.LONG);
    		}
    		for (String column : scalarColumns_Timestamp)
    		{
    			sqlQuery.addScalar (column , Hibernate.TIMESTAMP);
    		}
    	}
    }
    
    更多相关内容
  • 本课程详细讲解在C#Winform程序里,对DataGridView展示的数据进行自定义报表格式的设计、预览、打印如何实现
  • PB前端打印报表自定义修改功能: 1.不连接任何数据库,不重新创建数窗,所有属性都在原数据窗口上修改,最大限度保证原数据窗口的完整性; 1.可修改窗口上下左右打印边距; 2.可框选,多选对象; 2.可任意拖动,拉长,拉...
  • 好多朋友在开发C#项目的过程中,由于客户的要求或自身项目的完美,需要自定义报表/自定义单据的,可以下载本源码,本报表/单据自定义源码功能强大,相信可以满足你的需求!
  • 自定义报表工艺:两个任意历史时刻产量、生产效率统计、计算、任意位置、格式显示在Excel上、可打印或保存查询的报表!数据库用的是Access.依此为模版,可方便的自行制作年月日自定义产能报表!数据采集采用定时周期...
  • 中联HIS自定义报表大全(第二版) 适合中联公司HIS系统的报表开发,适合医院信息科工作人员使用。中联HIS自定义报表大全(第二版) 适合中联公司HIS系统的报表开发,适合医院信息科工作人员使用。
  • 易飞9.0系统的里面自定义报表的维护PPT文件,里面比较详细的阐述了一些注意事项。
  • PB自定义报表

    2018-12-24 12:36:13
    用PB实现前台自定义报表功能,直接生成src文件;用PB实现前台自定义报表功能,直接生成src文件;
  • 自定义报表开发工具

    2015-07-28 09:09:10
    自定义报表开发工具,能够实现报表的自定义开发。
  • NC自定义报表培训

    2018-09-27 18:07:39
    NC自定义报表培训录屏-
  • U8编写自定义报表的三种方法
  • 自定义报表插件.exe

    2020-09-17 13:51:28
    自定义U8报表控件,取代U8的UAP报表,增加打印模板设置,用于U8ERP系统中原系统无法实现的一些打印功能,适用版本U810.0---U813.0. 例如ERP系统的生产订单打印,无法打印材料出库的情况,可以在本插件中实现。
  • MrCRM 5.0版本是在CRM市场上第一个提出了真正由客户自己定义并通过多维的方式对数据进行分析的报表展现。MrCRM 5.0具有多维分析;全部多维报表都可以由客户自定义去实现;...自定义报表保存为固定报表等特点。
  • 自定义报表

    2014-08-12 14:36:25
    U8自定义报表的三种方法详解,包括:自定义报表栏写SQL语句、利用作业完成自定义报表、利用存储过程编写报表等。
  • net自定义报表.zip

    2019-07-14 21:49:34
    2、本程序提供一个报表设计器、报表生成器及Asp.Net调用例子 3、ReportTool是报表设计器,由他设计的报表保存在数据库表SysReports中;ReportServiceConfig 是报表生成器,该程序与Asp.Net关系紧密,参见...
  • 报表设计器在报表设计过程中以及报表运行的过程中都可以使用。使用StimulReport.Net,您可以创建基于各种不同数据源的报表。在运行时使用StimulReport.Net 的报表设计器不需要支付任何的运行时费用。所创建的报表...
  • PB自定义报表程序

    2018-11-07 09:33:12
    自定义报表的源代码,PB书写,可以自行导出excel,定义报表格式
  • web自定义报表插件

    热门讨论 2012-09-06 09:12:34
    web自定义报表插件,可以实现客户自定义报表样式和内容。
  • C#使用grid++report开发的自定义报表工具,可以独立运行的报表系统,供学习grid++report自定义报表,也可用于企业根据自己企业数据库,形成自己的报表系统。
  • C# 自定义报表设计器

    2014-07-03 14:05:05
    C# 使用自定义DataGridView实现的报表设计器,可以自定义设置报表内容,合并表头,合并单元格,导出报表到Excel 和打印报表
  • 报表模板实现网格式自定义报表

    千次阅读 2021-02-28 16:49:33
    用户需求为可以选择预添加的字段,并且可以增删,最终根据用户选择,生成结果报表,实现web端报表结果自定义功能。如下图所示。 报表实现:下面例子实现四列的自定义网格式报表。参数表单:利用参数,前端js,隐藏行...

    需求描述:

    一般报表模板设计的报表都是固定格式和字段的报表,如果要修改列字段或者排列顺序,需要设计人员修改报表模板。用户需求为可以选择预添加的字段,并且可以增删,最终根据用户选择,生成结果报表,实现web端报表结果自定义功能。如下图所示。

    66983d639f2696fd13feb04d8746a48d.png

    c08642b6be1c65e32589b50a1e434bb1.png

    报表实现:

    下面例子实现四列的自定义网格式报表。

    参数表单:

    利用参数,前端js,隐藏行属性等,为用户提供报表自定义的参数页面,用户可以添加或删除报表的列,并选择列字段。

    参数模板:param.raq

    参数配置:

    3789936cee2ae704676af93859bc7084.png

    num,整数,主要用于记录已添加的行,初值为1。

    数据集:建立内建数据集,A,B,C,D分别表示四列的可选字段。

    80e6cf35daa7f73f6d37ab284a383e69.png

    报表模板设计:

    dfee8fe71c5fd46e79105d8b3f8b529c.png

    报表模板设计重点主要包括一些几点

    1. 该报表可以填报,并且B2,B3,B4,B5可写,web变量名分别为col1,col2,col3,col4。

    2. 设置隐藏行属性,第3,4,5行都需要设置隐藏行属性,设置的方式相同。以第2行为例,隐藏行属性表达式为if(num>=2,false,true),表示如果当前以添加的列(num)大于等于2时,当前行是不隐藏的,否则隐藏该行。

    3.下拉编辑风格设置

    B2,B3,B4,B5提供下拉数据集的编辑风格,分别绑定ds1的A、B、C、D字段,并且提供动态过滤功能。B3下拉项不包括B2的选择项,B4下拉项不包括B2和B3的选择项,依以此类推。

    B2,B3的下拉数据集填报风格设置如下,B4,B5类似。

    ef2cf173156793992f1510cc646cdc3e.png

    383d58d81cf43b602b29ac85cba3168c.png

    4 添加超链接属性,利用js实现添加删除参数表单中的列选择。

    C2单元格添加了”超链接属性”:”javascript:add_col(“+A1+”)”,其中A1单元格值为num+1,表示的要添加的列数。调用页面js的函数add_col完成列添加。

    b4276c5eb95f33c86c5684a2e91fd7f5.png

    C3,C4,C5单元格同样需要添加”超链接属性”,以C3单元格为例,单元格表达式为: =if(num==2,”删除”,”"),如果参数num为2,值为删除,否则为空。超链接属性设置如下图,”javascript:del_col(2,’col2′)” ,调用页面js的函数del_col完成列删除。

    d51f6d00d2c7397def4d5ac0b7725786.png

    Js函数:

    add_col(num) 添加列选择,实际上是刷新当前页,传递参数值num,num的值是要添加的列,根据这个num值可以控制参数表单某些行是否隐藏,如num=2时,第3行显示,4,5行隐藏。

    del_col(num,col) 删除列选择,实际上也是刷新页面,传递参数num和指定的参数值。如要删除第3行,那么调用”javascript:del_col(2,’col2′)”,最终转向页面showParams.jsp?num=1&col2=,实现效果是隐藏了第三行并且清空了”第二列”(B3)的选择项

    function add_col(num)

    doPostBack(form1,’showParams.jsp?num=’+num);

    function del_col(num,col)

    var num1=num-1;

    doPostBack(form1,’showParams.jsp?num=’+num1+’&’+col+’=');

    //指定提交页面的url

    function doPostBack(formObj,actionFile){

    formObj.action=actionFile;

    formObj.submit();

    结果模板:result.raq

    利用动态宏实现单元格表达式的动态变化。

    参数设置:

    3ed0f18ef1b2c1cb9b3a2428add70a49.png

    分别接收来自于参数模板的4个列选择。

    宏设置:

    4b75a0a2d9cca88e9c59c64db43f7eb6.png

    Macro1:if(col1!=null&&col1!=”",”ds1.select(“+col1+”)”,null)

    Macro2:if(col2==null ,”",col2==”",”",”ds1.”+col2)

    Macro3:if(col3==null ,”",col3==”",”",”ds1.”+col3)

    Macro4:if(col4==null ,”",col4==”",”",”ds1.”+col4)

    数据集:

    7d9b837091f5d0a62b0da089bd40234f.png

    注意数据集的设置需要包含所有参数模板里面选择的列,这里取出了所有字段。

    报表模板设计:

    5222243b6acb2dbab49108aff8329625.png

    其中A1,B1,C1,D1代表表头的字段描述,接收对应列名参数col1,col2,col3,col4。

    A2根据宏计算动态生成单元格表达式,如果col1为空,表达式为空,如col1为”产品名称

    “,表达式就变为ds1.select(产品名称)。B2,C2,D2也是类似,根据宏生成表达式。

    小结:

    本例利用宏,参数,隐藏行,js实现了比较灵活的自定义报表,打破了报表模板设计只能设计固定格式报表的限制,增强了和终端用户的交互,说明灵活的应用润乾提供的属性功能可以组合设计出更灵活多变的报表。

    具体实现可以参考附件。

    展开全文
  • U9 自定义报表开发手册.PDF,希望可以帮助从事U9的同仁,对他们专业有指导
  • 鼎捷软件自定义报表的详细操作说明;自定义字段的说明,排列以及信息的抓取
  • 让用户自己设计和修订报表的用户自定义报表(又称即席报表)是Java报表工具很多年来所不断追求的一个境界。但在很多尝试之后,我们可以说离用户自定义报表还有很大的距离。现有的解决方案大致可以归为两类。第一种是把...

    让用户自己设计和修订报表的

    用户自定义报表(又称即席报表)是

    Java报表工具很多年来所不断追求的一个境界。但在很多尝试之后,我们可以说离用户自定义报表还有很大的距离。现有的解决方案大致可以归为两类。

    第一种是把桌面报表设计界面搬到浏览器上。

    第二种是提供一个简单的Wizard界面,让用户可以在不需要培训的情况下,可以自己做一些设计。

    把桌面设计界面直接搬到网上基本上是把技术的和应用混淆了。这类型里最具代表的报表工具厂家当属Cognos和它的ReportNet。ReportNet应该是最早应用AJAX技术在浏览器里全面实现报表设计界面的报表产品。从技术的角度,ReportNet的实现方式在2004年可以算是当之无愧的技术领先者。但这并不表示用了最新的技术就解决了用户的问题。

    其实用户是否需要安装一个软件,只是自定义报表的很多因素中的一个。在让用户可以任何时间都使用报表设计界面的基础上,这个软件还必须带来一个既易用又强大的工具。如果我们把一个给开发人员使用的工具交给终端用户,得到的结果只能是一群迷茫的用户。这往往还要改变报表工具的使用模式。

    而提供一个简单Wizard的方式往往太过限制。报表Wizard通常提供了一些基本的功能,比如数据选择,排序,过滤,汇总等。虽然这些功能听起来很多,但除了一些最简单的报表,用户基本上不能做出太多的东西。在实际操作中,Wizard大概只能满足不到30%的客户需求。

    Java报表工具厂家在追逐了用户自定义报表(即席报表)很多年以后,一直没有找到一个可行的解决方案。可以说现在已经是要换一个新的思路的时候了。

    从根本上解决用户自定义报表问题,我们必须要解决数据的提取和处理,同时需要简化报表的排列。

    简化数据的处理是一个很困难的任务。绝大多数用户并没有数据库的经验。要让他们掌握数据的提取,必须给他们提供一个十分所得及所见的环境。而大多数报表的软件往往把数据的功能限制在过滤,分组,和汇总的层面上,极大地限制了工具的灵活性。

    要克服这些缺点,Java报表工具必须摆脱传统的数据处理的模型。不止是提供一个可以提取回显示数据的功能,同时应用可视化的功能,让用户可以更加直观的和数据互动。通过直观的数据的显示和在图表上数据的操作,用户可以在不用学习数据结构的前提下直接对数据进行提前和处理。

    下面是一个典型的数据发布图。

    adhoc_new_theory_img001.jpg

    如果用户想要得到销售数量大而又打折很低的产品,只需要在图表上选择左上角的点。

    adhoc_new_theory_img002.jpg

    然后通过显示细节数据的功能来取出相应的数据。

    adhoc_new_theory_img003.jpg

    当然这只是通过可视化进行数据提取的形式之一。当一个Java报表工具提供了丰富的可视化互动功能时,用户可以几乎是无限制地对数据进行多样的操作。完全不需要被数据库的技术所限制。

    和此相辅相成的是对数据的呈现。数据可视化工具通常提供了一个让用户随心所欲的排列信息的功能。因为用户不需要关注最后数据的排版,界面的设计得到了极大的简化。比如在我们需要显示一个交叉表时,传统的Java报表软件要求用户考虑到数据的扩展和的排版。而在一个互动的界面里,数据的扩展完全可以通过滚动条来控制。

    adhoc_new_theory_img004.jpg

    有些读者可能会想,在电脑界面上使用滚动条固然好,但当要把结果输出到打印时,用户是否还是要对格式做一些指定。否则结果还是不能满足使用的需求。这里有一定的道理。具体的使用就要看这个Java报表软件是否有足够的功能来自动地处理信息的扩展和排列。

    在大部分的情况下,软件有足够的信息自动的扩展和调整内容的位置,从而达到一个让大部分用户可以接受的结果。

    adhoc_new_theory_img005.jpg

    在自动排版不能达到最理想效果的情况下,可视化软件必须提供一个让用户自己安排内容的途径。一种可行的方式是自动把可视化界面转化成用户可以更多控制的报表的格式。当然,这种解决方案需要相应的软件同时支持可视化和报表的功能。

    在今天高度信息化的环境里,电脑界面应该是一个主流的浏览和操作数据的途径。当然打印的输出也不能忽视。所以,通过可视化界面解决及时报表的方式,需要在这两方面都有一个完整的解决方案。这样,用户既可以很简易地生成自己需要的信息,又有足够的控制来生成最后的结果。

    展开全文
  • C#自定义报表源码

    2017-04-01 16:28:44
    C#自定义报表源码
  • C#完全自定义报表源码

    热门讨论 2011-08-01 16:20:52
    自定义报表源码 自定义 报表 源码
  • 报表设计器 C# 源码 自定义报表
  • 今天谈下自定义报表和可视化监控大屏设计方面的内容,准备分三个部分来讲,第一是先看下当前主流的商用报表工具的功能特点,其次分别谈下报表设计和可视化监控大屏设计。 商用报表工具的实现思路 图片来源网络 ...

    今天谈下自定义报表和可视化监控大屏设计方面的内容,准备分三个部分来讲,第一是先看下当前主流的商用报表工具的功能特点,其次分别谈下报表设计和可视化监控大屏设计。

    商用报表工具的实现思路

    图片来源网络

    最近在网上搜索自定义报表,监控大屏制作,搜索到了FineReport报表制作工具。

    FineReport报表软件是一款纯功能于一身的企业级web报表工具,它“专业、简捷、灵活”的特点和无码理念,仅需简单的拖拽操作便可以设计复杂的中国式报表,搭建数据决策分析系统。

    这款报表制作工具还是相对的火,你能够想到的常见报表自定义,报表的多维度分析,统计汇总,上钻和下钻,图形可视化等基本都能够实现。可以对接各种关系型数据库作为数据源,同时也支持你手工填报数据上来进行采集后汇总,然后报表呈现。关键是该报表很多能力基于Excel来完成,只有你有基础的Excel使用技能,并不需要太多的编码能力就能够完成报表的开发和制造。

    而对于监控大屏制作,是今年来报表的一个扩展关键能力,FinedReport刚好提供了该能力。

    可以看如下这篇文章介绍:http://bbs.fanruan.com/thread-94898-1-1.html

    相信大家看了这篇文章,会发现监控大屏制作可以这么容易,在没有这个工具的时候我们也在考虑如何做监控大屏,包括选择类似百度Echart做相关的图表,找美工进行整体界面风格的设计和配色,确定需要在监控大屏上显示的内容等。

    而看了上面这篇文章,给我最大的感受就是,做任何事情我们都可以从大量的特殊性和差异化中抽象中共性化的特征,同时将差异点进行参数化和模板化,以完成对这类事情的普适化模板和套路设计。

    拿监控大屏来说,你要达到上面的能力,首先你就需要有大量的监控到设计和开发实践,或者至少观察了大量的监控屏实现例子。其次你需要具备足够的抽象化能力,找寻共性,并完成从特殊到一般的过程。从FineReport体现的监大屏制作能力,该思路也完全适用于我们日常的产品化规划和设计工作。

    所谓的软件产品化,也就是是一个从大量个性化业务场景中进行共性能力抽取,个性能力参数化的过程而已。

    再回来看监控大屏实现,你会发现进行抽象和模板化后整个实现过程本身很简单。

    1. 选择布局和排版,这个本身可以表格化和模板化,足够解决问题。
    2. 选择基本的配色体系,在前面我们可以预设常用的配色体系,供选择即可。
    3. 选择每个Panel里面的数据呈现方式(文字,数字,表格,各种图形,地图,关系等)
    4. 为每个Panel的数据呈现配置相应的数据源
    5. 实现一些最后的点缀,动态实时效果等。

    而上面这些步骤也是我们自己进行监控大屏开发的时候常用的方法和步骤,只是FineReport把这个过程进一步参数化和模板化了而已。难的地方就在于大量观察和实践后,这种通用模型和能力的抽象。

    最后对于FineReport报表本身的简单易用性,强大的功能,网上有些总结,而这些总结本身体现的就是长期在一个专业方向或领域的持续不断的积累,对简单易用产品哲学的坚持,对用户使用场景的深刻洞察,对各种产品细节的不断优化,而所有上面的这些都缺一不可。

    一个产品要能够做成功,往往需要的就是这种长期的坚持和努力,不断优化改进,对一线用户使用需求的积极响应和分析。我们很多时候产品没有做好,一个是脱离用户,一个就是迎合潮流和赶时髦,很多产品做到中途由于推广的不好就放弃,又换一个新产品进行研发,和猴子掰玉米本质上并没有大的区别。

    真正的产品成功之道,里面最重要的就是长期的坚持和积累,不轻言放弃。真正好用的产品往往都是你对用户需求的重视,由用户需求帮你不断打磨和抽象出来的模型。

    FineReport网址:http://www.fanruan.com/finemax/

    自定义报表功能设计思路

    对于自定义报表,在前面讲的商用报表平台或工具来实现大屏展示,而实际上一谈到报表大家谈的比较多的还是BI分析应用中常用的各种报表类工具,类似水晶报表,国内的FineReport等。一个商用的报表平台或工具可以看到功能会很强大,但是总结来说还是数据采集,设计,呈现几个部分内容。

    1. 数据采集:从结构化数据库,各类文件数据源,也包括直接提供手工填报端的自动生成。
    2. 报表设计器:提供独立的报表设计器能力,支持类似分组,切片,钻取等各类复杂场景,支持各类图表。
    3. 报表展示:报表展示支持各类图表的展示,支持自定义参数查询,支持类似监控大屏等。

    在这里不打算详细讨论商用自定义报表能力。对于我们大部分业务系统来说,需要的报表能力往往并不需要类似BI系统报表这么强大,更多的可以理解为自定义查询能力 可定制的图表展现。那么我们在实现自定义报表的时候就应该从这两个方面来考虑一个报表如何实现。

    在考虑这个问题的时候,我们先考虑报表设计器的问题。对于最终的报表展现效果我们看到,分为自定义查询条件部分,和报表内容展示区域。报表内容展示区域可以理解为一个个的独立Widget面板,每个面板就展示一个内容,可以是一个曲线图,也可以是一个表格,Panel面板里面的内容可以自己进行定制。

    整体展示效果类似如下:

    下面来拆分下几个关键的功能。

    1. 数据源的定义

    数据源定义关键就是通过数据源形成可在报表界面上展示的数据集。因此该功能建议不仅仅是简单定义数据源,同时包括数据集或数据对象的定义。因为数据集本身也是可复用的,不需要重复设计。

    数据源连接可以是JDBC方式,也可以是WebService接口方式,而实际上最佳方案是采用WS服务接口方式来获取数据集。这样可以进一步保障后端数据库的安全性。

    为了更好的支撑参数化查询,对于数据集的定义可以带参数化查询条件,由外围传入。

    2. 单数据面板的定义

    单数据面板的定义实际上思路很简单,就是要实现数据集和数据展示组件之间的绑定。数据面板可以是常规的表格,折线图,曲线图,饼图等。当前如果采用百度Echart图表库的话,我们可以做到对Echart图表库的大部分图形展现都支持。

    数据集笼统来说就是一个二维结构的数据对象返回,这个二维结构可以很容易影响到表格,也可以映射为类似折线,曲线,饼图等各种我们希望展示的形状。

    3. 整体查询报表页面的设计和定义

    对整体查询报表的设计实际上可以看到,主要工作就是定义自定义查询面板,定义和选择需要在该报表中展示的单数据面板。确定查询结果面板的具体布局形式。

    对于面板布局采用最简单的Grid布局形式即可,在定义清楚一个标准的Grid布局后,我们就很容易来配置单个面板究竟占有几列几行。同时在单个面板设计的时候,我们还需要将单个面板中的待输入参数项和自定义查询中的查询条件参数进行映射和绑定,完成查询条件的传入工作。

    4. 最终的报表设计内容解析和呈现

    这里有两种实现方式,一种是代码动态生成然后再自动编译为独立的部署包。另外一种方式就是所有报表呈现都只有一套动态代码来执行,即整个页面是基于配置参数完全动态生成的。

    第一种方式性能更好,但是配置变更后需要重新部署;第二种方式性能稍差,但是好在能够完全动态调整。

    最终的单个完整报表的呈现可以理解为就是一个url地址,传入具体的报表id信息。同时单个报表的呈现还需要考虑单点集成,并预留用户id,组织id,姓名等Session相关的全局参数。

    可视化监控大屏的实现

    在网上搜索下,可以看到有不少专门做监控大屏可视化解决方案的,包括一些好的报表平台软件,也专门对监控大屏可视化做了优化,能够很好的做到定制和可配置。而对于监控大屏实现,当前我们完全可以采用百度Echart来定制实现,而这篇文章主要想谈下如何对监控大屏可视化做到灵活可配置。

    首先我们看到监控大屏可视化,实际上跟我们前面谈到的自定义报表相当类似,其核心仍然是单面板设计,多面板组装。基于这个思路我们逐一展开进行描述。

    在讲自定义报表的时候,我们单面板设计数据集和实际的数据呈现是耦合在一起的,而实际上更好的思路是数据集合和数据呈现进行分离。基于这个思路,逐一展开讲关键功能点实现。

    1.数据集设计

    数据源定义,对于数据源定义,最好也进行独立,一个报表前端呈现本身也可能涉及到多个数据源。数据集设计,即返回一个二维的数据集合,可以有多列。我们需要通过配置的方式来实现,即首先选择数据源,然后自定义Sql语句,然后返回具体的数据集对象。在sql过程中我们可以对字段标题名称等进行转义。

    更加解耦的方法是数据集可以直接选择具体的WS服务,由服务返回一个二维的数据集对象。这种方式可以进一步实现报表平台和底层数据库的解耦。

    2.单面板设计

    单面板设计简单来说就是将前端的呈现方式,究竟是折线图,饼图还是雷达图等,和后端的数据集进行绑定。在这个过程中重点是要确认具体的图表呈现的一些关键配置,包括X,Y轴显示,图表名称,图例是否显示等关键配置,都需要在单面板设计的是配置完成。

    单面板设计完成后,最好提供预览功能按钮,可以马上体验到单面板展示的效果。

    3.大屏设计

    对于大屏设计,实际上里面有几个关键点,首先就是大屏展示需要有一个CSS模板,这个模板决定了所有的单面板图表的配色风格,包括具体的底色,前端的色系选择等。选择模板就是确保最终的大屏展示各个单面板风格能够完全保持一致。

    大屏版面设计,仍然采用标准的Grid布局模式即可,可以看到所有的大屏展示基本都采用Grid布局模式。每个单面板你唯一要确定的就是横向跨几行,纵向跨几列即可。类似上面的图,我们采用4*4Grid进行布局,中间的地图展示则是横向跨3行,纵向跨两列。

    4.大屏整体的展示动态刷新能力

    在以上设计完成后,我们整个大屏展示效果也就出来了。在该大屏设计中我们没有考虑动态查询功能。但是大屏监控仍然需要动态进行刷新。因此在设计大屏的时候需要具备动态刷新能力,为了考虑后续具备一定的扩展性,我们需要能够将关键的一些变量参数传递到图表展示中。

    最关键的参数就是当前时间,当前的时间需要能够传递到每一个数据集Sql中,方便我们根据时间进行数据过滤。同时对于大屏我们需要配置定时刷新频率,基于该频率对展示内容进行动态刷新。

     

    展开全文
  • 随着公司业务发展,目前要应对几十家医院的文书、报表、BI,定制开发导致研发每天加班,现场需求也...网上也看了很多收费的自定义表单、自定义报表及自定义图表都不能完全满足医院客户需要,并且价格不菲,没办法撸...
  • 创建一个带有查询条件的自定义报表,可以选择 “建模引擎” 中的虚拟表单,将一个已有的数据库视图转换为表单。 获得虚拟表单后,可以创建 “建模引擎” 中的查询,引用该虚拟表单并设置查询条件等。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 67,740
精华内容 27,096
关键字:

自定义报表

友情链接: 点面icp.rar