birt系列(1)--冻结表头

小厂,用的开源birt做报表,不太符合用户对报表的操作习惯。

用户对报表希望:

  1. 自定义显示、隐藏列;
  2. 自定义报表列的显示顺序;
  3. 自定义报表列宽度;
  4. 按用户选择的列对表格数据排序
  5. 冻结表头

所有冻结表头,都是把表头元素设置成绝对定位,在页面滚动的时候,根据滚动值修正元素top值。

冻结表头的实现1:普通列表的表头冻结

结表头的实现2:单层交叉列表的表头冻结---交叉表头固定的情况

结表头的实现3:单层交叉列表的表头冻结---交叉表头是动态的

结表头的实现4:单层交叉列表的表头冻结---多层交叉表

   这种情况,把表头区分为固定区,固定区,固定区表头按固定区的方式处理

   动态区表头,需要分行处理

冻结表头的实现1:

原理:把table header 设置成绝对定位。然后,在滚动事件中,动态修改top值即可。

但是,设置成绝对定位后,由于元素脱离了原来的流。宽度缩小了,因此,代码中,要动态设置每列的宽度。

截图如下:

(简单设置绝对定位的效果) 

HTML/CSS里面的绝对定位是脱离标准文档流的吗?

是的,绝对定位和浮动都脱离了标准文档流,但是相对定位并没有脱离;

首先要解决脚本放什么地方的问题,其次要如何识别表头。

脚本放什么位置?上图说明

(前端代码位置) 

识别表头?就是设置表头id

(设置表头id的位置)

表头宽度设置,代码我考虑3种方式:

1、把table 设置position属性,把表头设置为相对定位,这样做的好处是不用设置表头列宽度,但这个方案测试了一把,通不过。如果把表头设置为绝对定位,就脱离原来的流u,一样会导致列宽改变。

2、把table header row 设置为绝对定位,取得整个表格的宽度?把头部宽度设成table宽度?整个测试无效果 

因为获取的table的width,值为100%,而表头已经脱离流了,不受table影响,除非设置成绝对值,但预估应该是不行的,没有继续测试了。 

3、获取表格的每一列宽度,设置到th当中去;

  这有3种做法:

       一个是从col属性当中获取;问题是birt得用原生的js获取col属性,另外,col是不是过时了?这个方法没有深入尝试。

        一个是特定行,从特定行当中,取得每个单元格的宽度,设置到TH当中;这个不想尝试,觉得麻烦。

       用新的属性,可以通过,但是,必须把表单布局改为固定布局,下面代码就是这种方式

<script>
function lockHeader(){
//设置表列头宽度的代码
    var widthArray=new Array();     
       var ras=document.getElementById('ra');
		var ths=ras.children;
		for(var i=0;i<ths.length;i++){
			console.log("i value:"+i);
			if(ths[i].tagName=="TH"){
				widthArray[i]=ths[i].getBoundingClientRect().width;
			    widthArray[i]=widthArray[i]-2;
			    ths[i].style.width =widthArray[i]+"px"	
                //有的浏览器 要设置th下的div元素宽度,建后面的ps说明
                ths[i].children[0].style.width =widthArray[i]+"px"		
			}
		}
		
//结束设置表列头宽度的代码


var oBtn = document.getElementById('Document');


	
	//上边第一行的样式
		document.getElementById('ra').style.lineHeight = '24px';
		document.getElementById('ra').style.top = '0px';
		document.getElementById('ra').style.background = '#E3E9F1';
		document.getElementById('ra').style.position = "absolute";
		
		//设置5个元素宽度
		
	
	
	
	//绑定滚动
	if (oBtn.attachEvent) { //IE 中
	
    	oBtn.attachEvent('onscroll',function () { 
    	document.getElementById('ra').style.position = "absolute";
    	var scrolltop = document.getElementById('Document').scrollTop;
    	document.getElementById('ra').style.top = scrolltop+"px";
    	});
	}else {//firefox googleChorme

    	oBtn.addEventListener('scroll', function () { 
    		var scrollleft = document.getElementById('Document').scrollLeft;
    		var scrolltop = document.getElementById('Document').scrollTop;
			//document.getElementById('ra').style。background-attachment="scroll";
				if(scrolltop<25){
					document.getElementById('ra').style.top = "0px";	
				}else{
					document.getElementById('ra').style.top = scrolltop+"px";	
			}
			
    	}, false);

	}
	
	
}

</script>

                                                                               (可以直接复用的代码)

这里,必须设置行头的id

问题:当birt页面采取auto布局的时候,列宽和表格列不一致!对IE有效否,不确定

效果:

  还有一个情况需要考虑:

合计行被绝对定位的元素覆盖了!因为,绝对定位的表头覆盖了第一行,解决办法,设置table的margin

上图:

(设置table的margin) 

另外一种设表列宽度的代码:


