你的位置:首页 > Java教程

[Java教程]表格实现行、列冻结


客户要求实现对表格数据的头几行或者头几列进行冻结,即滚动时保持这几行/列不动,通过网上查找代码,参考已有的代码的思路,实现了可以任意对行、列进行冻结。 
实现原理: 
创建多个div,div之间通过css实现层叠,每个div放置当前表格的克隆。例如:需要行冻结时,创建存放冻结行表格的div,通过设置z-index属性和position属性,让冻结行表格在数据表格的上层。同理,需要列冻结时,创建存放冻结列表格的div,并放置在数据表格的上层。如果需要行列都冻结时,则除了创建冻结行、冻结列表格的div,还需要创建左上角的固定行列表格的div,并放置在所有div的最上层。 
处理表格的滚动事件,在表格横向或者纵向滚动时,同时让相应的冻结行和冻结列也同步滚动。 
处理html的resize事件,同步修改表格的滚动区域宽度和高度 
代码如下:

 1 /* 2  * 锁定表头和列 3  *  4  * 参数定义 5  *   table - 要锁定的表格元素或者表格ID 6  *   freezeRowNum - 要锁定的前几行行数,如果行不锁定,则设置为0 7  *   freezeColumnNum - 要锁定的前几列列数,如果列不锁定,则设置为0 8  *   width - 表格的滚动区域宽度 9  *   height - 表格的滚动区域高度 10 */ 11 function freezeTable(table, freezeRowNum, freezeColumnNum, width, height) { 12   if (typeof(freezeRowNum) == 'string') 13     freezeRowNum = parseInt(freezeRowNum) 14      15   if (typeof(freezeColumnNum) == 'string') 16     freezeColumnNum = parseInt(freezeColumnNum) 17  18   var tableId; 19   if (typeof(table) == 'string') { 20     tableId = table; 21     table = $('#' + tableId); 22   } else 23     tableId = table.attr('id'); 24      25   var divTableLayout = $("#" + tableId + "_tableLayout"); 26    27   if (divTableLayout.length != 0) { 28     divTableLayout.before(table); 29     divTableLayout.empty(); 30   } else { 31     table.after("<div id='" + tableId + "_tableLayout' style='overflow:hidden;height:" + height + "px; width:" + width + "px;'></div>"); 32      33     divTableLayout = $("#" + tableId + "_tableLayout"); 34   } 35    36   var html = ''; 37   if (freezeRowNum > 0 && freezeColumnNum > 0) 38     html += '<div id="' + tableId + '_tableFix" ></div>'; 39      40   if (freezeRowNum > 0) 41     html += '<div id="' + tableId + '_tableHead" ></div>'; 42      43   if (freezeColumnNum > 0) 44     html += '<div id="' + tableId + '_tableColumn" ></div>'; 45      46   html += '<div id="' + tableId + '_tableData" ></div>'; 47    48    49   $(html).appendTo("#" + tableId + "_tableLayout"); 50    51   var divTableFix = freezeRowNum > 0 && freezeColumnNum > 0 ? $("#" + tableId + "_tableFix") : null; 52   var divTableHead = freezeRowNum > 0 ? $("#" + tableId + "_tableHead") : null; 53   var divTableColumn = freezeColumnNum > 0 ? $("#" + tableId + "_tableColumn") : null; 54   var divTableData = $("#" + tableId + "_tableData"); 55    56   divTableData.append(table); 57    58   if (divTableFix != null) { 59     var tableFixClone = table.clone(true); 60     tableFixClone.attr("id", tableId + "_tableFixClone"); 61     divTableFix.append(tableFixClone); 62   } 63    64   if (divTableHead != null) { 65     var tableHeadClone = table.clone(true); 66     tableHeadClone.attr("id", tableId + "_tableHeadClone"); 67     divTableHead.append(tableHeadClone); 68   } 69    70   if (divTableColumn != null) { 71     var tableColumnClone = table.clone(true); 72     tableColumnClone.attr("id", tableId + "_tableColumnClone"); 73     divTableColumn.append(tableColumnClone); 74   } 75    76   $("#" + tableId + "_tableLayout table").css("margin", "0"); 77    78   if (freezeRowNum > 0) { 79     var HeadHeight = 0; 80     var ignoreRowNum = 0; 81     $("#" + tableId + "_tableHead tr:lt(" + freezeRowNum + ")").each(function () { 82       if (ignoreRowNum > 0) 83         ignoreRowNum--; 84       else { 85         var td = $(this).find('td:first, th:first'); 86         HeadHeight += td.outerHeight(true); 87          88         ignoreRowNum = td.attr('rowSpan'); 89         if (typeof(ignoreRowNum) == 'undefined') 90           ignoreRowNum = 0; 91         else 92           ignoreRowNum = parseInt(ignoreRowNum) - 1; 93       } 94     }); 95     HeadHeight += 2; 96      97     divTableHead.css("height", HeadHeight); 98     divTableFix != null && divTableFix.css("height", HeadHeight); 99   }100   101   if (freezeColumnNum > 0) {102     var ColumnsWidth = 0;103     var ColumnsNumber = 0;104     $("#" + tableId + "_tableColumn tr:eq(" + freezeRowNum + ")").find("td:lt(" + freezeColumnNum + "), th:lt(" + freezeColumnNum + ")").each(function () {105       if (ColumnsNumber >= freezeColumnNum)106         return;107         108       ColumnsWidth += $(this).outerWidth(true);109       110       ColumnsNumber += $(this).attr('colSpan') ? parseInt($(this).attr('colSpan')) : 1;111     });112     ColumnsWidth += 2;113 114     divTableColumn.css("width", ColumnsWidth);115     divTableFix != null && divTableFix.css("width", ColumnsWidth);116   }117   118   divTableData.scroll(function () {119     divTableHead != null && divTableHead.scrollLeft(divTableData.scrollLeft());120     121     divTableColumn != null && divTableColumn.scrollTop(divTableData.scrollTop());122   });123   124   divTableFix != null && divTableFix.css({ "overflow": "hidden", "position": "absolute", "z-index": "50" });125   divTableHead != null && divTableHead.css({ "overflow": "hidden", "width": width - 17, "position": "absolute", "z-index": "45" });126   divTableColumn != null && divTableColumn.css({ "overflow": "hidden", "height": height - 17, "position": "absolute", "z-index": "40" });127   divTableData.css({ "overflow": "scroll", "width": width, "height": height, "position": "absolute" });128   129   divTableFix != null && divTableFix.offset(divTableLayout.offset());130   divTableHead != null && divTableHead.offset(divTableLayout.offset());131   divTableColumn != null && divTableColumn.offset(divTableLayout.offset());132   divTableData.offset(divTableLayout.offset());133 }134 135 /*136  * 调整锁定表的宽度和高度,这个函数在resize事件中调用137  * 138  * 参数定义139  *   table - 要锁定的表格元素或者表格ID140  *   width - 表格的滚动区域宽度141  *   height - 表格的滚动区域高度142 */143 function adjustTableSize(table, width, height) {144   var tableId;145   if (typeof(table) == 'string')146     tableId = table;147   else148     tableId = table.attr('id');149   150   $("#" + tableId + "_tableLayout").width(width).height(height);151   $("#" + tableId + "_tableHead").width(width - 17);152   $("#" + tableId + "_tableColumn").height(height - 17);153   $("#" + tableId + "_tableData").width(width).height(height);154 }155 156 function pageHeight() {157   if ($.browser.msie) {158     return document.compatMode == "CSS1Compat" ? document.documentElement.clientHeight : document.body.clientHeight;159   } else {160     return self.innerHeight;161   }162 };163 164 //返回当前页面宽度165 function pageWidth() {166   if ($.browser.msie) {167     return document.compatMode == "CSS1Compat" ? document.documentElement.clientWidth : document.body.clientWidth;168   } else {169     return self.innerWidth;170   }171 };172 173 $(document).ready(function() {174   var table = $("table");175   var tableId = table.attr('id');176   var freezeRowNum = table.attr('freezeRowNum');177   var freezeColumnNum = table.attr('freezeColumnNum');178   179   if (typeof(freezeRowNum) != 'undefined' || typeof(freezeColumnNum) != 'undefined') {180     freezeTable(table, freezeRowNum || 0, freezeColumnNum || 0, pageWidth(), pageHeight());181     182     var flag = false;183     $(window).resize(function() {184       if (flag) 185         return ;186       187       setTimeout(function() { 188         adjustTableSize(tableId, pageWidth(), pageHeight()); 189         flag = false; 190       }, 100);191       192       flag = true;193     });194   }195 });

使用时,只要在table元素设置freezeRowNum和freezeColumnNum属性值,即可实现冻结效果

<table id="reportTable" width="1900" freezeRowNum="2" freezeColumnNum="2" class="report" align="center">...</table>