在Java开发中,生成和导出Excel文件是一项常见的需求,广泛应用于数据报表、财务报表、订单导出等场景,本文将详细介绍Java中生成导出Excel的多种方式,包括Apache POI、EasyExcel、JXL等库的使用方法,以及不同场景下的技术选型和最佳实践。
Java操作Excel的主流技术选型
目前Java生态中操作Excel的主流库有Apache POI、EasyExcel和JXL,其中Apache POI功能最为全面,EasyExcel在性能和内存占用上更具优势,JXL则适合简单的Excel操作需求,开发者需要根据项目具体需求(如Excel版本、数据量、性能要求等)选择合适的工具库。
Apache POI
Apache POI是Apache软件基金会开放源码的函式库,提供API给Java程序对Microsoft Office格式档案进行读写操作,支持Excel 97-2003(.xls)和Excel 2007+(.xlsx)格式,功能强大但存在内存占用高的问题,处理大数据量时容易引发OOM(内存溢出)错误。
EasyExcel
EasyExcel是阿里巴巴开源的Excel处理工具,基于POI封装,解决了POI在内存占用上的缺陷,采用SAX模式读写,适合处理大数据量场景,支持Excel 2007+格式,并提供注解式的API,使用更加便捷。
JXL
JXL(Java Excel API)是一个简单的Excel操作工具,仅支持Excel 95-2003(.xls)格式,不支持.xlsx格式,其API简单易用,但功能相对有限,适合对Excel版本要求不高的简单场景。
使用Apache POI生成Excel文件
Apache POI是功能最全面的Excel操作库,下面以POI 5.2.3版本为例,介绍如何生成Excel文件。
添加依赖
在Maven项目的pom.xml中添加POI依赖:
<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>
生成Excel 2007+(.xlsx)文件
使用XSSFWorkbook类创建.xlsx格式文件,以下示例代码演示如何创建包含标题和数据的Excel文件:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public class PoiExportExample {
public static void main(String[] args) {
// 创建工作簿
Workbook workbook = new XSSFWorkbook();
// 创建工作表
Sheet sheet = workbook.createSheet("用户数据");
// 创建标题行
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("ID");
headerRow.createCell(1).setCellValue("姓名");
headerRow.createCell(2).setCellValue("年龄");
// 创建数据行
Row dataRow1 = sheet.createRow(1);
dataRow1.createCell(0).setCellValue(1);
dataRow1.createCell(1).setCellValue("张三");
dataRow1.createCell(2).setCellValue(25);
Row dataRow2 = sheet.createRow(2);
dataRow2.createCell(0).setCellValue(2);
dataRow2.createCell(1).setCellValue("李四");
dataRow2.createCell(2).setCellValue(30);
// 写入文件
try (FileOutputStream fileOut = new FileOutputStream("users.xlsx")) {
workbook.write(fileOut);
System.out.println("Excel文件生成成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
样式设置
可以通过CellStyle设置单元格样式,如字体、颜色、边框等:
// 创建样式
CellStyle style = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
font.setColor(IndexedColors.RED.getIndex());
style.setFont(font);
// 应用样式
Cell cell = headerRow.createCell(0);
cell.setCellValue("标题");
cell.setCellStyle(style);
使用EasyExcel生成Excel文件
EasyExcel在处理大数据量时具有明显优势,以下介绍其基本用法。
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
使用注解定义数据模型
import com.alibaba.excel.annotation.ExcelProperty;
public class UserData {
@ExcelProperty("ID")
private Integer id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
// getter和setter方法
}
写入Excel文件
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelExportExample {
public static void main(String[] args) {
// 准备数据
List<UserData> dataList = new ArrayList<>();
dataList.add(new UserData(1, "张三", 25));
dataList.add(new UserData(2, "李四", 30));
// 写入Excel
String fileName = "users_easyexcel.xlsx";
EasyExcel.write(fileName, UserData.class).sheet("用户数据").doWrite(dataList);
System.out.println("Excel文件生成成功");
}
}
大数据量写入
EasyExcel通过SAX模式实现流式写入,避免内存溢出:
// 写入大数据量
String bigDataFileName = "big_data.xlsx";
EasyExcel.write(bigDataFileName, UserData.class)
.sheet("大数据")
.doWrite(() -> {
// 模拟大数据查询
List<UserData> data = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
data.add(new UserData(i, "用户" + i, 20 + i % 30));
}
return data;
});
高级功能实现
合并单元格
使用Sheet的addMergedRegion方法合并单元格:
// 合并第一行的0-2列
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 2));
Cell mergedCell = sheet.getRow(0).createCell(0);
mergedCell.setCellValue("合并标题");
设置列宽
通过Sheet的setColumnWidth方法调整列宽:
// 设置第一列宽度为20个字符 sheet.setColumnWidth(0, 20 * 256);
数据验证
使用DataValidation添加下拉列表等数据验证:
DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createExplicitListConstraint("选项1,选项2,选项3");
CellRangeAddressList addressList = new CellRangeAddressList(1, 100, 0, 0);
DataValidation validation = helper.createValidation(constraint, addressList);
sheet.addValidationData(validation);
性能优化与最佳实践
内存优化
- 对于大数据量,优先选择EasyExcel等基于SAX模式的库
- 避免在内存中一次性加载所有数据,采用分批写入方式
- 及时关闭Workbook对象,释放资源
异常处理
- 处理文件写入时的IO异常
- 捕获POI可能出现的异常(如InvalidFormatException)
- 使用try-with-resources确保资源释放
版本兼容性
- 明确项目所需的Excel版本(.xls或.xlsx)
- 根据版本选择对应的POI组件(HSSFWorkbook/XSSFWorkbook)
- 测试不同Excel版本的兼容性
样式复用
- 创建公共样式工具类,避免重复创建CellStyle
- 使用Map缓存常用样式,减少内存占用
Java生成导出Excel文件有多种实现方式,开发者应根据项目需求选择合适的工具库,Apache POI功能全面但内存占用较高,适合中小数据量场景;EasyExcel在性能和内存管理上表现优异,适合大数据量导出;JXL则适合简单的Excel操作需求,在实际开发中,还需注意样式设置、异常处理、性能优化等问题,以确保导出功能的稳定性和高效性,通过合理的技术选型和代码实现,可以满足各种复杂的Excel导出需求。












