Java开发中如何用POI优雅的导入Excel文件
前言
接上一篇Java开发中如何用POI优雅的导出Excel文件. 本篇基于 注解
+ 反射
实现Excel导入功能的实现。
导入相对导出略复杂,需要考虑数据类型的合理转换。
实现
这里我们通过表头校验实现列数据的匹配。
废话不多说,直接上代码。相关注释已经足够完善。
工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
@Slf4j public class ExcelUtils {
static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static <T> void importExcel(MultipartFile multipartFile, Class<T> 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<T> list = new ArrayList<>();
InputStream inputStream = multipartFile.getInputStream(); Workbook wb = WorkbookFactory.create(inputStream);
Sheet sheet = wb.getSheetAt(0); 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<rownum; 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);
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 <T> 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; }
}
|
基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Slf4j @RestController public class ExcelController {
@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 "上传成功"; } }
|
最后
本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】支持一下。