var oBtn = document.getElementById('Document');
		var ras=document.getElementById('ra');
		var th=ras.childNodes
		console.log(th);
		var array=new Array();
		for(var i=0;i<th.length;i++){
			if(th[i].tagName=="TH"){
			console.log(i);
			var Y = th[i].getBoundingClientRect();	
			console.log(Y);
			if (oBtn.addEventListener){
			array.push(th[i].getBoundingClientRect().left+"-"+th[i].getBoundingClientRect().width);	
			}else{
			array.push(th[i].getBoundingClientRect().left);	
			}			
			}else {
				if (oBtn.addEventListener){
				array.push(0);
				}
			}
		}
		
		if (oBtn.addEventListener) {
		for(var i=0;i<th.length;i++){
		if(th[i].tagName=="TH"){
				th[i].style.position = "absolute";
				th[i].style.top='7px';
				console.log(array[i]);
				if(array[i]!=0){				
				th[i].style.left = (array[i].split("-")[0]-1)+"px";
				th[i].style.width = array[i].split("-")[1]+"px";
                //有的浏览器 要设置th下的div元素宽度,建后面的ps说明
                ths[i].children[0].style.width = array[i].split("-")[1]+"px";
				}
			}
		}

		}else{
		for(var i=0;i<th.length;i++){
			if(th[i].tagName=="TH"){
				th[i].style.position = "absolute";
				th[i].style.top='6px';
				console.log(array[i]);
				//if(array[i]!=0){				
				//Sth[i].style.left = (array[i]-1)+"px";
				//}
			}
		}
		
		}

但这个代码有个问题:如图:

目前还不知道怎么解决! 

<script>
function lockHeader(){
    var widthArray=new Array();
    var tab=document.getElementById('report_table_myId');
    //表格设为相对
    tab.style.position="relative";

		


var oBtn = document.getElementById('Document');


	
	//上边第一行的样式
		document.getElementById('ra').style.lineHeight = '24px';
		document.getElementById('ra').style.top = '0px';
		document.getElementById('ra').style.background = '#E3E9F1';
		document.getElementById('ra').style.position = "relative";
		//设置5个元素宽度
		
	
	
	
	//绑定滚动
	if (oBtn.attachEvent) { //IE 中
	
    	oBtn.attachEvent('onscroll',function () { 
    	document.getElementById('ra').style.position = "relative";
    	var scrolltop = document.getElementById('Document').scrollTop;
    	document.getElementById('ra').style.top = scrolltop+"px";
    	});
	}else {//firefox googleChorme

    	oBtn.addEventListener('scroll', function () { 
    		var scrollleft = document.getElementById('Document').scrollLeft;
    		var scrolltop = document.getElementById('Document').scrollTop;
			//document.getElementById('ra').style。background-attachment="scroll";
				if(scrolltop<25){
					document.getElementById('ra').style.top = "0px";	
				}else{
					document.getElementById('ra').style.top = scrolltop+"px";	
			}
			
    	}, false);

	}
	
	
}

</script>

(第一种固定表头无效代码)

		//初始化表头位置
var doc = document.getElementById('Document');
var ras=doc.getElementById('ra');  //ra 是自己定义的表头行的标签
var th=ras.childNodes
		
for(var i=0;i<th.length;i++){
    if(th[i].tagName=="TH"){
        th[i].style.position = "absolute";	
	th[i].style.top = '25px';
	th[i].style.width = 103+"px";
	th[i].style.height = 17+"px";
    }
}

	//绑定滚动
if (document.attachEvent) { //IE 中
	
    document.attachEvent('onscroll',function () { 
    var scrollVal = document.getElementById('Document').scrollTop;
    for(var i=0;i<th.length;i++){
     if(th[i].tagName=="TH"){
	th[i].style.position = "absolute";	
	th[i].style.top = scrollVal+'px';
    }
   }   	});
}else {//firefox googleChorme
    doc.addEventListener('scroll', function () { 
    var scrollleft = document.getElementById('Document').scrollLeft;
    var scrolltop = document.getElementById('Document').scrollTop;
    if(scrolltop<25){
		for(var i=0;i<th.length;i++){
		 if(th[i].tagName=="TH"){th[i].style.top = '25px';
	}
	}
}else{for(var i=0;i<th.length;i++){
	if(th[i].tagName=="TH"){
	    th[i].style.top = scrolltop+"px";			
	}}}}, false);}

(控制滚动的核心代码)

ps:表头前端结构:

有的浏览器下,还需要设置div宽度,有个不用设置,什么原因呢,还不知道

ps:

相对定位:该元素相对于自己原有位置,偏移一定距离。相对的是自己。

绝对定位:该元素相对于其父元素,偏移一定距离。相对的是父元素,重点是这个父元素也需要是设置了position属性。从最近的父元素开始找,直到找到body位置为止。

addEventListener的第三个参数

冻结表头的实现1-1  多行固定:

先看效果:

由于客户单是c#嵌入的报表,因此必须支持IE浏览器;

悲剧的是ie 下,对表格的解释和chrome大不相同

1、IE下对tr设置位置属性position,脱离不了table!

