java实现以下功能:扫描指定路径下的excel文件,若无则进行提示,若存在excel文件则循环读取所有的文件,利用实体类@Excel注解的方式读取excel的数据,将读取到的数据插入oracle数据库指定的表中
时间: 2023-12-06 17:44:12 浏览: 218
首先需要引入poi、poi-ooxml、commons-collections4、commons-lang3、commons-beanutils、oracle-jdbc驱动等相关依赖。
然后,可以编写一个ExcelUtil工具类,用于读取Excel文件并转换成对象列表:
```java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
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.xssf.usermodel.XSSFWorkbook;
public class ExcelUtil {
/**
* 读取Excel文件并转换成对象列表
*
* @param file Excel文件
* @param clazz 对象类型
* @return 对象列表
*/
public static <T> List<T> readExcel(File file, Class<T> clazz) throws IOException {
List<T> list = new ArrayList<>();
try (InputStream is = new FileInputStream(file); Workbook workbook = new XSSFWorkbook(is)) {
Sheet sheet = workbook.getSheetAt(0);
if (sheet == null) {
return list;
}
// 获取表头行
Row headerRow = sheet.getRow(0);
if (headerRow == null) {
return list;
}
// 获取表头字段名
List<String> headerFieldNames = new ArrayList<>();
for (int i = 0; i < headerRow.getLastCellNum(); i++) {
Cell cell = headerRow.getCell(i);
if (cell == null || cell.getCellType() == CellType.BLANK) {
headerFieldNames.add(null);
} else {
headerFieldNames.add(cell.getStringCellValue().trim());
}
}
// 获取字段映射关系
List<FieldMapping> fieldMappings = getFieldMappings(clazz, headerFieldNames);
// 遍历每一行数据
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row == null) {
continue;
}
T obj = clazz.newInstance();
// 遍历每一个单元格数据
for (FieldMapping fieldMapping : fieldMappings) {
Cell cell = row.getCell(fieldMapping.getIndex());
if (cell == null || cell.getCellType() == CellType.BLANK) {
continue;
}
setFieldValue(obj, fieldMapping.getField(), cell);
}
list.add(obj);
}
} catch (Exception e) {
throw new RuntimeException("Read Excel error", e);
}
return list;
}
/**
* 获取字段映射关系
*
* @param clazz 对象类型
* @param headerFieldNames 表头字段名列表
* @return 字段映射关系列表
*/
private static List<FieldMapping> getFieldMappings(Class<?> clazz, List<String> headerFieldNames) {
List<FieldMapping> fieldMappings = new ArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
Excel excel = field.getAnnotation(Excel.class);
if (excel == null) {
continue;
}
String fieldName = StringUtils.isBlank(excel.fieldName()) ? field.getName() : excel.fieldName();
int index = headerFieldNames.indexOf(fieldName);
if (index < 0) {
throw new RuntimeException("Excel header does not contain field: " + fieldName);
}
fieldMappings.add(new FieldMapping(field, index));
}
return fieldMappings;
}
/**
* 设置对象字段值
*/
private static void setFieldValue(Object obj, Field field, Cell cell) throws Exception {
String cellValue = getCellValue(cell);
Class<?> fieldType = field.getType();
if (StringUtils.isBlank(cellValue)) {
BeanUtils.setProperty(obj, field.getName(), null);
return;
}
if (fieldType == String.class) {
BeanUtils.setProperty(obj, field.getName(), cellValue);
} else if (fieldType == Integer.TYPE || fieldType == Integer.class) {
BeanUtils.setProperty(obj, field.getName(), Integer.parseInt(cellValue));
} else if (fieldType == Long.TYPE || fieldType == Long.class) {
BeanUtils.setProperty(obj, field.getName(), Long.parseLong(cellValue));
} else if (fieldType == Float.TYPE || fieldType == Float.class) {
BeanUtils.setProperty(obj, field.getName(), Float.parseFloat(cellValue));
} else if (fieldType == Double.TYPE || fieldType == Double.class) {
BeanUtils.setProperty(obj, field.getName(), Double.parseDouble(cellValue));
} else if (fieldType == Date.class) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
BeanUtils.setProperty(obj, field.getName(), sdf.parse(cellValue));
} else {
throw new RuntimeException("Unsupported field type: " + fieldType.getName());
}
}
/**
* 获取单元格值
*/
private static String getCellValue(Cell cell) {
if (cell == null) {
return null;
}
DecimalFormat df = new DecimalFormat("#");
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue().trim();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date date = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
} else {
return df.format(cell.getNumericCellValue());
}
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
return getCellValue(cell.getCachedFormulaResultType() == CellType.NUMERIC ? cell : cell.getSheet().getRow(cell.getRowIndex() + 1).getCell(cell.getColumnIndex()));
default:
return null;
}
}
/**
* 字段映射关系
*/
private static class FieldMapping {
private Field field;
private int index;
public FieldMapping(Field field, int index) {
this.field = field;
this.index = index;
}
public Field getField() {
return field;
}
public int getIndex() {
return index;
}
}
}
```
接着,可以定义一个Excel注解用于标记实体类的属性,以及一个扫描指定路径下Excel文件并插入数据库的方法:
```java
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.List;
public class ExcelDemo {
@Excel(fieldName = "姓名")
private String name;
@Excel(fieldName = "年龄")
private int age;
@Excel(fieldName = "性别")
private String gender;
@Excel(fieldName = "职业")
private String occupation;
public static void main(String[] args) throws IOException {
String excelDir = "path/to/excel/dir";
String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:orcl";
String username = "username";
String password = "password";
File dir = new File(excelDir);
if (!dir.exists() || !dir.isDirectory()) {
System.out.println("Excel directory does not exist");
return;
}
File[] files = dir.listFiles((dir1, name) -> name.toLowerCase().endsWith(".xlsx"));
if (files == null || files.length == 0) {
System.out.println("No Excel file found in directory");
return;
}
try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
for (File file : files) {
List<ExcelDemo> dataList = ExcelUtil.readExcel(file, ExcelDemo.class);
if (CollectionUtils.isEmpty(dataList)) {
continue;
}
String sql = "INSERT INTO T_EXCEL_DEMO (NAME, AGE, GENDER, OCCUPATION) VALUES (?, ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (ExcelDemo data : dataList) {
pstmt.setString(1, data.name);
pstmt.setInt(2, data.age);
pstmt.setString(3, data.gender);
pstmt.setString(4, data.occupation);
pstmt.executeUpdate();
}
}
}
} catch (Exception e) {
throw new RuntimeException("Insert data error", e);
}
}
}
```
其中,@Excel注解可以用于标记实体类的属性,指定其对应的Excel表头字段名:
```java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excel {
String fieldName();
}
```
阅读全文