Of course! Working with Excel 2007 (.xlsx files) in Java is a very common task. The key thing to understand is that Excel 2007 introduced a new file format based on OpenXML, which is a ZIP archive containing XML files. This is different from the older Excel 97-2003 format (.xls).

Here’s a comprehensive guide covering the most popular and effective libraries, with code examples.
Summary of Options
| Library | License | Format Support | Key Features | Recommendation |
|---|---|---|---|---|
| Apache POI | Apache 2.0 (Business-friendly) | .xlsx (Excel 2007+) |
The industry standard. Very powerful, mature, but can be memory-intensive for huge files. | Best for most use cases. The go-to solution. |
| EasyExcel | Apache 2.0 (Business-friendly) | .xlsx (Excel 2007+) |
Built on POI, but with a low-memory consumption model using the SAX (read) and write (streaming) API. | Excellent for large files (e.g., reading/writing millions of rows). |
| JExcelApi | LGPL | .xls (97-2003) and .xlsx (2007+) |
Lightweight and simple. Good for basic read/write operations. A good alternative if POI feels too heavy. | Good for simple tasks, but less feature-rich than POI. |
Apache POI (The Standard Choice)
Apache POI is the most widely used Java library for manipulating Microsoft Office documents. For Excel 2007 (.xlsx), you use the XSSF (XML Spreadsheet Format) API.
Step 1: Add Dependency
You need to add the POI dependencies to your project. If you're using Maven, add this to your pom.xml:
<dependencies>
<!-- For Excel 2007 (XSSF) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version> <!-- Use the latest stable version -->
</dependency>
<!-- For OOXML schemas (required by XSSF) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
Step 2: Writing an Excel 2007 (.xlsx) File
This example creates a new workbook, adds a sheet, writes data to cells, and saves the file.

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public class ApachePoiWriteExample {
public static void main(String[] args) {
// 1. Create a new Excel workbook (for .xlsx format)
Workbook workbook = new XSSFWorkbook();
// 2. Create a sheet in the workbook
Sheet sheet = workbook.createSheet("Employee Data");
// 3. Create a header row
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("ID");
headerRow.createCell(1).setCellValue("Name");
headerRow.createCell(2).setCellValue("Salary");
// 4. Create data rows
Object[][] employeesData = {
{101, "Alice", 75000.50},
{102, "Bob", 82000.00},
{103, "Charlie", 90000.75}
};
int rowNum = 1;
for (Object[] employee : employeesData) {
Row row = sheet.createRow(rowNum++);
int colNum = 0;
for (Object field : employee) {
Cell cell = row.createCell(colNum++);
if (field instanceof String) {
cell.setCellValue((String) field);
} else if (field instanceof Integer) {
cell.setCellValue((Integer) field);
} else if (field instanceof Double) {
cell.setCellValue((Double) field);
}
}
}
// 5. Auto-size columns for better visibility
for (int i = 0; i < 3; i++) {
sheet.autoSizeColumn(i);
}
// 6. Write the workbook to a file
try (FileOutputStream fileOut = new FileOutputStream("employees_poi.xlsx")) {
workbook.write(fileOut);
System.out.println("employees_poi.xlsx file has been created successfully.");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 7. Close the workbook to free resources
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Step 3: Reading an Excel 2007 (.xlsx) File
This example reads the file we just created and prints its contents to the console.
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class ApachePoiReadExample {
public static void main(String[] args) {
String filePath = "employees_poi.xlsx";
try (FileInputStream fileIn = new FileInputStream(filePath);
Workbook workbook = new XSSFWorkbook(fileIn)) {
// 1. Get the first sheet from the workbook
Sheet sheet = workbook.getSheetAt(0);
// 2. Iterate over rows
for (Row row : sheet) {
// 3. Iterate over cells in the current row
for (Cell cell : row) {
// 4. Print cell value based on its type
switch (cell.getCellType()) {
case STRING:
System.out.print(cell.getStringCellValue() + "\t");
break;
case NUMERIC:
// Check if it's an integer or a double
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(cell.getDateCellValue() + "\t");
} else {
System.out.print(cell.getNumericCellValue() + "\t");
}
break;
case BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "\t");
break;
case FORMULA:
System.out.print(cell.getCellFormula() + "\t");
break;
default:
System.out.print("UNKNOWN\t");
}
}
System.out.println(); // New line after each row
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
EasyExcel (For Large Files)
EasyExcel is a library from Alibaba that addresses a major limitation of POI: high memory usage. It uses a model similar to SAX parsing, which reads the file row by row without loading the entire file into memory.
Step 1: Add Dependency
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version> <!-- Use the latest stable version -->
</dependency>
Step 2: Define a Data Model
It's best practice to create a Java class that mirrors the columns in your Excel file.
// The class must match the Excel columns
public class Employee {
@ExcelProperty("ID") // Maps to the "ID" column header
private Integer id;
@ExcelProperty("Name")
private String name;
@ExcelProperty("Salary")
private Double salary;
// Getters and Setters are required
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Double getSalary() { return salary; }
public void setSalary(Double salary) { this.salary = salary; }
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", salary=" + salary +
'}';
}
}
Step 3: Writing with EasyExcel (Very Simple)
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelWriteExample {
public static void main(String[] args) {
// 1. Prepare data
List<Employee> list = new ArrayList<>();
list.add(new Employee(101, "Alice", 75000.50));
list.add(new Employee(102, "Bob", 82000.00));
list.add(new Employee(103, "Charlie", 90000.75));
// 2. Write to file
String fileName = "employees_easyexcel.xlsx";
EasyExcel.write(fileName, Employee.class).sheet("Employee Data").doWrite(list);
System.out.println(fileName + " file has been created successfully.");
}
}
Step 4: Reading with EasyExcel (Low-Memory)
The real power of EasyExcel is in reading large files.

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelReadExample {
// Step 1: Create a listener to handle each row of data
public static class EmployeeListener extends AnalysisEventListener<Employee> {
private static final int BATCH_COUNT = 100;
private List<Employee> cachedDataList = new ArrayList<>(BATCH_COUNT);
@Override
public void invoke(Employee employee, AnalysisContext context) {
System.out.println("Parsing data: " + employee);
cachedDataList.add(employee);
// Achieve batch commit to save memory
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
cachedDataList = new ArrayList<>(BATCH_COUNT);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
saveData();
System.out.println("All data parsing completed!");
}
private void saveData() {
// Here you would typically save the batch of data to a database
System.out.println("Saved " + cachedDataList.size() + " data to database.");
}
}
public static void main(String[] args) {
String fileName = "employees_easyexcel.xlsx";
// Step 2: Read the file
EasyExcel.read(fileName, Employee.class, new EmployeeListener()).sheet().doRead();
}
}
Which One Should You Choose?
-
Choose Apache POI if:
- You are working with small to medium-sized files.
- You need advanced features like complex formulas, charts, or rich formatting (colors, borders, fonts).
- It's the standard, well-documented choice, and your team is already familiar with it.
-
Choose EasyExcel if:
- You are working with very large Excel files (hundreds of thousands or millions of rows).
- Memory efficiency is a critical concern.
- Your use case is primarily simple read/write operations without complex formatting.
- You prefer a more modern, fluent API.
For most general-purpose applications, Apache POI is the safe and powerful choice. If you hit performance walls with large files, definitely switch to EasyExcel.
