Welcome to Apache POI Tutorial. Sometimes we need to read data from Microsoft Excel Files or we need to generate reports in Excel format, mostly for Business or Finance purposes. Java doesn’t provide built-in support for working with excel files, so we need to look for open source APIs for the job. When I started the hunt for Java APIs for excel, most of the people recommended JExcel or Apache POI. After further research, I found that Apache POI is the way to go for following main reasons. There are some other reasons related to advanced features but let’s not go into that much detail.
Apache POI provides excellent support for working with Microsoft Excel documents. Apache POI is able to handle both XLS and XLSX formats of spreadsheets. Some important points about Apache POI API are:
If you are using maven, add below Apache POI dependencies.
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
Current version of Apache POI is 3.10-FINAL. If you are having standalone java application, include jars from below image.
Let’s say we have an excel file “Sample.xlsx” with two sheets and having data like below image. We want to read the excel file and create the list of Countries. Sheet1 has some additional data, that we will ignore while parsing it. Our Country java bean code is: Country.java
package com.journaldev.excel.read;
public class Country {
private String name;
private String shortCode;
public Country(String n, String c){
this.name=n;
this.shortCode=c;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortCode() {
return shortCode;
}
public void setShortCode(String shortCode) {
this.shortCode = shortCode;
}
@Override
public String toString(){
return name + "::" + shortCode;
}
}
Apache POI example program to read excel file to the list of countries looks like below. ReadExcelFileToList.java
package com.journaldev.excel.read;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadExcelFileToList {
public static List<Country> readExcelData(String fileName) {
List<Country> countriesList = new ArrayList<Country>();
try {
//Create the input stream from the xlsx/xls file
FileInputStream fis = new FileInputStream(fileName);
//Create Workbook instance for xlsx/xls file input stream
Workbook workbook = null;
if(fileName.toLowerCase().endsWith("xlsx")){
workbook = new XSSFWorkbook(fis);
}else if(fileName.toLowerCase().endsWith("xls")){
workbook = new HSSFWorkbook(fis);
}
//Get the number of sheets in the xlsx file
int numberOfSheets = workbook.getNumberOfSheets();
//loop through each of the sheets
for(int i=0; i < numberOfSheets; i++){
//Get the nth sheet from the workbook
Sheet sheet = workbook.getSheetAt(i);
//every sheet has rows, iterate over them
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
String name = "";
String shortCode = "";
//Get the row object
Row row = rowIterator.next();
//Every row has columns, get the column iterator and iterate over them
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
//Get the Cell object
Cell cell = cellIterator.next();
//check the cell type and process accordingly
switch(cell.getCellType()){
case Cell.CELL_TYPE_STRING:
if(shortCode.equalsIgnoreCase("")){
shortCode = cell.getStringCellValue().trim();
}else if(name.equalsIgnoreCase("")){
//2nd column
name = cell.getStringCellValue().trim();
}else{
//random data, leave it
System.out.println("Random data::"+cell.getStringCellValue());
}
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.println("Random data::"+cell.getNumericCellValue());
}
} //end of cell iterator
Country c = new Country(name, shortCode);
countriesList.add(c);
} //end of rows iterator
} //end of sheets for loop
//close file input stream
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return countriesList;
}
public static void main(String args[]){
List<Country> list = readExcelData("Sample.xlsx");
System.out.println("Country List\n"+list);
}
}
The program is very easy to understand and contains following steps:
Workbook
instance based on the file type. XSSFWorkbook
for xlsx format and HSSFWorkbook
for xls format. Notice that we could have created a wrapper class with factory pattern to get the workbook instance based on the file name.Sheet
instance using getSheetAt(int i) method.Row
iterator and then Cell
iterator to get the Cell object. Apache POI is using iterator pattern here.Now when we run above Apache POI example program, it produces following output on console.
Random data::1.0
Random data::2.0
Random data::3.0
Random data::4.0
Country List
[India::IND, Afghanistan::AFG, United States of America::USA, Anguilla::AIA,
Denmark ::DNK, Dominican Republic ::DOM, Algeria ::DZA, Ecuador ::ECU]
Writing excel file in apache POI is similar to reading, except that here we first create the workbook. Then set sheets, rows and cells values and use FileOutputStream to write it to file. Let’s write a simple apache POI example where we will use list of countries from the above method to save into another file in a single sheet. WriteListToExcelFile.java
package com.journaldev.excel.read;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class WriteListToExcelFile {
public static void writeCountryListToFile(String fileName, List<Country> countryList) throws Exception{
Workbook workbook = null;
if(fileName.endsWith("xlsx")){
workbook = new XSSFWorkbook();
}else if(fileName.endsWith("xls")){
workbook = new HSSFWorkbook();
}else{
throw new Exception("invalid file name, should be xls or xlsx");
}
Sheet sheet = workbook.createSheet("Countries");
Iterator<Country> iterator = countryList.iterator();
int rowIndex = 0;
while(iterator.hasNext()){
Country country = iterator.next();
Row row = sheet.createRow(rowIndex++);
Cell cell0 = row.createCell(0);
cell0.setCellValue(country.getName());
Cell cell1 = row.createCell(1);
cell1.setCellValue(country.getShortCode());
}
//lets write the excel data to file now
FileOutputStream fos = new FileOutputStream(fileName);
workbook.write(fos);
fos.close();
System.out.println(fileName + " written successfully");
}
public static void main(String args[]) throws Exception{
List<Country> list = ReadExcelFileToList.readExcelData("Sample.xlsx");
WriteListToExcelFile.writeCountryListToFile("Countries.xls", list);
}
}
When I execute above apache POI example program, the excel file generated looks like below image.
Sometimes we need to handle complex excel files with formulas, let’s see a simple apache POI example to read the formula of a cell with it’s value. ReadExcelFormula.java
package com.journaldev.excel.read;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadExcelFormula {
public static void readExcelFormula(String fileName) throws IOException{
FileInputStream fis = new FileInputStream(fileName);
//assuming xlsx file
Workbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
switch(cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC:
System.out.println(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
System.out.println("Cell Formula="+cell.getCellFormula());
System.out.println("Cell Formula Result Type="+cell.getCachedFormulaResultType());
if(cell.getCachedFormulaResultType() == Cell.CELL_TYPE_NUMERIC){
System.out.println("Formula Value="+cell.getNumericCellValue());
}
}
}
}
}
public static void main(String args[]) throws IOException {
readExcelFormula("FormulaMultiply.xlsx");
}
}
When we execute above apache poi example program, we get following output.
1.0
2.0
3.0
4.0
Cell Formula=A1*A2*A3*A4
Cell Formula Result Type=0
Formula Value=24.0
Sometimes, we need to do some calculations and then write the cell values. We can use the excel formulas to do this calculation and that will make it more accurate because values will change if the cell values used in calculations are changed. Let’s see a simple example to write excel file with formulas using apache poi api. WriteExcelWithFormula.java
package com.journaldev.excel.read;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class WriteExcelWithFormula {
public static void writeExcelWithFormula(String fileName) throws IOException{
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Numbers");
Row row = sheet.createRow(0);
row.createCell(0).setCellValue(10);
row.createCell(1).setCellValue(20);
row.createCell(2).setCellValue(30);
//set formula cell
row.createCell(3).setCellFormula("A1*B1*C1");
//lets write to file
FileOutputStream fos = new FileOutputStream(fileName);
workbook.write(fos);
fos.close();
System.out.println(fileName + " written successfully");
}
public static void main(String[] args) throws IOException {
writeExcelWithFormula("Formulas.xlsx");
}
}
The excel file produced with above Apache POI API example program looks like below image. That’s all on Apache POI tutorial for working with excel files, look into Apache POI classes methods to learn more features of it. References: Apache POI Developers Guide
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
HI Pankaj, Is there any way to hide formula using Apache POI ? So that user can’t be able to edit it by mistake.
- RISHAB KUMAR
Hi Pankaj, Nice tutorial. I want to create a multiple sheets in same workbook for a different dropdown option. As soon as i select the option from dropdown data get populate and that has to be written in Excel file and then select a second value say ‘B’ from drop down and should create sheet’B’. For selecting a option from dropdown i have a method public void selectAProviderOption() throws Exception { providerOption.clear(); providerOption.click(); providerOption.sendKeys(“aurora”); Thread.sleep(3000); driver.findElement(By.xpath(“//*[text()=’ Aurora’]”)).click(); providerOption.sendKeys(Keys.ENTER); } I do have 6 methods for selecting the option from dropdown, for each option each method. public void clickOnPerformanceDetails() throws Exception { File file = new File(“C:\\Users\\pdholakia\\Desktop\\PCPPerformanceAtNavvisLevel_NO.xlsx”); XSSFWorkbook wb = (XSSFWorkbook) WorkbookFactory.create(new FileInputStream(file)); XSSFSheet sheet = wb.createSheet(" Scott"); // XSSFSheet sheet = wb.createSheet(“Khen”); // XSSFSheet sheet = wb.createSheet(“Tanii”); // XSSFSheet sheet = wb.createSheet(“Aurora”); // Excel code here } @Test{ performance_PlusTWOEx.selectAuroraProviderOption() ; performance_PlusTWOEx.selectProgram(); performance_PlusTWOEx.clickOnPerformanceDetails(); // performance_PlusTWOEx.selectBBProviderOption() ; // performance_PlusTWOEx.selectProgram(); // performance_PlusTWOEx.clickOnPerformanceDetails(); } Above code running successfully creating multiple sheets but i do have to comment all other 5 options if one of option is getting executing. Commenting creatsheet code and commenting methods of testclass. i am working with maven project using POM pattern and testng. Any help will be appreciated.
- Purvi
Hi Sir, i have a requirement like i have to design a excel sheet with 2 headers and my 1st header is merged with two columns and 2nd header as like single column single header. kindly can you give me some solutions for this
- Bikash Sahoo
package javaexcel; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; public class excelsheet { public static void main(String[] args) throws IOException { String path=“C:\\Users\\kjagtap\\OneDrive - TASI\\Desktop\\capture\\Book1.xlsx”; FileInputStream file = new FileInputStream(path); Workbook book= WorkbookFactory.create(file); Sheet s= book.getSheet(“sample”); Row row= s.getRow(0); Cell cell= row.getCell(0); String str=cell.getStringCellValue(); System.out.print(str); } } I have written this code but occurring lang null pointer exception on row class, can you please help me to handle this exception
- kajol
Hi , I have an issue . I want to write a code to populate a restricted excel sheet in which all the cells in excel must only contain the allowed values as drop down list ( as checkboxes i.e user can select more than one value from the drop down list to fill the excel sheet .So user have to select the multiple values from the list only. He cannot write something else) .
- Sumit Mamtani
Sir/mam kindly help me. What if i want to compare two excel Sheets data with uneven no.of rows using apache poi in java netbeans, and has to displayed automatically in new spreadsheet. I found some method related to it but their have compared excel sheets which has even no.of rows in it or can i use Comparison related API available for java, if i use comparison related API whether apache poi API will support or error will occur. Please help with this issue. Thank you in advance
- Annapoorani
hello, I have requirement of reading the data which is only marked true in checkbox and also the only data which is selected in dropdown list in an excel file to another excel file. Can anyone please help me with this?
- shraddha21
Can I create CheckBox through POI
- sunish
Hello, I am struggling to figure out the solution to my problem. I have an excel sheet .Xlsx with a pie chart and I want to copy this image to my another excel (sheet2). Will it possible using XSSFWorkbook in Apache poi? I went through many blogs but no help. Please suggest something…
- Shweta
Thank you very much for tutorial. I am having same type of application where POI and POI-OOXML are used together. But when I deploy them in Maven environment, I get these errors: Caused by: org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve resource com.icg.isg.returns.VendorReturnsTranslator [com.icg.isg.returns.VendorReturnsTranslator [327](R 327.0)] because it is exposed to package ‘org.apache.poi.ss.usermodel’ from resources wrap_mvn_org.apache.poi_poi-ooxml_3.15 [wrap_mvn_org.apache.poi_poi-ooxml_3.15 [325](R 325.0)] and wrap_mvn_org.apache.poi_poi_3.15 [wrap_mvn_org.apache.poi_poi_3.15 [324](R 324.0)] via two dependency chains. Chain 1: com.icg.isg.returns.VendorReturnsTranslator [com.icg.isg.returns.VendorReturnsTranslator [327](R 327.0)] import: (osgi.wiring.package=org.apache.poi.ss.usermodel) | export: osgi.wiring.package: org.apache.poi.ss.usermodel wrap_mvn_org.apache.poi_poi-ooxml_3.15 [wrap_mvn_org.apache.poi_poi-ooxml_3.15 [325](R 325.0)] Chain 2: com.icg.isg.returns.VendorReturnsTranslator [com.icg.isg.returns.VendorReturnsTranslator [327](R 327.0)] import: (osgi.wiring.package=org.apache.poi.hssf.usermodel) | export: osgi.wiring.package: org.apache.poi.hssf.usermodel; uses:=org.apache.poi.ss.usermodel export: osgi.wiring.package=org.apache.poi.ss.usermodel " Any help to resolve is appreciated.
- Chintan Desai