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

最近的工作中,要解决web报表的一系列问题。在客户端,我们利用delphi的ie浏览器组件,开发了一个报表容器,对报表进行数据录入、保存、和申报等操作,部分报表数据操作行为可以离线使用。同时,也要求报表也可以直接通过浏览器进行在线访问和操作。

 

原来我们的web报表系统是以web页面为中心的,一张报表一个独立页面。事实上,可能多张报表之间有公式计算关系,这样如果一张报表的某个字段值改变了,可能会引起其它报表字段值的改变。原有的以页面为中心的模式,不能很好的解决这个问题。

 

基于以上的需求,把各个有公式关系的报表作为一套报表,或者视为一个报表对象,以json来表示报表的数据,通过js公式解析器,来解析提前定义好的报表公式关系,并把值更新到当前显示的报表页面和json中。这样,后续对报表数据的处理,就完全以json为中心,可以通过delphi调用js,把报表数据持久化到客户端,同时也可以通过ajax的方式,把报表数据提交到java服务器端进行处理。

 

其实对报表的处理的核心就是对数据的处理,在我们这种模式中,就是对json的处理。而报表关系的核心,就是公式,用户在操作报表数据时,程序根据预先定义的公式,同时对当前显示的web报表页面报表json中的数据值进行修改。

 

下边给出测试代码。

 

json报表数据及公式的定义(testJson.js):

// 报表数据json表示
var testJson = {
	sb_zcfzb1:{
		sb_zcfzb_ncs_1:"0.00",sb_zcfzb_ncs_2:"0.00",sb_zcfzb_ncs_3:"0.00",sb_zcfzb_ncs_4:"0.00",sb_zcfzb_ncs_5:"0.00",sb_zcfzb_ncs_6:"0.00",
		sb_zcfzb_ncs_7:"0.00",sb_zcfzb_ncs_8:"0.00",sb_zcfzb_ncs_9:"0.00",sb_zcfzb_ncs_10:"0.00",sb_zcfzb_ncs_11:"0.00",sb_zcfzb_ncs_12:"0.00",
		sb_zcfzb_ncs_13:"0.00",sb_zcfzb_ncs_14:"0.00"
	},
	sb_zcfzb2:{
		sb_zcfzb_ncz_1:"0.00",sb_zcfzb_ncz_2:"0.00",sb_zcfzb_ncz_3:"0.00"
	}
};

// 报表公式关系表示
var testFormular = {
	sb_zcfzb1:"sb_zcfzb1.sb_zcfzb_ncs_14^$sb_zcfzb1.sb_zcfzb_ncs_1+$sb_zcfzb1.sb_zcfzb_ncs_2+$sb_zcfzb1.sb_zcfzb_ncs_3+$sb_zcfzb1.sb_zcfzb_ncs_4+$sb_zcfzb1.sb_zcfzb_ncs_5+$sb_zcfzb1.sb_zcfzb_ncs_6+$sb_zcfzb1.sb_zcfzb_ncs_7+$sb_zcfzb1.sb_zcfzb_ncs_8+$sb_zcfzb1.sb_zcfzb_ncs_9+$sb_zcfzb1.sb_zcfzb_ncs_10+$sb_zcfzb1.sb_zcfzb_ncs_11+$sb_zcfzb1.sb_zcfzb_ncs_12+$sb_zcfzb1.sb_zcfzb_ncs_13#4",
	sb_zcfzb2:"sb_zcfzb2.sb_zcfzb_ncz_1^$sb_zcfzb1.sb_zcfzb_ncs_1+$sb_zcfzb1.sb_zcfzb_ncs_2-$sb_zcfzb1.sb_zcfzb_ncs_3#1,"
			+"sb_zcfzb2.sb_zcfzb_ncz_2^$sb_zcfzb1.sb_zcfzb_ncs_1*$sb_zcfzb1.sb_zcfzb_ncs_2-$sb_zcfzb1.sb_zcfzb_ncs_3,"
			+"sb_zcfzb2.sb_zcfzb_ncz_3^$sb_zcfzb1.sb_zcfzb_ncs_1-$sb_zcfzb1.sb_zcfzb_ncs_2*$sb_zcfzb1.sb_zcfzb_ncs_3#3"
};
 

