springboot导入excel(POI)

news/2024/11/29 10:56:18/
POI官方文档

引入依赖

        <!--POI--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version></dependency>

编写导入工具类

        结合springboot导出(POI)用到的自定义注解,让导入使用起来更方便简洁且更容易扩展。

public class ExcelImportUtil {/** @description: 读取excel数据 <br>* @create: 2023/9/20 16:12 <br>* @param file* @param tClass* @return java.util.List<T>*/public static<T> List<T> readExcel(MultipartFile file, Class<T> tClass){if(file.isEmpty()){return new ArrayList<>();}//获取列名与属性名的映射Map<String, String> feildMap = getFeildMap(tClass);if(ObjectUtils.isEmpty(feildMap)){return new ArrayList<>();}InputStream inputStream = null;Workbook workbook = null;try {//解析文件inputStream = file.getInputStream();workbook = new XSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(0);int lastRowNum = sheet.getLastRowNum();int lastCellNum = sheet.getRow(0).getLastCellNum();//解析表头Row headerRow = sheet.getRow(0);List<String> headerNameList = new ArrayList<>();for (int i = 0; i < lastCellNum; i++) {headerNameList.add(headerRow.getCell(i).getStringCellValue());}//读取数据List<Map<String, Object>> dataList = new ArrayList<>();for (int i = 1; i <= lastRowNum; i++) {Row row = sheet.getRow(i);Map<String, Object> rowValueMap = new HashMap<>();for (int j = 0; j < lastCellNum; j++) {String key = feildMap.get(headerNameList.get(j));Object value = getCellValue(row.getCell(j));rowValueMap.put(key, value);}dataList.add(rowValueMap);}workbook.close();inputStream.close();List<T> list = convertToList(dataList);return list;} catch (IOException e) {e.printStackTrace();}finally {try {if(workbook != null){workbook.close();}if(inputStream !=null){inputStream.close();}} catch (IOException e) {e.printStackTrace();}}return new ArrayList<>();}/** @description: 解析导入的实体,获取列名与属性名的映射 <br>* @create: 2023/9/20 16:27 <br>* @param tClass* @return java.util.Map<java.lang.String,java.lang.String>*/private static<T> Map<String, String> getFeildMap(Class<T> tClass){Field[] fields = tClass.getDeclaredFields();if(ObjectUtils.isEmpty(fields)){return null;}Map<String, String> keyMap = new HashMap<>();for(Field field : fields){ExcelField excelField = field.getAnnotation(ExcelField.class);if(ObjectUtils.isNotEmpty(excelField)){keyMap.put(excelField.name(), field.getName());}}return keyMap;}/** @description: 获取单元格的值 <br>* @create: 2023/9/20 16:47 <br>* @param cell* @return java.lang.Object*/private static Object getCellValue(Cell cell){if(cell == null){return null;}CellType cellType = cell.getCellType();if(cellType.equals(CellType.BLANK)){return null;}//字符串if (cellType.equals(CellType.STRING)){return cell.getStringCellValue();}if(cellType.equals(CellType.NUMERIC)){//日期if(HSSFDateUtil.isCellDateFormatted(cell)){return cell.getDateCellValue();}else{//数值return cell.getNumericCellValue();}}//布尔if(cellType.equals(CellType.BOOLEAN)){return cell.getBooleanCellValue();}return null;}/** @description: 转list <br>* @create: 2023/9/20 17:54 <br>* @param obj* @return java.util.List<T>*/private static<T> List<T> convertToList(Object obj){ObjectMapper objectMapper = new ObjectMapper();//日期格式objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));//设置时区objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));//序列化-忽略null值的属性objectMapper.setSerializationInclusion(Include.NON_NULL);//序列化-允许序列化空对象objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);//反序列化-在遇到未知属性的时候不抛出异常objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);if(null == obj){return null;}return objectMapper.convertValue(obj, new TypeReference<List<T>>() {});}
}

测试

导入模板

导入的泛型(对象)

@Data
public class ImportTest {@ExcelField(name = "字符串")private String feild1;@ExcelField(name = "数值")private BigDecimal feild2;@ExcelField(name = "布尔")private Boolean feild3;@ExcelField(name = "日期")private Date feild4;
}

controller

@Api(tags = "测试")
@RestController
@RequestMapping("/test")
public class TestController {@ApiOperation("导入")@PostMapping("/importExcel")public ResponseEntity<List<ImportTest>> importExcel(@ApiParam(name = "file") @RequestPart("file") MultipartFile file){List<ImportTest> list = ExcelImportUtil.readExcel(file, ImportTest.class);System.out.print(list);return ResponseEntity.ok(list);}
}

response 


http://www.ppmy.cn/news/1129270.html

相关文章

P2466 [SDOI2008] Sue 的小球(区间dp)

P2466 [SDOI2008] Sue 的小球&#xff08;区间dp&#xff09; 链接&#xff1a;P2466 [SDOI2008] Sue 的小球 很有意思的一道题&#xff0c;想各种方法都无从下手&#xff0c;看了洛谷题解瞬间懂了。 题意 有 n n n 个物品&#xff0c;每个物品的位置在 x i x_i xi​&…

【每日一题Day340】LC2251花期内花的数目 | 差分+哈希表+排序 排序+二分查找

花期内花的数目【LC2251】 给你一个下标从 0 开始的二维整数数组 flowers &#xff0c;其中 flowers[i] [starti, endi] 表示第 i 朵花的 花期 从 starti 到 endi &#xff08;都 包含&#xff09;。同时给你一个下标从 0 开始大小为 n 的整数数组 people &#xff0c;people[…

React useRequest解读

源码结构&#xff1a; 可以看到虽然是一个hooks&#xff08;具有一定功能且具备状态的单一函数&#xff09; 但是各种文件功能分得也是很细的&#xff0c;方便抽离和复用 useRequest.ts 抽离的原则还是单一功能原则 可以看出 真正的hooks实现是在Implement里 对于类型type的引…

C#并发编程的实现方式

一、多线程&#xff1a;是一种并发编程技术&#xff0c;它允许一个应用程序同时执行多个线程。每个线程都有自己的指令集和堆栈&#xff0c;可以在不同的CPU核心上并行运行&#xff0c;或者在一个CPU核心上通过时间片轮转的方式交替运行。多线程的主要优点是可以利用多核处理器…

Python数据和Json数据的相互转换

什么是JSON&#xff1f; JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据 JSON本质上是一个带有特定格式的字符串 主要功能:JSON就是一种在各个编程语言中流通的数据格式&#xff0c;负责不同编程语言中的数据传递和交互 Python数据和Json数据的相互…

面试问到MySQL模块划分与架构体系怎么办

面试问到Mysql模块划分与架构体系怎么办 文章目录 1. 应用层连接管理器&#xff08;Connection Manager&#xff09;安全性和权限模块&#xff08;Security and Privilege Module&#xff09; 2. MySQL服务器层2.1. 服务支持和工具集2.2. SQL Interface2.3. 解析器举个解析器 …

MATLAB算法实战应用案例精讲-【优化算法】基于房地产市场的优化算法(REMARK)(附MATLAB代码实现)

代码实现 MATLAB main.m clc, clear rng(shuffle) format short e options.nDim = 2; options.nDemander = 80; options.nSupplier = ceil(options.nDemander/4); options.maxFrnd = ceil(options.nDemander/4); options.constrPer = 10; options.KsigmaD = 0.7; options.Ks…

docker-compose 网络配置- IP 主机名 hosts配置

docker-compose 配置IP、hostname、hosts配置 配置IP version: "3" networks:bd-network: # 声明网络external: true services:kafka: # 服务名称networks:bd-network: # 连接的网络名称ipv4_address: 172.2.0.102 # 配置IP配置 主机名 version: "3&quo…