| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { notification } from 'antd' |
| | | import * as XLSX from 'xlsx' |
| | | import * as XLSX from 'sheetjs-style' |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | class ExcelIn extends Component { |
| | | static propTpyes = { |
| | | btn: PropTypes.object, // 按钮信息 |
| | | MenuID: PropTypes.string, // 菜单ID |
| | | returndata: PropTypes.func // 获取返回数据 |
| | | btn: PropTypes.object, // 按钮信息 |
| | | returndata: PropTypes.func, // 获取返回数据 |
| | | triggerExcelIn: PropTypes.func // 修改上传状态 |
| | | } |
| | | |
| | | state = { |
| | |
| | | |
| | | exceltrigger = () => { |
| | | const { excelId } = this.state |
| | | let _excelInput = document.getElementById(excelId + this.props.MenuID) |
| | | let _excelInput = document.getElementById(excelId) |
| | | |
| | | if (_excelInput) { |
| | | _excelInput.click() |
| | |
| | | onImportExcel = file => { |
| | | const { btn } = this.props |
| | | |
| | | let columns = btn.verify.columns.map(option => option.Column) |
| | | let range = btn.verify.range || 0 |
| | | |
| | | // excel数据处理 |
| | | const { files } = file.target |
| | | const fileReader = new FileReader() |
| | | |
| | | this.props.triggerExcelIn() |
| | | fileReader.onload = event => { |
| | | try { |
| | | const { result } = event.target |
| | | // 以二进制流方式读取得到整份excel表格对象 |
| | | const workbook = XLSX.read(result, { type: 'binary' }) |
| | | |
| | | let errors = null |
| | | |
| | | if (!workbook.Sheets.hasOwnProperty(btn.verify.sheet)) { |
| | | errors = 'notexit' |
| | | } else if (range === 1) { |
| | | let header = XLSX.utils.sheet_to_json(workbook.Sheets[btn.verify.sheet], {header: columns})[0] |
| | | |
| | | if (!header) { |
| | | errors = 'empty' |
| | | } else { |
| | | let iserror = false |
| | | btn.verify.columns.forEach(op => { |
| | | if (header[op.Column] !== op.Text) { |
| | | iserror = true |
| | | } |
| | | }) |
| | | |
| | | if (iserror) { |
| | | errors = 'headerError' |
| | | if (btn.verify.excelHandle === 'true') { |
| | | // eslint-disable-next-line |
| | | let func = new Function('XLSX', 'workbook', 'btn', 'callback', btn.verify.excel_func) |
| | | func(XLSX, workbook, btn.verify, (data, error) => { |
| | | if (!error && (!data || data.length === 0)) { |
| | | error = '未获取到Excel数据!' |
| | | } |
| | | this.props.returndata(data, error) |
| | | }) |
| | | } else { |
| | | let btnColumns = btn.verify.columns.filter(option => option.import !== 'init') |
| | | let columns = btnColumns.map(option => option.Column) |
| | | let range = btn.verify.range || 0 |
| | | |
| | | let error = null |
| | | let sheetName = btn.verify.sheet |
| | | |
| | | if (sheetName === 'Sheet1' && Object.keys(workbook.Sheets).length === 1) { |
| | | sheetName = Object.keys(workbook.Sheets)[0] |
| | | } |
| | | |
| | | if (!workbook.Sheets.hasOwnProperty(sheetName)) { |
| | | error = '工作表《' + sheetName + '》不存在!' |
| | | } else if (range === 1) { |
| | | let header = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {header: columns})[0] |
| | | |
| | | if (!header) { |
| | | error = '工作表《' + sheetName + '》为空!' |
| | | } else { |
| | | btnColumns.forEach(op => { |
| | | if (error) return |
| | | |
| | | let _name = typeof(header[op.Column]) === 'string' ? header[op.Column].replace(/(^\s*|\s*$)/g, '') : header[op.Column] |
| | | let _text = op.Text ? op.Text.replace(/(^\s*|\s*$)/g, '') : op.Text |
| | | |
| | | if (!_name) { |
| | | error = `工作表《${sheetName}》表头错误,Excel中不存在(${_text})列!` |
| | | } else if (_name !== _text) { |
| | | error = `工作表《${sheetName}》表头错误,Excel中(${_name})与按钮列信息(${_text})不一致!` |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | let data = [] |
| | | |
| | | if (!error) { |
| | | data = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {header: columns, range: (range)}) |
| | | |
| | | if (!data || data.length === 0) { |
| | | error = '未获取到工作表《' + sheetName + '》数据!' |
| | | } |
| | | } |
| | | |
| | | // 最终获取到并且格式化后的 json 数据 |
| | | this.props.returndata(data, error) |
| | | } |
| | | |
| | | let data = [] |
| | | |
| | | if (!errors) { |
| | | data = XLSX.utils.sheet_to_json(workbook.Sheets[btn.verify.sheet], {header: columns, range: (range)}) |
| | | } |
| | | |
| | | // 最终获取到并且格式化后的 json 数据 |
| | | this.props.returndata(data, errors) |
| | | this.setState({ |
| | | excelId: '', |
| | | }, () => { |
| | |
| | | excelId: Utils.getuuid() |
| | | }) |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '文件解析错误,请检查文件格式!', |
| | | duration: 5 |
| | | }) |
| | | // 错误传递 |
| | | this.props.returndata([], 'other') |
| | | this.props.returndata([], '文件解析错误!') |
| | | } |
| | | } |
| | | |
| | |
| | | render() { |
| | | return ( |
| | | <span> |
| | | {this.state.excelId ? <input className="excel-in-input" id={this.state.excelId + this.props.MenuID} type='file' accept='.xlsx, .xls' onChange={this.onImportExcel} /> : null} |
| | | {this.state.excelId ? <input className="excel-in-input" id={this.state.excelId} type='file' accept='.xlsx, .xls' onAbort={this.onImportExcel} onChange={this.onImportExcel} /> : null} |
| | | </span> |
| | | ) |
| | | } |