ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelListener.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelResult.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-ui/src/views/demo/demo/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelListener.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,116 @@ package com.ruoyi.common.utils.poi; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.fastjson.JSON; import com.ruoyi.common.utils.ValidatorUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.validation.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * å ¬å ±excelçå¬ç±» * @param <T> */ public class ExcelListener<T> extends AnalysisEventListener<T> { private static final Logger LOGGER = LoggerFactory.getLogger(ExcelListener.class); /** æ°æ®å¯¹è±¡list */ private final List<T> list = new ArrayList<>(); /** é误信æ¯å表 */ private final List<String> errorList = new ArrayList<>(); /** éå°å¼å¸¸æ¯å¦è·³åºå¯¼å ¥ï¼é»è®¤ä¸ºæ¯ */ private Boolean skipException = Boolean.TRUE; /** æ¯å¦Validatoræ£éªï¼é»è®¤ä¸ºæ¯ */ private Boolean isValidate = Boolean.TRUE; /** * å¯¼å ¥åæ§ */ private final ExcelResult<T> excelResult = new ExcelResult<>(); public ExcelListener() { } public ExcelListener(boolean isValidate, boolean skipException) { this.isValidate = isValidate; this.skipException = skipException; } /** * å¤çå¼å¸¸ * * @param exception ExcelDataConvertException * @param context excelä¸ä¸æ */ @Override public void onException(Exception exception, AnalysisContext context) throws Exception { // å¦ææ¯æä¸ä¸ªåå æ ¼ç转æ¢å¼å¸¸ è½è·åå°å ·ä½è¡å· // 妿è¦è·å头çä¿¡æ¯ é ådoAfterAllAnalysedHeadMapä½¿ç¨ String errMsg = null; if (exception instanceof ExcelDataConvertException) { ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception; errMsg = StrUtil.format("第{}è¡-第{}åè§£æå¼å¸¸<br/>", excelDataConvertException.getRowIndex() + 1, excelDataConvertException.getColumnIndex() + 1); LOGGER.error(errMsg); } if (exception instanceof ConstraintViolationException) { ConstraintViolationException constraintViolationException = (ConstraintViolationException)exception; Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations(); String constraintViolationsMsg= CollUtil.join(constraintViolations .stream() .map(ConstraintViolation::getMessage) .collect(Collectors.toList()), ","); errMsg = StrUtil.format("第{}è¡æ°æ®æ ¡éªå¼å¸¸:{}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg); LOGGER.error(errMsg); } errorList.add(errMsg); if (!skipException){ throw new ExcelAnalysisException(errMsg); } } @Override public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { LOGGER.debug("è§£æå°ä¸æ¡å¤´æ°æ®:{}", JSON.toJSONString(headMap)); } @Override public void invoke(T data, AnalysisContext context) { if (isValidate) { ValidatorUtils.validate(data); } list.add(data); } @Override public void doAfterAllAnalysed(AnalysisContext context) { excelResult.setList(list); excelResult.setErrorList(errorList); LOGGER.debug("æææ°æ®è§£æå®æï¼"); } /** * è·åå¯¼å ¥æ°æ® * @return å¯¼å ¥æ°æ® */ public List<T> getList() { return list; } public ExcelResult<T> getExcelResult() { return excelResult; } } ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelResult.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,40 @@ package com.ruoyi.common.utils.poi; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import lombok.Data; import java.util.ArrayList; import java.util.List; @Data public class ExcelResult<T> { /** æ°æ®å¯¹è±¡list */ private List<T> list; /** é误信æ¯å表 */ private List<String> errorList; /** * è·åå¯¼å ¥åæ§ * @return å¯¼å ¥åæ§ */ public String getAnalysis() { int successCount = list.size(); int errorCount = errorList.size(); if (successCount == 0) { return "读åå¤±è´¥ï¼æªè§£æå°æ°æ®"; } else { if (errorList.size() == 0) { return StrUtil.format("æåæ¨ï¼å ¨é¨è¯»åæåï¼å ±{}æ¡", successCount); } else { return StrUtil.format("é¨å读åæåï¼å ¶ä¸æå{}æ¡ï¼å¤±è´¥{}æ¡ï¼é误信æ¯å¦ä¸ï¼<br/>{}", successCount, errorCount, CollUtil.join(errorList, "<br/>")); } } } } ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -6,6 +6,7 @@ import com.ruoyi.common.convert.ExcelBigNumberConvert; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUtils; import org.apache.poi.ss.formula.functions.T; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; @@ -30,6 +31,19 @@ return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync(); } /** * 对excel表åé»è®¤ç¬¬ä¸ä¸ªç´¢å¼åè½¬æ¢ælistï¼EasyExcelï¼ * * @param is è¾å ¥æµ * @return 转æ¢åéå */ public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, boolean isValidate, boolean skipException) { ExcelListener<T> listener = new ExcelListener<>(isValidate, skipException); EasyExcel.read(is, clazz, listener).sheet().doRead(); return listener.getExcelResult(); } /** * 对listæ°æ®æºå°å ¶éé¢çæ°æ®å¯¼å ¥å°excel表åï¼EasyExcelï¼ * ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
@@ -1,27 +1,31 @@ package com.ruoyi.demo.controller; import cn.hutool.core.bean.BeanUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import com.ruoyi.common.core.validate.QueryGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.ValidatorUtils; import com.ruoyi.common.utils.poi.ExcelResult; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.demo.domain.TestDemo; import com.ruoyi.demo.domain.bo.TestDemoBo; import com.ruoyi.demo.domain.bo.TestDemoImportVo; import com.ruoyi.demo.domain.vo.TestDemoVo; import com.ruoyi.demo.service.ITestDemoService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.*; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; @@ -65,6 +69,21 @@ return iTestDemoService.customPageList(bo); } @ApiOperation("å¯¼å ¥æµè¯å表") @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "å¯¼å ¥æä»¶", dataType = "java.io.File", required = true), }) @Log(title = "æµè¯å表", businessType = BusinessType.IMPORT) @PreAuthorize("@ss.hasPermi('demo:demo:import')") @PostMapping("/importData") public AjaxResult<Void> importData(@RequestPart("file") MultipartFile file) throws Exception { ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true, true); List<TestDemoImportVo> volist = excelResult.getList(); List<TestDemo> list = BeanUtil.copyToList(volist, TestDemo.class); iTestDemoService.saveAll(list); return AjaxResult.success(excelResult.getAnalysis()); } /** * å¯¼åºæµè¯å表å表 */ ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,66 @@ package com.ruoyi.demo.domain.bo; import com.alibaba.excel.annotation.ExcelProperty; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; /** * æµè¯å表ä¸å¡å¯¹è±¡ test_demo * * @author Lion Li * @date 2021-07-26 */ @Data @ApiModel("æµè¯å表ä¸å¡å¯¹è±¡") public class TestDemoImportVo { /** * é¨é¨id */ @ApiModelProperty("é¨é¨id") @NotNull(message = "é¨é¨idä¸è½ä¸ºç©º") @ExcelProperty(value = "é¨é¨id") private Long deptId; /** * ç¨æ·id */ @ApiModelProperty("ç¨æ·id") @NotNull(message = "ç¨æ·idä¸è½ä¸ºç©º") @ExcelProperty(value = "ç¨æ·id") private Long userId; /** * æåºå· */ @ApiModelProperty("æåºå·") @NotNull(message = "æåºå·ä¸è½ä¸ºç©º") @ExcelProperty(value = "æåºå·") private Long orderNum; /** * keyé® */ @ApiModelProperty("keyé®") @NotBlank(message = "keyé®ä¸è½ä¸ºç©º") @ExcelProperty(value = "keyé®") private String testKey; /** * å¼ */ @ApiModelProperty("å¼") @NotBlank(message = "å¼ä¸è½ä¸ºç©º") @ExcelProperty(value = "å¼") private String value; } ruoyi-ui/src/views/demo/demo/index.vue
@@ -73,6 +73,16 @@ </el-col> <el-col :span="1.5"> <el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['demo:demo:import']" >å¯¼å ¥</el-button> </el-col> <el-col :span="1.5"> <el-button type="warning" plain icon="el-icon-download" @@ -164,11 +174,34 @@ <el-button @click="cancel">å æ¶</el-button> </div> </el-dialog> <!-- ç¨æ·å¯¼å ¥å¯¹è¯æ¡ --> <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body> <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag > <i class="el-icon-upload"></i> <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> </el-upload> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> <el-button @click="upload.open = false">å æ¶</el-button> </div> </el-dialog> </div> </template> <script> import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo"; import {getToken} from "@/utils/auth"; export default { name: "Demo", @@ -198,6 +231,19 @@ open: false, // å建æ¶é´æ¶é´èå´ daterangeCreateTime: [], // ç¨æ·å¯¼å ¥åæ° upload: { // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼ç¨æ·å¯¼å ¥ï¼ open: false, // å¼¹åºå±æ é¢ï¼ç¨æ·å¯¼å ¥ï¼ title: "", // æ¯å¦ç¦ç¨ä¸ä¼ isUploading: false, // 设置ä¸ä¼ ç请æ±å¤´é¨ headers: { Authorization: "Bearer " + getToken() }, // ä¸ä¼ çå°å url: process.env.VUE_APP_BASE_API + "/demo/demo/importData" }, // æ¥è¯¢åæ° queryParams: { pageNum: 1, @@ -353,11 +399,32 @@ this.loading = false; }); }, /** å¯¼å ¥æé®æä½ */ handleImport() { this.upload.title = "ç¨æ·å¯¼å ¥"; this.upload.open = true; }, /** å¯¼åºæé®æä½ */ handleExport() { this.download('demo/demo/export', { ...this.queryParams }, `demo_${new Date().getTime()}.xlsx`) }, // æä»¶ä¸ä¼ ä¸å¤ç handleFileUploadProgress(event, file, fileList) { this.upload.isUploading = true; }, // æä»¶ä¸ä¼ æåå¤ç handleFileSuccess(response, file, fileList) { this.upload.open = false; this.upload.isUploading = false; this.$refs.upload.clearFiles(); this.$alert(response.msg, "å¯¼å ¥ç»æ", { dangerouslyUseHTMLString: true }); this.getList(); }, // æäº¤ä¸ä¼ æä»¶ submitFileForm() { this.$refs.upload.submit(); } } };