本文目录导读:

在Java中实现Excel导入导出,主要有两种主流的开源库:Apache POI 和 EasyExcel。
- Apache POI:功能最全,支持xls和xlsx,但内存消耗较大,速度较慢。
- EasyExcel(阿里开源的):基于POI进行了封装和重写,内存占用极低,特别适合处理大数据量,API更简洁。
下面是基于 EasyExcel 的完整案例(推荐使用),因为它最符合现代Java开发的需求(更少的代码、更低的内存),如果你需要兼容非常古老的xls格式或对POI有特殊需求,我也会在最后提到POI版本。
使用 EasyExcel(推荐)
首先在 pom.xml 中添加依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>4.0.3</version> <!-- 请使用最新稳定版 -->
</dependency>
定义数据模型(对应Excel表头)
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class UserData {
// index属性指定列的顺序(从0开始),value属性指定表头名称
@ExcelProperty(value = "用户ID", index = 0)
private Integer userId;
@ExcelProperty(value = "用户名", index = 1)
private String userName;
@ExcelProperty(value = "年龄", index = 2)
private Integer age;
@ExcelProperty(value = "邮箱", index = 3)
private String email;
}
导出 Excel(写入文件)
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.List;
public class ExcelExportDemo {
public static void main(String[] args) {
// 1. 准备数据(模拟数据库查询结果)
List<UserData> dataList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
UserData user = new UserData();
user.setUserId(i + 1);
user.setUserName("用户" + i);
user.setAge(20 + i % 30);
user.setEmail("user" + i + "@example.com");
dataList.add(user);
}
// 2. 定义导出的文件路径
String fileName = "用户数据.xlsx";
// 3. 写入文件
// 第一个参数:文件路径
// 第二个参数:数据模型的Class
// 第三个参数:数据集合
// sheet("用户列表"):指定Sheet页名称
EasyExcel.write(fileName, UserData.class)
.sheet("用户列表")
.doWrite(dataList);
System.out.println("导出成功!文件路径:" + fileName);
}
}
导入 Excel(读取文件)
EasyExcel最大的优势之一:通过监听器一行一行读取,避免内存溢出。
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import java.util.ArrayList;
import java.util.List;
// 自定义监听器,每次读取一行数据都会回调
public class UserDataListener implements ReadListener<UserData> {
// 缓存每批读取的数据(例如每100条批量处理一次)
private List<UserData> cachedDataList = new ArrayList<>();
// 每读取一行数据,该方法被调用
@Override
public void invoke(UserData data, AnalysisContext context) {
cachedDataList.add(data);
// 达到批量处理阈值时,可以进行数据库插入等操作
if (cachedDataList.size() >= 100) {
// 模拟批量保存
saveData(cachedDataList);
// 清空缓存
cachedDataList = new ArrayList<>();
}
}
// 所有数据读取完毕后,如果有剩余数据,也需要处理
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
if (cachedDataList.size() > 0) {
saveData(cachedDataList);
}
System.out.println("所有数据读取完成!");
}
// 模拟保存到数据库
private void saveData(List<UserData> dataList) {
System.out.println("成功处理 " + dataList.size() + " 条数据");
// 实际业务中这里调用数据库批量插入
}
}
调用导入方法:
public class ExcelImportDemo {
public static void main(String[] args) {
String fileName = "用户数据.xlsx";
// 第一个参数:文件路径
// 第二个参数:数据模型Class
// 第三个参数:监听器(new 一个)
EasyExcel.read(fileName, UserData.class, new UserDataListener())
.sheet() // 读取第一个Sheet
.doRead(); // 开始执行读取
System.out.println("导入完成!");
}
}
使用 Apache POI(传统方案)
如果你的项目必须使用POI(比如需要操作复杂的Excel样式、宏、xls格式),可以参考以下样板代码。
添加 Maven 依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <!-- 包含xlsx支持 -->
<version>5.3.0</version>
</dependency>
导出 Excel(POI实现)
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.util.List;
public class POIExportDemo {
public static void exportToExcel(List<UserData> userList, String filePath) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("用户列表");
// 1. 创建表头
Row headerRow = sheet.createRow(0);
String[] headers = {"用户ID", "用户名", "年龄", "邮箱"};
for (int i = 0; i < headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
// 给表头设置样式(可选)
CellStyle style = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
style.setFont(font);
cell.setCellStyle(style);
}
// 2. 填充数据
int rowIndex = 1;
for (UserData user : userList) {
Row row = sheet.createRow(rowIndex++);
row.createCell(0).setCellValue(user.getUserId());
row.createCell(1).setCellValue(user.getUserName());
row.createCell(2).setCellValue(user.getAge());
row.createCell(3).setCellValue(user.getEmail());
}
// 3. 写入文件
try (FileOutputStream fos = new FileOutputStream(filePath)) {
workbook.write(fos);
}
workbook.close(); // 关闭资源
}
}
导入 Excel(POI实现)
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
public class POIImportDemo {
public static List<UserData> importFromExcel(String filePath) throws Exception {
List<UserData> userList = new ArrayList<>();
// 注意:如果文件是xls格式,使用HSSFWorkbook
try (FileInputStream fis = new FileInputStream(filePath);
Workbook workbook = new XSSFWorkbook(fis)) {
Sheet sheet = workbook.getSheetAt(0); // 读取第一个Sheet
for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 从第1行开始(跳过表头)
Row row = sheet.getRow(i);
if (row == null) continue;
UserData user = new UserData();
// 注意:POI读取时需要处理单元格类型(数字、字符串等)
user.setUserId((int) row.getCell(0).getNumericCellValue());
user.setUserName(row.getCell(1).getStringCellValue());
user.setAge((int) row.getCell(2).getNumericCellValue());
user.setEmail(row.getCell(3).getStringCellValue());
userList.add(user);
}
}
return userList;
}
}
总结与选择建议
| 特性 | EasyExcel ✅ | Apache POI |
|---|---|---|
| 内存占用 | 极低(一行行读取) | 高(全部加载到内存) |
| API简洁度 | ⭐⭐⭐⭐⭐ 注解驱动 | ⭐⭐⭐ 原始API |
| 大文件支持 | 非常好(几百万行无压力) | 容易OOM |
| 样式/公式/宏 | 仅支持基础 | 非常强大 |
| xls格式 | 不支持 | 支持 |
我的建议:
- 95%的新项目:直接使用 EasyExcel,简单高效。
- 需要复杂的Excel样式(如合并单元格、条件格式、图表等):使用 POI。
- 需要兼容上古xls格式:使用 POI(HSSFWorkbook)。
就是Java实现Excel导入导出的完整案例,两种主流方式都覆盖了,你可以根据实际项目情况选择合适的方式。