React讀取Excel——js-xlsx 外掛的使用
介紹
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; }
來源:https://www.cnblogs.com/wx1993/p/9792716.html