对同一个单元格 不能进行合并,合并前要进行检查
合并前进行了哪些检查呢? 开始行 ==结束行 && 开始列==结束列
data_mode:是否显示某个位置上的单元格
stuct_mode:单元格跨行、列数字
mergercells:合并单元格的坐标数组
合并单元格的处理:
1、确定选择的单元范围(四个角的坐标)
2、把选择范围内的单元格,设置需要隐藏的单元格相关属性,如span属性都设置为0;
当然最重要的时候设置选择范围内左上角单元格相关属性;
3、把新的合并单元格加入mergeCellArray数组,当然 数组中重复的合并单元格必须去掉!
后端保存合并单元格的数据库:
各个动作对合并单元格数据的影响:
追加行、追加列队合并单元格无影响。
插入行 考虑内部和外部影响:
- 外部影响是指合并单元格在插入行以下的时候,这时,只用修正mergercells中当中,纵向坐标的情况。data_mode、data_mode不用动。
- 内部影响:修正stuct_mode跨行数,mergercells相关元素坐标;
- datamode :本来就插入的的一行,凡是合并单元格范围内跨列了的,值==0就好了.
外部影响是指合并单元格在插入行以下的时候,这时,只用修正mergercells中当中,纵向坐标的情况。data_mode、data_mode不用动:
let lowerPart=this.getMergeCellAtLower_2(p);
var arr_l = Object.keys(lowerPart[0]);
if(arr_l.length > 0) {
lowerPart[0].forEach((item, index) => {
let _position=lowerPart[1][index];
let t = this.state.mergeCellArray[_position];
t = [t[0] + 1, t[1], t[2] + 1, t[3]];
this.state.mergeCellArray[_position]=t;
});
}
内部影响:
if(arr.length > 0){
r[0].forEach((item, index) => {
let _position=lowerPart[1][index];
let t = this.state.mergeCellArray[_position];
//修正struct_mode
let c=table_model.struct_model[t[0]][t[1]];
table_model.struct_model[t[0]][t[1]][0]=c[0]+1;
t = [t[0], t[1], t[2] + 1, t[3]];
this.state.mergeCellArray[_position]=t;
});
}
- 3、data mode:插入一行数据,根据mergcell中,每个合并单元格列的数据,进行处理:
//插入行
doWithInsertRow=(table_model,p)=>{
let r=this.getMergeCell_2(p);
let lowerPart=this.getMergeCellAtLower_2(p);
var arr = Object.keys(r[0]);
var arr_l = Object.keys(lowerPart[0]);
if(arr_l.length > 0) {
lowerPart[0].forEach((item, index) => {
let _position=lowerPart[1][index];
let t = this.state.mergeCellArray[_position];
t = [t[0] + 1, t[1], t[2] + 1, t[3]];
this.state.mergeCellArray[_position]=t;
});
}
if(arr.length > 0){
r[0].forEach((item, index) => {
let _position=r[1][index];
let t = this.state.mergeCellArray[_position];
//修正struct_mode
let c=table_model.struct_model[t[0]][t[1]];
table_model.struct_model[t[0]][t[1]][0]=c[0]+1;
t = [t[0], t[1], t[2] + 1, t[3]];
this.state.mergeCellArray[_position]=t;
});
}
//插入行
// let newRow=table_model.data_model[0];
// let newRowData = [...newRow];
let _row_struct_model=table_model.struct_model[p]; //当前行的struct_mode
let _row_data_model=table_model.data_model[p];
r[0].forEach((item, index) => {
let _beginCol=item[1];
let _endCol=item[3];
for (let i = _beginCol; i <=_endCol; i++) {
_row_data_model[i]=0;
_row_struct_model[i]=[0,0];
}
});
}
删除行的完整代码:
//处理删除行的情况(合并单元格)
doWithDelRow=(p,table_model)=>{
let r=this.getMergeCell(p);
let lowerPart=this.getMergeCellAtLower(p);
var arr = Object.keys(r[0]);
var arr_l = Object.keys(lowerPart[0]);
//alert(arr.length == 0);//true 即为空对象
if(arr_l.length > 0) {
lowerPart[0].forEach((item, index) => {
let _position=lowerPart[1][index];
let t = this.state.mergeCellArray[_position];
t = [t[0] - 1, t[1], t[2] - 1, t[3]];
this.state.mergeCellArray[_position]=t;
});
}
if(arr.length > 0){
r[0].forEach((item, index)=>{
let y=item[0];
let x=item[1];
let c=table_model.struct_model[y][x];
if(item[0]==p){ //第一行
if(item[0]==item[2]){ //就一行数据
//struct_model、data_model、mergeCellArray[index]会被删除
// this.state.mergeCellArray=
// this.state.mergeCellArray.filter((element)=>{
// if(element[0]==item[0] && element[1]==item[1]&& element[2]==item[2]&& element[3]==item[3]){
// return false; //需要过滤吊顶
// }else{
// return true;
// }
// });//过滤好像不改变原来的数组
//标记一下 后面对这类数据进行删除
let _position=r[1][index];
this.state.mergeCellArray[_position]=[0,0,0,0];
}else{
table_model.struct_model[y+1][x][0]=c[0]-1;
table_model.struct_model[y+1][x][1]=c[1];
table_model.data_model[y+1][x]=1;
// 调整设计的mergecells中相应合并区记录的数据 首先是找到这个记录
let _position=r[1][index];
let t=this.state.mergeCellArray[_position];
t=[t[0],t[1],t[2]-1,t[3]];
this.state.mergeCellArray[_position]=t;
}
}else if(item[2]>=p){ //最后一行
table_model.struct_model[y][x][0]=c[0]-1;
// 调整设计的mergecells中相应合并区记录的数据 首先是找到这个记录
let _position=r[1][index];
let t=this.state.mergeCellArray[_position];
this.state.mergeCellArray[_position]=[t[0],t[1],t[2]-1,t[3]];
}
});
};
删除列的情况:
直观关键与行删除类似,应该是行换成列就可以,
对data_model的影响, 涉及合并单元格,如果合并单元格的第一列,则把下一列进行修正,如果不是第一列 则啥都不管
strcut_mode 如果是第一列,则意味着strucut_mode要调整到下一列上 如果不事合并单元格第一列 则调整跨列数字
merger 按需调整
//处理删除列的情况(合并单元格)
doWithDelCol=(table_model,p)=>{
let r=this.getMergeCellWithCrossCol(p);
let _mergeCellAtRight=this.getMergeCellAtRight(p);
var arr = Object.keys(r[0]);
var arr_l = Object.keys(_mergeCellAtRight[0]);
//alert(arr.length == 0);//true 即为空对象
if(arr_l.length > 0) {
_mergeCellAtRight[0].forEach((item, index) => {
let _position=_mergeCellAtRight[1][index];
let t = this.state.mergeCellArray[_position];
t = [t[0], t[1]-1, t[2], t[3]-1];
this.state.mergeCellArray[_position]=t;
});
}
if(arr.length > 0){
r[0].forEach((item, index)=>{
let y=item[0];
let x=item[1];
let c=table_model.struct_model[y][x];
if(item[1]==p){ //第一列
if(item[1]==item[3]){ //就一行数据
let _position=r[1][index];
this.state.mergeCellArray[_position]=[0,0,0,0];
}else{
table_model.struct_model[y][x+1][0]=c[0];
table_model.struct_model[y][x+1][1]=c[1]-1;
table_model.data_model[y][x+1]=1;
// 调整设计的mergecells中相应合并区记录的数据 首先是找到这个记录
let _position=r[1][index];
let t=this.state.mergeCellArray[_position];
t=[t[0],t[1],t[2],t[3]-1 ];
this.state.mergeCellArray[_position]=t;
}
}else if(item[3]>=p){ //非第一列
table_model.struct_model[y][x][1]=c[1]-1;
// 调整设计的mergecells中相应合并区记录的数据 首先是找到这个记录
let _position=r[1][index];
let t=this.state.mergeCellArray[_position];
this.state.mergeCellArray[_position]=[t[0],t[1],t[2],t[3]-1];
}
});
};
//结果删除行的处理 可能有的合并单元格已不是合并单元格,这个时候,需要从mergercell删除
if(this.state.mergeCellArray.length>0){
this.state.mergeCellArray=
this.state.mergeCellArray.filter((item)=>{
if(item[0]==item[2] && item[1]==item[3]){
return false; //需要过滤吊顶
}else{
return true;
}
});//过滤好像不改变原来的数组
}
table_model.data_model=this.deleteCol(table_model.data_model,p);
table_model.struct_model=this.deleteCol(table_model.struct_model,p);
}
后头看,我们前面搞两个colwidth数组,插入、删除、追加列的时候,还不能忘记对这个数组的处理。
ps:连续增删好像有点问题?是选中单元格错误导致的?可能应对办法是:insert row、delete row的时候,立即保存?