使用 Spring Boot + EasyExcel 實(shí)現(xiàn)百萬級數(shù)據(jù)導(dǎo)入導(dǎo)出功能開發(fā)
在當(dāng)今數(shù)據(jù)驅(qū)動的業(yè)務(wù)環(huán)境中,高效地處理大量數(shù)據(jù)是至關(guān)重要的。Spring Boot 作為一種流行的 Java 框架,提供了許多方便的功能來簡化開發(fā)過程。EasyExcel 則是一個強(qiáng)大的工具,專門用于處理 Excel 文件。本文將介紹如何結(jié)合使用 Spring Boot 和 EasyExcel 來實(shí)現(xiàn)百萬級數(shù)據(jù)的導(dǎo)入導(dǎo)出功能。
EasyExcel 框架及特性介紹
EasyExcel 是一個基于 Java 的 Excel 處理框架,具有以下顯著特性:
- 內(nèi)存優(yōu)化:能夠高效處理大文件,避免內(nèi)存溢出問題,尤其在處理百萬級數(shù)據(jù)時表現(xiàn)出色。
- 簡單易用:提供了簡潔直觀的 API,使開發(fā)人員可以輕松地進(jìn)行 Excel 文件的讀取、寫入和處理操作。
- 性能卓越:在數(shù)據(jù)處理速度方面具有優(yōu)勢,能夠快速完成大規(guī)模數(shù)據(jù)的操作。
- 支持多種格式:不僅可以處理常見的 Excel 格式,還能適應(yīng)不同的需求。
項目創(chuàng)建及依賴配置(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icoderoad</groupId>
<artifactId>easyexcel-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>EasyExcel Demo</name>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
項目文件結(jié)構(gòu):
project-root/
src/
main/
java/
com/
icoderoad/
Application.java // Spring Boot 啟動類
controller/ExcelController // 控制器類
service/ExcelService.java // 服務(wù)類
config/EasyExcelConfig.java
resources/
application.yaml // 配置文件
static/index.html // 靜態(tài)資源,如 CSS、JS、圖片等
pom.xml // Maven 項目配置文件
配置文件(application.yml)
# 在此處可添加您的應(yīng)用特定配置
easyexcel:
# 例如,設(shè)置最大讀取行數(shù)
max-read-rows: 1000000
# 大文件處理配置
large-file:
# 啟用大文件處理
enabled: true
# 內(nèi)存緩沖區(qū)大小(字節(jié))
buffer-size: 10485760
# 每次讀取的行數(shù)
read-rows-per-time: 10000
啟動類 Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
配置類 EasyExcelConfig.java
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.event.AnalysisEventListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.yaml.snakeyaml.Yaml;
/**
* EasyExcel 配置類,負(fù)責(zé)讀取和設(shè)置相關(guān)配置參數(shù)
*/
@Configuration
public class EasyExcelConfig {
@Value("${excel.read.maxRows}")
private int maxRows;
@Value("${excel.read.useDefaultListener}")
private boolean useDefaultListener;
@Value("${excel.read.readCacheSize}")
private int readCacheSize;
/**
* 創(chuàng)建 Excel 事件監(jiān)聽器
* @return 分析事件監(jiān)聽器實(shí)例
*/
@Bean
public AnalysisEventListener excelEventListener() {
return new ExcelListener();
}
/**
* 創(chuàng)建 EasyExcel 實(shí)例
* @return EasyExcel 實(shí)例
*/
@Bean
public EasyExcel easyExcel() {
return new EasyExcel();
}
/**
* 創(chuàng)建并設(shè)置 ReadExcelProperties
* @return ReadExcelProperties 實(shí)例
*/
@Bean
public ReadExcelProperties readExcelProperties() {
ReadExcelProperties properties = new ReadExcelProperties();
properties.setMaxRows(maxRows);
properties.setUseDefaultListener(useDefaultListener);
properties.setReadCacheSize(readCacheSize);
return properties;
}
}
服務(wù)接口定義及實(shí)現(xiàn) ExcelService.java
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import org.springframework.stereotype.Service;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@Service
public class ExcelService {
// 示例方法
public void exportData() {
// 創(chuàng)建數(shù)據(jù)列表
List<List<String>> data = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
List<String> row = new ArrayList<>();
row.add("Row " + i);
row.add("Column 1");
row.add("Column 2");
data.add(row);
}
// 創(chuàng)建輸出流
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream("exported_data.xlsx");
} catch (IOException e) {
e.printStackTrace();
}
// 創(chuàng)建 ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(outputStream)
.withTemplate("template.xlsx")
.build();
// 創(chuàng)建 WriteSheet
WriteSheet writeSheet = EasyExcel.writerSheet()
.sheetName("Sheet1")
.build();
// 填充數(shù)據(jù)
excelWriter.fill(data, new FillConfig());
// 關(guān)閉 ExcelWriter
excelWriter.finish();
// 關(guān)閉輸出流
try {
if (outputStream!= null) {
outputStream.close();
}
}
public void importData() {
EasyExcel.read("imported_data.xlsx", new ExcelListener()).sheet().doRead();
}
// 自定義監(jiān)聽器,用于處理導(dǎo)入的數(shù)據(jù)
static class ExcelListener extends AnalysisEventListener {
private List<List<String>> data = new ArrayList<>();
@Override
public void invoke(Object object, AnalysisContext context) {
if (object instanceof List<?>) {
List<String> rowData = (List<String>) object;
data.add(rowData);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 在此處添加導(dǎo)入完成后的其他處理邏輯,例如數(shù)據(jù)校驗(yàn)、數(shù)據(jù)存儲等
System.out.println("數(shù)據(jù)導(dǎo)入完成,共 " + data.size() + " 行數(shù)據(jù)。");
}
}
}
控制器類 ExcelController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExcelController {
@Autowired
private ExcelService excelService;
@GetMapping("/export")
public String exportData() {
excelService.exportData();
return "數(shù)據(jù)導(dǎo)出成功";
}
@GetMapping("/import")
public String importData() {
excelService.importData();
return "數(shù)據(jù)導(dǎo)入成功";
}
}
前端頁面 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Excel 操作</title>
</head>
<body>
<h1>Excel 操作</h1>
<button onclick="exportData()">導(dǎo)出數(shù)據(jù)</button>
<button onclick="importData()">導(dǎo)入數(shù)據(jù)</button>
<script>
function exportData() {
fetch('/export')
.then(response => response.text())
.then(data => {
alert(data);
})
.catch(error => {
alert('導(dǎo)出數(shù)據(jù)失敗: 'rror);
});
}
function importData() {
fetch('/import')
.then(response => response.text())
.then(data => {
alert(data);
})
.catch(error => {
alert('導(dǎo)入數(shù)據(jù)失敗: 'rror);
});
}
</script>
</body>
</html>
在實(shí)際開發(fā)中,大家需要根據(jù)具體的業(yè)務(wù)需求對數(shù)據(jù)的處理邏輯進(jìn)行進(jìn)一步的優(yōu)化和完善。同時,還需要考慮異常處理、數(shù)據(jù)校驗(yàn)等方面,以確保系統(tǒng)的穩(wěn)定性和可靠性。希望本文能夠幫助大家成功實(shí)現(xiàn)百萬級數(shù)據(jù)的導(dǎo)入導(dǎo)出功能,為大家的業(yè)務(wù)提供有力的支持。