java springboot poi 从controller 接收不同类型excel 文件处理
作者:爱睡懒觉的派大星 发布时间:2023-10-17 14:26:05
标签:spring,boot,excel
根据poi接收controller层的excel文件导入
可使用后缀名xls或xlsx格式的excel。
1.pom引入
<!-- poi 操作Excel -->
<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>
2.ExcelImportUtil 工具类创建
import com.guard.biz.common.util.excel.ExcelIn;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Wei
* @time 2019/10/29
* @Description excel 导入工具类
*/
public class ExcelImportUtil<T> {
private static final Logger log = LoggerFactory.getLogger(ExcelImportUtil.class);
private static BeanUtilsBean beanUtilsBean = new BeanUtilsBean();
static {
beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.DateConverter(null), java.util.Date.class);
}
/**
* 表头名字和对应所在第几列的下标,用于根据title取到对应的值
*/
private final Map<String, Integer> title_to_index = new HashMap<>();
/**
* 所有带有ExcelIn注解的字段
*/
private final List<Field> fields = new ArrayList<>();
/**
* 统计表格的行和列数量用来遍历表格
*/
private int firstCellNum = 0;
private int lastCellNum = 0;
private int firstRowNum = 0;
private int lastRowNum = 0;
private String sheetName;
private Sheet sheet;
public List<T> read(InputStream in, Class clazz) throws Exception {
gatherAnnotationFields(clazz);
configSheet(in);
configHeader();
List rList = null;
try {
rList = readContent(clazz);
} catch (IllegalAccessException e) {
throw new Exception(e);
} catch (InstantiationException e) {
throw new Exception(e);
} catch (InvocationTargetException e) {
throw new Exception(e);
}
return rList;
}
private List readContent(Class clazz) throws IllegalAccessException, InstantiationException, InvocationTargetException {
Object o = null;
Row row = null;
List<Object> rsList = new ArrayList<>();
Object value = null;
for (int i = (firstRowNum + 1); i <= lastRowNum; i++) {
o = clazz.newInstance();
row = sheet.getRow(i);
Cell cell = null;
for (Field field : fields) {
//根据注解中的title,取到表格中该列所对应的的值
Integer column = title_to_index.get(field.getAnnotation(ExcelIn.class).title());
if (column == null) {
continue;
}
cell = row.getCell(column);
value = getCellValue(cell);
if (null != value && StringUtils.isNotBlank(value.toString())) {
beanUtilsBean.setProperty(o, field.getName(), value);
}
}
rsList.add(o);
}
return rsList;
}
private void configSheet(InputStream in) throws Exception {
// 根据文件类型来分别创建合适的Workbook对象
try (Workbook wb = WorkbookFactory.create(in)) {
getSheetByName(wb);
} catch (FileNotFoundException e) {
throw new Exception(e);
} catch (IOException e) {
throw new Exception(e);
}
}
/**
* 根据sheet获取对应的行列值,和表头对应的列值映射
*/
private void configHeader() {
this.firstRowNum = sheet.getFirstRowNum();
this.lastRowNum = sheet.getLastRowNum();
//第一行为表头,拿到表头对应的列值
Row row = sheet.getRow(firstRowNum);
this.firstCellNum = row.getFirstCellNum();
this.lastCellNum = row.getLastCellNum();
for (int i = firstCellNum; i < lastCellNum; i++) {
title_to_index.put(row.getCell(i).getStringCellValue(), i);
}
}
/**
* 根据sheet名称获取sheet
*
* @param workbook
* @return
* @throws Exception
*/
private void getSheetByName(Workbook workbook) throws Exception {
int sheetNumber = workbook.getNumberOfSheets();
for (int i = 0; i < sheetNumber; i++) {
String name = workbook.getSheetName(i);
if (StringUtils.equals(this.sheetName, name)) {
this.sheet = workbook.getSheetAt(i);
return;
}
}
throw new Exception("excel中未找到名称为" + this.sheetName + "的sheet");
}
/**
* 根据自定义注解,获取所要导入表格的sheet名称和需要导入的字段名称
*
* @param clazz
* @throws Exception
*/
private void gatherAnnotationFields(Class clazz) throws Exception {
if (!clazz.isAnnotationPresent(ExcelIn.class)) {
throw new Exception(clazz.getName() + "类上没有ExcelIn注解");
}
ExcelIn excelIn = (ExcelIn) clazz.getAnnotation(ExcelIn.class);
this.sheetName = excelIn.sheetName();
// 得到所有定义字段
Field[] allFields = FieldUtils.getAllFields(clazz);
// 得到所有field并存放到一个list中
for (Field field : allFields) {
if (field.isAnnotationPresent(ExcelIn.class)) {
fields.add(field);
}
}
if (fields.isEmpty()) {
throw new Exception(clazz.getName() + "中没有ExcelIn注解字段");
}
}
private Object getCellValue(Cell cell) {
if (cell == null) {
return "";
}
Object obj = null;
switch (cell.getCellTypeEnum()) {
case BOOLEAN:
obj = cell.getBooleanCellValue();
break;
case ERROR:
obj = cell.getErrorCellValue();
break;
case FORMULA:
try {
obj = String.valueOf(cell.getStringCellValue());
} catch (IllegalStateException e) {
obj = numericToBigDecimal(cell);
}
break;
case NUMERIC:
obj = getNumericValue(cell);
break;
case STRING:
String value = String.valueOf(cell.getStringCellValue());
value = value.replace(" ", "");
value = value.replace("\n", "");
value = value.replace("\t", "");
obj = value;
break;
default:
break;
}
return obj;
}
private Object getNumericValue(Cell cell) {
// 处理日期格式、时间格式
if (HSSFDateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue();
} else if (cell.getCellStyle().getDataFormat() == 58) {
// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
double value = cell.getNumericCellValue();
return org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
} else {
return numericToBigDecimal(cell);
}
}
private Object numericToBigDecimal(Cell cell) {
String valueOf = String.valueOf(cell.getNumericCellValue());
BigDecimal bd = new BigDecimal(valueOf);
return bd;
}
}
3.ExcelIn注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Lei
* @time 2019/10/29
* @Description
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.FIELD})
public @interface ExcelIn {
/**
* 导入sheet名称
*
* @return
*/
String sheetName() default "";
/**
* 字段对应的表头名称
*
* @return
*/
String title() default "";
}
4.创建excel中的对象
import lombok.Data;
import lombok.ToString;
import java.util.Date;
/**
* @author Lei
* @time 2019/10/29
* @Description
*/
@ToString
@Data
@ExcelIn(sheetName = "用户")
public class User {
private String id;
@ExcelIn(title = "姓名")
private String name;
@ExcelIn(title = "年龄")
private Integer age;
@ExcelIn(title = "出生日期")
private Date birthDate;
}
5.controller层接收
@PostMapping("/batch/excel")
@ApiOperation(value = "根据excel文件批量导入")
public ResponseVO batchAddDeviceByExcelImport(MultipartFile multipartFile) {
return new ResponseVO(deviceService.addDeviceByExcelImport(multipartFile));
}
6.service处理(此处仅打印)
public boolean addDeviceByExcelImport(MultipartFile multipartFile) {
File file = null;
try {
file = File.createTempFile("temp", null);
} catch (IOException e) {
e.printStackTrace();
}
try {
multipartFile.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
file.deleteOnExit();
InputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ExcelImportUtil<User> reader = new ExcelImportUtil<>();
List<User> userList = null;
try {
userList = reader.read(inputStream, User.class);
} catch (Exception e) {
log.error(e.getMessage());
throw new CodeException("51302", e.getMessage());
}
userList.stream().forEach(e -> log.info(e.toString()));
return true;
}
7.测试
(1)两种文件类型的excel
(2)excel中格式如下,注意红色箭头所指的地方 对应user对象中的字段以及sheet名
(3)swagger测试
(4)成功打印
总结
以上所述是小编给大家介绍的java springboot poi 从controller 接收不同类型excel 文件处理,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://www.cnblogs.com/wei57960/archive/2019/10/30/11763020.html
0
投稿
猜你喜欢
- Java BufferWriter写文件之后文件是空的或者数据不全在编程的过程中,读写文件是非常常见的操作,在这里我问介绍一下最近我遇到的集
- 泛型泛型的语法定义class 类名 <泛型标识,泛型标识,…>{ private 泛型标识1,变量名;常用
- 准备:wildfly/tomcat或者其他服务器你的数据库的Driver,(此处用的mysql-connecter-java-5.1.39-
- 1、static是什么意思?static 关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。例如Main类pa
- JLabel 对象可以显示文本、图像或同时显示二者。可以通过设置垂直和水平对齐方式,指定标签显示区中标签内容在何处对齐。默认情况下,标签在其
- java 解决异常 2 字节的 UTF-8 序列的字节 2 无效的问题  
- 配置文件中设置通常在公司级别的项目中,我们可能会写多个application- dev/prod.yml ,然后我们通常会在applicat
- 发现问题:问题如图所示,在eclipse中开启tomcat服务器时报错:端口已被占用。这是因为在tomcat开启的状态下,eclipse异常
- 先说一句:密码是无法解密的。大家也不要再问松哥微人事项目中的密码怎么解密了!密码无法解密,还是为了确保系统安全。今天松哥就来和大家聊一聊,密
- 在java中,单例有很多种写法,面试时,手写代码环节,除了写算法题,有时候也会让手写单例模式,这里记录一下单例的几种写法和优缺点。1.初级写
- 大多数网站会设置用户权限,如过滤非法用户,用户不登录时不能进行访问,或者设置访问的权限,如部分内容仅对VIP开放等等,这些权限的控制都可以用
- 一、JAVA简要概述先说一下java之父,詹姆斯·高斯林这是一个爱喝咖啡而又强大的男人。再来看一下JAVA有多火在TIOBE排行榜上JAVA
- 1、SpringBoot配置文件1.1 优先级关于SpringBoot配置文件可以是properties或者是yaml格式的文件,但是在Sp
- 本文实例为大家分享了Android实现比赛时间闪动效果的具体代码,供大家参考,具体内容如下效果代码上代码public class Twink
- 前言先放一个官网吧,其实本案例就是根据官网案例来的,只是进行了修改配置。Mybatis-plus官网一、搭建一个springboot项目&n
- Mybatis的Dao层实现传统开发方式1、编写UserDao接口public interface UserMapper {public L
- Spring中提供了很多PostProcessor供开发者进行拓展,例如:BeanPostProcessor、BeanFactoryPost
- 前面讲了 Spock框架Mock对象方法经验总结一、静态方法Mock静态方法我们使用PowerMock结合Mockito的方案,首先在测试类
- 网络应用分为客户端和服务端两部分,而Socket类是负责处理客户端通信的Java类。通过这个类可以连接到指定IP或域名的服务器上,并且可以和
- 在mybatis中sql是写在xml映射文件中的,如果sql中有一些特殊字符的话,在解析xml文件的时候就会被转义,如若不希望被转义,那该怎