杰瑞科技汇

Java如何将Excel数据高效导入数据库?

Java 导入 Excel 到数据库

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

Java如何将Excel数据高效导入数据库?-图1
(图片来源网络,侵删)

使用 Apache POI + JDBC

Apache POI 是最流行的 Java Excel 处理库,可以读取 Excel 文件内容。

步骤:

  1. 添加依赖(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>
  2. 实现代码:

    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;

Java如何将Excel数据高效导入数据库?-图2
(图片来源网络,侵删)

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>
  1. 定义数据模型:
    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,可以更方便地实现:

  1. 添加依赖:

    Java如何将Excel数据高效导入数据库?-图3
    (图片来源网络,侵删)
    <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>
  2. 创建实体类:

    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);
    }
}

注意事项

  1. 数据验证:在导入前验证Excel数据的格式和有效性
  2. 事务管理:确保数据库操作在事务中执行,数据一致性
  3. 性能优化:使用批处理(batch)而不是单条插入
  4. 错误处理:捕获并处理可能的异常
  5. 内存管理:对于大文件,考虑使用SAX模式(EasyExcel支持)
  6. 进度反馈:对于大文件导入,提供进度反馈

错误处理示例

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 则功能更全面。

分享:
扫描分享到社交APP
上一篇
下一篇