1、安装 npm install xlsx
一、前端
<el-uploadstyle="display: inline-block"actionaccept=".xlsx, .xls":auto-upload="false":show-file-list="false":on-change="handleUpload"><el-button type="primary" icon="el-icon-upload2" round>导入</el-button></el-upload>
二、逻辑
npm install xlsx <script>/* eslint-disable */import * as XLSX from "xlsx";// 导入handleUpload(ev){let yearMonth =this.selectForm.yearMonth// 如果有数据则给出提示if(this.tableCount >0){this.$confirm(yearMonth+'有数据,是否进行替换?','提示',{confirmButtonText: '确定',cancelButtonText: '取消',type:'warning'}).then(() =>{const file = ev.rawconst fileReader = new FileReader();fileReader.readAsArrayBuffer(file);fileReader.onload = (ev) =>{const data = new Uint8Array(ev.target.result);const workbook = XLSX.read(data, { type: 'array' });const firstSheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[firstSheetName];// 转译范围const range = { s: { r: 2, c: 3 }, e: { r: 32, c: 18 } }this.importData =(XLSX.utils.sheet_to_json(worksheet,{ header: 1,defval:'',range: range}));let formData={list: JSON.parse(JSON.stringify(this.importData)),yearMonth: this.selectForm.yearMonth}importData(formData).then((res) =>{if(res.code == 200){this.getDataList()this.$publicmethod.showMessage("导入成功",this.$publicmethod.SuccessType)}else{this.$publicmethod.showMessage("导入失败-选择的模版不正确!",this.$publicmethod.ErrorType)}})}})}else{const file = ev.rawconst fileReader = new FileReader();fileReader.readAsArrayBuffer(file);fileReader.onload = (ev) =>{const data = new Uint8Array(ev.target.result);const workbook = XLSX.read(data, { type: 'array' });const firstSheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[firstSheetName];// 转译范围const range = { s: { r: 2, c: 3 }, e: { r: 32, c: 18 } }this.importData =(XLSX.utils.sheet_to_json(worksheet,{ header: 1,defval:'',range: range}));let formData={list: JSON.parse(JSON.stringify(this.importData)),yearMonth: this.selectForm.yearMonth}importData(formData).then((res) =>{if(res.code == 200){this.getDataList()this.$publicmethod.showMessage("导入成功",this.$publicmethod.SuccessType)}else{this.$publicmethod.showMessage("导入失败-选择的模版不正确!",this.$publicmethod.ErrorType)}})}}}, </script>
三、接口
export function importData(data) {return request({url: 'api/operation_report/importData',method: 'post',data}) }
四、后端实现
1、控制器类@ApiOperation(value = "导入数据")@PostMapping(value = "/importData")public JsonBean importData( @RequestBody @Validated ReportQueryDo queryDo) {List<String> list =queryDo.getList();String yearMonth = queryDo.getYearMonth();return operationReportService.importData(list,yearMonth);}2、实现类// 导入@Override@Transactional(value = "MainTransactionManager", rollbackFor = Exception.class)public JsonBean importData(List<String> list,String yearMonth) {try{List<OperationReport> addList = new ArrayList<>();// 将 excel数据保存在数据库中,传过来的是字符串,将字符串转成对应的对象进行数据的添加list.stream().forEach(data ->{OperationReport report = new OperationReport();report.setId(SnowIdUtil.getId());report.setYearMonth(yearMonth);JSONArray arrayData =JSON.parseArray(data);// 将数据转换成list集合进行操作if(arrayData !=null){// 公司名称String orgName = arrayData.getString(0);int orgId=getOrgId(orgName);// -1 代表没有当前组织if(orgId != -1){report.setOrgId(orgId);}else{String msg="不存在"+orgName+"公司";logger.error(msg);throw new RuntimeException(msg);}report = changeDataEntity(report,arrayData);addList.add(report);}});// 数据批量添加if(CollectionUtils.isNotEmpty(addList)){// 先删除数据再进行添加Map<String,Object> map = new HashMap<>();map.put("yearMonth",yearMonth);operationReportMapper.delete(map);operationReportMapper.batchInsert(addList);}return new JsonBean(ResultCode.SERVICE_OK);}catch (Exception e){logger.error(e.toString());return new JsonBean(ResultCode.SERVICE_ERR);}}// 将excel表格数据转成实体private OperationReport changeDataEntity(OperationReport report,JSONArray arrayData){// 人员总数String personnelTotalCount = arrayData.getString(1);if(StringUtils.isNotEmpty(personnelTotalCount)){report.setPersonnelTotalCount(Integer.parseInt(personnelTotalCount));}else{report.setPersonnelTotalCount(0);}// 机关人员总数String officialCount = arrayData.getString(2);if(StringUtils.isNotEmpty(officialCount)){report.setOfficialCount(Integer.parseInt(officialCount));}else{report.setOfficialCount(0);}// 一线业务人员String frontLineBusinessCount = arrayData.getString(3);if(StringUtils.isNotEmpty(frontLineBusinessCount)){report.setFrontLineBusinessCount(Integer.parseInt(frontLineBusinessCount));}else{report.setFrontLineBusinessCount(0);}// 车辆总数String vehicleCount = arrayData.getString(4);if(StringUtils.isNotEmpty(vehicleCount)){report.setVehicleCount(Integer.parseInt(vehicleCount));}else{report.setVehicleCount(0);}.....return report;}3、根据公司名称获取对应的公司编号public class ConstantEnum {// 创建HashMap来存储城市公司名称和编号的映射private static HashMap<String,Integer> orgMap = new HashMap<>();// 静态代码块,初始化公司编号数据static{orgMap.put("A",00001);orgMap.put("B",00002);}// 根据公司名称获取公司编号的方法public static int getOrgId(String orgName){return orgMap.containsKey(orgName)?orgMap.get(orgName):-1;}} 4、批量添加xml<!--批量添加 --><insert id="batchInsert" parameterType="java.util.List">insert into operation_report (id,org_id,yearMonth,personnel_total_count) values<foreach collection="list" item="item" index="index" separator=",">(#{item.id},#{item.orgId},#{item.yearMonth},#{item.personnelTotalCount})</foreach></insert>
五、导入的文件模版(行、列数据,只是转译内容,前面的数据不需要)