【案例分享】在 React 框架中使用 SpreadJS 純前端表格控件

本期葡萄城公開課,將由國電聯合動力技術有限公司,資深前端開發工程師——李林慧女士,與你們在線分享「在 React 框架中使用 SpreadJS 純前端表格控件」的實戰開發經驗。前端

圖片描述

直播地址:http://live.vhall.com/723418543react

直播時間:2019-07-03(星期三)下午 14:00數據庫

國電聯合動力技術有限公司於2007年6月成立,註冊資本3.13億元,擁有五個全資子公司及五個控股公司,總部位於北京,在全國設有多家生產基地。做爲中國國電集團爲發展中國綠色能源事業須要,解決風電關鍵、重大設備國產化問題而組建的高新技術公司,國電聯合動力技術有限公司爲構建低碳和諧社會、鑄造值得信賴的國產風機品牌提供了強大的技術支持,公司主營業務包括風電機組設計、生產製造、研究開發、銷售服務等。服務器

如下是本期公開課部分精彩內容:app

項目背景:

428690-20190702111045172-1084575084.png

公司採購SpreadJS 純前端表格控件,其主要應用場景是開發一套完善的平常業務流程管理系統,該系統以部門爲單位劃分,每週由各部門填報人員,根據系統運行狀況、平常運營數據等在系統中進行填報,後交由部門進行數據彙總,並在移動端/PC端系統頁面進行數據展現。框架

在採購SpreadJS 純前端表格控件以前,公司使用excel進行數據彙總,沒法保證各部門的數據流通及時、共享。在通過技術調研後,決定使用SpreadJS(該控件的功能、佈局和操做均接近原生Excel)開發業務流程管理系統。經過該系統,部門領導能夠實時查看業務運行情況並給予反饋意見,保證數據流通實時、有效。函數

選擇SpreadJS的主要緣由:

  1. 功能、佈局與Excel高度一致,數據操做、使用習慣均接近原生Excel
  2. 可在前端導入、導出 Excel 文件,且保持文件的最大完整性
  3. 支持全部常見的Excel公式函數

本期公開課大綱:

  1. SpreadJS經常使用組件及其屬性佈局

    • SpreadSheets
    • Worksheet
  2. 渲染過程
  3. 自定義數據驗證及Demo演示
  4. 課程答疑

SpreadJS經常使用組件及其屬性

<SpreadSheets>this

<SpreadSheets

            backColor="aliceblue"

            hostStyle={{ width: `${tableWidth}px`, height: '600px' }}

            rowChanged={(_, sheet) => this.handleRowChanged(sheet)}

            valueChanged={(_, sheet) => this.handleValueChanged(sheet)}

            rangeChanged={(_, sheet) => this.handleRangeChanged(sheet)}

            workbookInitialized={spread => this.init(spread)}

          >

rowChanged:主要用於刪除整行觸發,須要判斷 propertyName 屬性lua

handleRowChanged(content) {// 整行刪除觸發

    const {sheet, propertyName} = content

    if (propertyName === 'deleteRows') {

      const {originalItem: {reportId}} = sheet.getDeletedRows()[0]

      if (reportId) {

        this.setState({loading: true})

        setTimeout(() => {

          alert('刪除成功!')

        }, 2000)

      }

    }

  }

valueChanged:改變單元格值觸發

handleValueChanged(sheet) {

    const {changedRow} = this.state

    changedRow.push(sheet.row)

    this.setState({changedRow: Array.from(new Set(changedRow))})

  }

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)) });

  }

workbookInitialized:初始化表格控件,返回一個 spread 實例

<Worksheet>

<Worksheet dataSource = {data}  name="簡單綜合示例" autoGenerateColumns={false}>

          {tableHead.length > 0 ? tableHead.map(item => (

            <Column

              dataField={item.name}

              key={item.name}

              headerText={item.displayName}

              width={item.width}

              style={{wordWrap: 'break-wrap', locked: false}}

              formatter={item.formatter}

            />

          )): null}

        </Worksheet>

dataSource:數據源
name:工做簿名稱
<Column>
……

渲染過程

  1. workbookInitialized返回一個spread實例,在init方法裏能夠對options按需進行配置。有了spread實例後也就能夠生成一個Excel實例對象,其中包含了經常使用的spread和spreadNS,以及自定義的一些經常使用spread方法,好比搜索功能、自適應高度等。
  2. 從服務器端獲取報表數據後,再根據報表保存的模板id獲取對應的表頭模板,渲染表頭時能夠作一些前期工做,如定義選項類的單元格、定義單元格的格式、公式等。
  3. 將報表數據賦值給Worksheet組件的dataSource屬性。
  4. 渲染完畢。

自定義數據驗證及Demo演示

數據驗證高亮樣式(Data Validation Highlight Style):SpreadJS 支持自定義數據驗證樣式和不一樣的單元格突出顯示類型,包括 circle,dogear 和 icon。

428690-20190702111113432-1753978370.png

數據驗證代碼

// 數據驗證

  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, colCount

    sheet.resumePaint()

  }

課程答疑Q&A

Q:爲什麼數據量很小,但頁面加載時會出現卡頓

A:凡是涉及到表格重繪的地方最好都用 spread.suspendPaint() 和 spread.resumePaint() 包裹起來,避免頻繁重繪引發卡頓。

Q: 如何渲染多重表頭?

A:Column組件還沒有支持多重表頭,針對這個問題,能夠在渲染表頭步驟時(此時已獲取到有樹形結構的表頭模板),先給表格setDataSource,獲取全部表頭模板的葉子節點後按列進行表單級別的綁定,而後經過操做表頭區域的賦值、合併單元格等操做手動渲染表頭。

Q:爲何要引入表頭模板?

A:SpreadJS中每一列的列頭顯示的是中文,可是實際上存取對應的是數據庫中的一個字段,因此須要經過數據綁定把表格數據和字段映射起來。其中模板在系統管理內另有維護入口,支持增刪改等基本功能。

公開課示例下載

SpreadJS-ReactSample

擴展閱讀

《3分鐘建立SpreadJS的React項目》
《如何在 React 框架中使用 SpreadJS》

相關文章
相關標籤/搜索