2、margin-top也和chrome下的表现不大相同,解决办法:针对不同浏览器,js调整了一下

3、第2行曾经想用tr的left属性设置,结果,在ie下突破表格右边

想到的解决办法?把th下div设置位置属性,结果不显示!(奇怪的是在调试模式下,点击相关dom元素,就显示出来)

我一个前端同事告诉我,利用表格合并!把前面几个单元格合并!

我想:以后ie下,操作表格,优先考虑使用table 的单元格属性!

4、第一行rowspan=2的情况下,th的内容不显示,前端同事怀疑收到第2行的影响,把rowspan="1",问题解决!

代码如下:

<script>


	function lockHeader(){
		 var _doc = document.getElementById('Document');
		var _f=false;
		//alert(_doc.attachEvent)
		if(_doc.attachEvent){
			_f=true;
		}
		//console.log(_f)
	
		var _myTab = document.getElementById('mytab');
		if(!_f){  //chrome browser
			_myTab.style.marginTop="55px"
		}

        var ras=document.getElementById('ra');
		var ths=ras.children;
			//console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1')
			
       var _rb=document.getElementById('rb');
	   var _ths2=_rb.children;
	   

	   	var  _initWidth_r1=new Array();

		for(var i=0;i<ths.length;i++){
			if(ths[i].tagName=="TH"){
				if(_f){
					_initWidth_r1[i]=ths[i].offsetWidth;
				}else{
					_initWidth_r1[i]=ths[i].getBoundingClientRect().width-3;  
				}
				//console.log('22222222222222222222222222222222222222222222222222222222:'+_initWidth_r1[i])
				
					 
			}
		}
	   
	   
		//control second row
		var  _initWidth_r2=new Array();
		var  _initLeft_r2=new Array();
		for(var i=0;i<_ths2.length;i++){
			if(_ths2[i].tagName=="TH"){
				if(_f){
					_initWidth_r2[i]=_ths2[i].offsetWidth;
					_initLeft_r2[i]=_ths2[i].offsetLeft;
				}else{
					_initWidth_r2[i]=_ths2[i].getBoundingClientRect().width-3;  
				}
				//console.log('3333333333333333333333333333333333333:'+_initWidth_r2[i])
			}
		}
		
		
		
		
		if (_f) {
			//IE 中 得对th单元格中div 元素控制位置,所以不能在tr  th 上设置position属性
			document.getElementById('ra').style.position = "absolute";
			document.getElementById('rb').style.position = "absolute"
			 	//上边第一行的样式  如果多行固定,且單元格存在跨列,则要根据实际设置lineHeight
			document.getElementById('ra').style.top = '0px';
			document.getElementById('ra').style.background = '#E3E9F1';
			document.getElementById('rb').style.top = '32px';
			document.getElementById('rb').style.background = '#E3E9F1';
		}else{
			document.getElementById('ra').style.position = "absolute";
			document.getElementById('rb').style.position = "absolute"
			 	//上边第一行的样式  如果多行固定,且單元格存在跨列,则要根据实际设置lineHeight
			document.getElementById('ra').style.top = '0px';
			document.getElementById('ra').style.background = '#E3E9F1';
			document.getElementById('rb').style.top = '32px';
			//document.getElementById('rb').style.background = '#E3E9F1';
		}	
		//console.log("控制第一行...........")	
		//debugger;		

//控制第一行
		var ths=ras.children;
		//console.log("ths..........."+ths.length)
		for(var i=0;i<ths.length;i++){
			if(ths[i].tagName=="TH"){
				if(_f){
				//IE 中 得对th单元格中set rowSpan=0 
					//ths[i].children[0].style.position="absolute"
					//ths[i].children[0].style.top="1px"
					ths[i].rowSpan='1'
				}
				//console.log(_initWidth_r1[i])
				ths[i].children[0].style.width =_initWidth_r1[i]+"px"
                ths[i].children[0].style.height ="58px"				
				ths[i].children[0].style.background="#E3E9F1"

			}
		}
		//console.log("ths[10].style.verticalAlign...........")
		ths[10].style.verticalAlign="text-top";
		ths[11].style.verticalAlign="text-top";
		ths[12].style.verticalAlign="text-top";

//console.log("控制第二行...........")	

	//控制第二行

	
	
		if(!_f){	//对ie而言 这个方法引起整行偏移 偏移出表格了  
			document.getElementById('rb').style.left =ths[10].offsetLeft+"px";
		}else{   //ie
			//document.getElementById('rb').style.left =ths[10].offsetLeft+"px";
			_ths2[0].colSpan="11";
			_ths2[0].style.textAlign="right";
		}
		
		document.getElementById('rb').style.lineHeight = '24px';

		for(var i=0;i<_ths2.length;i++){
			if(_ths2[i].tagName=="TH"){
				if(_f){	//ie
					//_ths2[i].children[0].style.position="absolute";
					//_ths2[i].children[0].style.left=_initLeft_r2[i]+"px"
					//_ths2[i].children[0].style.zIndex=5000

				
				}
            _ths2[i].children[0].style.width =_initWidth_r2[i]+"px"
			}
		}
		
		
		
	//console.log("马上绑定滚动事件...........")	
	//绑定滚动
	if (_doc.attachEvent) { //IE 中
		//console.log("马上绑定滚动事件")
    	_doc.attachEvent('onscroll',function () { 

		    	var scrolltop = document.getElementById('Document').scrollTop;
				//console.log("----scrolltop----"+scrolltop)
				if(scrolltop<25){
					document.getElementById('ra').style.top = "0px";
					document.getElementById('rb').style.top = "32px";
				
				}else{
					//console.log("触发滚动,",scrolltop)
					document.getElementById('ra').style.top = scrolltop+"px";
					document.getElementById('rb').style.top = 32+scrolltop+"px";
			}
		
    	});
	}else {//firefox googleChorme
 
    	_doc.addEventListener('scroll', function () { 
    		var scrollleft = document.getElementById('Document').scrollLeft;
    		var scrolltop = document.getElementById('Document').scrollTop;
			//document.getElementById('ra').style.background-attachment="scroll";
				if(scrolltop<25){
					document.getElementById('ra').style.top = "0px";
					document.getElementById('rb').style.top = "32px";
				
				}else{
					document.getElementById('ra').style.top = scrolltop+"px";
					document.getElementById('rb').style.top = 32+scrolltop+"px";
			}
			
    	}, false);
	}  
} 

