Fiooona 发表于 2020-9-22 15:35:20

SpreadJS 绑定数据源报错问题

背景:从V13.1.0 版本开始,SpreadJS 增强了表格的功能,以前没有表格内部新增行功能,新增行是在sheet上新增。         V13.1.0之后表格的行可以自增,不需要在sheet 上整行进行插入。在这种模式下,表格下方有合并单元格或其他表格或者sheet行数不够时,表格内新增行时就会报错。如下图所示的情形就是典型的情形之一,表格下方有合并单元格,表格内新增行时会引起,合并单元格被拆分,表单报错。


如图所示,用户在设计器中设计了如下图所示的表单:


在V13.1.0以前的版本,绑定数据源后,是如下图所示的效果,数据源有4条数据,源表单设计了6条数据的位置,绑定数据源后,原本的25,26行被删除,包括table及table 外的表单。

在新版本中,绑定数据源后,效果如下图,table 内的行数减少,并未影响右侧表单其他部分的样式:

为解决这种差异,在绑定数据源之前,可以添加如下的代码,思路是判断sheet中的table 有没有绑定数据源,如果绑定了数据源,就根据数据源的行数提前在sheet上新增或删除行,添加这样的逻辑后可以保持与原来版本的效果一致。

      // 升级临时解决方案
      function beforeSetDataSource(sheet, source) {
            console.log('source=', source)
            sheet.suspendPaint();
            var deleteTables = [];
            for (let i = 0; i < sheet.tables.all().length; i++) {
                var table = sheet.tables.all();
                var bindingPath = table.bindingPath();
                for (let i in source.xf) {
                  if (i == bindingPath) {
                        var length = source.xf.length;
                        var range = table.range()
                        if (length > range.rowCount) {
                            var rindex = range.row + range.rowCount - 1;
                            var rcount = length - range.rowCount + 1;
                            sheet.addRows(rindex, rcount)
                            break
                        }
                        if (length < range.rowCount) {

                            var rindex = range.row + range.rowCount - 1;
                            var rcount = range.rowCount - length - 1;
                            var deleteIndex = rindex - rcount
                            sheet.deleteRows(deleteIndex, rcount)
                            break
                        }
                  }
                }
                // debugger
            }
            sheet.resumePaint()
      }在数据源的行数小于原先设计的行数时,如果想要保持原先的设计,不删除多余的行,实现思路是在绑定数据源前复制一份表单,绑定数据源后,将原先删除的行复制粘贴至绑定数据源后对应的位置,效果如下图所示:

核心代码:
//删除后新增原来的行数不改变样式
   function afterInsertRows(sheet, tables) {
            // 如果删除了的话,就直接进行instert操作,没有话不执行,放置多种table的情况
            if (tables.length > 0) {
                let sheetCount = sheet.getRowCount(GC.Spread.Sheets.SheetArea.viewport);
                console.log('tables', tables)
                tables.forEach(({table, deleteIndex, rcount,nsheet}, index) => {
                  if (index === 0) {
                        // 保持行高
                        let actualRowHeight = sheet.getRowHeight(deleteIndex - 1);
                        sheet.addRows(deleteIndex+1,rcount)
                        for (let key = 0; key < rcount; key++) {
                            sheet.setRowHeight(deleteIndex + 1 + key, actualRowHeight);
                        }
                        var fromRanges = new GC.Spread.Sheets.Range(deleteIndex+1, 0, rcount, nsheet.getColumnCount());
                                var pastedRange = new GC.Spread.Sheets.Range(deleteIndex+1, 0, rcount, sheet.getColumnCount());
                                spread.commandManager().execute({
                                        cmd: "clipboardPaste",
                                        sheetName: sheet.name(),
                                        fromSheet: nsheet,
                                        fromRanges: ,
                                        pastedRanges: ,
                                        isCutting: false,
                                        clipboardText: "",
                                        pasteOption: GC.Spread.Sheets.ClipboardPasteOptions.all
                                });
                  }
                  spread.removeSheet(spread.getSheetIndex(nsheet.name()))
                })
            }
      }完整示例可查看附件代码。
页: [1]
查看完整版本: SpreadJS 绑定数据源报错问题