找回密码
 立即注册

QQ登录

只需一步,快速开始

alizee10251 讲师达人认证 悬赏达人认证 SpreadJS 开发认证

银牌会员

98

主题

150

帖子

2758

积分

银牌会员

积分
2758

活字格认证活字格高级认证微信认证勋章

alizee10251 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
银牌会员   /  发表于:2019-7-2 15:38  /   查看:3566  /  回复:1

本期葡萄城公开课,将由国电联合动力技术有限公司,资深前端开发工程师——李林慧女士,与大家在线分享“在 React 框架中使用SpreadJS 纯前端表格控件”的实战开发经验。



【本期公开课精彩回放】:
[mp4]http://video1.grapecity.com.cn/SpreadJS/pulicclass/spjs_20190703.mp4[/mp4]


国电联合动力技术有限公司于2007年6月成立,注册资本3.13亿元,拥有五个全资子公司及五个控股公司,总部位于北京,在全国设有多家生产基地。作为中国国电集团为发展中国绿色能源事业需要,解决风电关键、重大设备国产化问题而组建的高新技术公司,国电联合动力技术有限公司为构建低碳和谐社会、铸造值得信赖的国产风机品牌提供了强大的技术支持,公司主营业务包括风电机组设计、生产制造、研究开发、销售服务等。


以下是本期公开课部分精彩内容:

项目背景:
公司采购SpreadJS 纯前端表格控件,其主要应用场景是开发一套完善的日常业务流程管理系统,该系统以部门为单位划分,每周由各部门填报人员,根据系统运行情况、日常运营数据等在系统中进行填报,后交由部门进行数据汇总,并在移动端/PC端系统页面进行数据展示。

在采购SpreadJS 纯前端表格控件之前,公司使用excel进行数据汇总,无法保证各部门的数据流通及时、共享。在经过技术调研后,决定使用SpreadJS(该控件的功能、布局和操作均接近原生Excel)开发业务流程管理系统。通过该系统,部门领导可以实时查看业务运行状况并给予反馈意见,保证数据流通实时、有效。

选择SpreadJS的主要原因:

1.     功能、布局与Excel高度一致,数据操作、使用习惯均接近原生Excel
2.     可在前端导入、导出 Excel 文件,且保持文件的最大完整性
3.     支持所有常见的Excel公式函数

本期公开课大纲:

1.     SpreadJS常用组件及其属性
        a.      SpreadSheets
        b.     Worksheet
2.     渲染过程
3.     自定义数据验证及Demo演示
4.     课程答疑


SpreadJS常用组件及其属性

<SpreadSheets>

  1.           <SpreadSheets
  2.             backColor="aliceblue"
  3.             hostStyle={{ width: `${tableWidth}px`, height: '600px' }}
  4.             rowChanged={(_, sheet) => this.handleRowChanged(sheet)}
  5.             valueChanged={(_, sheet) => this.handleValueChanged(sheet)}
  6.             rangeChanged={(_, sheet) => this.handleRangeChanged(sheet)}
  7.             workbookInitialized={spread => this.init(spread)}
  8.           >
复制代码

·      rowChanged:主要用于删除整行触发,需要判断propertyName 属性
  1.   handleRowChanged(content) {// 整行删除触发
  2.     const {sheet, propertyName} = content
  3.     if (propertyName === 'deleteRows') {
  4.       const {originalItem: {reportId}} = sheet.getDeletedRows()[0]
  5.       if (reportId) {
  6.         this.setState({loading: true})
  7.         setTimeout(() => {
  8.           alert('删除成功!')
  9.         }, 2000)
  10.       }
  11.     }
  12.   }
复制代码

·      valueChanged:改变单元格值触发
  1.   handleValueChanged(sheet) {
  2.     const {changedRow} = this.state
  3.     changedRow.push(sheet.row)
  4.     this.setState({changedRow: Array.from(new Set(changedRow))})
  5.   }
复制代码

·      rangeChanged:输入公式、delete 删除数据、移动单元格触发
  1.   handleRangeChanged({ changedCells }) { // 输入公式、delete删除数据、移动单元格触发
  2.     const { changedRow } = this.state;
  3.     for (let i = 0; i < changedCells.length; i++) {
  4.       changedRow.push(changedCells.row);
  5.     }
  6.     this.setState({ changedRow: Array.from(new Set(changedRow)) });
  7.   }
复制代码

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

<Worksheet>

  1.            <Worksheet dataSource = {data}  name="简单综合示例" autoGenerateColumns={false}>
  2.               {tableHead.length > 0 ? tableHead.map(item => (
  3.                 <Column
  4.                   dataField={item.name}
  5.                   key={item.name}
  6.                   headerText={item.displayName}
  7.                   width={item.width}
  8.                   style={{wordWrap: 'break-wrap', locked: false}}
  9.                   formatter={item.formatter}
  10.                 />
  11.               )): null}
  12.             </Worksheet>
复制代码

·      dataSource:数据源
·      name:工作簿名称
·      <Column>
……


渲染过程

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

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

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

4.     渲染完毕。

自定义数据验证及Demo演示

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


2.     数据验证代码

  1.   // 数据验证
  2.   dataValidate() {
  3.     function MyCondition(reg) {
  4.       this.reg = reg
  5.       GC.Spread.Sheets.ConditionalFormatting.Condition.apply(this, arguments)
  6.     }
  7.     MyCondition.prototype = new GC.Spread.Sheets.ConditionalFormatting.Condition()
  8.     MyCondition.prototype.evaluate = function(evaluator, baseRow, baseColumn, actualObj) {
  9.       const reg = new RegExp (this.reg)
  10.       if (reg.test(actualObj)) {
  11.         return true
  12.       }
  13.       else {
  14.         return false
  15.       }
  16.     }
  17.     // 数据验证相关变量
  18.     const {spread} = this.state,
  19.       sheet = spread.getSheet(0),
  20.       sheetActive = spread.getActiveSheet(),
  21.       nCondition = new MyCondition(/[+-]?\d+(\.\d+)?|^\s+$/),
  22.       validator = new GC.Spread.Sheets.DataValidation.DefaultDataValidator(nCondition)
  23.     // 数据验证
  24.     spread.suspendPaint()
  25.     validator.type(GC.Spread.Sheets.DataValidation.CriteriaType.custom)
  26.     spread.options.highlightInvalidData = true
  27.     validator.showInputMessage(true)
  28.     validator.inputMessage('必须填写数字!')
  29.     validator.inputTitle('提示')
  30.     sheetActive.setDataValidator(0, 4, sheet.getRowCount(), 1, validator) // rowIndex, colIndex,rowCount, colCount
  31.     sheet.resumePaint()
  32.   }
复制代码

课程答疑Q&A


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

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

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


公开课示例下载

扩展阅读


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

1 个回复

倒序浏览
alizee10251讲师达人认证 悬赏达人认证 SpreadJS 开发认证
银牌会员   /  发表于:2019-7-4 10:52:15
沙发
本期公开课精彩回放已经上传,欢迎大家观看学习
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部