表格绑定如何绑定公式
本帖最后由 ClarkPan 于 2020-5-25 01:50 编辑背景: SpreadJS的数据绑定功能在数据填报场景中是最常用的功能,可以很方便的将数据绑定在工作表的指定位置上。在纯数据的表格中,会给使用带来很大的遍历。由于Excel电子表格的特殊性,往往实际应用场景中经常会遇到数据的某个字段是公式,而不是计算的结果。但SpreadJS源生并不支持公式的绑定,对于这部分数据用户往往束手无策。本教程讲述通过代码对SpreadJS的数据绑定逻辑做一些改进,已达到支持数据绑定的效果并且无需修改源码,仅仅是在SpreadJS的绑定逻辑上做扩展就可以达到支持公式绑定的功能。
思路:
在设置绑定关系的时候单独对公式进行处理,并将公式的绑定设置以tag的形式存在表格的起始单元格上。function bindingPathEnhancement(tableStartRow,tableStartColumn,bindingPathSchema){
var tableColumns = [];
var bindingPath = bindingPathSchema.bindingPath;
var properties = bindingPathSchema.properties;
//用tag记录公式列
var tag = {};
var formulaCoulumns = []
tag.bindingPath = bindingPath;
var table = sheet.tables.add('tableRecords', tableStartRow, tableStartColumn, 2, properties.length);
table.autoGenerateColumns(false);
for(var i=0;i<properties.length;i++){
var tableColumn = new GC.Spread.Sheets.Tables.TableColumn();
if(!properties.isFormula){
tableColumn.name(properties.displayName);
tableColumn.dataField(properties.dataField);
tableColumns.push(tableColumn);
}else{
tableColumn.name(null);
tableColumn.dataField(null);
tableColumns.push(tableColumn);
var formulaColumn = {}
formulaColumn.index = i;
formulaColumn.displayName = properties.displayName;
formulaColumn.dataField = properties.dataField;
formulaCoulumns.push(formulaColumn);
}
}
tag.formulaCoulumns = formulaCoulumns;
sheet.setTag(tableStartRow,tableStartColumn,tag);
table.bindColumns(tableColumns);
table.bindingPath(bindingPath);
}
在绑定数据时,读取tag,然后将公式在SpreadJ数据绑定完成之后单独设置。
spread.suspendPaint();
spread.suspendCalcService();
source = new GC.Spread.Sheets.Bindings.CellBindingSource(dataSource);
sheet.setDataSource(source);
var tables = sheet.tables.all();
for(var i=0;i<tables.length;i++){
var tableTag = sheet.getTag(tables.startRow(),tables.startColumn());
if(tableTag){
if(tableTag.bindingPath && tableTag.formulaCoulumns){
var bindingPath = tableTag.bindingPath;
var tableSource = dataSource;
for(var j=0;j<tableTag.formulaCoulumns.length;j++){
var dataField = tableTag.formulaCoulumns.dataField;
var displayName = tableTag.formulaCoulumns.displayName;
var index = tableTag.formulaCoulumns.index;
sheet.setValue(tables.startRow(),tables.startColumn()+index,displayName);
for(var k=0;k<tableSource.length;k++){
sheet.setFormula(tables.startRow()+1+k,tables.startColumn()+index,tableSource);
}
}
}
}
}
spread.resumeCalcService();
spread.resumePaint();
之后为了支持双向绑定,监听CellChanged事件,在数据源中实时修改结果。
sheet.bind(GC.Spread.Sheets.Events.CellChanged, function (e, info) {
if(info.propertyName == "formula"){
var table = sheet.tables.find(info.row,info.col);
var tableTag = sheet.getTag(table.startRow(),table.startColumn());
if(table && sheet.getTag(table.startRow(),table.startColumn())){
var bindingPath = tableTag.bindingPath;
var tableSource = dataSource;
var index = info.col-table.startColumn();
if(tableTag.formulaCoulumns){
for(var i=0;i<tableTag.formulaCoulumns.length;i++){
if(index == tableTag.formulaCoulumns.index){
var dataField = tableTag.formulaCoulumns.dataField;
tableSource = "="+ info.newValue;
break;
}
}
}
}
}
});
完整demo详见附件
运行后效果如下:
点击setBindingPath加载一个带有数据与公式绑定的表格
之后点击setDataSource给这个表格加载数据源
加载之后结果如下:
之后我们可以试试双向绑定的功能(修改数据和公式,下图更改了H8的值与J7的公式):
点击getDataSource看一下效果,公式与值的改变都被记录下来
可以附件放个完整demo嘛 附件就是完整demo Clark.Pan 发表于 2022-3-25 15:37
附件就是完整demo
哦哦看到了,刚只看见了图片截图,多谢 :mj72:
页:
[1]