diff --git a/README.md b/README.md index 7eff1a1..773a678 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # import-demo -数据导入demo \ No newline at end of file +数据导入demo + +启动后访问:http://localhost:8080/doc.html#/default/%E5%AF%BC%E5%85%A5/importDetailUsingPOST \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a2ea92e --- /dev/null +++ b/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + + com.fly + import-demo + 0.0.1-SNAPSHOT + import-demo + Demo project for Spring Boot + + 17 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + com.github.xiaoymin + knife4j-spring-boot-starter + 3.0.3 + + + cn.afterturn + easypoi-spring-boot-starter + 4.2.0 + + + org.springframework.boot + spring-boot-starter-validation + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/src/main/java/com/example/demo/ImportDemoApplication.java b/src/main/java/com/example/demo/ImportDemoApplication.java new file mode 100644 index 0000000..979b591 --- /dev/null +++ b/src/main/java/com/example/demo/ImportDemoApplication.java @@ -0,0 +1,13 @@ +package com.example.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ImportDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ImportDemoApplication.class, args); + } + +} diff --git a/src/main/java/com/example/demo/controller/ImportController.java b/src/main/java/com/example/demo/controller/ImportController.java new file mode 100644 index 0000000..8e150e4 --- /dev/null +++ b/src/main/java/com/example/demo/controller/ImportController.java @@ -0,0 +1,44 @@ +package com.example.demo.controller; + +import com.example.demo.dto.ExampleData; +import com.example.demo.dto.R; +import com.example.demo.service.DataService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * @author guoxiang + * @see 简书TinyThing + * @since 2022/7/21 13:33 + */ +@RestController +@RequestMapping("/importTest") +@Api(tags = "导入") +@RequiredArgsConstructor +@Slf4j +public class ImportController { + + private final DataService dataService; + + @PostMapping("/import") + @ApiOperation("导入") + R> importDetail(@RequestPart MultipartFile file) { + + log.info("- import data..."); + + R> data = dataService.importData(file); + + log.info("- import finish"); + return data; + } + +} diff --git a/src/main/java/com/example/demo/dto/ExampleData.java b/src/main/java/com/example/demo/dto/ExampleData.java new file mode 100644 index 0000000..b8a7cbf --- /dev/null +++ b/src/main/java/com/example/demo/dto/ExampleData.java @@ -0,0 +1,42 @@ +package com.example.demo.dto; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.handler.inter.IExcelDataModel; +import cn.afterturn.easypoi.handler.inter.IExcelModel; +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; + +/** + * @author guoxiang + * @see 简书TinyThing + * @since 2022/7/21 13:58 + */ +@Data +public class ExampleData implements IExcelModel, IExcelDataModel { + @NotBlank(message = "不能为空") + @Excel(name = "证件号码") + private String id; + + @Excel(name = "名称") + @NotBlank(message = "名称不能为空") + private String name; + + @Excel(name = "年龄") + @Max(value = 150, message = "年龄不能超过150") + @Min(value = 1, message = "年龄不能小于1") + private Integer age; + + @Excel(name = "学校") + private String college; + + @Excel(name = "职位") + private String position; + + @Excel(name = "导入错误信息") + private String errorMsg; + + private Integer rowNum; +} diff --git a/src/main/java/com/example/demo/dto/R.java b/src/main/java/com/example/demo/dto/R.java new file mode 100644 index 0000000..27738dc --- /dev/null +++ b/src/main/java/com/example/demo/dto/R.java @@ -0,0 +1,75 @@ +package com.example.demo.dto; + +import lombok.*; +import lombok.experimental.Accessors; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 响应信息主体 + * + * @param + */ +@ToString +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class R implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private int code; + + @Getter + @Setter + private String msg; + + @Getter + @Setter + private T data; + + public static R ok() { + return restResult(null, 0, null); + } + + public static R ok(T data) { + return restResult(data, 0, null); + } + + public static R ok(T data, String msg) { + return restResult(data, 0, msg); + } + + public static R failed() { + return restResult(null, 1, null); + } + + public static R failed(String msg) { + return restResult(null, 1, msg); + } + + public static R failed(T data,int code, String msg) { + return restResult(data, code, msg); + } + + public static R failed(T data) { + return restResult(data, 1, null); + } + + public static R failed(T data, String msg) { + return restResult(data, 1, msg); + } + + private static R restResult(T data, int code, String msg) { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + +} diff --git a/src/main/java/com/example/demo/service/DataService.java b/src/main/java/com/example/demo/service/DataService.java new file mode 100644 index 0000000..d695c45 --- /dev/null +++ b/src/main/java/com/example/demo/service/DataService.java @@ -0,0 +1,66 @@ +package com.example.demo.service; + +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; +import com.example.demo.dto.ExampleData; +import com.example.demo.dto.R; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * @author guoxiang + * @see 简书TinyThing + * @since 2022/7/21 13:43 + */ +@Service +@Slf4j +public class DataService { + + /** + * 导入数据 + * @param file excel文件 + * @return 结果 + */ + public R> importData(MultipartFile file) { + //导入的基本配置 + ImportParams params = new ImportParams(); + //代表导入这里是需要验证的(根据字段上的注解校验) + params.setNeedVerify(true); + params.setTitleRows(0); + //使用框架自身导入工具 + ExcelImportResult result; + try { + result = ExcelImportUtil.importExcelMore(file.getInputStream(), ExampleData.class, params); + } catch (Exception e) { + log.error("导入数据错误", e); + throw new IllegalArgumentException(); + } + + //如果存在校验失败的数据,则返回给用户 + if (result.isVerifyFail()) { + //失败结果集 + List failList = result.getFailList(); + return R.failed(failList); + } + + //校验成功的数据 + List list = result.getList(); + //将数据保存到数据库 + saveToDataBase(list); + + return R.ok(); + } + + /** + * 保存到数据库 + * + * @param list 数据 + */ + private void saveToDataBase(List list) { + list.forEach(data -> log.info("data = {}", data)); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..82d4f8d --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.mvc.pathmatch.matching-strategy=ant_path_matcher \ No newline at end of file diff --git a/src/main/resources/导入模板.xlsx b/src/main/resources/导入模板.xlsx new file mode 100644 index 0000000..2a03290 Binary files /dev/null and b/src/main/resources/导入模板.xlsx differ diff --git a/src/test/java/com/example/demo/ImportDemoApplicationTests.java b/src/test/java/com/example/demo/ImportDemoApplicationTests.java new file mode 100644 index 0000000..66a98b9 --- /dev/null +++ b/src/test/java/com/example/demo/ImportDemoApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.demo; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ImportDemoApplicationTests { + + @Test + void contextLoads() { + } + +}