程序员蜗牛
1 year ago
22 changed files with 805 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||
# easyexcelTest |
|||
根据阿里的easyexcel通过validation+正则实现excel导入校验 |
|||
包含了简单的导入导入导出demo,所涉及到的都是web的导入导出 |
@ -0,0 +1,89 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>2.2.2.RELEASE</version> |
|||
<relativePath/> <!-- lookup parent from repository --> |
|||
</parent> |
|||
<groupId>com.zhy</groupId> |
|||
<artifactId>easyexceldemo</artifactId> |
|||
<version>0.0.1-SNAPSHOT</version> |
|||
<name>easyexceldemo</name> |
|||
<description>Demo project for Spring Boot</description> |
|||
|
|||
<properties> |
|||
<java.version>1.8</java.version> |
|||
</properties> |
|||
|
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-test</artifactId> |
|||
<scope>test</scope> |
|||
<exclusions> |
|||
<exclusion> |
|||
<groupId>org.junit.vintage</groupId> |
|||
<artifactId>junit-vintage-engine</artifactId> |
|||
</exclusion> |
|||
</exclusions> |
|||
</dependency> |
|||
|
|||
<!--easyExcel--> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>easyexcel</artifactId> |
|||
<version>2.1.4</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.apache.poi</groupId> |
|||
<artifactId>poi</artifactId> |
|||
<version>3.17</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.poi</groupId> |
|||
<artifactId>poi-ooxml</artifactId> |
|||
<version>3.17</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>cglib</groupId> |
|||
<artifactId>cglib</artifactId> |
|||
<version>3.1</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.poi</groupId> |
|||
<artifactId>ooxml-schemas</artifactId> |
|||
<version>1.1</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<scope>provided</scope> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>fastjson</artifactId> |
|||
<version>1.2.60</version> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
|
|||
</project> |
@ -0,0 +1,15 @@ |
|||
package com.zhy.easyexceldemo; |
|||
|
|||
import org.springframework.boot.SpringApplication; |
|||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|||
import org.springframework.context.annotation.ComponentScan; |
|||
|
|||
@SpringBootApplication |
|||
@ComponentScan(value = {"com.zhy.easyexceldemo.config","com.zhy"}) |
|||
public class EasyexceldemoApplication { |
|||
|
|||
public static void main(String[] args) { |
|||
SpringApplication.run(EasyexceldemoApplication.class, args); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,20 @@ |
|||
package com.zhy.easyexceldemo.common; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
public class BaseRest { |
|||
|
|||
public Result addSucResult() { |
|||
return this.addResult(true, ResultCodeEnum.SUCCESS.getValue(), ResultCodeEnum.SUCCESS.getLabel(), (Object)null); |
|||
} |
|||
|
|||
public <T> Result addResult(boolean result, String code, String message, T data) { |
|||
Result<T> rs = new Result(); |
|||
rs.setResult(result); |
|||
rs.setCode(code); |
|||
rs.setMessage(message); |
|||
rs.setData(data); |
|||
return rs; |
|||
} |
|||
} |
@ -0,0 +1,20 @@ |
|||
package com.zhy.easyexceldemo.common; |
|||
|
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Data |
|||
public class Result<T> { |
|||
|
|||
public static final String SUCCESS_MSG = "操作成功!"; |
|||
private static final long serialVersionUID = -34684491868853686L; |
|||
private boolean result; |
|||
private String code; |
|||
private String message; |
|||
private String token; |
|||
private Long count; |
|||
private T data; |
|||
|
|||
} |
@ -0,0 +1,28 @@ |
|||
package com.zhy.easyexceldemo.common; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
public enum ResultCodeEnum { |
|||
SUCCESS("200", "操作成功."), |
|||
ERROR("500", "系统未知错误."), |
|||
IMPORT_ERROR("500001", "导入错误."), |
|||
; |
|||
|
|||
|
|||
private final String value; |
|||
private final String label; |
|||
|
|||
private ResultCodeEnum(String value, String label) { |
|||
this.value = value; |
|||
this.label = label; |
|||
} |
|||
|
|||
public String getValue() { |
|||
return this.value; |
|||
} |
|||
|
|||
public String getLabel() { |
|||
return this.label; |
|||
} |
|||
} |
@ -0,0 +1,58 @@ |
|||
package com.zhy.easyexceldemo.config; |
|||
|
|||
|
|||
import com.alibaba.fastjson.serializer.SerializerFeature; |
|||
import com.alibaba.fastjson.support.config.FastJsonConfig; |
|||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.http.converter.HttpMessageConverter; |
|||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Configuration |
|||
public class WebMvcInterceptorConfig extends WebMvcConfigurationSupport { |
|||
|
|||
/** |
|||
* @title: |
|||
* @projectName |
|||
* @description: fastjson处理返回结果 |
|||
* @author zhy |
|||
* @date 2019/9/5 11:32 |
|||
*/ |
|||
@SuppressWarnings("deprecation") |
|||
@Override |
|||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { |
|||
super.configureMessageConverters(converters); |
|||
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); |
|||
List<MediaType> supportedMediaTypes = new ArrayList<>(); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_JSON); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_PDF); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); |
|||
supportedMediaTypes.add(MediaType.APPLICATION_XML); |
|||
supportedMediaTypes.add(MediaType.IMAGE_GIF); |
|||
supportedMediaTypes.add(MediaType.IMAGE_JPEG); |
|||
supportedMediaTypes.add(MediaType.IMAGE_PNG); |
|||
supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); |
|||
supportedMediaTypes.add(MediaType.TEXT_HTML); |
|||
supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); |
|||
supportedMediaTypes.add(MediaType.TEXT_PLAIN); |
|||
supportedMediaTypes.add(MediaType.TEXT_XML); |
|||
fastConverter.setSupportedMediaTypes(supportedMediaTypes); |
|||
FastJsonConfig fastJsonConfig = new FastJsonConfig(); |
|||
fastConverter.setDateFormat("yyyy-MM-dd HH:mm:ss"); |
|||
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullListAsEmpty,SerializerFeature.WriteNullStringAsEmpty); |
|||
fastConverter.setFastJsonConfig(fastJsonConfig); |
|||
converters.add(fastConverter); |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
package com.zhy.easyexceldemo.dto; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import com.alibaba.excel.annotation.write.style.ColumnWidth; |
|||
import com.zhy.easyexceldemo.easyexcel.ExcelPatternMsg; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.hibernate.validator.constraints.Length; |
|||
|
|||
import javax.validation.constraints.Null; |
|||
import javax.validation.constraints.Pattern; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Data |
|||
public class UserExcelDto implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
//名称
|
|||
@ExcelProperty(index = 0,value = "名称") |
|||
@ColumnWidth(30) |
|||
@Length(max = 10) |
|||
private String name; |
|||
|
|||
//性别
|
|||
@ExcelProperty(index = 1,value = "性别") |
|||
@ColumnWidth(30) |
|||
@Length(max = 2) |
|||
private String sex; |
|||
|
|||
//年龄
|
|||
@ExcelProperty(index = 2,value = "年龄") |
|||
@ColumnWidth(30) |
|||
@Pattern(regexp = ExcelPatternMsg.NUMBER,message = ExcelPatternMsg.NUMBER_MSG) |
|||
private String age; |
|||
|
|||
|
|||
//生日
|
|||
@ExcelProperty(index = 3,value = "生日") |
|||
@Pattern(regexp = ExcelPatternMsg.DATE_TIME1,message = ExcelPatternMsg.DATE_TIME1_MSG) |
|||
private String birthday; |
|||
} |
@ -0,0 +1,27 @@ |
|||
package com.zhy.easyexceldemo.dto; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import com.alibaba.excel.annotation.write.style.ColumnWidth; |
|||
import com.zhy.easyexceldemo.easyexcel.ExcelPatternMsg; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.hibernate.validator.constraints.Length; |
|||
|
|||
import javax.validation.constraints.Pattern; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper=false) |
|||
public class UserExcelErrDto extends UserExcelDto { |
|||
|
|||
|
|||
//错误信息
|
|||
@ExcelProperty(index = 4,value = "错误信息") |
|||
@ColumnWidth(50) |
|||
private String errMsg; |
|||
|
|||
|
|||
} |
@ -0,0 +1,130 @@ |
|||
package com.zhy.easyexceldemo.easyexcel; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import com.alibaba.excel.context.AnalysisContext; |
|||
import com.alibaba.excel.event.AnalysisEventListener; |
|||
import com.alibaba.excel.exception.ExcelAnalysisException; |
|||
import com.alibaba.excel.util.StringUtils; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.util.*; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = false) |
|||
public class EasyExcelListener<T> extends AnalysisEventListener<T> { |
|||
|
|||
//成功结果集
|
|||
private List<T> successList = new ArrayList<>(); |
|||
|
|||
//失败结果集
|
|||
private List<ExcelCheckErrDto<T>> errList = new ArrayList<>(); |
|||
|
|||
//处理逻辑service
|
|||
private ExcelCheckManager<T> excelCheckManager; |
|||
|
|||
private List<T> list = new ArrayList<>(); |
|||
|
|||
//excel对象的反射类
|
|||
private Class<T> clazz; |
|||
|
|||
public EasyExcelListener(ExcelCheckManager<T> excelCheckManager) { |
|||
this.excelCheckManager = excelCheckManager; |
|||
} |
|||
|
|||
public EasyExcelListener(ExcelCheckManager<T> excelCheckManager, Class<T> clazz) { |
|||
this.excelCheckManager = excelCheckManager; |
|||
this.clazz = clazz; |
|||
} |
|||
|
|||
@Override |
|||
public void invoke(T t, AnalysisContext analysisContext) { |
|||
String errMsg; |
|||
try { |
|||
//根据excel数据实体中的javax.validation + 正则表达式来校验excel数据
|
|||
errMsg = EasyExcelValiHelper.validateEntity(t); |
|||
} catch (NoSuchFieldException e) { |
|||
errMsg = "解析数据出错"; |
|||
e.printStackTrace(); |
|||
} |
|||
if (!StringUtils.isEmpty(errMsg)) { |
|||
ExcelCheckErrDto excelCheckErrDto = new ExcelCheckErrDto(t, errMsg); |
|||
errList.add(excelCheckErrDto); |
|||
} else { |
|||
list.add(t); |
|||
} |
|||
//每1000条处理一次
|
|||
if (list.size() > 1000) { |
|||
//校验
|
|||
ExcelCheckResult result = excelCheckManager.checkImportExcel(list); |
|||
successList.addAll(result.getSuccessDtos()); |
|||
errList.addAll(result.getErrDtos()); |
|||
list.clear(); |
|||
} |
|||
} |
|||
|
|||
//所有数据解析完成了 都会来调用
|
|||
@Override |
|||
public void doAfterAllAnalysed(AnalysisContext analysisContext) { |
|||
ExcelCheckResult result = excelCheckManager.checkImportExcel(list); |
|||
successList.addAll(result.getSuccessDtos()); |
|||
errList.addAll(result.getErrDtos()); |
|||
list.clear(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* @param headMap 传入excel的头部(第一行数据)数据的index,name |
|||
* @description: 校验excel头部格式,必须完全匹配 |
|||
*/ |
|||
@Override |
|||
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { |
|||
super.invokeHeadMap(headMap, context); |
|||
if (clazz != null) { |
|||
try { |
|||
Map<Integer, String> indexNameMap = getIndexNameMap(clazz); |
|||
Set<Integer> keySet = indexNameMap.keySet(); |
|||
for (Integer key : keySet) { |
|||
if (StringUtils.isEmpty(headMap.get(key))) { |
|||
throw new ExcelAnalysisException("解析excel出错,请传入正确格式的excel"); |
|||
} |
|||
if (!headMap.get(key).equals(indexNameMap.get(key))) { |
|||
throw new ExcelAnalysisException("解析excel出错,请传入正确格式的excel"); |
|||
} |
|||
} |
|||
|
|||
} catch (NoSuchFieldException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
@SuppressWarnings("rawtypes") |
|||
public Map<Integer, String> getIndexNameMap(Class clazz) throws NoSuchFieldException { |
|||
Map<Integer, String> result = new HashMap<>(); |
|||
Field field; |
|||
Field[] fields = clazz.getDeclaredFields(); |
|||
for (int i = 0; i < fields.length; i++) { |
|||
field = clazz.getDeclaredField(fields[i].getName()); |
|||
field.setAccessible(true); |
|||
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); |
|||
if (excelProperty != null) { |
|||
int index = excelProperty.index(); |
|||
String[] values = excelProperty.value(); |
|||
StringBuilder value = new StringBuilder(); |
|||
for (String v : values) { |
|||
value.append(v); |
|||
} |
|||
result.put(index, value.toString()); |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,53 @@ |
|||
package com.zhy.easyexceldemo.easyexcel; |
|||
|
|||
import com.alibaba.excel.EasyExcelFactory; |
|||
import com.alibaba.excel.write.metadata.style.WriteCellStyle; |
|||
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; |
|||
import org.apache.poi.ss.usermodel.IndexedColors; |
|||
|
|||
import javax.servlet.ServletOutputStream; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
public class EasyExcelUtils { |
|||
|
|||
private EasyExcelUtils(){} |
|||
|
|||
|
|||
@SuppressWarnings("rawtypes") |
|||
public static void webWriteExcel(HttpServletResponse response, List objects, Class clazz, String fileName) throws IOException { |
|||
String sheetName = fileName; |
|||
webWriteExcel(response,objects,clazz,fileName,sheetName); |
|||
} |
|||
|
|||
|
|||
@SuppressWarnings("rawtypes") |
|||
public static void webWriteExcel(HttpServletResponse response, List objects, Class clazz, String fileName, String sheetName) throws IOException { |
|||
response.setContentType("application/vnd.ms-excel"); |
|||
response.setCharacterEncoding("utf-8"); |
|||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); |
|||
// 头的策略
|
|||
WriteCellStyle headWriteCellStyle = new WriteCellStyle(); |
|||
// 背景设置为白
|
|||
headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); |
|||
// 内容的策略
|
|||
WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); |
|||
HorizontalCellStyleStrategy horizontalCellStyleStrategy = |
|||
new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); |
|||
ServletOutputStream outputStream = response.getOutputStream(); |
|||
try { |
|||
EasyExcelFactory.write(outputStream, clazz).registerWriteHandler(horizontalCellStyleStrategy).sheet(sheetName).doWrite(objects); |
|||
}catch (Exception e){ |
|||
e.printStackTrace(); |
|||
}finally { |
|||
outputStream.close(); |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,37 @@ |
|||
|
|||
package com.zhy.easyexceldemo.easyexcel; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
|
|||
import javax.validation.ConstraintViolation; |
|||
import javax.validation.Validation; |
|||
import javax.validation.Validator; |
|||
import javax.validation.groups.Default; |
|||
import java.lang.reflect.Field; |
|||
import java.util.Set; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
public class EasyExcelValiHelper { |
|||
|
|||
private EasyExcelValiHelper(){} |
|||
|
|||
private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); |
|||
|
|||
public static <T> String validateEntity(T obj) throws NoSuchFieldException { |
|||
StringBuilder result = new StringBuilder(); |
|||
Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class); |
|||
if (set != null && !set.isEmpty()) { |
|||
for (ConstraintViolation<T> cv : set) { |
|||
Field declaredField = obj.getClass().getDeclaredField(cv.getPropertyPath().toString()); |
|||
ExcelProperty annotation = declaredField.getAnnotation(ExcelProperty.class); |
|||
result.append(annotation.value()[0]+cv.getMessage()).append(";"); |
|||
} |
|||
} |
|||
return result.toString(); |
|||
} |
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.zhy.easyexceldemo.easyexcel; |
|||
|
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Data |
|||
public class ExcelCheckErrDto<T> { |
|||
private T t; |
|||
|
|||
private String errMsg; |
|||
|
|||
public ExcelCheckErrDto(T t, String errMsg){ |
|||
this.t = t; |
|||
this.errMsg = errMsg; |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.zhy.easyexceldemo.easyexcel; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
public interface ExcelCheckManager<T> { |
|||
|
|||
/** |
|||
* @description: 校验方法 |
|||
* @param objects |
|||
* @throws |
|||
* @return com.cec.moutai.common.easyexcel.ExcelCheckResult |
|||
* @author zhy |
|||
* @date 2019/12/24 14:57 |
|||
*/ |
|||
ExcelCheckResult checkImportExcel(List<T> objects); |
|||
} |
@ -0,0 +1,26 @@ |
|||
package com.zhy.easyexceldemo.easyexcel; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Data |
|||
public class ExcelCheckResult<T> { |
|||
private List<T> successDtos; |
|||
|
|||
private List<ExcelCheckErrDto<T>> errDtos; |
|||
|
|||
public ExcelCheckResult(List<T> successDtos, List<ExcelCheckErrDto<T>> errDtos){ |
|||
this.successDtos =successDtos; |
|||
this.errDtos = errDtos; |
|||
} |
|||
|
|||
public ExcelCheckResult(List<ExcelCheckErrDto<T>> errDtos){ |
|||
this.successDtos =new ArrayList<>(); |
|||
this.errDtos = errDtos; |
|||
} |
|||
} |
@ -0,0 +1,58 @@ |
|||
package com.zhy.easyexceldemo.easyexcel; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
public class ExcelPatternMsg { |
|||
|
|||
private ExcelPatternMsg(){} |
|||
|
|||
//只能输入整数或者小数
|
|||
public static final String DECIMAL = "^[0-9]+\\.{0,1}[0-9]{0,2}$"; |
|||
public static final String DECIMAL_MSG = "只能输入整数或者小数"; |
|||
|
|||
//日期格式 yyyy/MM/dd
|
|||
public static final String DATE1 = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\/02\\/29)$"; |
|||
public static final String DATE1_MSG = "输入正确的日期格式:yyyy/MM/dd"; |
|||
|
|||
//日期格式 yyyy-MM-dd
|
|||
public static final String DATE2 = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)$"; |
|||
public static final String DATE2_MSG = "输入正确的日期格式:yyyy-MM-dd"; |
|||
|
|||
|
|||
//日期格式 yyyyMMdd
|
|||
public static final String DATE3 = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)$"; |
|||
public static final String DATE3_MSG = "输入正确的日期格式:yyyyMMdd"; |
|||
|
|||
//日期格式 yyyy-MM-dd HH:mm:ss
|
|||
public static final String DATE_TIME1 = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; |
|||
public static final String DATE_TIME1_MSG = "输入正确的日期格式:yyyy-MM-dd HH:mm:ss"; |
|||
|
|||
|
|||
//日期格式 yyyy/MM/dd HH:mm:ss
|
|||
public static final String DATE_TIME2 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\/02\\/29))\\s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; |
|||
public static final String DATE_TIME2_MSG = "输入正确的日期格式:yyyy/MM/dd HH:mm:ss"; |
|||
|
|||
//日期格式 yyyyMMddHHmmss
|
|||
public static final String DATE_TIME3 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229))([0-1][0-9]|2[0-3])([0-5][0-9])([0-5][0-9])$"; |
|||
public static final String DATE_TIME3_MSG = "输入正确的日期格式:yyyyMMddHHmmss"; |
|||
|
|||
|
|||
//日期格式 yyyyMMddHHmmssSSS
|
|||
public static final String DATE_TIME4 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229))([0-1][0-9]|2[0-3])([0-5][0-9])([0-5][0-9])([0-9]{3})$"; |
|||
public static final String DATE_TIME4_MSG = "输入正确的日期格式:yyyyMMddHHmmssSSS"; |
|||
|
|||
|
|||
//日期格式 yyyyMMdd HH:mm:ss
|
|||
public static final String DATE_TIME5 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[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-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229))\\s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; |
|||
public static final String DATE_TIME5_MSG = "输入正确的日期格式:yyyyMMdd HH:mm:ss"; |
|||
|
|||
|
|||
//数字和字母
|
|||
public static final String NUMBER_LETTER = "^[a-z0-9A-Z]+$"; |
|||
public static final String NUMBER_LETTER_MSG = "只能输入数字和字母"; |
|||
|
|||
//数字
|
|||
public static final String NUMBER = "^[0-9]*$"; |
|||
public static final String NUMBER_MSG = "只能输入数字"; |
|||
} |
@ -0,0 +1,31 @@ |
|||
package com.zhy.easyexceldemo.pojo; |
|||
|
|||
import com.alibaba.fastjson.annotation.JSONField; |
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Data |
|||
public class User implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
//名称
|
|||
private String name; |
|||
|
|||
//性别
|
|||
private String sex; |
|||
|
|||
//年龄
|
|||
private Integer age; |
|||
|
|||
//生日
|
|||
@JSONField(format="yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat( pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") |
|||
private Date birthday; |
|||
} |
@ -0,0 +1,61 @@ |
|||
package com.zhy.easyexceldemo.rest; |
|||
|
|||
import com.alibaba.excel.EasyExcelFactory; |
|||
import com.alibaba.fastjson.JSON; |
|||
import com.zhy.easyexceldemo.common.BaseRest; |
|||
import com.zhy.easyexceldemo.common.Result; |
|||
import com.zhy.easyexceldemo.dto.UserExcelDto; |
|||
import com.zhy.easyexceldemo.dto.UserExcelErrDto; |
|||
import com.zhy.easyexceldemo.easyexcel.EasyExcelListener; |
|||
import com.zhy.easyexceldemo.easyexcel.EasyExcelUtils; |
|||
import com.zhy.easyexceldemo.easyexcel.ExcelCheckErrDto; |
|||
import com.zhy.easyexceldemo.pojo.User; |
|||
import com.zhy.easyexceldemo.service.UserService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
import java.util.ArrayList; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@RestController |
|||
@RequestMapping("/user") |
|||
public class UserRest extends BaseRest { |
|||
|
|||
@Autowired |
|||
private UserService userService; |
|||
|
|||
/** |
|||
* easyexcel通过validation和正则实现excel导入校验 |
|||
* 导入表头校验 |
|||
* 导入数据校验 |
|||
* 导入业务逻辑校验 |
|||
*/ |
|||
@PostMapping("/importExcel") |
|||
public Result importExcel(HttpServletResponse response, @RequestParam MultipartFile file) throws IOException { |
|||
EasyExcelListener easyExcelListener = new EasyExcelListener(userService, UserExcelDto.class); |
|||
EasyExcelFactory.read(file.getInputStream(), UserExcelDto.class, easyExcelListener).sheet().doRead(); |
|||
List<ExcelCheckErrDto<UserExcelDto>> errList = easyExcelListener.getErrList(); |
|||
if (!errList.isEmpty()) { |
|||
//如果包含错误信息就导出错误信息
|
|||
exportErrorMsg(response, errList); |
|||
} |
|||
return addSucResult(); |
|||
} |
|||
|
|||
private static void exportErrorMsg(HttpServletResponse response, List<ExcelCheckErrDto<UserExcelDto>> errList) throws IOException { |
|||
List<UserExcelErrDto> excelErrDtos = errList.stream().map(excelCheckErrDto -> { |
|||
UserExcelErrDto userExcelErrDto = JSON.parseObject(JSON.toJSONString(excelCheckErrDto.getT()), UserExcelErrDto.class); |
|||
userExcelErrDto.setErrMsg(excelCheckErrDto.getErrMsg()); |
|||
return userExcelErrDto; |
|||
}).collect(Collectors.toList()); |
|||
EasyExcelUtils.webWriteExcel(response, excelErrDtos, UserExcelErrDto.class, "用户导入错误信息"); |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
package com.zhy.easyexceldemo.service; |
|||
|
|||
import com.zhy.easyexceldemo.dto.UserExcelDto; |
|||
import com.zhy.easyexceldemo.easyexcel.ExcelCheckManager; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
public interface UserService extends ExcelCheckManager<UserExcelDto> { |
|||
} |
@ -0,0 +1,42 @@ |
|||
package com.zhy.easyexceldemo.service.impl; |
|||
|
|||
import com.alibaba.excel.util.StringUtils; |
|||
import com.zhy.easyexceldemo.dto.UserExcelDto; |
|||
import com.zhy.easyexceldemo.easyexcel.ExcelCheckErrDto; |
|||
import com.zhy.easyexceldemo.easyexcel.ExcelCheckResult; |
|||
import com.zhy.easyexceldemo.service.UserService; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @author woniu |
|||
*/ |
|||
@Service |
|||
public class UserServiceImpl implements UserService { |
|||
|
|||
public static final String ERR_NAME = "蜗牛哥"; |
|||
|
|||
@Override |
|||
public ExcelCheckResult checkImportExcel(List<UserExcelDto> userExcelDtos) { |
|||
//成功结果集
|
|||
List<UserExcelDto> successList = new ArrayList<>(); |
|||
//错误数组
|
|||
List<ExcelCheckErrDto<UserExcelDto>> errList = new ArrayList<>(); |
|||
for (UserExcelDto userExcelDto : userExcelDtos) { |
|||
//错误信息
|
|||
StringBuilder errMsg = new StringBuilder(); |
|||
//根据自己的业务去做判断
|
|||
if (ERR_NAME.equals(userExcelDto.getName())) |
|||
errMsg.append("请输入正确的名字").append(";"); |
|||
if (StringUtils.isEmpty(errMsg.toString())){ |
|||
//这里有两个选择,1、一个返回成功的对象信息,2、进行持久化操作
|
|||
successList.add(userExcelDto); |
|||
}else{//添加错误信息
|
|||
errList.add(new ExcelCheckErrDto(userExcelDto,errMsg.toString())); |
|||
} |
|||
} |
|||
return new ExcelCheckResult(successList,errList); |
|||
} |
|||
} |
@ -0,0 +1,2 @@ |
|||
server: |
|||
port: 8888 |
@ -0,0 +1,13 @@ |
|||
package com.zhy.easyexceldemo; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.springframework.boot.test.context.SpringBootTest; |
|||
|
|||
@SpringBootTest |
|||
class EasyexceldemoApplicationTests { |
|||
|
|||
@Test |
|||
void contextLoads() { |
|||
} |
|||
|
|||
} |
Loading…
Reference in new issue