公式解析计算器的定义及web报表页面及json公式的触发(test.js)

	// 引用公式解析计算器
	var calculator = tohot.commons.declaration.ExpressionCalculator;
	calculator.report = testJson;

	// 设置页面报表公式触发
	function setFormular()
    {
	 	sb_zcfzb1.sb_zcfzb_ncs_1.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_1',sb_zcfzb1.sb_zcfzb_ncs_1.value,testFormular.sb_zcfzb1,'2');");
		sb_zcfzb1.sb_zcfzb_ncs_2.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_2',sb_zcfzb1.sb_zcfzb_ncs_2.value,testFormular.sb_zcfzb1,'2')");;
		sb_zcfzb1.sb_zcfzb_ncs_3.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_3',sb_zcfzb1.sb_zcfzb_ncs_3.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_4.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_4',sb_zcfzb1.sb_zcfzb_ncs_4.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_5.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_5',sb_zcfzb1.sb_zcfzb_ncs_5.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_6.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_6',sb_zcfzb1.sb_zcfzb_ncs_6.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_7.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_7',sb_zcfzb1.sb_zcfzb_ncs_7.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_8.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_8',sb_zcfzb1.sb_zcfzb_ncs_8.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_9.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_9',sb_zcfzb1.sb_zcfzb_ncs_9.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_10.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_10',sb_zcfzb1.sb_zcfzb_ncs_10.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_11.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_11',sb_zcfzb1.sb_zcfzb_ncs_11.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_12.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_12',sb_zcfzb1.sb_zcfzb_ncs_12.value,testFormular.sb_zcfzb1,'2')");
		sb_zcfzb1.sb_zcfzb_ncs_13.onblur = new Function("calculator.doCalculateCurr('sb_zcfzb1.sb_zcfzb_ncs_13',sb_zcfzb1.sb_zcfzb_ncs_13.value,testFormular.sb_zcfzb1,'2')");
	}

	// 实际情况下,该函数是在保存报表数据之前被调用
	function setJson() {
		// 根据公式定义,计算json值
		calculator.doCalculateJson(testFormular);

		// 遍历json,显示报表数据
		for(var key in testJson){
			for(var key1 in testJson[key]){
				alert(key + "." + key1 + "=" + testJson[key][key1]);
			}
		}
	}

 

 html测试页面(test.html)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>XXX表</title>
<link href="css/css.css" rel="stylesheet" type="text/css">
<script language=javascript src="json2.js"></script>
<script language="javascript" src="tohot.commons.declaration.ExpressionCalculator.js"></script>
<script language=javascript src="testJson.js"></script>
<script language=javascript src="test.js"></script>
</head>

<body onload="javascript:setFormular();">
<form method="post" id="sb_zcfzb1" name="sb_zcfzb1">
  <div class="reportTable" style="width:1000px">
  <table cellspacing="1" id="reportTable">
  	<tr class="reportTableTitle">
  	  <td width="20%" rowspan="2" class="report_top_left">资产<br></td>
  	  <td width="4%" rowspan="2" class="report_top_middle">行<br>次<br></td>
  	  <td width="13%" class="report_top_middle">年初数<br></td>
  	</tr>
  	<tr class="reportTableTitle">
  	  <td class="report_middle_middle">&nbsp;</td>
  	  <td class="report_middle_middle">&nbsp;</td>
  	  <td class="report_middle_middle">&nbsp;</td>
  	  <td class="report_middle_middle">&nbsp;</td>
  	</tr>
  	<tr>
  	  <td class="report_middle_left">流动资产:<br></td>
  	  <td class="report_middle_middle">&nbsp;</td>
  	  <td class="report_middle_middle">-<br></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">货币资金<br></td>
  	  <td class="report_middle_middle">1</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_1" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_1"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">短期投资<br></td>
  	  <td class="report_middle_middle">2</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_2" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_2"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">应收票据<br></td>
  	  <td class="report_middle_middle">3</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_3" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_3"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">应收股利<br></td>
  	  <td class="report_middle_middle">4</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_4" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_4"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">应收利息<br></td>
  	  <td class="report_middle_middle">5</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_5" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_5"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">应收账款<br></td>
  	  <td class="report_middle_middle">6</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_6" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_6"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">其它应收款</td>
  	  <td class="report_middle_middle">7</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_7" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_7"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2"> 预付帐款<br></td>
  	  <td class="report_middle_middle">8</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_8" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_8"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2"> 应收补贴款<br></td>
  	  <td class="report_middle_middle">9</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_9" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_9"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">存货<br></td>
  	  <td class="report_middle_middle">10</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_10" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_10"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">待摊费用<br></td>
  	  <td class="report_middle_middle">11</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_11" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_11"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">一年内到期的长期债券投资<br></td>
  	  <td class="report_middle_middle">21</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_12" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_12"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  	  <td class="report_blank_left2">其他流动资产<br></td>
  	  <td class="report_middle_middle">24</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_13" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_13"  size="15" class="reportTableInputEditRight"></td>
  	</tr>
  	<tr>
  		<td class="report_blank_left2">流动资产合计<br></td>
  	  <td class="report_middle_middle">31</td>
  	  <td class="report_middle_middle"><input name="sb_zcfzb_ncs_14" onfocus="this.select()" type="text" id="sb_zcfzb_ncs_14"  size="15" readonly class="reportTableInputTitleRight"></td>
  	</tr>
  	<input type="button" value="test" onclick="setJson()">
</form>
</body>
</html>

 

javascript公式解析计算器的简单说明和源码放在我的另外一篇博客文章里(http://huangyuanmu.iteye.com/admin/blogs/469190),有兴趣的话,可以看看。

你可能感兴趣的:(JavaScript,应用服务器,json,css,Delphi)