Java 导入 Excel 到数据库
在 Java 中将 Excel 文件导入数据库是一个常见的需求,以下是几种实现方法的详细说明:

使用 Apache POI + JDBC
Apache POI 是最流行的 Java Excel 处理库,可以读取 Excel 文件内容。
步骤:
-
添加依赖(Maven):
<dependencies> <!-- Apache POI for Excel --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <!-- Database driver (example for MySQL) --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> </dependencies> -
实现代码:
import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement;

public class ExcelToDatabaseImporter {
public static void main(String[] args) {
String excelFilePath = "path/to/your/file.xlsx";
String dbUrl = "jdbc:mysql://localhost:3306/your_database";
String dbUser = "username";
String dbPassword = "password";
try (FileInputStream fis = new FileInputStream(excelFilePath);
Workbook workbook = new XSSFWorkbook(fis);
Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword)) {
// 假设数据在第一个工作表
Sheet sheet = workbook.getSheetAt(0);
// 准备SQL语句
String sql = "INSERT INTO your_table (column1, column2, column3) VALUES (?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
// 跳过标题行(如果有)
int rowIndex = 1;
for (Row row : sheet) {
if (rowIndex == 0) {
rowIndex++;
continue; // 跳过标题行
}
// 获取单元格值
String value1 = getCellValueAsString(row.getCell(0));
String value2 = getCellValueAsString(row.getCell(1));
String value3 = getCellValueAsString(row.getCell(2));
// 设置参数
pstmt.setString(1, value1);
pstmt.setString(2, value2);
pstmt.setString(3, value3);
// 添加到批处理
pstmt.addBatch();
// 每处理1000行执行一次批处理
if (rowIndex % 1000 == 0) {
pstmt.executeBatch();
}
rowIndex++;
}
// 执行剩余的批处理
pstmt.executeBatch();
System.out.println("数据导入成功,共处理 " + (rowIndex - 1) + " 行");
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getCellValueAsString(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue().toString();
} else {
return String.valueOf(cell.getNumericCellValue());
}
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
return cell.getCellFormula();
default:
return "";
}
}
## 2. 使用 EasyExcel
EasyExcel 是阿里巴巴开源的 Excel 处理库,性能更好,内存占用更小。
### 步骤:
1. 添加依赖:
```xml
<dependencies>
<!-- EasyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
<!-- Database driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
- 定义数据模型:
import com.alibaba.excel.annotation.ExcelProperty;
public class ExcelData { @ExcelProperty("姓名") private String name;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("邮箱")
private String email;
// getters and setters
3. 实现代码:
```java
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelImporter {
public static void main(String[] args) {
String excelFilePath = "path/to/your/file.xlsx";
String dbUrl = "jdbc:mysql://localhost:3306/your_database";
String dbUser = "username";
String dbPassword = "password";
// 读取Excel数据
List<ExcelData> dataList = new ArrayList<>();
EasyExcel.read(excelFilePath, ExcelData.class, new AnalysisEventListener<ExcelData>() {
@Override
public void invoke(ExcelData data, AnalysisContext context) {
dataList.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("Excel读取完成");
}
}).sheet().doRead();
// 写入数据库
try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword)) {
String sql = "INSERT INTO your_table (name, age, email) VALUES (?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
for (ExcelData data : dataList) {
pstmt.setString(1, data.getName());
pstmt.setInt(2, data.getAge());
pstmt.setString(3, data.getEmail());
pstmt.addBatch();
// 每处理1000行执行一次批处理
if (dataList.size() % 1000 == 0) {
pstmt.executeBatch();
}
}
// 执行剩余的批处理
pstmt.executeBatch();
System.out.println("数据导入成功,共处理 " + dataList.size() + " 行");
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用 Spring Boot + EasyExcel
如果你使用 Spring Boot,可以更方便地实现:
-
添加依赖:
(图片来源网络,侵删)<dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- EasyExcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.1.1</version> </dependency> <!-- Spring Boot Starter Data JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- Database driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> </dependencies> -
创建实体类:
import javax.persistence.Entity; import javax.persistence.Id;
@Entity public class YourEntity { @Id private Long id; private String name; private Integer age; private String email;
// getters and setters
3. 创建服务类:
```java
import com.alibaba.excel.EasyExcel;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Service
public class ExcelImportService {
private final YourEntityRepository repository;
public ExcelImportService(YourEntityRepository repository) {
this.repository = repository;
}
@Transactional
public void importExcel(MultipartFile file) throws IOException {
List<YourEntity> entities = new ArrayList<>();
EasyExcel.read(file.getInputStream(), YourEntity.class, new AnalysisEventListener<YourEntity>() {
@Override
public void invoke(YourEntity data, AnalysisContext context) {
entities.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("Excel读取完成");
}
}).sheet().doRead();
repository.saveAll(entities);
}
}
注意事项
- 数据验证:在导入前验证Excel数据的格式和有效性
- 事务管理:确保数据库操作在事务中执行,数据一致性
- 性能优化:使用批处理(batch)而不是单条插入
- 错误处理:捕获并处理可能的异常
- 内存管理:对于大文件,考虑使用SAX模式(EasyExcel支持)
- 进度反馈:对于大文件导入,提供进度反馈
错误处理示例
try {
// 导入逻辑
} catch (DuplicateKeyException e) {
// 处理重复键错误
System.err.println("发现重复数据: " + e.getMessage());
} catch (DataIntegrityViolationException e) {
// 处理数据完整性约束错误
System.err.println("数据完整性错误: " + e.getMessage());
} catch (Exception e) {
// 处理其他异常
e.printStackTrace();
}
方法可以根据你的具体需求和技术栈选择合适的实现方式,EasyExcel 在处理大文件时性能更好,而 Apache POI 则功能更全面。
