zoukankan      html  css  js  c++  java
  • 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;
    }

    【参考】

    前端读取Excel报表文件

    SheetJS的使用(js-xlsx)

    SheetJS js-xlsx

    webpack externals 深入理解

     
  • 相关阅读:
    SharedPreferences 使用
    activity在activity上面
    组合组件
    浏览器的渲染原理
    Node 入门<1>
    css 样式优先级
    z-index
    事件代理
    XSS && CRLF && property&attribute
    webpack 学习笔记
  • 原文地址:https://www.cnblogs.com/wx1993/p/9792716.html
Copyright © 2011-2022 走看看