1.需求提出
在B/S业务系统开发与应用过程中,经常存在大量的数据需要以表格方式呈现,但由于HTML本身的技术限制,在大量数据查询时,因为不能对数据的行、列进行有效的控制,导致数据查询困难、表现形式不直观等问题。
需要有一个方案来实现数据表表头、左侧列的锁定功能,实现Web模式下的数据动态查看。
2.实现原理
由于HTML的表格(TABLE)本身并不能提供类似的功能,要实现数据表表头、左侧列的锁定功能,必须通过人工将HTML表格进行分区,对不同区域的表格数据进行控制,来达到类似的目的。
要实现数据表分区,有两种基本的方法实现,一种是通过在客户端执行脚本来进行控制、一种是直接通过在服务器端进行数据分区来实现。客户端通过脚本控制执行效率存在问题,本方案只从服务器端实现的角度提出解决方案。
对于HTML表格来说,要实现行、列锁定,必须实现的4个分区。各分区的位置及特点如下:
序号 | 分区类型 | 特点 |
1 | 左上角分区 | 固定不动 |
2 | 上分区 | 可横向滚动,上下固定,不显示滚动条 |
3 | 左侧分区 | 可纵向滚动,左右固定,不显示滚动条 |
4 | 中心区 | 可自由滚动,根据需要显示滚动条 |
下面为示意图:
要实现表格的锁定与滚动功能,需要用到HTML中的DIV控件,DIV容器控件有多种内容显示模式,包括自动扩充,剪切、自动处理、显示滚动条。通过对表格分区的定义可知,左上角的区域自动扩充显示(全部显示),上部及左侧的区域使用裁剪模式,主数据区域使用自动处理或显示滚动条模式。
由于数据表为分割在多个不同的DIV中,要实现行、列之间的严格对齐,必须要使用到CSS中的样式控制。在HTML页面显示时,页面呈现的尺寸由多个因素所决定,并根据窗口情况进行动态计算,内部控件、内容及上层控件等样式与属性都可能影响表格的呈现尺寸与位置。而table-layout样式中的fix属性,用来强制当前控件采用指定的固定格式(长、宽)显示,而不受其他参数影响。表格的行列锁定必须使用改参数。
3.实现方法
l 源数据的构造
源数据的来源很多,一般在业务页面处理及报表统计时,都需要构造Table对象,对表格进行数据填充,这类数据一般有1行或多行表头,比较典型的如DataGrid中的表头等。源数据的来源与一般的业务处理类似,此处不再详述。需要主要的是,要实现固定表行、列,必须要指定数据表行的高度及每一列的宽度。
l 数据表的分割与控制实现过程的讲解能否再详细?看得不是很明白
要对源数据表进行分割,首先要指定要固定行与列的数量,依据指定的固定行列数量,对表格的单元格进行重新划分。分别填充到4个新的表格(Table)中。系统自动构造一个两行两列的容器表格,将4个分割的表格通过Panel(DIV)包装后,分别放置在单元格中。
需要注意的是,一般在表格中,只是对表头的宽度进行了指定,要实现表格高宽的绝对定义,需要对拆分后的4个表格的表头行的宽度执行手工指定。由于表头可能存在跨行、跨列的情况,直接指定并不能覆盖到所有的行、列。这里的技巧是,在每个表格的表头增加一行,根据表格位置批量增加高度为0,宽度为指定宽度的单元格,这样每个表格的宽度就可以固定了;而高度的固定,可以通过样式直接指定。
整个处理过程示意图如下:
源表格 |
切块分区 |
目标表格 |
DIV |
l 客户端控制
表格呈现在客户端浏览器时,默认情况下,上部区域显示左侧内容、左侧区域显示上部分类型,中心区域显示左上部分内容,要浏览其他内容,需要进行表格滚动条拖动,由于在中心区域有滚动条,只需要实现左侧区域与上部区域的联动即可,实现很简单,注册中西区域的onscroll拖动事件,代码如下:
上部区域实现与主区域横向滚动位置的联动 document.all.topPanel.scrollLeft=this.scrollLeft; 左侧区域实现与主区域纵向滚动位置的联动 document.all.leftPanel.scrollTop=this.scrollTop;" |
l 辅助功能实现
辅助功能包括:
1. 全屏显示,根据客户端浏览器的宽度与高度,自动计算并配置表格各区域的宽度、高度,实现全屏显示。基本原理为:
上部与中心区域DIV宽度=窗口客户区宽度-页面宽度+当前DIV宽度
左侧与中心区域DIV高度=窗口客户区高度-页面高度+当前DIV高度
也可以在窗口尺寸变化时,响应window的onsize事件来动态调整表格的高、宽度。
2. 类 Excel虚拟列
Excel中,处理数据区域外,还有大量无数据的行、列,这些行、列的存在为数据的对比提供了方便。为了实现Web下的数据表格对比,如:将最后一列数据移动紧靠左侧数据区,可以在上部及中心区域的表格中增加一列空白列,并指定合适的宽度,这样滚动条在最右侧时,最后一列数据能紧靠左侧数据列,便于数据查看。
3. 表格行选中
与一般的表格行选中有所区别,在此功能所呈现的表格中,数据的一行包含在两个表格中,所以需要在用户鼠标选择一行时,需要同时手动选择对应表格的同一行,使用JS脚本较容易实现。
最终显示效果