溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

發(fā)布時(shí)間:2022-08-08 16:04:59 來源:億速云 閱讀:264 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件文章都會(huì)有所收獲,下面我們一起來看看吧。

    需求分析

    最近遇到一個(gè)需求:前端導(dǎo)出excel文件,其中有部分?jǐn)?shù)據(jù)用戶不能操作,部分列數(shù)據(jù)可以篩選,并且存在前一列的數(shù)據(jù)值會(huì)影響后一列數(shù)據(jù)值的輸入范圍的情況。

    前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

    需要導(dǎo)出的前端表格如上圖所示,其中:

    • Group、Type、Region可篩選

    • 紅色框內(nèi)的數(shù)據(jù)用戶不可操作,綠色框內(nèi)用戶可以操作

    • 當(dāng)Type的值為BOOL時(shí),Region的有效輸入為:["Holding Register","Input Register"],否則為:["Coil","Discrete Input"]

    • Address的輸入范圍為:[0,65535]

    項(xiàng)目使用的是React + AntD

    常用的庫

    在這個(gè)需求出來之前,前端導(dǎo)入導(dǎo)出excel文件時(shí)我使用的是xlsx這個(gè)庫。但是,如果想要修改excel表格樣式的話,是需要使用收費(fèi)的專業(yè)版本。帶著開源第一,絕不花錢的基本原則,本人就找到了ExcleJS這個(gè)庫。

    ExcleJS

    ExcleJS不僅完全開源,還配備著中文文檔這可真的是用著放心也開心!

    具體實(shí)現(xiàn)

    安裝:

    npm install exceljs
    npm install file-saver

    創(chuàng)建workbook,添加名為Demo的sheet,設(shè)置默認(rèn)行高為20,設(shè)置列(表頭);

    添加行信息(allData前端頁面表格中的數(shù)據(jù));

    最后給表頭添加顏色。

        // 創(chuàng)建工作簿
        const workbook = new ExcelJs.Workbook();
        // 添加sheet
        const worksheet = workbook.addWorksheet('Demo');
        // 設(shè)置 sheet 的默認(rèn)行高
        worksheet.properties.defaultRowHeight = 20;
        // 設(shè)置列
        worksheet.columns = [
          { header: 'Index', key: 'index', width: 10 },
          { header: 'Name', key: 'name', width: 25 },
          { header: 'Type', key: 'group', width: 25, outlineLevel: 1 },
          { header: 'Group', key: 'type', width: 25, outlineLevel: 1 },
          { header: 'Region', key: 'modbusRegion', width: 25, outlineLevel: 1 },
          { header: 'Address', key: 'modbusAddress', width: 25, outlineLevel: 1 },
        ];
        // 添加行
        worksheet.addRows(allData);
        // 給表頭添加背景色
        let headerRow = worksheet.getRow(1);
        headerRow.eachCell((cell) => {
          cell.fill = {
            type: 'pattern',
            pattern: 'solid',
            fgColor: {argb: 'dde0e7'},
          }
        })
    • 將自動(dòng)篩選器設(shè)置為從 A2 到 F1 (Group、Type、Region)

        // 將自動(dòng)篩選器設(shè)置為從 A2 到 F1
        worksheet.autoFilter = {
          from: 'C1',
          to: 'E1',
        }
    • 鎖定整個(gè)excel表格,可篩選但不能選中鎖定的單元格

        // 鎖定工資表
        await worksheet.protect('the-password', 
                                 {
                                  autoFilter:true,
                                  selectLockedCells:false,
                                  });
    • 通過循環(huán)判斷,哪些單元格可以被用戶操作,并且判斷該單元格的輸入限制是什么

       const allData = [...this.state.dataSource]
       let length = allData.length
       for(let i = 0 ;i < length; i++){
          // Region的輸入范圍
          let coilArr = ['"Coil,Discrete Input"']
          let registerArr = ['"Holding Register,Input Register"']
          let listArr = []
          if(allData[i].type === 'BOOL'){
            listArr = coilArr
          }
          else{
            listArr = registerArr
          }
          // 可編輯的單元格在E、F中
          worksheet.getCell(`E${i+2}`).protection = {
            locked: false,
          };
          // Region的輸入校驗(yàn)
          worksheet.getCell(`E${i+2}`).dataValidation = {
            type: 'list',
            allowBlank: true,
            formulae: listArr,
            showErrorMessage: true,
            errorTitle: '非法輸入',
            error: '取值范圍為:'+listArr
          };
          worksheet.getCell(`F${i+2}`).protection = {
            locked: false,
          };
          // Address的輸入校驗(yàn)
          worksheet.getCell(`F${i+2}`).dataValidation = {
            type: 'whole',
            operator: 'between',
            allowBlank: true,
            showErrorMessage: true,
            formulae: [0,65535],
            errorTitle: '非法輸入',
            error: '取值范圍為:[0,65535]'
          };
        }

    以上的代碼中,worksheet.getCell(E${i+2}).dataValidation是進(jìn)行單元格數(shù)據(jù)驗(yàn)證的函數(shù),具體的使用可參考官方文檔。

    • 導(dǎo)出名為"xlsx-demo.xlsx"的excel文件

        // 導(dǎo)出excel
        this.saveWorkbook(workbook, 'xlsx-demo.xlsx');

    結(jié)果展示

    • Group、Type、Region可篩選(?)

    前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

    • 紅色框內(nèi)的數(shù)據(jù),用戶不可操作,藍(lán)色框內(nèi)用戶可以操作(?)

    前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

    • 當(dāng)Type的值為BOOL時(shí),Region的有效輸入為:["Holding Register","Input Register"],否則為:["Coil","Discrete Input"](?)

    前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

    前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

    前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

    用戶輸入錯(cuò)誤給出錯(cuò)誤提醒,并且不保存錯(cuò)誤數(shù)據(jù)。

    • Address的輸入范圍為:[0,65535](?)

    前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件

    用戶輸入錯(cuò)誤給出錯(cuò)誤提醒,并且不保存錯(cuò)誤數(shù)據(jù)。

    整個(gè)函數(shù)展示

      // 導(dǎo)出xls
      exportXLS = async () =>{
        const allData = [...this.state.dataSource]
        let length = allData.length
        // 創(chuàng)建工作簿
        const workbook = new ExcelJs.Workbook();
        // 添加sheet
        const worksheet = workbook.addWorksheet('demo');
        // 設(shè)置 sheet 的默認(rèn)行高
        worksheet.properties.defaultRowHeight = 20;
        // 設(shè)置列
        worksheet.columns = [
          { header: 'Index', key: 'index', width: 10 },
          { header: 'Name', key: 'name', width: 25 },
          { header: 'Group', key: 'group', width: 25, outlineLevel: 1 },
          { header: 'Type', key: 'type', width: 25, outlineLevel: 1 },
          { header: 'Region', key: 'modbusRegion', width: 25, outlineLevel: 1 },
          { header: 'Address', key: 'modbusAddress', width: 25, outlineLevel: 1 },
        ];
        // 添加行
        worksheet.addRows(allData);
        // 給表頭添加背景色
        let headerRow = worksheet.getRow(1);
        // 通過 cell 設(shè)置背景色,更精準(zhǔn)
        headerRow.eachCell((cell) => {
          cell.fill = {
            type: 'pattern',
            pattern: 'solid',
            fgColor: {argb: 'dde0e7'},
          }
        })
        // 將自動(dòng)篩選器設(shè)置為從 C1 到 F1
        worksheet.autoFilter = {
          from: 'C1',
          to: 'E1',
        }
        // 鎖定工資表
        await worksheet.protect('the-password', 
                                 {
                                  autoFilter:true,
                                  selectLockedCells:false,
                                  });
        // 判斷哪些單元格可以被用戶操作,并且判斷該單元格的輸入限制是什么
        for(let i = 0 ;i < length; i++){
          // 根據(jù)不同類型選擇篩選的框
          let coilArr = ['"Coil,Discrete Input"']
          let registerArr = ['"Holding Register,Input Register"']
          let listArr = []
          if(allData[i].type === 'BOOL'){
            listArr = coilArr
          }
          else{
            listArr = registerArr
          }
          // 可編輯的單元格在E、F中
          worksheet.getCell(`E${i+2}`).protection = {
            locked: false,
          };
          worksheet.getCell(`E${i+2}`).dataValidation = {
            type: 'list',
            allowBlank: true,
            formulae: listArr,
            showErrorMessage: true,
            errorTitle: '非法輸入',
            error: '取值范圍為:'+listArr
          };
          worksheet.getCell(`F${i+2}`).protection = {
            locked: false,
          };
          worksheet.getCell(`F${i+2}`).dataValidation = {
            type: 'whole',
            operator: 'between',
            allowBlank: true,
            showErrorMessage: true,
            formulae: [0,65535],
            errorTitle: '非法輸入',
            error: '取值范圍為:[0,65535]'
          };
        }
        // 導(dǎo)出excel
        this.saveWorkbook(workbook, 'xlsx-demo.xlsx');
      }

    關(guān)于“前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“前端如何使用xlsx庫導(dǎo)出帶有樣式的excel文件”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI