poi java 导入excel_Java开发中如何用POI优雅的导入Excel文件

前言

接上一篇Java 开发中如何用 POI 优雅的导出 Excel 文件. 本篇基于 注解 + 反射 实现 Excel 导入功能的实现。

导入相对导出略复杂,需要考虑数据类型的合理转换。

实现

这里我们通过表头校验实现列数据的匹配。

废话不多说,直接上代码。相关注释已经足够完善。

工具类

@Slf4j

public class ExcelUtils {

static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

/**

*

* @param multipartFile

* @param clz VO对象,对应Excel表头

* @param

* @throws IOException

* @throws NoSuchMethodException

* @throws IllegalAccessException

* @throws InvocationTargetException

* @throws InstantiationException

*/

public static void importExcel(MultipartFile multipartFile, Class clz) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

if(null == multipartFile) {

throw new NullPointerException("请选择文件");

}

log.info(multipartFile.getName());

log.info("文件类型:{}", multipartFile.getContentType());

String fileName = multipartFile.getOriginalFilename();

log.info("文件名:{}", fileName);

if(!"application/vnd.ms-excel".equals(multipartFile.getContentType())) {

throw new RuntimeException("请选择正确的文件类型与文件!");

}

// 返回数据

List list = new ArrayList<>();

InputStream inputStream = multipartFile.getInputStream();

Workbook wb = WorkbookFactory.create(inputStream);

// 读取第一个sheet

Sheet sheet = wb.getSheetAt(0);

// 获取最大行数(或者sheet.getLastRowNum())

int rownum = sheet.getPhysicalNumberOfRows();

// 反射获取字段

Field[] fields = clz.getDeclaredFields();

// 获取第一行(表头)

Row row = sheet.getRow(0);

// 获取最大列数

int column = row.getPhysicalNumberOfCells();

// 表头校验

for (int j = 0; j < fields.length; j++){

Field field = fields[j];

if (field.isAnnotationPresent(ExcelHeader.class)) {

ExcelHeader annotation = field.getAnnotation(ExcelHeader.class);

Cell cell = row.getCell(j);

if (cell == null || !getCellValue(cell).equals(annotation.value())) {

throw new RuntimeException("Excel格式错误");

}

}

}

// 处理行数据

for (int i = 1; i

row = sheet.getRow(i);

// 遇到空行则结束

if (row == null) {

break;

}

T rowData = clz.getDeclaredConstructor().newInstance();

// 处理列数据

for (int j = 0; j < fields.length; j++){

Field field = fields[j];

// 设置属性可访问

field.setAccessible(true);

if (field.isAnnotationPresent(ExcelHeader.class)) {

ExcelHeader annotation = field.getAnnotation(ExcelHeader.class);

// 这里默认按列顺序,也可以根据columnIndex设置列顺序

int columnIndex = annotation.columnIndex();

Cell cell = row.getCell(j);

if (cell == null) {

continue;

}

// 获取列值

Object value = getCellValue(cell);

// 设置属性

setFieldValue(rowData, field, value);

}

}

list.add(rowData);

}

log.info("上传数据={}", list.toString());

}

private static void setFieldValue(T rowData, Field field, Object value) throws IllegalAccessException {

if (field.getType() == int.class || field.getType() == Integer.class) {

field.set(rowData, value);

} else if (field.getType() == long.class || field.getType() == Long.class) {

field.set(rowData, value);

} else if (field.getType() == double.class || field.getType() == Double.class) {

field.set(rowData, value);

} else if (field.getType() == String.class) {

field.set(rowData, String.valueOf(value));

} else if (field.getType() == LocalDateTime.class) {

field.set(rowData, LocalDateTime.parse(String.valueOf(value), dateTimeFormatter));

}

}

private static Object getCellValue(Cell cell) {

CellType cellType = cell.getCellType();

Object cellValue = null;

if (cellType == CellType._NONE) {

} else if (cellType == CellType.NUMERIC) {

// 数值型

if (DateUtil.isCellDateFormatted(cell)) {

// 日期类型

Date d = cell.getDateCellValue();

cellValue = dateTimeFormatter.format(LocalDateTime.ofInstant(d.toInstant(), ZoneId.systemDefault()));

} else {

double numericCellValue = cell.getNumericCellValue();

BigDecimal bdVal = new BigDecimal(numericCellValue);

if ((bdVal + ".0").equals(Double.toString(numericCellValue))) {

// 整型

cellValue = bdVal;

} else if (String.valueOf(numericCellValue).contains("E10")) {

// 科学记数法

cellValue = new BigDecimal(numericCellValue).toPlainString();

} else {

// 浮点型

cellValue = numericCellValue;

}

}

} else if (cellType == CellType.STRING) {

// 字符串型

cellValue = cell.getStringCellValue();

} else if (cellType == CellType.FORMULA) {

// 公式型

} else if (cellType == CellType.BLANK) {

// 空值

} else if (cellType == CellType.BOOLEAN) {

// 布尔型

cellValue = cell.getBooleanCellValue();

} else if (cellType == CellType.ERROR) {

// 错误

cellValue = cell.getErrorCellValue();

}

log.info("cellType={}, cellValue={}", cellType.name(), cellValue);

return cellValue;

}

}

基本使用

@Slf4j

@RestController

public class ExcelController {

/**

* http://localhost:8080/import

* @param request

* @return

*/

@PostMapping("/import")

public Object importExcel(HttpServletRequest request) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {

if (request instanceof MultipartHttpServletRequest) {

MultipartFile multipartFile = ((MultipartHttpServletRequest)request).getFile("file");

ExcelUtils.importExcel(multipartFile, User.class);

}

return "上传成功";

}

}

最后

本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】支持一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值