</script>

固定表头的实现2(交叉报表固定表头):

先看效果:

思路:

1、固定每个表头的id

     交叉项目的表头,同样设置固定id,办法?上图:

2、取得父元素的宽度,设置到表头上,可惜的是,还得用fixed layout

注意这里的表头,是TH标签中的<div>

document.getElementById(cell[i]).parentNode.clientWidth+'px';

详细代码如下:

<script>
var offsetLeftMoveVal2 = 55;

function lockHeader(){
//上边第一列
cell = ['13','14','15','16','17','一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'];


//固定行的样式
for(i=0;i<cell.length;i++){

	document.getElementById(cell[i]).style.lineHeight = '32px';
	document.getElementById(cell[i]).style.top = '0px';
	document.getElementById(cell[i]).style.background = '#E3E9F1';

	document.getElementById(cell[i]).style.width = 	document.getElementById(cell[i]).parentNode.clientWidth+'px';
	var oBtn = document.getElementById('Document');
	
	if(oBtn.attachEvent){
		document.getElementById(cell[i]).style.backgroundImage =       document.getElementById(cell[i]).parentNode.currentStyle.backgroundImage;
	document.getElementById(cell[i]).style.position = "absolute";
	document.getElementById(cell[i]).style.background = '#E3E9F1';
	var cellObj = document.getElementById(cell[i]);
		var  leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;
		cellObj.style.left = leftVal+'px';
	}else{
		document.getElementById(cell[i]).style.backgroundImage =  document.defaultView.getComputedStyle
(document.getElementById(cell[i]).parentNode, null).backgroundImage;
document.getElementById(cell[i]).style.position = "absolute";
	    }
	}



	var oBtn = document.getElementById('Document');

if (oBtn.attachEvent) { //IE 中
    oBtn.attachEvent('onscroll',function () { 
        var scrolltop = document.getElementById('Document').scrollTop;
		
		
	
		//上边第一行
		for(i=0;i<cell.length;i++){
		
				document.getElementById(cell[i]).style.top = scrolltop+"px";
				document.getElementById(cell[i]).style.background = '#E3E9F1';	
			}
    
    });
}else {//firefox googleChorme
    oBtn.addEventListener('scroll', function () {
    	   var scrolltop = document.getElementById('Document').scrollTop;
	
		
		//上边第一行
		for(i=0;i<cell.length;i++){
		
				document.getElementById(cell[i]).style.top = scrolltop+"px";
				document.getElementById(cell[i]).style.background = '#E3E9F1';	
			}
      //上边第二行
	
    }, false);
    }

}

</script>

问题:这里我是知道动态列就是月份名称的,还有不知道动态的怎么办,看固定表头的实现3(交叉报表固定表头2)

固定表头的实现3(交叉报表固定表头2):

先看完成的效果:

解决的思路: 

1 设法防取得取得动态的列名

2 web 页面渲染的时候,动态改变每个列的width 等样式

<script>

