一:创建数据库:
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等待:
生成表格示例:
分享到:
相关推荐
Struts2 的使用AJAX动态从数据库获取数据生成树形菜单
Struts2树形结构资料大全
很容易上手的struts2的树形结构,已经有struts2包,直接部署到tomcat目录就可以是使用,地址为:http://localhost:8080/DtreeDemo/,端口改为自己的端口。更详解的解说,请进我的博客:...
可以动态显示,添加新目录有点东西要修改。附带建表SQL,用JDBC+struts2
struts、ibatis、树形结构 组件可以用于参考相应业务的树形表达
Struts1和dTree的结合,显示树形结构,欢迎大家下载,并说出你们的看法,谢谢
struts+hibernate树形菜单
struts实现java树形菜单,用dtree实现
树形菜单、用JS配合Struts1.2、Spring2。0、Ajax2.0的树形菜单,还包括了一个角色的添加,修改,也是相当于一个小的角色分配,希望可以帮到大家!~!
Struts2 实现动态树 结合Hebernate
struts2树的编写,动态输出struts2树
struts2.0+ztree+jquery动态生成树结构,两种方法
struts2+spring+hibernate+生成excel报表
Struts2的验证码生成
利用Struts 2标签创建ex3.jsp页面,此页面提交给tag.action,在structs.xml中配置这个action的转发视图为result.jsp在result.jsp页面中显示ex3.jsp页面控件的值。(源代码和实验报告)
struts2生成图片验证码
本资源为.jsp文件,是struts2中tree标签的一个实例。当初我做这个的时候很希望能弄到个实例,但结果很失望。现在我自己做了这个 希望对需要的人有点帮助和启发。
struts标签写成树形结构。不比dtree差,我看起来画面好比ext的界面。喜爱的朋友过来看看。不强求!!
使用ext2.2 struts2集成生成的一棵树,主要是对struts2返回json数据进行一些处理,树使用ext本身自带的例子
用于生成最新struts2框架文档,介绍非常详细