在Java开发中,处理Excel文件是常见需求,尤其是.xlsx格式的文件(基于Office Open XML标准),本文将详细介绍如何使用Java打开、读取和操作xlsx文件,涵盖主流库选择、基础操作步骤、代码示例及常见问题解决方案。
主流库选择:Apache POI与EasyExcel对比
Java生态中处理xlsx文件的库主要有Apache POI和EasyExcel(阿里巴巴开源),Apache POI功能全面,支持Excel所有版本,但大数据量时内存占用较高;EasyExcel采用模型映射和流式读取,内存优化更优,适合海量数据处理,两者各有侧重,开发者可根据场景选择:
- Apache POI:适合需要复杂操作(如图表、公式)或兼容旧版.xls文件的场景。
- EasyExcel:适合大数据量读取(如百万行数据)、写入或对内存敏感的场景。
基础操作步骤:以Apache POI为例
Apache POI操作xlsx文件的核心类是XSSFWorkbook(代表工作簿)、XSSFSheet(代表工作表)、XSSFRow(代表行)、XSSFCell(代表单元格),以下是基础操作流程:
添加依赖
在Maven项目的pom.xml中添加POI依赖(注意版本需匹配,建议使用5.x以上):
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
读取xlsx文件
读取文件需通过FileInputStream打开文件流,用XSSFWorkbook加载工作簿,再逐层获取数据:
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
public class ReadXlsx {
public static void main(String[] args) throws Exception {
// 1. 文件路径
String filePath = "example.xlsx";
// 2. 获取文件流
FileInputStream fis = new FileInputStream(filePath);
// 3. 创建工作簿对象
Workbook workbook = new XSSFWorkbook(fis);
// 4. 获取第一个工作表(索引从0开始)
Sheet sheet = workbook.getSheetAt(0);
// 5. 遍历行(跳过表头)
for (Row row : sheet) {
if (row.getRowNum() == 0) continue; // 跳过表头
// 遍历单元格
for (Cell cell : row) {
switch (cell.getCellType()) {
case STRING:
System.out.print(cell.getStringCellValue() + "\t");
break;
case NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t");
break;
case BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "\t");
break;
}
}
System.out.println();
}
// 6. 关闭资源
workbook.close();
fis.close();
}
}
写入xlsx文件
写入操作需创建XSSFWorkbook,通过createSheet添加工作表,再用createRow和createCell填充数据,最后用FileOutputStream写入文件:
import org.apache.poi.ss.usermodel.*;
import java.io.FileOutputStream;
public class WriteXlsx {
public static void main(String[] args) throws Exception {
// 1. 创建工作簿
Workbook workbook = new XSSFWorkbook();
// 2. 创建工作表
Sheet sheet = workbook.createSheet("Sheet1");
// 3. 创建表头行
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("姓名");
headerRow.createCell(1).setCellValue("年龄");
// 4. 创建数据行
Row dataRow = sheet.createRow(1);
dataRow.createCell(0).setCellValue("张三");
dataRow.createCell(1).setCellValue(25);
// 5. 写入文件
FileOutputStream fos = new FileOutputStream("output.xlsx");
workbook.write(fos);
// 6. 关闭资源
workbook.close();
fos.close();
System.out.println("文件写入成功!");
}
}
常见问题及解决方案
内存溢出问题
POI默认将整个文件加载到内存,若处理大文件(如100MB以上)易导致OutOfMemoryError,解决方案:
- 使用EasyExcel:通过
AnalysisEventListener监听器实现流式读取,逐行解析并处理数据,避免全量加载。 - POI的SXSSFWorkbook:仅保留部分数据在内存,其余写入临时文件,适合大数据量写入。
日期格式处理
xlsx文件中的日期可能存储为数字(Excel序列值),需用DataFormatter或CellStyle格式化:
DataFormatter formatter = new DataFormatter(); String dateStr = formatter.formatCellValue(cell); // 自动识别日期格式
单元格类型判断
避免直接使用cell.getCellType(),建议通过cell.getCellType()结合cell.getCellTypeEnum()(POI 3.15+)或switch-case处理,确保兼容性。
性能优化与最佳实践
- 批量操作:写入时尽量一次性设置数据,减少IO操作;读取时使用
Sheet.iterator()而非Sheet.getPhysicalNumberOfRows()预判行数。 - 关闭资源:务必关闭
Workbook、FileInputStream等资源,避免内存泄漏,可通过try-with-resources简化代码:try (FileInputStream fis = new FileInputStream("example.xlsx"); Workbook workbook = new XSSFWorkbook(fis)) { // 操作代码 } // 自动关闭资源 - 版本兼容性:POI 5.x以上对Office 365新特性支持更好,建议升级最新版本;EasyExcel推荐2.x以上,性能更优。
通过以上方法,开发者可高效处理Java中的xlsx文件操作,根据实际需求选择合适库,遵循内存优化和异常处理原则,能显著提升程序稳定性和性能。