function lockHeader()
{
	//动态适配数组,'placeHolder' 会被替换为'甲银行',‘乙银行’,....  
	var _DynAdapters = ['placeHolder'];
	console.log("_DynAdapters"+_DynAdapters.length)
	console.log("_DynAdapters o"+_DynAdapters)
	//存放的交叉表动态列头
	var _DynamicColHeaders = new Array();
	//构造上边第二列的id
	var a=0;
	for(i=0;i<_DynAdapters.length;i++)
	{
		_DynamicColHeaders[a] = _DynAdapters[i];
		a++;
	}
	var oBtn = document.getElementById('Document');
	var _FixedColHeaders = ['1','2','3','4','5','6'];
	var cellObiOne = document.getElementById(_FixedColHeaders[0]);
	var leftOne = "";
	var k = 0;
	//左边的固定列
	for(i=0;i<_FixedColHeaders.length;i++)
	{
	    var _fixColHeader=document.getElementById(_FixedColHeaders[i]);
		if(oBtn.attachEvent)
		{	
			_fixColHeader.style.lineHeight = '28px';
			_fixColHeader.style.top = '0px';
			_fixColHeader.style.width = _fixColHeader.parentNode.clientWidth+'px';
			_fixColHeader.style.backgroundImage =       		_fixColHeader.parentNode.currentStyle.backgroundImage;
			_fixColHeader.style.position = "absolute";
			var cellObj = _fixColHeader;
			var leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;	
			if(k == 0)
			{
				leftOne = cellObiOne.offsetLeft-offsetLeftMoveVal2;
				k++;
			}
			cellObj.style.left = leftVal - leftOne +'px';
		}
		else
		{
			_fixColHeader.style.width=_fixColHeader.parentNode.clientWidth+'px';
			_fixColHeader.style.backgroundImage =		document.defaultView.getComputedStyle(_fixColHeader.parentNode, null).backgroundImage;
			_fixColHeader.style.position = "absolute";
		}
	}
				
	//右边边的动态列
	for(i=0;i<_DynamicColHeaders.length;i++)
	{
		var colHeader=document.getElementById(_DynamicColHeaders[i]);
		if(oBtn.attachEvent)
		{
			colHeader.style.lineHeight = '28px';
			colHeader.style.top = '0px';
			colHeader.style.width = colHeader.parentNode.clientWidth+'px';
			colHeader.style.backgroundImage =       		colHeader.parentNode.currentStyle.backgroundImage;
			colHeader.style.position = "absolute";
			//document.getElementById(_DynamicColHeaders[i]).style.overflow = "hidden";		
			var cellObjTwo =colHeader;
			var leftValTwo=cellObjTwo.offsetLeft-offsetLeftMoveVal2;
			cellObjTwo.style.left = leftValTwo - leftOne +'px';
		}
		else
		{
			colHeader.style.backgroundImage =		document.defaultView.getComputedStyle(colHeader.parentNode, null).backgroundImage;
			colHeader.style.width = colHeader.parentNode.clientWidth+'px';
			colHeader.style.position = "absolute";
		}
	}

	if (oBtn.attachEvent) //IE 中
	{ 
		oBtn.attachEvent('onscroll', function () 
		{

			var scrolltop = document.getElementById('Document').scrollTop;
						
			//上边第一行
			for(i=0;i<_FixedColHeaders.length;i++)
			{
				if(scrolltop<25)
				{
					document.getElementById(_FixedColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
				
			//后边的动态列
			for(i=0;i<_DynamicColHeaders.length;i++)
			{
				if(scrolltop<25)
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
		});
	}
	else //firefox googleChorme
	{
		oBtn.addEventListener('scroll', function () 
		{
			var scrolltop = document.getElementById('Document').scrollTop;
			_FixedColHeaders = ['1','2','3','4','5','6'];
			//左边前六列
			for(i=0;i<_FixedColHeaders.length;i++)
			{
				document.getElementById(_FixedColHeaders[i]).style.position = "absolute";
				if(scrolltop<25)
				{
					document.getElementById(_FixedColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
			//后边的动态列
			for(i=0;i<_DynamicColHeaders.length;i++)
			{
				document.getElementById(_DynamicColHeaders[i]).style.position = "absolute";
				if(scrolltop<25)
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
		}, false);

	}

}

</script>

(web 页面渲染的时候,动态改变每个列的width 等样式) 

如何在渲染页面前取得交叉列头的数据:

首先当然是取得数据,然后把取得数据转换为js的数组!

(通过计算列 获取数据?这个办法也许不是最优?完全可在设计器当中做个数据集(dataset)啊!

在脚本的块当中,通过形式上的变换,把脚本块转换为数组的办法:

1、在脚本块当中,写入 var _DynAdapters = ['placeHolder'];

2、在脚本oncreate中,进行替换

if(row["RlineOne"] != null && row["RlineOne"] != "")
{
    this.text = this.text.replace("placeHolder",row["RlineOne"]);
}

截图说明:

这里还有个问题,有点动态列显示的字比较多,换行了,我想到的解决思路是:

1、调整列头的行高,配套的,要修改背景颜色等 我们用了图片,以后还是用颜色吧,这样性能会好一点?

2、把margin top设置大一点,免得覆盖下面的数据?

3、不解决,这里,我就暂时不解决这个问题吧

如何认识row["RlineOne"],textArea 设置数据源啊,把这个数据源设置成包含row的dataset就好了

操作步骤总结:

  1. 通过数据集设法获取动态列的数据
  2. 引入textArea,其类型属性设置为html 类型,写oncreate事件,写textcont脚本
  3. 写脚本的时候,注意区分固定列和动态列,独立列要根据实际情况处理

这里根据上述步骤,写一个完整的例子:

通过数据集设法获取动态列的数据:

数据集结果预览一下:

引入text,

设置相关属性后,写2段脚本:

<script>
 
function lockHeader()
{
	//动态适配数组,'placeHolder' 会被替换为'甲银行',‘乙银行’,....  
	var _DynAdapters = ["placeHolder"];
	console.log("_DynAdapters"+_DynAdapters.length)
	console.log("_DynAdapters o"+_DynAdapters)
	//存放的交叉表动态列头
	var _DynamicColHeaders = new Array();
	//构造上边第二列的id
	var a=0;
	for(i=0;i<_DynAdapters.length;i++)
	{
		_DynamicColHeaders[a] = _DynAdapters[i];
		a++;
	}
	var oBtn = document.getElementById('Document');
	var _FixedColHeaders = ['1','2','3','4','5'];
	var cellObiOne = document.getElementById(_FixedColHeaders[0]);
	var leftOne = "";
	var k = 0;
	//左边的固定列
	for(i=0;i<_FixedColHeaders.length;i++)
	{
	    var _fixColHeader=document.getElementById(_FixedColHeaders[i]);
		if(oBtn.attachEvent)
		{	
			_fixColHeader.style.lineHeight = '28px';
			_fixColHeader.style.top = '0px';
			_fixColHeader.style.width = _fixColHeader.parentNode.clientWidth+'px';
			_fixColHeader.style.backgroundImage =       		_fixColHeader.parentNode.currentStyle.backgroundImage;
			_fixColHeader.style.position = "absolute";
			var cellObj = _fixColHeader;
			var leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;	
			if(k == 0)
			{
				leftOne = cellObiOne.offsetLeft-offsetLeftMoveVal2;
				k++;
			}
			cellObj.style.left = leftVal - leftOne +'px';
		}
		else
		{
			_fixColHeader.style.width=_fixColHeader.parentNode.clientWidth+'px';
			_fixColHeader.style.backgroundImage =		document.defaultView.getComputedStyle(_fixColHeader.parentNode, null).backgroundImage;
			_fixColHeader.style.position = "absolute";
		}
	}
				
	//右边边的动态列
	for(i=0;i<_DynamicColHeaders.length;i++)
	{
		var colHeader=document.getElementById(_DynamicColHeaders[i]);
		if(colHeader==undefined)  continue;
		if(colHeader==null)  continue;
		if(oBtn.attachEvent)
		{
			colHeader.style.lineHeight = '28px';
			colHeader.style.top = '0px';
			colHeader.style.width = colHeader.parentNode.clientWidth+'px';
			colHeader.style.backgroundImage =       		colHeader.parentNode.currentStyle.backgroundImage;
			colHeader.style.position = "absolute";
			//document.getElementById(_DynamicColHeaders[i]).style.overflow = "hidden";		
			var cellObjTwo =colHeader;
			var leftValTwo=cellObjTwo.offsetLeft-offsetLeftMoveVal2;
			cellObjTwo.style.left = leftValTwo - leftOne +'px';
		}
		else
		{
			colHeader.style.backgroundImage =		document.defaultView.getComputedStyle(colHeader.parentNode, null).backgroundImage;
			colHeader.style.width = colHeader.parentNode.clientWidth+'px';
			colHeader.style.position = "absolute";
		}
	}
 
	if (oBtn.attachEvent) //IE 中
	{ 
		oBtn.attachEvent('onscroll', function () 
		{
 
			var scrolltop = document.getElementById('Document').scrollTop;
						
			//上边第一行
			for(i=0;i<_FixedColHeaders.length;i++)
			{
				if(scrolltop<25)
				{
					document.getElementById(_FixedColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
				
			//后边的动态列
			for(i=0;i<_DynamicColHeaders.length;i++)
			{
				var _colHeader=document.getElementById(_DynamicColHeaders[i]);
			   	if(_colHeader==undefined)  continue;
		        if(_colHeader==null)  continue;
			
				if(scrolltop<25)
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
		});
	}
	else //firefox googleChorme
	{
		oBtn.addEventListener('scroll', function () 
		{
			var scrolltop = document.getElementById('Document').scrollTop;
			//_FixedColHeaders = ['1','2','3','4','5'];
			//左边前六列
			for(i=0;i<_FixedColHeaders.length;i++)
			{
			    //console.log('t=====',document.getElementById(_FixedColHeaders[i]))
				document.getElementById(_FixedColHeaders[i]).style.position = "absolute";
				if(scrolltop<25)
				{
					document.getElementById(_FixedColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
			//后边的动态列
			for(i=0;i<_DynamicColHeaders.length;i++)
			{
				var _colHeader=document.getElementById(_DynamicColHeaders[i]);
			   	if(_colHeader==undefined)  continue;
		        if(_colHeader==null)  continue;
				document.getElementById(_DynamicColHeaders[i]).style.position = "absolute";
				if(scrolltop<25)
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = "0px";	
				}
				else
				{
					document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";	
				}
			}
		}, false);
 
	}
 
}
 
</script>

 

 ps:上面代码写个比较粗糙,需要进一步整理。

lockheader()函数?完全可以不用函数吧,代码可以直接执行

全局函数中,有如下内容

结表头的实现4:交叉列表的表头冻结---多层交叉表 

   这种情况,把表头区分为固定区,固定区,固定区表头按固定区的方式处理

   动态区表头,需要分行处理

内容固定的表头,处理方式同前。

交叉表头,首先要给交叉表头动态赋予id,方便后边识别

不多说直接上图与代码:

(第一层表头绑定)

(第2层表头绑定id)

代码部分:

function lockHeader(){

//固定行  最好改为二维数组?
_fixedCells = ['c','d','g','h'];
//上边第一列
_cells_inRow1 = ['1','2','3'];
//上边第二列
cellTwo = ['1','2','3','4','5','6','7'];

_cells_inRow2 = new Array();
//构造左边第二列的id
var a = 0;

//构造上边第二列的id
a=0;
for(i=0;i<_cells_inRow1.length;i++){
 for(j=0;j<cellTwo.length;j++){
	_cells_inRow2[a] = _cells_inRow1[i]+cellTwo[j];
 	a++;
 }
}

//固定行的样式
for(i=0;i<_fixedCells.length;i++){
    if(i<2){  //fixed cell in row1 
	document.getElementById(_fixedCells[i]).style.lineHeight = '28px';
	document.getElementById(_fixedCells[i]).style.top = '0px';
	document.getElementById(_fixedCells[i]).style.width = 	document.getElementById(_fixedCells[i]).parentNode.clientWidth+'px';  //th
	var _doc = document.getElementById('Document');
	if(_doc.attachEvent){   //区别浏览器  ie
		document.getElementById(_fixedCells[i]).style.backgroundImage =       document.getElementById(_fixedCells[i]).parentNode.currentStyle.backgroundImage;
		document.getElementById(_fixedCells[i]).style.position = "absolute";
		//document.getElementById(_fixedCells[i]).style.background = '#E3E9F1';
		var cellObj = document.getElementById(_fixedCells[i]);
		//为什么要加修正值
		//var  leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;  
		//var  leftVal=cellObj.offsetLeft; 
		//cellObj.style.left = leftVal+'px';
		//取得父元素左边
		//cellObj.style.left =cellObj.parentNode.style.left+"px";
		//console.log(cellObj.parentNode.offsetLeft);
		//console.log(cellObj.offsetLeft);
		cellObj.style.left=cellObj.parentNode.offsetLeft+"px"
	}else{  //chromel
		document.getElementById(_fixedCells[i]).style.backgroundImage =  document.defaultView.getComputedStyle
		(document.getElementById(_fixedCells[i]).parentNode, null).backgroundImage;
		document.getElementById(_fixedCells[i]).style.position = "absolute";
	    }
	}else{	//row2
	document.getElementById(_fixedCells[i]).style.lineHeight = '28px';
	document.getElementById(_fixedCells[i]).style.top = '28px';
	document.getElementById(_fixedCells[i]).style.width = 	document.getElementById(_fixedCells[i]).parentNode.clientWidth+'px';
	
	if(_doc.attachEvent){  //ie
		document.getElementById(_fixedCells[i]).style.backgroundImage =  document.getElementById(_fixedCells[i]).parentNode.currentStyle.backgroundImage;
		document.getElementById(_fixedCells[i]).style.position = "absolute";
		//document.getElementById(_fixedCells[i]).style.background = '#E3E9F1';
		var cellObj = document.getElementById(_fixedCells[i]);
		//var  leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;
		//var  leftVal=cellObj.offsetLeft;
		//cellObj.style.left = leftVal+'px';
				//取得父元素左边
		//cellObj.style.left =cellObj.parentNode.style.left+"px";
		//console.log(cellObj.parentNode.offsetLeft);
		//console.log(cellObj.offsetLeft);
		cellObj.style.left=cellObj.parentNode.offsetLeft+"px"
	}else{
		document.getElementById(_fixedCells[i]).style.backgroundImage =  document.defaultView.getComputedStyle
			(document.getElementById(_fixedCells[i]).parentNode, null).backgroundImage;
		document.getElementById(_fixedCells[i]).style.position = "absolute";
	}
}
}
//上边第一行(动态部分)的样式
for(i=0;i<_cells_inRow1.length;i++){
	document.getElementById(_cells_inRow1[i]).style.lineHeight = '28px';
	document.getElementById(_cells_inRow1[i]).style.top = '0px';
	document.getElementById(_cells_inRow1[i]).style.width = 	document.getElementById(_cells_inRow1[i]).parentNode.clientWidth
	+'px';
	
	if(_doc.attachEvent){   //ie
		document.getElementById(_cells_inRow1[i]).style.backgroundImage =  document.getElementById(_cells_inRow1[i]).parentNode.currentStyle.backgroundImage;
		document.getElementById(_cells_inRow1[i]).style.position = "absolute";
		var cellOneObj= document.getElementById(_cells_inRow1[i]);
		cellOneObj.style.left=cellOneObj.parentNode.offsetLeft+"px"
	}else{  //chrome
		document.getElementById(_cells_inRow1[i]).style.backgroundImage =  document.defaultView.getComputedStyle(document.getElementById(_cells_inRow1[i]).parentNode, null).backgroundImage;
		document.getElementById(_cells_inRow1[i]).style.position = "absolute";
	}
}

//上边第二行的样式
for(i=0;i<_cells_inRow2.length;i++){
	if(document.getElementById(_cells_inRow2[i])){
		document.getElementById(_cells_inRow2[i]).style.lineHeight = '28px';
		document.getElementById(_cells_inRow2[i]).style.top = '28px';
 		document.getElementById(_cells_inRow2[i]).style.width = 	document.getElementById(_cells_inRow2
		[i]).parentNode.clientWidth+'px';
		if(_doc.attachEvent){	//IE
			document.getElementById(_cells_inRow2[i]).style.backgroundImage =  document.getElementById(_cells_inRow2[i]).parentNode.currentStyle.backgroundImage;
			document.getElementById(_cells_inRow2[i]).style.position = "absolute";
			var cellTwoObj = document.getElementById(_cells_inRow2[i]);
			cellTwoObj.style.left=cellTwoObj.parentNode.offsetLeft+"px"
		}else{
			document.getElementById(_cells_inRow2[i]).style.backgroundImage =  document.defaultView.getComputedStyle(document.getElementById(_cells_inRow2[i]).parentNode, null).backgroundImage;
			document.getElementById(_cells_inRow2[i]).style.position = "absolute";
		}
	}
}
	var _doc = document.getElementById('Document');

if (_doc.attachEvent){ //IE 中
    _doc.attachEvent('onscroll',function(){ 
        var scrolltop = document.getElementById('Document').scrollTop;
		//固定行样式
		for(i=0;i<_fixedCells.length;i++){
			if(i<2){  //first row
					document.getElementById(_fixedCells[i]).style.top = scrolltop+"px";
			}else{
					if(scrolltop<29){
					document.getElementById(_fixedCells[i]).style.top = 28+"px";
					}else{
					   document.getElementById(_fixedCells[i]).style.top = 28+scrolltop+"px";
					}
			}	
		}
		//上边第一行
		for(i=0;i<_cells_inRow1.length;i++){
				document.getElementById(_cells_inRow1[i]).style.top = scrolltop+"px";	
		}
		
		//动态列头 上边第二行
		for(i=0;i<_cells_inRow2.length;i++){
			if(document.getElementById(_cells_inRow2[i])){
				if(scrolltop<29){
					document.getElementById(_cells_inRow2[i]).style.top = 28+"px";	
				}else{
					document.getElementById(_cells_inRow2[i]).style.top = 28+scrolltop+"px";	
				}
			}
		}
    
    });
}else {//firefox googleChorme
    _doc.addEventListener('scroll', function () {
    	   var scrolltop = document.getElementById('Document').scrollTop;
		//固定行样式
		for(i=0;i<_fixedCells.length;i++){
			if(i<2){
					document.getElementById(_fixedCells[i]).style.top = scrolltop+"px";
			}else{
					if(scrolltop<29){
						document.getElementById(_fixedCells[i]).style.top = 28+"px";
					}else{
					   document.getElementById(_fixedCells[i]).style.top = 28+scrolltop+"px";
					}
			}	
		}
		
		
		//上边第一行
		for(i=0;i<_cells_inRow1.length;i++){
				document.getElementById(_cells_inRow1[i]).style.top = scrolltop+"px";	
		}
      //上边第二行
	  for(i=0;i<_cells_inRow2.length;i++){
			if(document.getElementById(_cells_inRow2[i])){
				if(scrolltop<29){
					document.getElementById(_cells_inRow2[i]).style.top = 28+"px";	
				}else{
					document.getElementById(_cells_inRow2[i]).style.top = 28+scrolltop+"px";	
				}
			}
		}
    }, false);

}
}

ie兼容性处理:

ie下,设置position属性,设置top,发现left 有偏移现象,必须设置left

这里采取取得父元素offsetleft方式,给当前元素赋予left属性,注意,offsetleft没有单位,left属性要单位。

ps:网上查到另外一个方案 没有试:

后面有机会测试一遍;

birt报表合并以及表头锁定功能的实现

其他:

birt报表 交叉报表相关表达式的理解:例如:data["NUM_Group3/BILLNAME_ODR/ODR"]

“_”可以理解为交叉,group3/billname、odr/odr 可以看成维度成员。

下一节:birt系列(2)--拖动表头调整列宽

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值