1. 程式人生 > >React讀取Excel——js-xlsx 插件的使用

React讀取Excel——js-xlsx 插件的使用

segment loader put com accep erro https absolut dmi

介紹

SheetJS js-xlsx 是一款能夠讀寫多種格式表格的插件,瀏覽器支持良好,並且能在多個語言平臺上使用,目前在 github 上有 12602 個 star,

剛好項目中遇到了前端解析 excel 的需求,所以就嘗試使用了一下,這裏將使用方法和遇到的問題簡單記錄一下。

插件地址:https://github.com/SheetJS/js-xlsx

使用

1. 安裝依賴

進入項目文件夾,安裝 xlsx

npm install xlsx

2. 在項目中引入

import * as XLSX from ‘xlsx‘;

3. 定義上傳 input

<input type=‘file‘ accept=‘.xlsx, .xls‘ onChange={this.onImportExcel} />
accept 屬性定義了上傳文件支持的類型,onChange 操作中的 importExcel 方法定義了上傳文件時執行的操作。

4. 定義獲取和解析 excel 對象的方法

onImportExcel = file => {
    // 獲取上傳的文件對象
    const { files } = file.target;
    // 通過FileReader對象讀取文件
    const fileReader = new FileReader();
    fileReader.onload = event => {
      try {
        const { result } 
= event.target; // 以二進制流方式讀取得到整份excel表格對象 const workbook = XLSX.read(result, { type: ‘binary‘ }); let data = []; // 存儲獲取到的數據 // 遍歷每張工作表進行讀取(這裏默認只讀取第一張表) for (const sheet in workbook.Sheets) { if (workbook.Sheets.hasOwnProperty(sheet)) {
// 利用 sheet_to_json 方法將 excel 轉成 json 數據 data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet])); // break; // 如果只取第一張表,就取消註釋這行 } } console.log(data); } catch (e) { // 這裏可以拋出文件類型錯誤不正確的相關提示 console.log(‘文件類型不正確‘); return; } }; // 以二進制方式打開文件 fileReader.readAsBinaryString(files[0]); }

定義方法後在瀏覽器中報了如下錯誤:

技術分享圖片

Failed to compile
./node_modules/xlsx/dist/cpexcel.js
Module not found: Can‘t resolve ‘./cptable‘ in ‘/Users/wangxi/Desktop/Code/admin/node_modules/xlsx/dist‘

大意是說在 cpexcel.js 文件中找不到 ./captable 模塊,於是在 github 上的 issue 中輸入問題,發現問題還是挺普遍的,官方給出的解決方案如下:

技術分享圖片

即在 webpack 配置文件中添加如下 external 配置:

externals: [
    {
        ‘./cptable‘: ‘var cptable‘,
        ‘../xlsx.js‘: ‘var _XLSX‘
    }
]        

保存並重新編譯,瀏覽器又拋出如下錯誤:

The externals config must be Plain Object or Function, but got [object Object]

"externals 配置項必須為純對象或函數,但是卻得到了對象形式的數組",所以原因是 externals 的格式不對:

externals 配置支持三種形式,分別是 Array、Object 和 Reg,上述的配置項內容是一個對象,所以應該為用 Object 形式,所以只要把外面的中括號去掉就可以了:

externals: {
    ‘./cptable‘: ‘var cptable‘,
    ‘../xlsx.js‘: ‘var _XLSX‘
 }

更多關於 webpack externals 配置的學習,可以參考:【webpack externals 深入理解】

測試

運行代碼,在瀏覽器中打開頁面顯示如下:

技術分享圖片

點擊 Choose File,在本地選擇一個內容如下的 excel 文件:

技術分享圖片

點擊確定,上傳後在瀏覽器控制臺查看打印信息:

技術分享圖片

可以發現,excel 已經讀取成功並且轉換成了 json 格式的數據,之後就可以對 json 數據進行分析和處理啦。

完善

1. 使用原生 input 標簽顯示效果比較粗糙,因為對組件簡單地進行了樣式上的美化,效果如下:

技術分享圖片

2. 針對文件上傳和讀取結果分別做了對應的提示(這裏使用 ant design 中的 message 組件)

技術分享圖片 技術分享圖片

demo 完整代碼如下:

// excel.js
import React, { Component } from ‘react‘;
import { Button, Icon, message } from ‘antd‘;
import * as XLSX from ‘xlsx‘;
import styles from ‘./index.less‘;

class Excel extends Component {
  onImportExcel = file => {
    // 獲取上傳的文件對象
    const { files } = file.target;
    // 通過FileReader對象讀取文件
    const fileReader = new FileReader();
    fileReader.onload = event => {
      try {
        const { result } = event.target;
        // 以二進制流方式讀取得到整份excel表格對象
        const workbook = XLSX.read(result, { type: ‘binary‘ });
         // 存儲獲取到的數據
        let data = [];
        // 遍歷每張工作表進行讀取(這裏默認只讀取第一張表)
        for (const sheet in workbook.Sheets) {
          // esline-disable-next-line
          if (workbook.Sheets.hasOwnProperty(sheet)) {
            // 利用 sheet_to_json 方法將 excel 轉成 json 數據
            data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
            // break; // 如果只取第一張表,就取消註釋這行
          }
        }
        // 最終獲取到並且格式化後的 json 數據
        message.success(‘上傳成功!‘)
        console.log(data);
      } catch (e) {
        // 這裏可以拋出文件類型錯誤不正確的相關提示
        message.error(‘文件類型不正確!‘);
      }
    };
    // 以二進制方式打開文件
    fileReader.readAsBinaryString(files[0]);
  }
  render() {
    return (
      <div style={{ marginTop: 100 }}>
        <Button className={styles[‘upload-wrap‘]}>
          <Icon type=‘upload‘ />
          <input className={styles[‘file-uploader‘]} type=‘file‘ accept=‘.xlsx, .xls‘ onChange={this.onImportExcel} />
          <span className={styles[‘upload-text‘]}>上傳文件</span>
        </Button>
        <p className={styles[‘upload-tip‘]}>支持 .xlsx、.xls 格式的文件</p>
      </div >
    );
  }
}

export default Excel;
// index.less
.upload-wrap {
  display: inline-block;
  position: relative;
  width: 124px;
  padding: 3px 5px;
  overflow: hidden;
}

.file-uploader {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  outline: none;
  opacity: 0;
  background-color: transparent;
}

.upload-text {
  display: inline-block;
  margin-left: 5px;
}

.upload-tip {
  display: inline-block;
  margin-left: 10px;
  color: #999;
}

【參考】

前端讀取Excel報表文件

SheetJS的使用(js-xlsx)

SheetJS js-xlsx

webpack externals 深入理解

技術分享圖片

React讀取Excel——js-xlsx 插件的使用