多语言展示
当前在线:1710今日阅读:91今日分享:37

在 React 框架中使用 SpreadJS 纯前端表格控件

应用场景:开发一套完善的日常业务流程管理系统,该系统以部门为单位划分,每周由各部门填报人员,根据系统运行情况、日常运营数据等在系统中进行填报,后交由部门进行数据汇总,并在移动端/PC端系统页面进行数据展示。选择SpreadJS的主要原因:功能、布局与Excel高度一致,数据操作、使用习惯均接近原生Excel可在前端导入、导出 Excel 文件,且保持文件的最大完整性支持所有常见的Excel公式函数.
方法/步骤
1

this.handleRowChanged(sheet)}    valueChanged={(_, sheet) => this.handleValueChanged(sheet)}    rangeChanged={(_, sheet) => this.handleRangeChanged(sheet)}    workbookInitialized={spread => this.init(spread)}    >

2

rowChanged:主要用于删除整行触发,需要判断 propertyName 属性 handleRowChanged(content) {// 整行删除触发    const {sheet, propertyName} = content    if (propertyName === 'deleteRows') {      const {originalItem: {reportId}} = sheet.getDeletedRows()[0]      if (reportId) {        this.setState({loading: true})        setTimeout(() => {          alert('删除成功!')        }, 2000)      }    }

3

valueChanged:改变单元格值触发handleValueChanged(sheet) {    const {changedRow} = this.state    changedRow.push(sheet.row)    this.setState({changedRow: Array.from(new Set(changedRow))})  }

4

rangeChanged:输入公式、delete 删除数据、移动单元格触发 handleRangeChanged({ changedCells }) { // 输入公式、delete删除数据、移动单元格触发    const { changedRow } = this.state;    for (let i = 0; i < changedCells.length; i++) {      changedRow.push(changedCells[i].row);    }    this.setState({ changedRow: Array.from(new Set(changedRow)) });  }

5

workbookInitialized:初始化表格控件,返回一个 spread 实例

方法/步骤
1

    {tableHead.length > 0 ? tableHead.map(item => (        )): null}

2

dataSource:数据源name:工作簿名称

渲染过程
1

workbookInitialized 返回一个 spread 实例,在 init 方法里可以对 options 按需进行配置。有了 spread 实例后也就可以生成一个 Excel 实例对象,其中包含了常用的 spread 和 spreadNS,以及自定义的一些常用 spread 方法,比如搜索功能、自适应高度等。

2

从服务器端获取报表数据后,再根据报表保存的模板id获取对应的表头模板,渲染表头时可以做一些前期工作,如定义选项类的单元格、定义单元格的格式、公式等。

3

将报表数据赋值给Worksheet组件的dataSource属性。

4

渲染完毕。

自定义数据验证及Demo演示
1

数据验证高亮样式(Data Validation Highlight Style):SpreadJS 支持自定义数据验证样式和不同的单元格突出显示类型,包括 circle,dogear 和 icon。

2

数据验证代码 // 数据验证dataValidate() {function MyCondition(reg) {    this.reg = reg    GC.Spread.Sheets.ConditionalFormatting.Condition.apply(this, arguments) } MyCondition.prototype = new GC.Spread.Sheets.ConditionalFormatting.Condition() MyCondition.prototype.evaluate = function(evaluator, baseRow, baseColumn, actualObj) {    const reg = new RegExp (this.reg)    if (reg.test(actualObj)) {    return true    }    else {    return false    } }// 数据验证相关变量const {spread} = this.state,    sheet = spread.getSheet(0),    sheetActive = spread.getActiveSheet(),    nCondition = new MyCondition(/[+-]?\d+(\.\d+)?|^\s+$/),    validator = new GC.Spread.Sheets.DataValidation.DefaultDataValidator(nCondition)// 数据验证 spread.suspendPaint() validator.type(GC.Spread.Sheets.DataValidation.CriteriaType.custom) spread.options.highlightInvalidData = true validator.showInputMessage(true) validator.inputMessage('必须填写数字!') validator.inputTitle('提示') sheetActive.setDataValidator(0, 4, sheet.getRowCount(), 1, validator) // rowIndex, colIndex, rowCount, colCountsheet.resumePaint() }

课程答疑Q&A
1

Q:为何数据量很小,但页面加载时会出现卡顿A:凡是涉及到表格重绘的地方最好都用 spread.suspendPaint() 和 spread.resumePaint() 包裹起来,避免频繁重绘引起卡顿。

2

Q: 如何渲染多重表头?A:Column组件尚未支持多重表头,针对这个问题,可以在渲染表头步骤时(此时已获取到有树形结构的表头模板),先给表格setDataSource,获取所有表头模板的叶子节点后按列进行表单级别的绑定,然后通过操作表头区域的赋值、合并单元格等操作手动渲染表头。

3

Q:为什么要引入表头模板?A:SpreadJS中每一列的列头显示的是中文,但是实际上存取对应的是数据库中的一个字段,所以需要通过数据绑定把表格数据和字段映射起来。其中模板在系统管理内另有维护入口,支持增删改等基本功能

公开课示例下载

SpreadJS-ReactSample

扩展阅读

《3分钟创建SpreadJS的React项目》《如何在 React 框架中使用 SpreadJS》

注意事项

您对SpreadJS产品的任何技术问题,都有技术支持工程师提供1对1专业解答,可进入葡萄城官网在线预约。

推荐信息