一:创建数据库:
create database InterViewTest1
use InterViewTeat1;
create table Category
(
id int(10) auto_increment,
name varchar(50),
code varchar(50),
parentCode varchar(50),
serNum int,--排序号
primary key(id)
)ENGINE=INNODB DEFAULT CHARSET=gbk;
关于示例数据请看附件的sql文件
二:核心算法
本算法主要是利用递归实现把树形结构的每条从根节点到叶子节点的路径放到一个二维String数组中,当有些路径的元素个数不能达到最大深度的时候,此路径元素个数与最多元素个数相差num,那么这个位置就用c_num填补。
private String rootName;
private int height;//树的深度
private int width;//树的叶子个数
private String[][] array=null;
private CategoryService cs=null;
public CategoryOp(String rootName){
this.rootName=rootName;
}
private void getAllNode(List<String> list,Category[] c){
if(c!=null){
for(int i=0;i<c.length;i++){
list.add(c[i].getName());
if(c[i].getChildCategory().length!=0){
getAllNode(list,c[i].getChildCategory());
}else{
int k=0;
for(String str:list){
array[this.width][k]=str;
k++;
}
for(int j=k;j<this.height;j++){
array[this.width][j] ="c_"+ (this.height+1-k);
}
this.width++;
}
list.remove(list.size()-1);
}
}
}
private void getNum(List<String> list,Category[] c){
if(c!=null){
for(int i=0;i<c.length;i++){
list.add(c[i].getName());
if(c[i].getChildCategory().length!=0){
getNum(list,c[i].getChildCategory());
}else{
if(this.height<list.size()){
this.height=list.size();
}
this.width++;
}
list.remove(list.size()-1);
}
}
}
public String getWidthAndHeight(){
cs=new CategoryService(this.rootName);
Category[] category=cs.getAllCategory();
this.width=0;
this.height=0;
List<String> list=new ArrayList<String>();
this.getNum(list, category);
return this.height+","+this.width;
}
public String[][] initArray(){
this.array=null;
this.width=0;
this.height=0;
this.getWidthAndHeight();
array=new String[this.width][this.height];
cs = new CategoryService(this.rootName);
Category[] c = cs.getAllCategory();
// this.height = 0;
this.width = 0;
List<String> list = new ArrayList<String>();
this.getAllNode(list, c);
return array;
}
public String getTable(){
this.initArray();
int w=this.width;
int h=this.height;
int num=0;
for(int i=0;i<w;i++){//这是为了合并表头
for(int j=0;j<h;j++){
if(array[i][j].startsWith("c_")){
String temp=array[i][j].substring(2);
if(this.isNumeric(temp)!=-1&&this.isNumeric(temp)>num){
num=this.isNumeric(temp);
}
}
}
}
StringBuilder sb=new StringBuilder();
sb.append("<table id=\"data\" border=\"1\" style=\"float\">");
sb.append("<tr>");
sb.append("<td align=\"center\">项目</td>");
sb.append("<td colspan=\""+num+1+"\" align=\"center\">科目</td>");
sb.append("</tr>");
for(int i=0;i<w;i++){
sb.append("<tr>");
for(int j=0;j<h;j++){
if (j < h - 1 && array[i][j + 1].startsWith("c_"))
{
String tmp = array[i][j + 1].substring(2);
sb.append("<td align='center' colspan='" + (this.isNumeric(tmp) + 1) + "'>" + array[i][j] + "</td>");
break;
}
else
{
sb.append("<td align='center' >" + array[i][j] + "</td>");
}
}
sb.append("</tr>");
}
sb.append("</table>");
return sb.toString();
}
三:应用jquery实现每列相同文本的单元格合并:
function _w_table_lefttitle_rowspan(_w_table_id,_w_table_mincolnum,_w_table_maxcolnum){
if(_w_table_mincolnum == void 0){_w_table_mincolnum=1;}
if(_w_table_maxcolnum == void 0){_w_table_maxcolnum=_w_table_mincolnum;}
if(_w_table_mincolnum>_w_table_maxcolnum){
return "";
}else{
var _w_table_splitrow=new Array();
for(iLoop=_w_table_mincolnum;iLoop<=_w_table_maxcolnum;iLoop++){
_w_table_onerowspan(iLoop);
}
}
function _w_table_onerowspan(_w_table_colnum){
_w_table_firstrow = 0;//前一列合并区块第一行
_w_table_SpanNum = 0;//合并单元格时的,单元格Span个数
_w_table_splitNum = 0;//数组的_w_table_splitrow的当前元素下标
_w_table_Obj = $(_w_table_id + " tr td:nth-child(" + _w_table_colnum + ")");
_w_table_curcol_rownum = _w_table_Obj.length-1;//此列最后一行行数
if(_w_table_splitrow.length==0){_w_table_splitrow[0] = _w_table_curcol_rownum;}
_w_table_lastrow = _w_table_splitrow[0];//前一列合并区块最后一行
var _w_table_firsttd;
var _w_table_currenttd;
var _w_table_curcol_splitrow=new Array();
_w_table_Obj.each(function(i){
if(i==_w_table_firstrow){
_w_table_firsttd = $(this);
_w_table_SpanNum = 1;
}else{
_w_table_currenttd = $(this);
if(_w_table_firsttd.text()==_w_table_currenttd.text()){
_w_table_SpanNum++;
_w_table_currenttd.hide(); //remove();
_w_table_firsttd.attr("rowSpan",_w_table_SpanNum);
}else{
_w_table_firsttd = $(this);
_w_table_SpanNum = 1;
setTableRow(i-1);
}
if(i==_w_table_lastrow){setTableRow(i);}
}
function setTableRow(_splitrownum){
if(_w_table_lastrow<=_splitrownum&&_w_table_splitNum++<_w_table_splitrow.length){
//_w_table_firstrow=_w_table_lastrow+1;
_w_table_lastrow=_w_table_splitrow[_w_table_splitNum];
}
_w_table_curcol_splitrow[_w_table_curcol_splitrow.length]=_splitrownum;
if(i<_w_table_curcol_rownum){_w_table_firstrow=_splitrownum+1;}
}
_w_table_splitrow=_w_table_curcol_splitrow;
});
}
}
三:为了增加适用性,我用了jquery的ajax效果
function btnCreate(){
$("#ajax").html("<img src=\"images/spinner3-greenie.gif\"/>");
$.ajax({
type:"post",
url:"create.action",
data:"",
complete:function(){},
success:function(data){
$("#ajax").html(data);
_w_table_lefttitle_rowspan("#data",1,90);
}
});
}
四:显示效果:
数据库数据存储:
jquery等待:
生成表格示例:
分享到:
相关推荐
Struts 2 标签库(文档手册) Tags-API-CLSW-JSP <%@ taglib prefix="s" uri="/struts-tags" %> 就能使用struts2.0的标签库 下面就介绍每个标签的具体应用实例说明:按字母排列 ...treenode标签:生成树形结构的节点。
在实际应用中,TableTree4J 可能会与Spring MVC、Struts2等Web框架集成,通过后台数据库查询数据,然后通过Ajax技术将数据传递到前端,渲染成树形结构。开发者可以通过配置文件或代码来设定树的初始状态,以及决定...
`<s:tree>`标签用于生成树形结构,适用于层次数据的展示。 `<s:treenode>`定义树结构中的节点。 T. `<s:updownselect>`,`<s:url>`: `<s:updownselect>`创建一个多选下拉框,支持上下选择选项。 `<s:url>`用于创建...
3. **数据展示标签**:用于展示数据,如表格、树形结构等。 4. **条件逻辑标签**:提供条件判断等功能。 5. **国际化标签**:支持多语言应用开发。 6. **辅助标签**:包括调试、数据操作等辅助功能。 #### 详细标签...
`<s:token>` 用于防止重复提交,`<s:tree>` 创建树形结构,`<s:treenode>` 定义树节点,`<s:updownselect>` 创建可上下选择的多选框,`<s:url>` 生成URL,通常与Action关联。 以上就是Struts标签的基本介绍,它们极...
Struts2框架是Java Web开发中的一个重要组成部分,它极大地简化了Web应用程序的开发过程。在Struts2中,标签库(Tag Library)扮演着非常重要的角色,它们为开发者提供了丰富的功能,帮助快速构建动态网页。下面将...
Struts 2 是一个基于 Java 的开源 Web 应用框架,它继承了 Struts 1 的优点,并在灵活性、易用性以及功能扩展方面进行了大量的改进。其中一个重要特性是其丰富的标签库,这些标签能够帮助开发者快速构建动态的网页,...
- **DOM**:将XML文档转换成内存中的树形结构,适合小文档。 - **SAX**:基于事件驱动模型的解析器,适用于大文档。 - **StAX**:流式API,提供了一种更高效的解析XML文档的方法。 #### 21. Serializable是什么意思...
- **DOM(Document Object Model)**:将XML文档加载到内存中,并以树形结构呈现,适合处理较小的XML文档。 - **SAX(Simple API for XML)**:基于事件驱动的模型,适合处理大型文档,因为它不把整个文档加载到内存...
3、interpolation:由 ${var} 或 #{var} 限定,由计算值代替输出。 4、FTL标记 二.表达式 1、直接指定值: 1-1、字符串: 由双引号或单引号括起来的字符串,其中的特殊字符(如' " \等)需要转义。 1-2、raw...