`
huangyuanmu
  • 浏览: 289816 次
  • 性别: Icon_minigender_1
  • 来自: 龙城
社区版块
存档分类
最新评论

web报表页面及json数据公式解析计算器

阅读更多

前一段时间,为了满足公司的web报表系统的需求,利用javascript开发了一个自定义公式解析计算器。开发人员可以根据一定规则,自定义web页面元素或者json字段之间的公式关系,实现算术运算和一些逻辑运算。

 

另外,还对页面的输入,数据的有效位数等进行了处理,每个数据字段的有效位数,开发人员都可以自定义。

 

该公式解析计算器的具体使用的例子,在我另外一篇博客文章中(http://huangyuanmu.iteye.com/admin/blogs/469180),有兴趣的话,可以看看。

 

下边给出具体实现代码:

/**
 *  模拟java的包,或者C#中的命名空间的概念
 * */
var tohot = tohot ? tohot : {};
tohot.commons = tohot.commons ? tohot.commons : {};
tohot.commons.declaration = tohot.commons.declaration ? tohot.commons.declaration : {};
/**
 * 报表公式计算器实现
 */
var tohotCalculator = tohot.commons.declaration.ExpressionCalculator = tohot.commons.declaration.ExpressionCalculator ? tohot.commons.declaration.ExpressionCalculator : {

	description : "通用web报表公式解析计算器,根据自定义的报表计算公式,自动进行公式解析和报表数据计算,操作web报表页面数据和json数据。",
	author : "huangyuanmu",
	version : "1.0(2009-07-29)",

	report : {},

	// 根据公式,获取计算以后的值
	getValue : function(report,formular_str,dataType)
	{

		// 解析公式
		function _parseFormular() {
			if (mathing_begin)
	          {
	            mathing_str += formular_str.substr(i,1);
	            return true;
	          }
	          else
	          {
	            if (IsVar)
	            {
	              formular_str_ana += ")";
	              CurVar_Length += ")".length;
	              //判断当前的变量的值是否为空
	              tmpEl = eval(formular_str_ana.substr(CurVar_start,CurVar_Length));
	              if (isNaN(tmpEl))
	              {
	                formular_str_ana = formular_str_ana.substr(0,CurVar_start);
	                formular_str_ana += "0";
	              }
	            }
	            formular_str_ana += formular_str.substr(i,1);
	            IsVar = false;
	            return true;
	          }
	          return false;
		}

	    var formular_str_ana;
	    var returnValue;
	    var IsVar;   //表示该处的字符表示变量
	    var CurVar_start,CurVar_Length;   //表示当前的变量型字符串
	    var mathing_begin = false;   //字符串的匹配操作是否开始
	    var mathing_str = "";  //接受并解析匹配字符串
	    returnValue = 0;
	    IsVar = false;
	    var el_chang  =  "report.";
	    formular_str_ana = "";

	    if(dataType == null){
	    	dataType = "2";
	    }

	    for (i = 0;i<formular_str.length;i++)
	    {
	      switch(formular_str.substr(i,1))
	      {
	        case "$":
	        {
	          if (mathing_begin)
	          {
	            mathing_str += formular_str.substr(i,1);
	            break;
	          }
	          else
	          {
	            //变量的开始
	            CurVar_start = formular_str_ana.length;
	            formular_str_ana +=  "parseFloat("  + el_chang;
	            CurVar_Length = ("parseFloat(" + el_chang).length;
	            IsVar = true;
	            break;
	          }
	        }
	        case "@":
	        {
	          //匹配字符串的解释
	          if (mathing_begin)
	          {
	            //匹配字符串结束
	            mathing_begin = false;
	            mathing_str_arr = mathing_str.split(";");
	            formular_str_ana += "/^" + mathing_str_arr[0] + "$/i.test(";
	            if (mathing_str_arr[1].substr(0,1)  == "$")
	            {
	              formular_str_ana += "report" + "." + mathing_str_arr[1].substr(1,mathing_str_arr[1].length-1) + ")";
	            }
	            else
	            {
	              //非变量
	              formular_str_ana += "'" + mathing_str_arr[1].substr(0,mathing_str_arr[1].length) + "')";
	            }
	          }
	          else
	          {
	            //匹配字符串开始
	            mathing_begin = true;
	            mathing_str = "";
	          }
	          break;
	        }
	        case "+":
	        {
				if(_parseFormular()) {
					break;
				}
	        }
	        case "-":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "*":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "/":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "%":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case ")":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "?":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case ":":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "<":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "=":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case ">":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "!":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "|":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        case "&":
	        {
	          if(_parseFormular()) {
					break;
				}
	        }
	        default:
	        {
	          if (mathing_begin)
	          {
	            mathing_str += formular_str.substr(i,1);
	            break;
	          }
	          else
	          {
	            if (IsVar)
	            {
	              CurVar_Length++;
	            }
	            formular_str_ana += formular_str.substr(i,1);
	          }
	        }
	      }
	    }
	    if (IsVar)
	    {
	      formular_str_ana += ")";
	      CurVar_Length += ")".length;
	      //判断当前的变量的值是否为空
	      tmpEl = eval(formular_str_ana.substr(CurVar_start,CurVar_Length));
	      if (isNaN(tmpEl))
	      {
	        formular_str_ana = formular_str_ana.substr(0,CurVar_start);
	        formular_str_ana += "0";
	      }
	      IsVar = false;
	    }
	    if (mathing_begin)
	    {
	      //匹配字符串结束
	      mathing_begin = false;
	      mathing_str_arr = mathing_str.split(",");
	      formular_str_ana += "/" + mathing_str_arr[0] + "/i.test(";
	      if (mathing_str_arr[1].substr(0,1) == "$")
	      {
	        formular_str_ana += "report" + "." + mathing_str_arr[1].substr(1,mathing_str_arr[1].length-1) + ")";
	      }
	      else
	      {
	        //非变量
	        formular_str_ana += "'" + mathing_str_arr[1].substr(0,mathing_str_arr[1].length) + "')";
	      }
	    }
	    returnValue = eval(formular_str_ana);
	    // 如果公式计算的值小于0.005,则认为为零
	    if (Math.abs((returnValue - 0.00))<0.005)
	    {
	    	returnValue = tohotCalculator.formatData("0",dataType);
	    }else{
			returnValue = tohotCalculator.formatData(returnValue + "",dataType);
	    }
	    return returnValue;
	},

	// 格式化整数
	formatInteger: function (IntegerStr){
	    //获取字符串的长度和首字符和次字符,然后进行判断
	    var strLen = IntegerStr.length;
	    var firstStr = IntegerStr.substr(0,1);
	    var secondStr = IntegerStr.substr(1,1);
	    var tmpStr = IntegerStr;
	    //针对正数的处理
	    if(firstStr != "-"){
	      if ((firstStr == "0") && (strLen > 1)){
	        tmpStr = tmpStr.substr(1,strLen-1);
	        tmpStr = tohotCalculator.formatInteger(tmpStr);
	      }
	    }
	    else{
	      //负数的处理
	      if((secondStr == "0") && (strLen > 2)){
	        tmpStr = "-" + tmpStr.substr(2,strLen-2);
	        tmpStr = tohotCalculator.formatInteger(tmpStr);
	      }
	    }
	    return tmpStr;
	},

	 // 格式化浮点数
	 formatFloat: function (FloatStr){
	    //将字符串组合成整数部分和小数部分
	    var FloatStrArr = FloatStr.split(".");
	    var Integer_part = FloatStrArr[0];
	    var Float_part = FloatStrArr[1];
	    var FloatPartLen = Float_part.length;
	    //处理整数部分
	    if((Integer_part == "-") || (Integer_part == "")){
	      Integer_part += "0";
	    }
	    Integer_part = tohotCalculator.formatInteger(Integer_part);
	    //处理小数部分
	    if(FloatPartLen == 0){
	      Float_part += "00";
	    }
	    else{
	      if(FloatPartLen == 1){
	        Float_part += "0";
	      }
	    }
	    //合并
	    return (Integer_part + "." + Float_part);
	},

	// 数据验证,并设置json对象元素的值
	formatData: function (DataStr,DataType){
		var returnValue = "0.00";
		var IntegerCode,FloatCode;//数字的整数验证码和小数验证码
	    IntegerCode = /^[-]?[0-9]+$/i; //整数
	    FloatCode = /^[-]?[0-9]*[.][0-9]+$/i;
	    //整数
	    if (DataStr != ""){
			    if(DataType == "1")
			    {
			      if (DataStr.match(IntegerCode) == null)
			      {
			        if ((DataStr.match(FloatCode) == null))
			           {
			           	 returnValue = "0";
			           }
			           else{
			           	 var reVal = parseFloat(tohotCalculator.formatFloat(DataStr));
			             returnValue = ""+reVal.toFixed(0);
			           }
			      }
			      else{
			        returnValue = tohotCalculator.formatInteger(DataStr);
			      }
			    }
			    else if((DataType == "2") || (DataType == "3") || (DataType == "4"))
			         {
			          if (DataStr.match(IntegerCode) == null)
			     		 {
				           if ((DataStr.match(FloatCode) == null))
				           {
				           	 if(DataType == "2")
			     	   			returnValue = "0.00";
			     	   		if(DataType == "3")
			     	   			returnValue = "0.0000";
			     	   		if(DataType == "4")
			     	   			returnValue = "0.000000";
				           }
				           else{
				           	 var reVal = parseFloat(tohotCalculator.formatFloat(DataStr));
				             returnValue = reVal.toFixed(parseInt(DataType)+ (parseInt(DataType) - 2));
				           }
				         }
						else{
							if(DataType == "2")
			     	   			returnValue = tohotCalculator.formatInteger(DataStr + ".00");
			     	   		if(DataType == "3")
			     	   			returnValue = tohotCalculator.formatInteger(DataStr + ".0000");
			     	   		if(DataType == "4")
			     	   			returnValue = tohotCalculator.formatInteger(DataStr + ".000000");
			     		 }
			     	}else{
				           returnValue = "0.00";
				         }

	    }else{
	    	if(DataType == "1"){
	    	  	returnValue = "0";
	    	}else if(DataType == "2"){
			    returnValue = "0.00";
		   	}else if(DataType == "3"){
		   		returnValue = "0.0000";
		   	}else if(DataType == "4"){
		   		returnValue = "0.000000";
		   	}else{
		   		 returnValue = "0.00";
		   	}
	    }
	    return returnValue;
	},

	doCalculateFormular : function (formular) {

		var formualr_is_arr = /[,]/i;

		//解析公式
	      if (formular.match(formualr_is_arr) == null)
	      {
	        //单个公式
	        each_formular_arr = formular.split("^");
	        // 解析目标json值的有效位数
		    var targetArray = each_formular_arr[1].split("#");
	        // 设置报表json对象的值
	        var value = tohotCalculator.getValue(tohotCalculator.report,targetArray[0],targetArray[1]);
	        eval("tohotCalculator.report." + each_formular_arr[0] + "=value");
			// 设置页面元素的值
	        var el = eval(each_formular_arr[0]);
	    	el.value = value;
	      }
	      else
	      {
	        //公式数组
	        all_formular_arr = formular.split(",");
	        for (k=0;k<all_formular_arr.length;k++)
	        {
	          //单个公式
	          	each_formular_arr = all_formular_arr[k].split("^");
	          	// 解析目标json值的有效位数
		    	var targetArray = each_formular_arr[1].split("#");
	        	// 设置报表json对象的值
	        	var value = tohotCalculator.getValue(tohotCalculator.report,targetArray[0],targetArray[1]);
		        eval("tohotCalculator.report." + each_formular_arr[0] + "=value");
				// 设置页面元素的值
		        var el = eval(each_formular_arr[0]);
		    	el.value = value;
	        }
	      }
	},

	// 计算整个json报表对象,在保存报表的时候调用
	doCalculateJson : function (reportFormular) {

		_calculatorJson(reportFormular);

		// 计算报表json对象的公式触发
		function _calculatorJson(reportFormular) {
			var EachArrStr = "";
		    var FoumularArr; //公式数组
		    var formualr_is_arr = /[,]/i;
		    var e1;

			//解析公式
			for(key in reportFormular){
				formular = reportFormular[key];
				if (formular.match(formualr_is_arr) == null)
				{
				    //单个公式
					each_formular_arr = formular.split("^");
					// 解析目标json值的有效位数
		        	var targetArray = each_formular_arr[1].split("#");
					var value = tohotCalculator.getValue(tohotCalculator.report,targetArray[0],targetArray[1]);
					eval("tohotCalculator.report." + each_formular_arr[0] + "=value");
				}
				else
				{
				    //公式数组
					all_formular_arr = formular.split(",");
					for (k=0;k<all_formular_arr.length;k++)
					{
					  	//单个公式
					  	each_formular_arr = all_formular_arr[k].split("^");
					  	// 解析目标json值的有效位数
		        		var targetArray = each_formular_arr[1].split("#");
						var value = tohotCalculator.getValue(tohotCalculator.report,targetArray[0],targetArray[1]);
					 	eval("tohotCalculator.report." + each_formular_arr[0] + "=value");
					}
				}
			}
		}
	},

	// 根据公式计算当前页面的表单元素的值,在页面onblur事件的时候调用
	doCalculateCurr : function (cur_el_name,el_value,formular,DataType){

		_calculatorCurr(cur_el_name,el_value,formular,DataType);

		// 计算当前页面的公式触发
		function _calculatorCurr(cur_el_name,el_value,formular,DataType)
		{
		    var EachArrStr = "";
		    var FoumularArr; //公式数组
		    var formualr_is_arr = /[,]/i;
		    var e1;
		    if(_dataAuth(cur_el_name,el_value,DataType))
		    {
		      //解析公式
		      if (formular.match(formualr_is_arr) == null)
		      {
		        //单个公式
		        each_formular_arr = formular.split("^");

		        // 解析目标单元格的有效位数
		        var targetArray = each_formular_arr[1].split("#");

		        // 设置报表json对象的值
			    var form_el_value = tohotCalculator.formatData(el_value,DataType);
			    eval("tohotCalculator.report." + cur_el_name + "=form_el_value");

		        var value = tohotCalculator.getValue(tohotCalculator.report,targetArray[0],targetArray[1]);
		        eval("tohotCalculator.report." + each_formular_arr[0] + "=value");
				// 设置页面元素的值
		        var el = eval(each_formular_arr[0]);
		    	el.value = value;
		      }
		      else
		      {
		        //公式数组
		        all_formular_arr=formular.split(",");
		        for (k=0;k<all_formular_arr.length;k++)
		        {
		          //单个公式
		          	each_formular_arr = all_formular_arr[k].split("^");

		          	// 解析目标单元格的有效位数
		        	var targetArray = each_formular_arr[1].split("#");

		          	// 设置报表json对象的值
			        var form_el_value = tohotCalculator.formatData(el_value,DataType);
			    	eval("tohotCalculator.report." + cur_el_name + "=form_el_value");

			        var value = tohotCalculator.getValue(tohotCalculator.report,targetArray[0],targetArray[1]);
			        eval("tohotCalculator.report." + each_formular_arr[0] + "=value");
					// 设置页面元素的值
			        var el = eval(each_formular_arr[0]);
			    	el.value = value;
		        }
		      }
		    }
		}

		// 数据验证,并设置页面元素的值
		function _dataAuth(DataStr_el_name,DataStr,DataType){
			var DataStr_el = eval(DataStr_el_name);
			DataStr_el.value = tohotCalculator.formatData(DataStr,DataType);
		    return true;
		}
	}
}
分享到:
评论

相关推荐

    json复杂数据解析demo

    在本示例"json复杂数据解析demo"中,我们将探讨如何处理结构复杂、层次丰富的JSON数据。 首先,我们需要理解JSON的基本结构。JSON数据由键值对组成,键用引号包围,后面跟着冒号,值可以是字符串、数字、布尔值、...

    以json为中心的报表数据表示及js公式解析计算的应用

    标题中的“以json为中心的报表数据表示及js公式解析计算的应用”主要涵盖了两个核心概念:JSON(JavaScript Object Notation)和JavaScript公式解析计算在报表数据处理中的应用。JSON是一种轻量级的数据交换格式,它...

    PB解析json,解析JSON案例,解析jsondemo

    标题中的“PB解析json,解析JSON案例,解析jsondemo”表明了本文主要关注的是PowerBuilder(简称PB)如何处理JSON数据。在现代软件开发中,JSON(JavaScript Object Notation)是一种广泛使用的轻量级数据交换格式,...

    Android_JSON数据解析

    本篇将详细讲解如何在Android应用中解析JSON数据,主要涉及以下几个方面: 1. JSON基本结构 JSON由两种基本结构构成:对象(Object)和数组(Array)。对象是以花括号 `{}` 包围的键值对集合,键用双引号括起,如`...

    基于python+pyqt+paho.mqtt 的MQTT客户端实现及json数据解析

    基于python+pyqt+paho.mqtt 的MQTT客户端实现及json数据解析 基于python+pyqt+paho.mqtt 的MQTT客户端实现及json数据解析 基于python+pyqt+paho.mqtt 的MQTT客户端实现及json数据解析 基于python+pyqt+paho.mqtt 的...

    C++实现的服务器post访问并实现JSON数据流解析

    在本文中,我们将深入探讨如何...在给定的项目中,`Httppost`文件很可能是实现这些功能的源代码,包含了POST请求的发送和JSON数据解析的细节。通过分析和理解这个文件,你可以更深入地学习C++在服务器编程中的应用。

    易语言页面订单json解析

    综上所述,"易语言页面订单json解析"涵盖了网络数据获取、JSON解析、数据结构操作以及用户界面交互等多个重要知识点。掌握这些技能,开发者能够构建起一个能够从网页抓取并处理订单数据的系统,这对于电商平台、在线...

    安卓网站交互JSONxmlWebserviceUPnP相关-获取聚合数据的json数据并且解析.rar

    在安卓应用开发中,与服务器进行交互是必不可少的环节,特别是在构建动态、数据驱动的网站应用时。...对于学习Android网络编程和数据解析的开发者来说,这是一个宝贵的资源,尽管需要自行调试和验证代码的适用性。

    json数据解析源码

    总的来说,这个“json数据解析源码”项目涵盖了从获取到解析JSON数据,再到对数据进行操作和输出的整个流程。在实际应用中,根据具体需求,可能还需要处理错误、验证数据格式、优化性能等方面的问题。理解并掌握这些...

    C++实现http客户端连接服务端及客户端json数据的解析

    此代码用c++实现了http客户端的编写,其中包括了多字节转utf8(已在ExecuteRequest函数中实现,不用再引用所给的编码转换),get和post两种请求方式,后面有json数据的解析以及实现,详情可去博客...

    Android端解析web端传来的json数据

    本篇文章将深入探讨如何在Android端解析Web端传来的JSON数据。 首先,了解JSON的基本结构至关重要。JSON是一种数据交换格式,它允许我们以键值对的形式存储数据,可以包含数组和对象。例如: ```json { "name": ...

    kettle解析json串

    - 在数据处理过程中,经常需要解析JSON文件以提取所需的信息,这在Web服务数据交互、日志分析等领域尤为重要。 ### Java中解析JSON的方法 #### 1. **使用JSON Simple库** - `JSON Simple`是一个轻量级的Java库,...

    基于python+pyqt+paho.mqtt 的MQTT客户端实现及json数据解析(源码),开箱即用

    基于python+pyqt+paho.mqtt 的MQTT客户端实现及json数据解析(源码),开箱即用! 基于python+pyqt+paho.mqtt 的MQTT客户端实现及json数据解析(源码),开箱即用! 基于python+pyqt+paho.mqtt 的MQTT客户端实现及...

    android获取页面json格式数据并解析

    最近在整理自己写过的一些应用,发现这个也许对大家有帮助,android通过http页面获取json标准格式数据并且解析其中对象的全过程,其中包含android连接http页面方法,android解析json格式数据方法,json标准化格式...

    Java Json解析,Java Web Json解析,Java Web服务端获取Json数据,客户端通过HTTP获取Json数据

    Java JSON解析是Web开发中的重要技能,特别是在Java Web服务端和客户端之间传递数据时。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,因其易于人阅读和编写,同时也易于机器解析和生成,被广泛...

    PB9生成和解析JSON

    总结来说,PB9生成和解析JSON的功能虽然需要借助额外的库或自定义函数,但通过这些工具,开发者可以轻松地在PB9应用中与JSON数据交互,从而与各种现代Web服务和API无缝对接。这极大地扩展了PB9应用程序的能力,使其...

    json离线解析工具

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,被广泛用于Web应用程序之间传递数据。它基于JavaScript的一个子集,格式简洁清晰,易于人类阅读和编写,同时也易于机器解析和生成。在处理JSON数据...

    android之json和gson数据解析最完整的代码例子(包括各种样式的json数据)

    JSON(JavaScript Object Notation)和Gson是Android开发中常用的数据序列化和反序列化工具,...以上就是关于“Android之json和gson数据解析最完整的代码例子”的详细介绍,希望对您在学习和使用JSON及Gson时有所帮助。

    基于Newtonsoft.Json实现Json数据解析和封装

    Newtonsoft.Json已经足够强大,易用性也没得说。但是在使用过程中存在着一个问题,如果数据不存在...JsonObject类和JsonArray类可以相互嵌套,支持原生类的JsonPath检索能力,满足Json数据解析和Json数据封装常见需求。

    json 数据解析包

    标题提到的“json 数据解析包”是一组Java库,它们可以帮助开发者在Java环境中解析和操作JSON数据。以下是这些库的详细介绍: 1. **commons-collections-3.2.jar**:Apache Commons Collections是Apache软件基金会...

Global site tag (gtag.js) - Google Analytics