- Apache POI: 用于读取 Excel 文件(
.xls和.xlsx)。 - Oracle JDBC Driver: 用于连接 Oracle 数据库并执行 SQL 语句。
整体流程概览
整个过程可以分为以下几个核心步骤:

- 环境准备: 安装必要的软件(JDK, Oracle, Excel)并添加项目依赖。
- 建立数据库连接: 编写 Java 代码连接到 Oracle 数据库。
- 读取 Excel 文件: 使用 Apache POI 读取 Excel 中的数据。
- 数据导入与处理: 遍历 Excel 数据,并将其插入到 Oracle 数据库中,这是最关键的一步,需要考虑性能、事务和错误处理。
- 资源释放: 关闭所有打开的资源(文件流、数据库连接等)。
第一步:环境准备
安装软件
- JDK: 确保 Java Development Kit (JDK 8 或更高版本) 已安装并配置好环境变量。
- Oracle 数据库: 确保你有一个可用的 Oracle 数据库实例,并知道
hostname,port,service_name/sid,username和password。 - IDE: 如 IntelliJ IDEA 或 Eclipse。
- Excel 文件: 准备一个用于测试的 Excel 文件。
创建 Oracle 表
假设我们要导入一个包含员工信息的 Excel 文件,内容如下:
| ID | NAME | AGE | DEPARTMENT | HIRE_DATE |
|---|---|---|---|---|
| 1001 | 张三 | 28 | 技术部 | 2025-01-15 |
| 1002 | 李四 | 35 | 市场部 | 2025-05-20 |
| 1003 | 王五 | 31 | 财务部 | 2025-11-01 |
在 Oracle 中创建对应的表:
CREATE TABLE employees (
id NUMBER(10) PRIMARY KEY,
name VARCHAR2(100) NOT NULL,
age NUMBER(3),
department VARCHAR2(100),
hire_date DATE
);
添加项目依赖
如果你使用 Maven,在 pom.xml 文件中添加以下依赖:
<dependencies>
<!-- Apache POI for Excel (both .xls and .xlsx) -->
<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>
<!-- Oracle JDBC Driver -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
</dependencies>
如果你使用 Gradle,在 build.gradle 文件中添加:

dependencies {
// Apache POI for Excel
implementation 'org.apache.poi:poi:5.2.3'
implementation 'org.apache.poi:poi-ooxml:5.2.3'
// Oracle JDBC Driver
implementation 'com.oracle.database.jdbc:ojdbc8:19.3.0.0'
}
注意:
ojdbc8适用于 JDK 8,如果你使用 JDK 11 或更高版本,请使用ojdbc11。
第二步:核心代码实现
下面是一个完整的 Java 类,实现了从 Excel 导入数据到 Oracle 的功能。
我们将重点介绍两种插入方式:
- 逐条插入: 简单直接,但性能较差。
- 批量插入: 强烈推荐,性能极高。
逐条插入 (Simple Approach)
这种方式代码简单,但每次插入都会与数据库进行一次网络交互,对于大量数据来说非常慢。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExcelToOracleSimple {
private static final String DB_URL = "jdbc:oracle:thin:@your_hostname:your_port:your_service_name";
private static final String DB_USER = "your_username";
private static final String DB_PASSWORD = "your_password";
public static void main(String[] args) {
String excelFilePath = "path/to/your/employees.xlsx";
// 1. 读取Excel文件
try (FileInputStream fis = new FileInputStream(excelFilePath);
Workbook workbook = new XSSFWorkbook(fis)) {
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 2. 建立数据库连接
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
// 关闭自动提交,以便在循环中使用事务
conn.setAutoCommit(false);
// 3. 准备SQL语句
String sql = "INSERT INTO employees (id, name, age, department, hire_date) VALUES (?, ?, ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 4. 遍历Excel行,从第二行开始(跳过标题行)
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row == null) continue;
Cell idCell = row.getCell(0);
Cell nameCell = row.getCell(1);
Cell ageCell = row.getCell(2);
Cell deptCell = row.getCell(3);
Cell dateCell = row.getCell(4);
// 设置参数
pstmt.setInt(1, (int) idCell.getNumericCellValue());
pstmt.setString(2, nameCell.getStringCellValue());
pstmt.setInt(3, (int) ageCell.getNumericCellValue());
pstmt.setString(4, deptCell.getStringCellValue());
// 处理日期
if (dateCell.getCellType() == CellType.NUMERIC) {
Date hireDate = dateCell.getDateCellValue();
pstmt.setDate(5, new java.sql.Date(hireDate.getTime()));
} else {
// 如果是字符串格式,需要手动解析
String dateStr = dateCell.getStringCellValue();
java.util.Date utilDate = sdf.parse(dateStr);
pstmt.setDate(5, new java.sql.Date(utilDate.getTime()));
}
// 5. 执行插入
pstmt.executeUpdate();
System.out.println("成功插入第 " + (i + 1) + " 行数据。");
}
// 6. 提交事务
conn.commit();
System.out.println("所有数据已成功导入数据库!");
} catch (Exception e) {
// 发生异常,回滚事务
conn.rollback();
System.err.println("导入过程中发生错误,已回滚。");
e.printStackTrace();
}
}
} catch (IOException | SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
批量插入 (High-Performance Approach)
这是处理大量数据(如上万行)的最佳实践,它通过 addBatch() 和 executeBatch() 将多个 SQL 语句一次性发送给数据库执行,极大地减少了网络开销。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExcelToOracleBatch {
private static final String DB_URL = "jdbc:oracle:thin:@your_hostname:your_port:your_service_name";
private static final String DB_USER = "your_username";
private static final String DB_PASSWORD = "your_password";
// 每批量插入1000条数据后执行一次
private static final int BATCH_SIZE = 1000;
public static void main(String[] args) {
String excelFilePath = "path/to/your/employees.xlsx";
try (FileInputStream fis = new FileInputStream(excelFilePath);
Workbook workbook = new XSSFWorkbook(fis)) {
Sheet sheet = workbook.getSheetAt(0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
conn.setAutoCommit(false); // 关闭自动提交,使用手动事务
String sql = "INSERT INTO employees (id, name, age, department, hire_date) VALUES (?, ?, ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
int count = 0;
// 从第二行开始遍历
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row == null) 