Read and Write Excel Files in Java with Apache POI

Read and Write Excel Files in Java with Apache POI
⏱ 2 min readUpdated 27 September 2026

Java is common in enterprise back-ends, and sooner or later those systems need to produce or consume Excel files. Apache POI is the standard open-source library for that. Here is the minimum you need.

In this article
  1. Add the dependency
  2. Read an Excel file
  3. Write a new Excel file
  4. Common pitfalls

Add the dependency

With Maven, add org.apache.poi:poi-ooxml (use the latest 5.x version) to your pom.xml. It pulls in everything needed for .xlsx files.

Read an Excel file

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;

public class ReadExcel {
    public static void main(String[] args) throws Exception {
        DataFormatter fmt = new DataFormatter();   // shows values as Excel displays them
        try (FileInputStream in = new FileInputStream("sales.xlsx");
             Workbook wb = new XSSFWorkbook(in)) {
            Sheet sheet = wb.getSheet("Data");
            for (Row row : sheet) {
                if (row.getRowNum() == 0) continue;          // skip header
                String rep = fmt.formatCellValue(row.getCell(0));
                double qty = row.getCell(1).getNumericCellValue();
                System.out.println(rep + " sold " + qty);
            }
        }
    }
}
πŸ’‘ DataFormatter saves a lot of pain: it returns what the user sees in Excel (dates, percentages, leading zeros) instead of raw doubles.

Write a new Excel file

try (Workbook wb = new XSSFWorkbook();
     FileOutputStream out = new FileOutputStream("report.xlsx")) {
    Sheet s = wb.createSheet("Report");
    CellStyle bold = wb.createCellStyle();
    Font f = wb.createFont(); f.setBold(true); bold.setFont(f);

    Row header = s.createRow(0);
    String[] cols = {"Region", "Revenue"};
    for (int i = 0; i < cols.length; i++) {
        Cell c = header.createCell(i);
        c.setCellValue(cols[i]);
        c.setCellStyle(bold);
    }
    Row r = s.createRow(1);
    r.createCell(0).setCellValue("North");
    r.createCell(1).setCellValue(265739);
    s.createRow(2).createCell(1).setCellFormula("SUM(B2:B2)");
    s.autoSizeColumn(0);
    wb.write(out);
}

Common pitfalls

  • Null cells: empty cells return null from getCell(). Use row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).
  • Huge files: XSSFWorkbook keeps everything in memory. For writing large exports use SXSSFWorkbook, which streams rows to disk.
  • Old .xls files: use HSSFWorkbook, or WorkbookFactory.create(file) to handle both formats.
  • Formulas are not calculated when you write them; Excel recalculates on open. To read calculated values in Java use a FormulaEvaluator.