'use strict'; import React, { useState, useEffect } from 'react'; import { connect } from 'react-redux'; import { Modal, Form, Button, Notification } from '@douyinfe/semi-ui'; import { IconUpload } from '@douyinfe/semi-icons'; import XLSX from 'xlsx'; import moment from 'moment'; //下载模板和上传文件读取 const ImportModal = props => { const { dispatch, actions, user, onCancel } = props const { humanAffairs } = actions; const [msg, setMsg] = useState('') const [loading, setLoading] = useState('') const [postData, setPostData] = useState([]) //初始化 useEffect(() => { }, []); const confirm = () => { if (postData.length) { setLoading(true) dispatch(humanAffairs.importDepartmentTrainRecord(postData)).then(res => { if (res.success) { onCancel() } setLoading(false) }) } else { Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 }) } } const download = () => { const head = [["部门", "实际培训类型", "培训时间", "培训内容", "培训针对人群", "培训讲师", "培训方式", "考核形式", "培训时长"]]; let sheetName = '部门培训台账'; let workbook = { SheetNames: [sheetName], Sheets: {} }; workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet(head);//json转excel workbook.Sheets[sheetName]['!cols'] = [ { wch: 12 }, { wch: 12 }, { wch: 15 }, { wch: 20 }, { wch: 12 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }]; let wopts = { bookType: 'xlsx', type: 'buffer' };// 生成excel的配置项 XLSX.writeFile(workbook, '部门培训记录导入模板.xlsx', wopts); } const error = (msg) => { setMsg(msg) onError({ message: msg }) } const getFileBlob = (url) => { return new Promise((resolve, reject) => { let request = new XMLHttpRequest() request.open("GET", url, true) request.responseType = "blob" request.onreadystatechange = e => { if (request.readyState == 4) { if (request.status == 200) { if (window.FileReader) { let reader = new FileReader(); reader.readAsBinaryString(request.response); reader.onload = event => { try { const { result } = event.target; // 以二进制流方式读取得到整份excel表格对象 const workbook = XLSX.read(result, { type: "binary", cellDates: true,//设为true,将天数的时间戳转为时间格式 codepage: 936//解决了乱码问题 }); let data = []; // 存储获取到的数据 // 遍历每张工作表进行读取(这里默认只读取第一张表) for (const sheet in workbook.Sheets) { if (workbook.Sheets.hasOwnProperty(sheet)) { data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet])); } } resolve(data);//导出数据 } catch (e) { reject("失败"); error(`文件解析失败,请检查编码格式`) } } } } } } request.send(); }) } const judgeNull = (value) => { return value ? String(value).trim().replace(/\s*/g, "") : null; } const changeTime = (v) => { //注意的点:xlsx将excel中的时间内容解析后,会小一天 //如2020/8/1,xlsx会解析成 Fri Jul 31 2020 23:59:17 GMT+0800 小了43秒 let a = new Date(v); a.setTime(a.getTime() + 43 * 1000); return a; } return ( { setMsg('') setLoading(false) setPostData([]) onCancel() }} >
{ setMsg(''); setPostData([]); }} customRequest={(data) => { const { file, onSuccess, onError } = data getFileBlob(file.url).then(res => { if (res.length > 1000) { error('一次性上传数据行数应小于1000行,请分批上传') return } if (!res.length) { error('请填写至少一行数据') return } let postData = []; let ymdhms = /([0-9]{3}[1-9]|[0-9][1-9][0-9]2022-01-07 19:29:33|[0-9]2022-01-07 19:29:33[1-9][0-9]|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))([ ])([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])/; for (let i = 0; i < res.length; i++) { let d = res[i]; let departmentName = judgeNull(d['部门']); let trainingType = judgeNull(d['实际培训类型']); let trainDate = d['培训时间']; let trainContent = judgeNull(d['培训内容']); let trainWho = judgeNull(d['培训针对人群']); let trainer = judgeNull(d['培训讲师']); let trainMethod = judgeNull(d['培训方式']); let appraisalMethod = judgeNull(d['考核形式']); let trainTime = judgeNull(d['培训时长']); if (!departmentName) { error(`第${i + 2}行【部门】为空,请填写`) return } if (user.allDepartment && user.allDepartment.departments) { let dept = user.allDepartment.departments.find(d => !d.delete && d.name === departmentName); if (dept) { departmentName = dept.name; } else { error(`第${i + 2}行【部门】数据有误,请确认后重新填写`) return } } if (!trainingType) { error(`第${i + 2}行【实际培训类型】为空,请填写`) return } if (!trainDate) { error(`第${i + 2}行【培训时间】为空,请填写`) return } if (trainDate instanceof Date) { trainDate = moment(trainDate).format("YYYY-MM-DD HH:mm:ss"); if (!ymdhms.test(trainDate)) { error(`第${i + 2}行【培训时间】填写错误,请填写yyyy/mm/dd hh:mm格式`) return } } else { error(`第${i + 2}行【培训时间】填写错误,请确认后重新填写`) return } trainDate = changeTime(trainDate); if (!trainContent) { error(`第${i + 2}行【培训内容】为空,请填写`) return } if (!trainMethod) { error(`第${i + 2}行【培训方式】为空,请填写`) return } if (!appraisalMethod) { error(`第${i + 2}行【考核形式】为空,请填写`) return } if (!trainTime) { error(`第${i + 2}行【培训时长】为空,请填写`) return } postData.push({ departmentName, trainingType, trainDate, trainContent, trainWho: trainWho || '', trainer: trainer || '', trainMethod, appraisalMethod, trainTime, origin: 'import' }) } setPostData(postData) let msg = '文件解析完成,点击确定按钮上传保存!' setMsg(msg) onSuccess({ message: msg }) }) }}> {msg}
最大不超过200M,导入文件需与 download()} style={{ cursor: 'pointer', color: '#0066FF' }}>导入模板 一致
) } function mapStateToProps(state) { const { auth, global } = state; return { user: auth.user, actions: global.actions, } } export default connect(mapStateToProps)(ImportModal);