V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GrapeCityChina
V2EX  ›  推广

构建基于 React18 的电子表格程序

  •  
  •   GrapeCityChina · 2022-06-09 13:47:34 +08:00 · 576 次点击
    这是一个创建于 904 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    2022 年 3 月 29 日,React 正式发布 18.0.0 。本次升级内容包括开箱即用的改进,如自动批处理、新的 API (如 startTransition )和支持 Suspense 的流式服务器端渲染。关于此次发布新增的功能可以参考**官方文档**。

    作为一个构建用户界面的 JavaScript 库,React 一直被认为是一个严谨而优秀的前端框架,随着新版本的发行,使用热度也是越来越高。一个热知识,在大部分使用 React 开发的业务系统中,基本对表格都有需求。大部分情况下,我们使用 react 集成 antd 就可以完成一些常规的表格需求。但是在普通的表格中,如果要做一些公式函数的计算,或者在表格内部使用一些图表等功能时,这种常规的行列表就很难满足需求了。

    除此之外,虽然 React 中使用了虚拟 DOM 及 DOM DIFF 算法,但如果表格中数据量大且需要经常性修改更新时,浏览器性能并不会太好。

    因此,为了更好地满足业务系统中复杂的表格需求,本文将为大家介绍如何基于 React18 ,构建一个功能更加强大的前端电子表格系统。

    实战

    首先,我们需要创建一个 react 项目,可以使用**create-react-app或者Vite**来创建。但由于 Vite 使用 esbuild **预构建依赖**,esbuild 使用 Go 编写,相比较于 JavaScript 编写的打包器预构建依赖快 10-100 倍,整体上来说,使用效率要高于 cra 。因此本文使用 Vite 来创建 React 项目。需要注意的是,使用 Vite 需要 Node 的版本高于 12 ,如果 Node 的版本过低,注意升级 Node 哦。

    进入想要创建项目的目标文件夹之后,根据自己用的工具,执行以下命令的一种,即可创建一个最简单的 React 项目:

    # npm 6.x 
    npm create vite@latest vite-react --template react
    
    # npm 7+, extra double-dash is needed:
    npm create vite@latest vite-react --template react
    
    # yarn
    yarn create vite vite-react --template react
    
    # pnpm
    pnpm create vite vite-react -- --template react
    
    

    上述命令中 vite-react 表示创建的工程名称,--template 表示创建项目时使用的模板,react 模板默认使用 js ,如果要使用 ts ,需要将--template react 替换为--template react-ts 。

    创建完成之后,进入到项目目录,执行 npm install ,依赖资源安装完成之后,执行 npm run dev ,项目即可启动。

    当然,这些命令在创建项目完成之后,终端都会有提示,如上图所示。

    打开 package.json ,可以看到 React 的版本为 18.0.0 的最新版,在创建项目时,默认都会使用最新版本的 React ,如上图。

    项目启动之后,app.jsx 中会有很多不需要的内容,大家可以自行删掉,构建一个最简洁的项目。接下来我们引入前端表格组件,在 package.json 中添加以下代码(紫色内容),之后执行 npm install ,安装新增的依赖资源:

    "dependencies": {
        "react": "^18.0.0",
        "react-dom": "^18.0.0",
        "@grapecity/spread-sheets": "15.0.7",
        "@grapecity/spread-sheets-react": "15.0.7",
        "@grapecity/spread-excelio": "15.0.7",
        "@grapecity/spread-sheets-charts": "15.0.7",
        "@grapecity/spread-sheets-print": "15.0.7",
        "@grapecity/spread-sheets-pdf": "15.0.7",
        "@grapecity/spread-sheets-barcode": "15.0.7",
        "@grapecity/spread-sheets-shapes": "15.0.7",
        "@grapecity/spread-sheets-resources-ko": "15.0.7",
        "@grapecity/spread-sheets-resources-ja": "15.0.7",
        "@grapecity/spread-sheets-resources-zh": "15.0.7",
        "@grapecity/spread-sheets-languagepackages": "15.0.7",
        "@grapecity/spread-sheets-pivot-addon": "15.0.7",
        "@grapecity/spread-sheets-designer": "15.0.7",
        "@grapecity/spread-sheets-designer-resources-cn": "15.0.7",
        "@grapecity/spread-sheets-designer-react": "15.0.7",
        "@grapecity/spread-sheets-tablesheet": "15.0.7"
      },
    
    

    依赖安装之后,我们需要创建两个 jsx 文件,用来引入 SpreadJS 的不同部分,OnlineSpread 表示当前组件为 SpreadJS 运行时组件,实现该组件的核心代码如下所示:

    import {Component} from 'react'
    import GC from '@grapecity/spread-sheets';
    import '@grapecity/spread-sheets-resources-zh';
    GC.Spread.Common.CultureManager.culture("h-zcn");
    import { SpreadSheets, Worksheet, Column } from '@grapecity/spread-sheets-react';
    
    
    export default class OnlineSpread extends Component {
        constructor(props) {
            super(props);
            this.spread = null;
        }
        initSpread(spread) {
            this.spread = spread;
             //设置当前 spread 中工作表的数量
            this.spread.setSheetCount(2)
            //获取第一个工作表
            let sheet = spread.getSheet(0)   //or let sheet = spread.getSheetFromName('Sheet1')
            //设置列宽
            sheet.setColumnWidth(0,150)    //第一个参数为列索引,第二个参数为列宽
    
    
            //单个单元格设置值
            sheet.setValue(0,0,'Hello Grapecity')   //参数依次表示行索引、列索引、内容
    
    
            //设置单元格公式
            sheet.setFormula(0,1,'=SUM(A2:A5)')      //参数依次为行索引、列索引、公式
    
    
            //设置区域内容
            //表示从行索引为 2 ,列索引为 0 的单元格开始,设置 2 行 3 列的数据
            sheet.setArray(2,0,[[1,'hello','grapecity'],[2,'hello','javascript']])  
    
    
            //设置文字颜色
            sheet.getCell(2,1).foreColor('#f00')
        }
    
    
        render(){
            return(
                <SpreadSheets workbookInitialized={spread=>this.initSpread(spread)}>
                    <Worksheet>
                    </Worksheet>
                </SpreadSheets>
            )
        }
       
    }
    
    
    

    在 app.jsx 中引入 OnlineSpread ,页面展示效果如下:

    接下来,我们需要引入包含工具栏的部分,新建一个 OnlineDesigner.jsx ,核心代码如下:

    import { Component, PropsWithChildren, ReactNode } from 'react'
    import '@grapecity/spread-sheets-designer-resources-cn';
    import "@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css"
    import '@grapecity/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css'
    import "@grapecity/spread-sheets-tablesheet";
    import "@grapecity/spread-sheets-barcode";
    import "@grapecity/spread-sheets-charts";
    import "@grapecity/spread-sheets-shapes";
    import "@grapecity/spread-sheets-languagepackages";
    import "@grapecity/spread-sheets-print";
    import "@grapecity/spread-sheets-pdf";
    import "@grapecity/spread-sheets-pivot-addon";
    import "@grapecity/spread-sheets-resources-zh";
    import "@grapecity/spread-sheets-designer-resources-cn";
    import * as GCDesigner from '@grapecity/spread-sheets-designer';
    import "@grapecity/spread-sheets-resources-zh"
    import GC from "@grapecity/spread-sheets"
    import { Designer } from '@grapecity/spread-sheets-designer-react';
    GC.Spread.Common.CultureManager.culture('zh-cn')
    
    
    
    
    export default class OnlineDesigner extends Component{
      constructor(props){
        super(props)
        this.designer = null
      }
    
    
      designerInitialized = (designer) => {
        this.designer = designer
        console.log(designer)
        // 获取与 designer 相关联的工作簿(Spread)
        let spread = this.designer.getWorkbook()
        let sheet = spread.getActiveSheet()
        //设置数值
        sheet.setValue(0,0,'Hello Grapecity')
        //设置行高
        sheet.setColumnWidth(0,120)
        //设置区域内容
        sheet.setArray(1,0,[[2,3,5]])
        //设置公式
        sheet.setFormula(3,0,'=sum(A2:C2)')
    
    
      }
    
    
      render(){
          return(
              <Designer
                spreadOptions={{sheetCount: 3}}
                styleInfo={{height: '98vh'}}
                designerInitialized = {this.designerInitialized}
              />
          )
      }
    }
    
    
    

    在 app.jsx 中引入 OnlineDesigner,页面中显示如下:

    到这里我们就正式完成基于 React18 构件纯前端表格,在该表格上,我们可以继续设置大量数据、公式,也可以实现报表设计,报表设计操作形式与 Excel 类似。

    Demo 下载地址:**https://github.com/GrapeCityXA/SpreadJS_vite_react18**

    更多 demo 体验:

    https://demo.grapecity.com.cn/spreadjs/gc-sjs-samples/index.html?id=34

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2906 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 02:42 · PVG 10:42 · LAX 18:42 · JFK 21:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.