Все знакомы с табличным процессором Excel, который входит в стандартный пакет Microsoft Office. Напрямую в Excel очень удобно и приятно работать, но мало кто знает, что в Java этот процесс не менее приятный и увлекательный.
Последнее время мне приходилось программно парсить файлы формата .xls и .xlsx. Чтобы осуществить парсинг Excel-файла, понадобилась библиотека Apache POI. С помощью этой библиотеки можно парсить не только файлы в формате .xls, но и DOC, PPT, а также форматы, которые появились в версии Microsoft Office 2007.
В этой статье мы познакомимся с чтением данных из xls
или xlsx
файла в Java с помощью библиотеки Apache POI. Как всегда, немного теории по основам и практика на примере чтения простого xls
файла. Пример создания нового Excel файла представлен здесь.
Подключаем библиотеку для работы с Excel в Java
Для начала нужно создать Maven-проект и в файле pom.xml прописать следующий код зависимостей
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.11</version> </dependency> |
Чтение Excel файла на Java
Библиотека Apache POI предоставляет простой в использовании API для чтения любого xls файла. Ниже мы рассмотрим наиболее используемые классы для чтения содержимого Excel таблиц:
Код для чтения Excel документов в формате xls
В листинге ниже приведен типичный пример инициализации HSSFWorkbook
и HSSFSheet
для считывания данных из .xls
файлов.
// получаем файл в формате xls FileInputStream file = new FileInputStream(new File(«C:\simplexcel.xls»)); // формируем из файла экземпляр HSSFWorkbook HSSFWorkbook workbook = new HSSFWorkbook(file); // выбираем первый лист для обработки // нумерация начинается с 0 HSSFSheet sheet = workbook.getSheetAt(0); // получаем Iterator по всем строкам в листе Iterator<Row> rowIterator = sheet.iterator(); // получаем Iterator по всем ячейкам в строке Iterator<Cell> cellIterator = row.cellIterator(); |
Код для чтения Excel документов в формате .xlsx
Ниже приведен фрагмент кода для инициализации работы с Excel файлами в формате .xlsx
:
// получаем файл в формате xlsx FileInputStream file = new FileInputStream(new File(«C:\simplexcelx.xlsx»)); // получаем экземпляр XSSFWorkbook для обработки xlsx файла XSSFWorkbook workbook = new XSSFWorkbook (file); // выбираем первый лист для обработки // нумерация начинается из 0 XSSFSheet sheet = workbook.getSheetAt(0); // получаем Iterator по всем строкам в листе Iterator<Row> rowIterator = sheet.iterator(); // получаем Iterator по всем ячейкам в строке Iterator<Cell> cellIterator = row.cellIterator(); |
Практика. Создаем простой Excel для работы
Пишем парсер на Java
Назовем класс ExcelParser.java с методом parse, который принимает текстовый параметр fileName
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
package ua.com.prologistic.excel; 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 java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; public class ExcelParser { public static String parse(String fileName) { //инициализируем потоки String result = «»; InputStream inputStream = null; HSSFWorkbook workBook = null; try { inputStream = new FileInputStream(fileName); workBook = new HSSFWorkbook(inputStream); } catch (IOException e) { e.printStackTrace(); } //разбираем первый лист входного файла на объектную модель Sheet sheet = workBook.getSheetAt(0); Iterator<Row> it = sheet.iterator(); //проходим по всему листу while (it.hasNext()) { Row row = it.next(); Iterator<Cell> cells = row.iterator(); while (cells.hasNext()) { Cell cell = cells.next(); int cellType = cell.getCellType(); //перебираем возможные типы ячеек switch (cellType) { case Cell.CELL_TYPE_STRING: result += cell.getStringCellValue() + «=»; break; case Cell.CELL_TYPE_NUMERIC: result += «[« + cell.getNumericCellValue() + «]»; break; case Cell.CELL_TYPE_FORMULA: result += «[« + cell.getNumericCellValue() + «]»; break; default: result += «|»; break; } } result += «n»; } return result; } } |
Создаем главный класс-ранер, где и запустим парсер:
package ua.com.prologistic; import ua.com.prologistic.excel.ExcelParser; public class MainClass { public static void main(String[] args){ System.out.println(Parser.parse(«excel.xls»)); } } |
Результат выполнения парсера Excel
Бонька=[4.0] Баюн=[2.0] Полкан=[6.0] Барон=[3.0] Общий вес=[15.0] |
Работа с запароленным Excel файлом
В Apache POI с каждой новой версией добавляются новые возможности по работе с закрытыми/запароленными файлами. Например, мы может работать с защищенными файлами XLS (используя org.apache.poi.hssf.record.crypt
) и защищенными файлами XLSX (с помощью org.apache.poi.poifs.crypt
).
Если вы используете HSSF (для файла XLS), то проверить является ли он запаролленым нам поможет метод isWriteProtected(). А для работы с ним необходимо указать пароль перед самым открытием файла:
... org.apache.poi.hssf.record.crypto.Biff8EncryptionKey.setCurrentUserPassword(«здесь пароль»); |
После этого можем работать с файлом.
Для XSSF
нам понадобится что-то вроде такого:
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(«protected.xlsx»)); EncryptionInfo info = new EncryptionInfo(fs); Decryptor d = new Decryptor(info); d.verifyPassword(Decryptor.DEFAULT_PASSWORD); XSSFWorkbook wb = new XSSFWorkbook(d.getDataStream(fs)); |
При работе с более новыми версиями Apache POI, можно просто указать пароль при создании Workbook
:
Workbook wb = WorkbookFactory.create(new File(«protected.xls»), «здесь пароль»)); |
Этот код будет работать как для HSSF, так и для XSSF.
Также смотрите примеры чтения Word документа и создания нового документа Word с помощью Apache POI.
Подписывайтесь на обновления!
Excel Parser Examples
HSSF — Horrible Spreadsheet Format – not anymore. With few annotations, excel parsing can be done in one line.
We had a requirement in our current project to parse multiple excel sheets and store the information to database. I hope most of the projects involving excel sheet parsing would be doing the same. We built a extensible framework to parse multiple sheets and populate JAVA objects with annotations.
Usage
This JAR is currently available in Sonatype maven repository.
Maven:
<dependency> <groupId>org.javafunk</groupId> <artifactId>excel-parser</artifactId> <version>1.0</version> </dependency>
Gradle:
compile 'org.javafunk:excel-parser:1.0'
Thanks to tobyclemson for publishing this to Maven repository.
Student Information Example
Consider we have an excel sheet with student information.
While parsing this excel sheet, we need to populate one “Section” object and multiple “Student” objects related to a Section. You can see that Student information is available in multiple rows whereas the Section details (Year, Section) is available in column B.
Step 1: Annotate Domain Classes
First we will see the steps to annotate Section object:
@ExcelObject(parseType = ParseType.COLUMN, start = 2, end = 2) public class Section { @ExcelField(position = 2) private String year; @ExcelField(position = 3) private String section; @MappedExcelObject private List <Student> students; }
You can find three different annotation in this class.
ExcelObject
: This annotation tells the parser about the parse type (Row or Column), number of objects to create (start, end). Based on the above annotation, Section value should be parsed Columnwise and information can be found in Column 2 (“B”) of the Excelsheet.ExcelField
: This annotation tells the parser to fetch “year” information from Row 2 and “section” information from Row 3.MappedExcelObject
: Apart from Simple datatypes like “Double”,”String”, we might also try to populate complex java objects while parsing. In this case, each section has a list of student information to be parsed from excel sheet. This annotation will help the parser in identifying such fields.
Then, annotate the Student class:
@ExcelObject(parseType = ParseType.ROW, start = 6, end = 8) public class Student { @ExcelField(position = 2) private Long roleNumber; @ExcelField(position = 3) private String name; @ExcelField(position = 4) private Date dateOfBirth; @ExcelField(position = 5) private String fatherName; @ExcelField(position = 6) private String motherName; @ExcelField(position = 7) private String address; @ExcelField(position = 8) private Double totalScore; }
ExcelObject
: As shown above, this annotation tells parser to parse Rows 6 to 8 (create 3 student objects). NOTE: Optional field “zeroIfNull” , if set to true, will populate Zero to all number fields (Double,Long,Integer) by default if the data is not available in DB.ExcelField
: Student class has 7 values to be parsed and stored in the database. This is denoted in the domain class as annotation.MappedExcelObject
: Student class does not have any complex object, hence this annoation is not used in this domain class.
Step 2: Invoke Sheet Parser
Once the annotation is done, you have just invoke the parser with the Sheet and the Root class you want to populate.
//Get the sheet using POI API. String sheetName = "Sheet1"; SheetParser parser = new SheetParser(); InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Student Profile.xls"); Sheet sheet = new HSSFWorkbook(inputStream).getSheet(sheetName); //Invoke the Sheet parser. List entityList = parser.createEntity(sheet, sheetName, Section.class);
Thats all it requires. Parser would populate all the fields based on the annotation for you.
Development
- JDK 8
- Run «gradle idea» to setup the project
- Install Lombok plugin
- Enable «Enable annotation processing» as this project uses Lombok library. [Compiler > Annotation Processors > Enable annotation processing: checked ]
Contributors
- @nvenky
- @cv
- @tobyclemson
Часто ли вам приходилось на живую работать с Excel? Думаю, что несколько раз приходилось. Так вот, на днях у меня для собственного проекта появилась необходимость распарсить Excel файл.
Как известно то формат Excel файла *.xsl, но после выхода Microsoft Office 2007 появился новый формат Excel файла *.xlsx, так вот для того, чтобы иметь возможность парсить Excel я использую библиотеку Apache POI все мои пожелания по поводу Excel файла она удовлетворила.
Шаг 1
Для начало создадим Maven проект и добавим следующую зависимость:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency>
Шаг 2
Теперь создадим Excel файл и добавим в него несколько записей.
Файл прикреплен к исходнику.
Шаг 3
Теперь попробуем распарсить файл testfile.xls, для этого напишем парсер.
Создаем класс Parser.java и в нем создадим статический метод parse(String name);
package com.devcolibri.excel; 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 java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; public class Parser { public static String parse(String name) { String result = ""; InputStream in = null; HSSFWorkbook wb = null; try { in = new FileInputStream(name); wb = new HSSFWorkbook(in); } catch (IOException e) { e.printStackTrace(); } Sheet sheet = wb.getSheetAt(0); Iterator<Row> it = sheet.iterator(); while (it.hasNext()) { Row row = it.next(); Iterator<Cell> cells = row.iterator(); while (cells.hasNext()) { Cell cell = cells.next(); int cellType = cell.getCellType(); switch (cellType) { case Cell.CELL_TYPE_STRING: result += cell.getStringCellValue() + "="; break; case Cell.CELL_TYPE_NUMERIC: result += "[" + cell.getNumericCellValue() + "]"; break; case Cell.CELL_TYPE_FORMULA: result += "[" + cell.getNumericCellValue() + "]"; break; default: result += "|"; break; } } result += "n"; } return result; } }
Шаг 4
Теперь давайте проверим все это, создаем класс Main.java со следующим содержимым:
package com.devcolibri; import com.devcolibri.excel.Parser; public class Main { public static void main(String... args){ System.out.println(Parser.parse("testfile.xls")); } }
Шаг 5
Запускаем все это дело, и получаем следующий результат:
Александр Барчук=[5000.0] Виктор Пупкин=[10000.0] Дмитрий Федкин=[1500.0] Максим Панков=[300.0] Данил Муев=[8000.0] Анастасия Валяева=[8900.0] Екатерина Максимова=[7000.0] Company=[40700.0]
- None Found
1. Introduction
In this article, we are going to present a custom XLSX parser based on Java annotations. The application will be using the Apache POI library to read the structure of the Excel file and then map all entries into the POJO object.
2. Setup project
The project will use several dependencies from apache-poi. We also used Lombok to generate common methods for POJO classes like setters, getters, and constructors.
The pom.xml
file will contain the following items:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>libraries</artifactId>
<groupId>com.frontbackend.libraries</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apache-poi</artifactId>
<properties>
<lombok.version>1.16.22</lombok.version>
<apache.poi.version>3.17</apache.poi.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${apache.poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${apache.poi.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
The latest versions of used libraries could be found in our Maven Repository:
- apache-poi latest libraries,
- Lombok Maven artifacts.
3. Project structure
The project is organized in the following structure:
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── frontbackend
│ │ │ └── libraries
│ │ │ └── apachepoi
│ │ │ ├── MainParseXLSXUsingAnnotations.java
│ │ │ ├── model
│ │ │ │ └── Post.java
│ │ │ └── parser
│ │ │ ├── XLSXField.java
│ │ │ ├── XLSXHeader.java
│ │ │ └── XLSXParser.java
│ │ └── resources
│ │ └── posts.xlsx
4. XLSX Parser classes
We can distinguish three classes responsible for processing XLSX files:
XLSXField
— custom annotation used to mark field in POJO class and connect it with the column from XLSX document,XLSXHeader
— is a wrapper class used to hold information about fields, columns, and columns positions in the Excel file,XLSXParser
— the main class responsible for parsing XLSX files and set values into POJO objects.
Starting with the XLSXField
— which is an annotation used to connect column with a field in Java class:
package com.frontbackend.libraries.apachepoi.parser;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XLSXField {
String column() default "";
}
The XLSXHeader
is a helper class that wraps data like class field name, column name from XLSX file, and column index:
package com.frontbackend.libraries.apachepoi.parser;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
@AllArgsConstructor
@Getter
@ToString
public class XLSXHeader {
private final String fieldName;
private final String xlsxColumnName;
private final int columnIndex;
}
And finally the base utility class responsible for parsing Excel files — XLSXParser
:
package com.frontbackend.libraries.apachepoi.parser;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class XLSXParser<T> {
private static final int HEADER_ROW_INDEX = 0;
private static final int SHEET_INDEX = 0;
public List<T> parse(InputStream inputStream, Class<T> cls) throws Exception {
List<T> out = new ArrayList<>();
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
Sheet sheet = workbook.getSheetAt(SHEET_INDEX);
List<XLSXHeader> xlsxHeaders = modelObjectToXLSXHeader(cls, sheet);
for (Row row : sheet) {
if (row.getRowNum() > HEADER_ROW_INDEX) {
out.add(createRowObject(xlsxHeaders, row, cls));
}
}
return out;
}
private T createRowObject(List<XLSXHeader> xlsxHeaders, Row row, Class<T> cls) throws Exception {
T obj = cls.newInstance();
Method[] declaredMethods = obj.getClass()
.getDeclaredMethods();
for (XLSXHeader xlsxHeader : xlsxHeaders) {
Cell cell = row.getCell(xlsxHeader.getColumnIndex());
String field = xlsxHeader.getFieldName();
Optional<Method> setter = Arrays.stream(declaredMethods)
.filter(method -> isSetterMethod(field, method))
.findFirst();
if (setter.isPresent()) {
Method setMethod = setter.get();
setMethod.invoke(obj, cell.getStringCellValue());
}
}
return obj;
}
private boolean isSetterMethod(String field, Method method) {
return method.getName()
.equals("set" + field.substring(0, 1)
.toUpperCase()
+ field.substring(1));
}
private List<XLSXHeader> modelObjectToXLSXHeader(Class<T> cls, Sheet sheet) {
return Stream.of(cls.getDeclaredFields())
.filter(field -> field.getAnnotation(XLSXField.class) != null)
.map(field -> {
XLSXField importField = field.getAnnotation(XLSXField.class);
String xlsxColumn = importField.column();
int columnIndex = findColumnIndex(xlsxColumn, sheet);
return new XLSXHeader(field.getName(), xlsxColumn, columnIndex);
})
.collect(Collectors.toList());
}
private int findColumnIndex(String columnTitle, Sheet sheet) {
Row row = sheet.getRow(HEADER_ROW_INDEX);
if (row != null) {
for (Cell cell : row) {
if (CellType.STRING.equals(cell.getCellTypeEnum()) && columnTitle.equals(cell.getStringCellValue())) {
return cell.getColumnIndex();
}
}
}
return 0;
}
}
Note that for the sake of simplicity we assume that the first row in an Excel file will be our table header, and also the first sheet will contain all the data:
private static final int HEADER_ROW_INDEX = 0;
private static final int SHEET_INDEX = 0;
The parse(...)
method is responsible for reading XLSX documents using the Apache POI library and parsing values from it into a specific Java model instance.
In the first step, we create a list of helper classes that contains all the necessary information like field name, related column, and column index:
List<XLSXHeader> xlsxHeaders = modelObjectToXLSXHeader(cls, sheet);
In modelObjectToXLSXHeader()
method we iterate over all declared in specified class fields and filter all marked with XLSXField
annotation. Then we are searching for a column in an Excel file with the same name as provided in the annotation column
property. The method returns the list of wrapped objects XLSXHeader
.
private List<XLSXHeader> modelObjectToXLSXHeader(Class<T> cls, Sheet sheet) {
return Stream.of(cls.getDeclaredFields())
.filter(field -> field.getAnnotation(XLSXField.class) != null)
.map(field -> {
XLSXField importField = field.getAnnotation(XLSXField.class);
String xlsxColumn = importField.column();
int columnIndex = findColumnIndex(xlsxColumn, sheet);
return new XLSXHeader(field.getName(), xlsxColumn, columnIndex);
})
.collect(Collectors.toList());
}
The createRowObject()
method creates an instance of a specified POJO object and filled the fields with values according to the data from the XLSX file.
As a result parse()
method returns a list of POJO objects.
5. Run and test a sample program
In order to test the implementation of the XLSX parser, we created a simple object with three fields marked with @XLSXField
annotation:
package com.frontbackend.libraries.apachepoi.model;
import com.frontbackend.libraries.apachepoi.parser.XLSXField;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
public class Post {
@XLSXField(column = "Title")
private String title;
@XLSXField(column = "Content")
private String content;
@XLSXField(column = "URL")
private String url;
}
Fields will be related with the following column from the Excel file:
Field | Column |
title | Title |
content | Content |
url | URL |
Our sample XLSX file with have the following structure:
The sample Java program that will parse the posts.xlsx
file located in the project resource
folder looks as follows:
package com.frontbackend.libraries.apachepoi;
import java.io.InputStream;
import java.util.List;
import com.frontbackend.libraries.apachepoi.model.Post;
import com.frontbackend.libraries.apachepoi.parser.XLSXParser;
public class MainParseXLSXUsingAnnotations {
public static void main(String[] args) {
XLSXParser<Post> postsXLSXParser = new XLSXParser<>();
InputStream xlsxFile = postsXLSXParser.getClass()
.getClassLoader()
.getResourceAsStream("posts.xlsx");
try {
List<Post> list = postsXLSXParser.parse(xlsxFile, Post.class);
System.out.println(list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here:
- first, we created an instance of
XLSXParser
dedicated for thePost
class, - in the next step we retrieved data from the
posts.xlsx
file, - then file stream is used to parse the file using the
XLSXParser.parse(...)
method.
As a result, we have a list of three POJO instances that correspond to the rows in the Excel document:
[Post(title=Java IO Tutorial, content=Awesome Java IO Tutorials, url=https://frontbackend.com/java/java-io-tutorial),
Post(title=Mockito Tutorial, content=Awesome Mockito Tutorials, url=https://frontbackend.com/java/mockito-tutorial),
Post(title=Thymeleaf Tutorial, content=Awesome Thymeleaf Tutorials, url=https://frontbackend.com/thymeleaf/thymeleaf-tutorial)]
6. Conclusion
In this article, we presented how to create an XLSX parser based on annotations in Java using the Apache POI library. Note that we showed a simple example of an Excel file, also we convert all values into strings, but it a good point to start some more complex functionality.
As always the code used in this article is available in our GitHub repository.
In this section, we are going to learn how we can read data from an excel file.
In Java, reading excel file is not similar to read word file because of cells in excel file. JDK does not provide direct API to read or write Microsoft Excel or Word document. We have to rely on the third-party library that is Apache POI.
What is Apache POI?
Apache POI (Poor Obfuscation Implementation) is a Java API for reading and writing Microsoft Documents in both formats .xls and .xlsx. It contains classes and interfaces. The Apache POI library provides two implementations for reading excel files:
- HSSF (Horrible SpreadSheet Format) Implementation: It denotes an API that is working with Excel 2003 or earlier versions.
- XSSF (XML SpreadSheet Format) Implementation: It denotes an API that is working with Excel 2007 or later versions.
Interfaces and Classes in Apache POI
Interfaces
- Workbook: It represents an Excel Workbook. It is an interface implement by HSSFWorkbook and XSSFWorkbook.
- Sheet: It is an interface that represents an Excel worksheet. A sheet is a central structure of a workbook, which represents a grid of cells. The Sheet interface extends java.lang.Iterable.
- Row: It is also an interface that represents the row of the spreadsheet. The Row interface extends java.lang.Iterable. There are two concrete classes: HSSFRow and XSSFRow.
- Cell: It is an interface. It is a high-level representation of a cell in a row of the spreadsheet. HSSFCell and XSSFCell implement Cell interface.
Classes
XLS Classes
- HSSFWorkbook: It is a class representing the XLS file.
- HSSFSheet: It is a class representing the sheet in an XLS file.
- HSSFRow: It is a class representing a row in the sheet of XLS file.
- HSSFCell: It is a class representing a cell in a row of XLS file.
XLSX Classes
- XSSFWorkbook: It is a class representing the XLSX file.
- XSSFSheet: It is a class representing the sheet in an XLSX file.
- XSSFRow: It is a class representing a row in the sheet of XLSX file.
- XSSFCell: It is a class representing a cell in a row of XLSX file.
Steps to read data from XLS file
Step 1: Create a simple Java project in eclipse.
Step 2: Now, create a lib folder in the project.
Step 3: Download and add the following jar files in the lib folder:
- commons-collections4-4.1.jar Click Here
- poi-3.17.jar Click Here
- poi-ooxml-3.17.jar Click Here
- poi-ooxml-schemas-3.17.jar Click Here
- xmlbeans-2.6.0.jar Click Here
Step 4: Set the Class Path:
Right-click on the project ->Build Path ->Add External JARs -> select all the above jar files -> Apply and close.
Step 5: Now create a class file with the name ReadExcelFileDemo and write the following code in the file.
Step 6: Create an excel file with the name «student.xls» and write some data into it.
Step 7: Save and run the program.
Example of reading excel file (.xls) file
Output:
Name Age Height Swarit 23.0 5" Puneet 25.0 6'1" Swastik 22.0 5'5" Tejas 12.0 4'9"
Reading XLSX File
All steps will remain same except file format.
Table: employee.xslx
Example of read excel file (.xlsx)
In this example we use XSSFWorkbook class.
Output:
Employee ID Employee Name Salary Designation Department 1223.0 Harsh 20000.0 Marketing Manager Marketing 3213.0 Vivek 15000.0 Financial Advisor Finance 6542.0 Krishna 21000.0 HR Manager HR 9213.0 Sarika 34000.0 Sales Manager Sales
Reading a particular cell value from a excel file (.xlsx)
Table: EmployeeData.xlsx
Example
In the following example, we read the value of the 2nd row and the 2nd column. The row and column counting start from 0. So the program returns «Software Engineer.»
Output:
I want to read and write an Excel file from Java with 3 columns and N rows, printing one string in each cell. Can anyone give me simple code snippet for this? Do I need to use any external lib or does Java have built-in support for it?
I want to do the following:
for(i=0; i <rows; i++)
//read [i,col1] ,[i,col2], [i,col3]
for(i=0; i<rows; i++)
//write [i,col1], [i,col2], [i,col3]
Paolo Forgia
6,5328 gold badges46 silver badges58 bronze badges
asked Oct 4, 2009 at 10:54
1
Try the Apache POI HSSF. Here’s an example on how to read an excel file:
try {
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(file));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row;
HSSFCell cell;
int rows; // No of rows
rows = sheet.getPhysicalNumberOfRows();
int cols = 0; // No of columns
int tmp = 0;
// This trick ensures that we get the data properly even if it doesn't start from first few rows
for(int i = 0; i < 10 || i < rows; i++) {
row = sheet.getRow(i);
if(row != null) {
tmp = sheet.getRow(i).getPhysicalNumberOfCells();
if(tmp > cols) cols = tmp;
}
}
for(int r = 0; r < rows; r++) {
row = sheet.getRow(r);
if(row != null) {
for(int c = 0; c < cols; c++) {
cell = row.getCell((short)c);
if(cell != null) {
// Your code here
}
}
}
}
} catch(Exception ioe) {
ioe.printStackTrace();
}
On the documentation page you also have examples of how to write to excel files.
answered Oct 4, 2009 at 10:59
rogeriopvlrogeriopvl
50.8k8 gold badges54 silver badges58 bronze badges
7
Apache POI can do this for you. Specifically the HSSF module. The quick guide is most useful. Here’s how to do what you want — specifically create a sheet and write it out.
Workbook wb = new HSSFWorkbook();
//Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow((short)0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);
// Or do it on one line.
row.createCell(1).setCellValue(1.2);
row.createCell(2).setCellValue(
createHelper.createRichTextString("This is a string"));
row.createCell(3).setCellValue(true);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
answered Oct 4, 2009 at 10:57
Brian AgnewBrian Agnew
267k36 gold badges333 silver badges441 bronze badges
2
First add all these jar files in your project class path:
- poi-scratchpad-3.7-20101029
- poi-3.2-FINAL-20081019
- poi-3.7-20101029
- poi-examples-3.7-20101029
- poi-ooxml-3.7-20101029
- poi-ooxml-schemas-3.7-20101029
- xmlbeans-2.3.0
- dom4j-1.6.1
Code for writing in a excel file:
public static void main(String[] args) {
//Blank workbook
XSSFWorkbook workbook = new XSSFWorkbook();
//Create a blank sheet
XSSFSheet sheet = workbook.createSheet("Employee Data");
//This data needs to be written (Object[])
Map<String, Object[]> data = new TreeMap<String, Object[]>();
data.put("1", new Object[]{"ID", "NAME", "LASTNAME"});
data.put("2", new Object[]{1, "Amit", "Shukla"});
data.put("3", new Object[]{2, "Lokesh", "Gupta"});
data.put("4", new Object[]{3, "John", "Adwards"});
data.put("5", new Object[]{4, "Brian", "Schultz"});
//Iterate over data and write to sheet
Set<String> keyset = data.keySet();
int rownum = 0;
for (String key : keyset)
{
//create a row of excelsheet
Row row = sheet.createRow(rownum++);
//get object array of prerticuler key
Object[] objArr = data.get(key);
int cellnum = 0;
for (Object obj : objArr)
{
Cell cell = row.createCell(cellnum++);
if (obj instanceof String)
{
cell.setCellValue((String) obj);
}
else if (obj instanceof Integer)
{
cell.setCellValue((Integer) obj);
}
}
}
try
{
//Write the workbook in file system
FileOutputStream out = new FileOutputStream(new File("C:\Documents and Settings\admin\Desktop\imp data\howtodoinjava_demo.xlsx"));
workbook.write(out);
out.close();
System.out.println("howtodoinjava_demo.xlsx written successfully on disk.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
Code for reading from excel file
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
public static void main(String[] args) {
try {
FileInputStream file = new FileInputStream(new File("C:\Documents and Settings\admin\Desktop\imp data\howtodoinjava_demo.xlsx"));
//Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
//Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
//For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
//Check the cell type and format accordingly
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "t");
break;
}
}
System.out.println("");
}
file.close();
} catch (Exception e) {
e.printStackTrace();
}
}
answered Aug 2, 2013 at 9:15
0
You can also consider JExcelApi. I find it better designed than POI. There’s a tutorial here.
answered Oct 4, 2009 at 13:06
javashlookjavashlook
10.3k1 gold badge26 silver badges33 bronze badges
3
There is a new easy and very cool tool (10x to Kfir): xcelite
Write:
public class User {
@Column (name="Firstname")
private String firstName;
@Column (name="Lastname")
private String lastName;
@Column
private long id;
@Column
private Date birthDate;
}
Xcelite xcelite = new Xcelite();
XceliteSheet sheet = xcelite.createSheet("users");
SheetWriter<User> writer = sheet.getBeanWriter(User.class);
List<User> users = new ArrayList<User>();
// ...fill up users
writer.write(users);
xcelite.write(new File("users_doc.xlsx"));
Read:
Xcelite xcelite = new Xcelite(new File("users_doc.xlsx"));
XceliteSheet sheet = xcelite.getSheet("users");
SheetReader<User> reader = sheet.getBeanReader(User.class);
Collection<User> users = reader.read();
answered Dec 23, 2014 at 8:21
Ran AdlerRan Adler
3,52128 silver badges27 bronze badges
0
For reading a xlsx file we can use Apache POI libs
Try this:
public static void readXLSXFile() throws IOException
{
InputStream ExcelFileToRead = new FileInputStream("C:/Test.xlsx");
XSSFWorkbook wb = new XSSFWorkbook(ExcelFileToRead);
XSSFWorkbook test = new XSSFWorkbook();
XSSFSheet sheet = wb.getSheetAt(0);
XSSFRow row;
XSSFCell cell;
Iterator rows = sheet.rowIterator();
while (rows.hasNext())
{
row=(XSSFRow) rows.next();
Iterator cells = row.cellIterator();
while (cells.hasNext())
{
cell=(XSSFCell) cells.next();
if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING)
{
System.out.print(cell.getStringCellValue()+" ");
}
else if(cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC)
{
System.out.print(cell.getNumericCellValue()+" ");
}
else
{
//U Can Handel Boolean, Formula, Errors
}
}
System.out.println();
}
}
answered Apr 13, 2017 at 8:16
.csv or POI will certainly do it, but you should be aware of Andy Khan’s JExcel. I think it’s by far the best Java library for working with Excel there is.
answered Oct 4, 2009 at 12:50
duffymoduffymo
304k44 gold badges368 silver badges558 bronze badges
2
A simple CSV file should suffice
answered Oct 4, 2009 at 11:01
John La RooyJohn La Rooy
292k52 gold badges363 silver badges501 bronze badges
8
String path="C:\Book2.xlsx";
try {
File f = new File( path );
Workbook wb = WorkbookFactory.create(f);
Sheet mySheet = wb.getSheetAt(0);
Iterator<Row> rowIter = mySheet.rowIterator();
for ( Iterator<Row> rowIterator = mySheet.rowIterator() ;rowIterator.hasNext(); )
{
for ( Iterator<Cell> cellIterator = ((Row)rowIterator.next()).cellIterator() ; cellIterator.hasNext() ; )
{
System.out.println ( ( (Cell)cellIterator.next() ).toString() );
}
System.out.println( " **************************************************************** ");
}
} catch ( Exception e )
{
System.out.println( "exception" );
e.printStackTrace();
}
and make sure to have added the jars poi and poi-ooxml (org.apache.poi) to your project
instinct
4301 gold badge7 silver badges24 bronze badges
answered Apr 11, 2014 at 10:24
ToumiToumi
2,8673 gold badges37 silver badges30 bronze badges
For reading data from .xlsx workbooks we need to use XSSFworkbook classes.
XSSFWorkbook xlsxBook = new XSSFWorkbook(fis);
XSSFSheet sheet = xlsxBook.getSheetAt(0);
etc.
We need to use Apache-poi 3.9 @ http://poi.apache.org/
For detailed info with example visit
: http://java-recent.blogspot.in
CuberChase
4,4305 gold badges33 silver badges52 bronze badges
answered Jun 18, 2013 at 1:47
1
Sure , you will find the code below useful and easy to read and write. This is a util
class which you can use in your main method and then you are good to use all methods below.
public class ExcelUtils {
private static XSSFSheet ExcelWSheet;
private static XSSFWorkbook ExcelWBook;
private static XSSFCell Cell;
private static XSSFRow Row;
File fileName = new File("C:\Users\satekuma\Pro\Fund.xlsx");
public void setExcelFile(File Path, String SheetName) throws Exception
try {
FileInputStream ExcelFile = new FileInputStream(Path);
ExcelWBook = new XSSFWorkbook(ExcelFile);
ExcelWSheet = ExcelWBook.getSheet(SheetName);
} catch (Exception e) {
throw (e);
}
}
public static String getCellData(int RowNum, int ColNum) throws Exception {
try {
Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
String CellData = Cell.getStringCellValue();
return CellData;
} catch (Exception e) {
return "";
}
}
public static void setCellData(String Result, int RowNum, int ColNum, File Path) throws Exception {
try {
Row = ExcelWSheet.createRow(RowNum - 1);
Cell = Row.createCell(ColNum - 1);
Cell.setCellValue(Result);
FileOutputStream fileOut = new FileOutputStream(Path);
ExcelWBook.write(fileOut);
fileOut.flush();
fileOut.close();
} catch (Exception e) {
throw (e);
}
}
}
answered May 6, 2015 at 14:58
satendersatender
1,16913 silver badges12 bronze badges
using spring apache poi repo
if (fileName.endsWith(".xls")) {
File myFile = new File("file location" + fileName);
FileInputStream fis = new FileInputStream(myFile);
org.apache.poi.ss.usermodel.Workbook workbook = null;
try {
workbook = WorkbookFactory.create(fis);
} catch (InvalidFormatException e) {
e.printStackTrace();
}
org.apache.poi.ss.usermodel.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_STRING:
System.out.print(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue());
break;
}
System.out.print(" - ");
}
System.out.println();
}
}
goto
7,79110 gold badges48 silver badges58 bronze badges
answered Feb 22, 2017 at 9:53
I edited the most voted one a little cuz it didn’t count blanks columns or rows well not totally, so here is my code i tested it and now can get any cell in any part of an excel file. also now u can have blanks columns between filled column and it will read them
try {
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(Dir));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row;
HSSFCell cell;
int rows; // No of rows
rows = sheet.getPhysicalNumberOfRows();
int cols = 0; // No of columns
int tmp = 0;
int cblacks=0;
// This trick ensures that we get the data properly even if it doesn't start from first few rows
for(int i = 0; i <= 10 || i <= rows; i++) {
row = sheet.getRow(i);
if(row != null) {
tmp = sheet.getRow(i).getPhysicalNumberOfCells();
if(tmp >= cols) cols = tmp;else{rows++;cblacks++;}
}
cols++;
}
cols=cols+cblacks;
for(int r = 0; r < rows; r++) {
row = sheet.getRow(r);
if(row != null) {
for(int c = 0; c < cols; c++) {
cell = row.getCell(c);
if(cell != null) {
System.out.print(cell+"n");//Your Code here
}
}
}
}} catch(Exception ioe) {
ioe.printStackTrace();}
answered Oct 4, 2015 at 20:16
If column number are varing you can use this
package com.org.tests;
import org.apache.poi.xssf.usermodel.*;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelSimpleTest
{
String path;
public FileInputStream fis = null;
private XSSFWorkbook workbook = null;
private XSSFSheet sheet = null;
private XSSFRow row =null;
private XSSFCell cell = null;
public ExcelSimpleTest() throws IOException
{
path = System.getProperty("user.dir")+"\resources\Book1.xlsx";
fis = new FileInputStream(path);
workbook = new XSSFWorkbook(fis);
sheet = workbook.getSheetAt(0);
}
public void ExelWorks()
{
int index = workbook.getSheetIndex("Sheet1");
sheet = workbook.getSheetAt(index);
int rownumber=sheet.getLastRowNum()+1;
for (int i=1; i<rownumber; i++ )
{
row = sheet.getRow(i);
int colnumber = row.getLastCellNum();
for (int j=0; j<colnumber; j++ )
{
cell = row.getCell(j);
System.out.println(cell.getStringCellValue());
}
}
}
public static void main(String[] args) throws IOException
{
ExcelSimpleTest excelwork = new ExcelSimpleTest();
excelwork.ExelWorks();
}
}
The corresponding mavendependency can be found here
Ohmen
6,1343 gold badges26 silver badges35 bronze badges
answered Aug 26, 2016 at 6:06
1
Another way to read/write Excel files is to use Windmill. It provides a fluent API to process Excel and CSV files.
Import data
try (Stream<Row> rowStream = Windmill.parse(FileSource.of(new FileInputStream("myFile.xlsx")))) {
rowStream
// skip the header row that contains the column names
.skip(1)
.forEach(row -> {
System.out.println(
"row n°" + row.rowIndex()
+ " column 'User login' value : " + row.cell("User login").asString()
+ " column n°3 number value : " + row.cell(2).asDouble().value() // index is zero-based
);
});
}
Export data
Windmill
.export(Arrays.asList(bean1, bean2, bean3))
.withHeaderMapping(
new ExportHeaderMapping<Bean>()
.add("Name", Bean::getName)
.add("User login", bean -> bean.getUser().getLogin())
)
.asExcel()
.writeTo(new FileOutputStream("Export.xlsx"));
answered Sep 30, 2017 at 15:07
amanteauxamanteaux
1,94319 silver badges23 bronze badges
You need Apache POI library and this code below should help you
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
//*************************************************************
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
//*************************************************************
public class AdvUse {
private static Workbook wb ;
private static Sheet sh ;
private static FileInputStream fis ;
private static FileOutputStream fos ;
private static Row row ;
private static Cell cell ;
private static String ExcelPath ;
//*************************************************************
public static void setEcxelFile(String ExcelPath, String SheetName) throws Exception {
try {
File f= new File(ExcelPath);
if(!f.exists()){
f.createNewFile();
System.out.println("File not Found so created");
}
fis = new FileInputStream("./testData.xlsx");
wb = WorkbookFactory.create(fis);
sh = wb.getSheet("SheetName");
if(sh == null){
sh = wb.getSheet(SheetName);
}
}catch(Exception e)
{System.out.println(e.getMessage());
}
}
//*************************************************************
public static void setCellData(String text , int rowno , int colno){
try{
row = sh.getRow(rowno);
if(row == null){
row = sh.createRow(rowno);
}
cell = row.getCell(colno);
if(cell!=null){
cell.setCellValue(text);
}
else{
cell = row.createCell(colno);
cell.setCellValue(text);
}
fos = new FileOutputStream(ExcelPath);
wb.write(fos);
fos.flush();
fos.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
//*************************************************************
public static String getCellData(int rowno , int colno){
try{
cell = sh.getRow(rowno).getCell(colno);
String CellData = null ;
switch(cell.getCellType()){
case STRING :
CellData = cell.getStringCellValue();
break ;
case NUMERIC :
CellData = Double.toString(cell.getNumericCellValue());
if(CellData.contains(".o")){
CellData = CellData.substring(0,CellData.length()-2);
}
break ;
case BLANK :
CellData = ""; break ;
}
return CellData;
}catch(Exception e){return ""; }
}
//*************************************************************
public static int getLastRow(){
return sh.getLastRowNum();
}
answered Mar 30, 2019 at 16:48
Abdo BmzAbdo Bmz
6221 gold badge10 silver badges24 bronze badges
You can not read & write same file in parallel(Read-write lock). But, we can do parallel operations on temporary data(i.e. Input/output stream). Write the data to file only after closing the input stream. Below steps should be followed.
- Open the file to Input stream
- Open the same file to an Output Stream
- Read and do the processing
- Write contents to output stream.
- Close the read/input stream, close file
- Close output stream, close file.
Apache POI — read/write same excel example
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class XLSXReaderWriter {
public static void main(String[] args) {
try {
File excel = new File("D://raju.xlsx");
FileInputStream fis = new FileInputStream(excel);
XSSFWorkbook book = new XSSFWorkbook(fis);
XSSFSheet sheet = book.getSheetAt(0);
Iterator<Row> itr = sheet.iterator();
// Iterating over Excel file in Java
while (itr.hasNext()) {
Row row = itr.next();
// Iterating over each column of Excel file
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "t");
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "t");
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "t");
break;
default:
}
}
System.out.println("");
}
// writing data into XLSX file
Map<String, Object[]> newData = new HashMap<String, Object[]>();
newData.put("1", new Object[] { 1d, "Raju", "75K", "dev",
"SGD" });
newData.put("2", new Object[] { 2d, "Ramesh", "58K", "test",
"USD" });
newData.put("3", new Object[] { 3d, "Ravi", "90K", "PMO",
"INR" });
Set<String> newRows = newData.keySet();
int rownum = sheet.getLastRowNum();
for (String key : newRows) {
Row row = sheet.createRow(rownum++);
Object[] objArr = newData.get(key);
int cellnum = 0;
for (Object obj : objArr) {
Cell cell = row.createCell(cellnum++);
if (obj instanceof String) {
cell.setCellValue((String) obj);
} else if (obj instanceof Boolean) {
cell.setCellValue((Boolean) obj);
} else if (obj instanceof Date) {
cell.setCellValue((Date) obj);
} else if (obj instanceof Double) {
cell.setCellValue((Double) obj);
}
}
}
// open an OutputStream to save written data into Excel file
FileOutputStream os = new FileOutputStream(excel);
book.write(os);
System.out.println("Writing on Excel file Finished ...");
// Close workbook, OutputStream and Excel file to prevent leak
os.close();
book.close();
fis.close();
} catch (FileNotFoundException fe) {
fe.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
}
}
}
answered Jul 20, 2018 at 21:46
RajuRaju
2,8628 gold badges38 silver badges57 bronze badges
Please use Apache POI libs and try this.
try
{
FileInputStream x = new FileInputStream(new File("/Users/rajesh/Documents/rajesh.xls"));
//Create Workbook instance holding reference to .xlsx file
Workbook workbook = new HSSFWorkbook(x);
//Get first/desired sheet from the workbook
Sheet sheet = workbook.getSheetAt(0);
//Iterate through each rows one by one
for (Iterator<Row> iterator = sheet.iterator(); iterator.hasNext();) {
Row row = (Row) iterator.next();
for (Iterator<Cell> iterator2 = row.iterator(); iterator2
.hasNext();) {
Cell cell = (Cell) iterator2.next();
System.out.println(cell.getStringCellValue());
}
}
x.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Majid Laissi
19k19 gold badges65 silver badges105 bronze badges
answered Nov 28, 2014 at 11:41
When using the apache poi 4.1.2. The celltype changes a bit. Below is an example
try {
File excel = new File("/home/name/Downloads/bb.xlsx");
FileInputStream fis = new FileInputStream(excel);
XSSFWorkbook book = new XSSFWorkbook(fis);
XSSFSheet sheet = book.getSheetAt(0);
Iterator<Row> itr = sheet.iterator();
// Iterating over Excel file in Java
while (itr.hasNext()) {
Row row = itr.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
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;
default:
}
}
System.out.println("");}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
answered May 22, 2020 at 8:44
mumbasamumbasa
5526 silver badges11 bronze badges
If you go for third party library option, try using Aspose.Cells API that enables Java Applications to create (read/write) and manage Excel spreadsheets efficiently without requiring Microsoft Excel.
e.g
Sample code:
1.
//Load sample workbook
Workbook wb = new Workbook(dirPath + "sample.xlsx");
//Access first worksheet
Worksheet ws = wb.getWorksheets().get(0);
//Access cells iterator
Iterator itrat = ws.getCells().iterator();
//Print cells name in iterator
while(itrat.hasNext())
{
Cell cell = (Cell)itrat.next();
System.out.println(cell.getName() + ": " + cell.getStringValue().trim());
}
Workbook book = new Workbook("sample.xlsx");
Worksheet sheet = book.getWorksheets().get(0);
Range range = sheet.getCells().getMaxDisplayRange();//You may also create your desired range (in the worksheet) using, e.g sheet.getCells().createRange("A1", "J11");
Iterator rangeIterator = range.iterator();
while(rangeIterator.hasNext())
{
Cell cell = (Cell)rangeIterator.next();
//your code goes here.
}
Hope, this helps a bit.
PS. I am working as Support developer/ Evangelist at Aspose.
answered Sep 2, 2020 at 19:29
Amjad SahiAmjad Sahi
1,7531 gold badge9 silver badges15 bronze badges
If you need to do anything more with office documents in Java, go for POI as mentioned.
For simple reading/writing an excel document like you requested, you can use the CSV format (also as mentioned):
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class CsvWriter {
public static void main(String args[]) throws IOException {
String fileName = "test.xls";
PrintWriter out = new PrintWriter(new FileWriter(fileName));
out.println("a,b,c,d");
out.println("e,f,g,h");
out.println("i,j,k,l");
out.close();
BufferedReader in = new BufferedReader(new FileReader(fileName));
String line = null;
while ((line = in.readLine()) != null) {
Scanner scanner = new Scanner(line);
String sep = "";
while (scanner.hasNext()) {
System.out.println(sep + scanner.next());
sep = ",";
}
}
in.close();
}
}
answered Oct 4, 2009 at 12:02
Adriaan KosterAdriaan Koster
15.8k5 gold badges45 silver badges60 bronze badges
This will write a JTable to a tab separated file that can be easily imported into Excel. This works.
If you save an Excel worksheet as an XML document you could also build the XML file for EXCEL with code. I have done this with word so you do not have to use third-party packages.
This could code have the JTable taken out and then just write a tab separated to any text file and then import into Excel. I hope this helps.
Code:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JTable;
import javax.swing.table.TableModel;
public class excel {
String columnNames[] = { "Column 1", "Column 2", "Column 3" };
// Create some data
String dataValues[][] =
{
{ "12", "234", "67" },
{ "-123", "43", "853" },
{ "93", "89.2", "109" },
{ "279", "9033", "3092" }
};
JTable table;
excel() {
table = new JTable( dataValues, columnNames );
}
public void toExcel(JTable table, File file){
try{
TableModel model = table.getModel();
FileWriter excel = new FileWriter(file);
for(int i = 0; i < model.getColumnCount(); i++){
excel.write(model.getColumnName(i) + "t");
}
excel.write("n");
for(int i=0; i< model.getRowCount(); i++) {
for(int j=0; j < model.getColumnCount(); j++) {
excel.write(model.getValueAt(i,j).toString()+"t");
}
excel.write("n");
}
excel.close();
}catch(IOException e){ System.out.println(e); }
}
public static void main(String[] o) {
excel cv = new excel();
cv.toExcel(cv.table,new File("C:\Users\itpr13266\Desktop\cs.tbv"));
}
}
answered Feb 26, 2014 at 22:58
Doug HaufDoug Hauf
3,0158 gold badges45 silver badges69 bronze badges
1
Learn to read a large excel file in Java using the Apache POI and SAX parser library. The SAX parser is an event-based parser. Unlike a DOM parser, a SAX parser creates no parse tree and sends event notifications when a sheet, row or cell is processed sequentially from top to bottom.
In this example, we will be able to:
- Use custom logic to choose if we want to process a specific sheet (by sheet name).
- Notify when a new sheet starts or the current sheet ends.
- Get the first row in the sheet as headers.
- Get the other rows in the sheet as a Map of column name and cell value pairs.
- 1. Maven Dependencies
- 2. Core Classes
- 3. Reading Excel with SAX Parser
- 3.1. Overriding DefaultHandler
- 3.2. Creating Row Handler
- 4. Demo
- 5. Conclusion
1. Maven Dependencies
Add the latest version of org.apache.poi:poi and org.apache.poi:poi-ooxml in the application, if not added already.
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
2. Core Classes
- OPCPackage: A
.xlsx
file is built on top of the OOXML package structure, and OPCPackage represents a container that can store multiple data objects. - XSSFReader: makes it easy to get at individual parts of an OOXML .xlsx file, suitable for low memory sax parsing.
- DefaultHandler: provides default implementations for all callbacks in the other core SAX2 handler classes. We have extended this class and overrode the necessary methods to handle event callbacks.
- SAXParser: parses a document and sends notification of various parser events to a registered event handler.
- SharedStringsTable: It stores a table of strings shared across all sheets in a workbook. It helps in improving performance when some strings are repeated across many rows or columns. The shared string table contains all the necessary information for displaying the string: the text, formatting properties, and phonetic properties.
See Also: DOM vs SAX Parser
3. Reading Excel with SAX Parser
3.1. Overriding DefaultHandler
Let us start with creating the event handler for parsing events. The following SheetHandler extends DefaultHandler and provides the following methods:
startElement()
: is called when a new row or cell begins.endElement()
: is called when the current row or cell ends.readExcelFile()
: takes an excel file and uses SAXParser and XSSFReader to parse the file, sheet by sheet.
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutionException;
public class SheetHandler extends DefaultHandler
{
protected Map<String, String> header = new HashMap<>();
protected Map<String, String> rowValues = new HashMap<>();
private SharedStringsTable sharedStringsTable;
protected long rowNumber = 0;
protected String cellId;
private String contents;
private boolean isCellValue;
private boolean fromSST;
protected static String getColumnId(String attribute) throws SAXException {
for (int i = 0; i < attribute.length(); i++) {
if (!Character.isAlphabetic(attribute.charAt(i))) {
return attribute.substring(0, i);
}
}
throw new SAXException("Invalid format " + attribute);
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// Clear contents cache
contents = "";
// element row represents Row
switch (name) {
case "row" -> {
String rowNumStr = attributes.getValue("r");
rowNumber = Long.parseLong(rowNumStr);
}
// element c represents Cell
case "c" -> {
cellId = getColumnId(attributes.getValue("r"));
// attribute t represents the cell type
String cellType = attributes.getValue("t");
if (cellType != null && cellType.equals("s")) {
// cell type s means value will be extracted from SharedStringsTable
fromSST = true;
}
}
// element v represents value of Cell
case "v" -> isCellValue = true;
}
}
@Override
public void characters(char[] ch, int start, int length) {
if (isCellValue) {
contents += new String(ch, start, length);
}
}
@Override
public void endElement(String uri, String localName, String name) {
if (isCellValue && fromSST) {
int index = Integer.parseInt(contents);
contents = new XSSFRichTextString(sharedStringsTable.getItemAt(index).getString()).toString();
rowValues.put(cellId, contents);
cellId = null;
isCellValue = false;
fromSST = false;
} else if (isCellValue) {
rowValues.put(cellId, contents);
isCellValue = false;
} else if (name.equals("row")) {
header.clear();
if (rowNumber == 1) {
header.putAll(rowValues);
}
try {
processRow();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
rowValues.clear();
}
}
protected boolean processSheet(String sheetName) {
return true;
}
protected void startSheet() {
}
protected void endSheet() {
}
protected void processRow() throws ExecutionException, InterruptedException {
}
public void readExcelFile(File file) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
try (OPCPackage opcPackage = OPCPackage.open(file)) {
XSSFReader xssfReader = new XSSFReader(opcPackage);
sharedStringsTable = (SharedStringsTable) xssfReader.getSharedStringsTable();
System.out.println(sharedStringsTable.getUniqueCount());
Iterator<InputStream> sheets = xssfReader.getSheetsData();
if (sheets instanceof XSSFReader.SheetIterator sheetIterator) {
while (sheetIterator.hasNext()) {
try (InputStream sheet = sheetIterator.next()) {
String sheetName = sheetIterator.getSheetName();
if(!processSheet(sheetName)) {
continue;
}
startSheet();
saxParser.parse(sheet, this);
endSheet();
}
}
}
}
}
}
3.2. Creating Row Handler
The following class ExcelReaderHandler extends SheetHandler class as given in the previous section. It overrides the following methods so we can write our custom logic for processing the data read from each sheet in the excel file.
processSheet()
: for determining if we want to read a sheet or not. It takes the sheet name as a parameter that we can use to determine the decision.startSheet()
: is invoked everytime a new sheet starts.endSheet()
: is invoked everytime the current sheet ends.processRow()
: is invoked once for each row, and provides cell values in that row.
public class ExcelReaderHandler extends SheetHandler {
@Override
protected boolean processSheet(String sheetName) {
//Decide which sheets to read; Return true for all sheets
//return "Sheet 1".equals(sheetName);
System.out.println("Processing start for sheet : " + sheetName);
return true;
}
@Override
protected void startSheet() {
//Any custom logic when a new sheet starts
System.out.println("Sheet starts");
}
@Override
protected void endSheet() {
//Any custom logic when sheet ends
System.out.println("Sheet ends");
}
@Override
protected void processRow() {
if(rowNumber == 1 && !header.isEmpty()) {
System.out.println("The header values are at line no. " + rowNumber + " " +
"are :" + header);
}
else if (rowNumber > 1 && !rowValues.isEmpty()) {
//Get specific values here
/*String a = rowValues.get("A");
String b = rowValues.get("B");*/
//Print whole row
System.out.println("The row values are at line no. " + rowNumber + " are :" + rowValues);
}
}
}
4. Demo
Let us understand how to read the excel file using a demo program. We are reading a file that has 2 sheets and some values in the sheets.
Let us use ExcelReaderHandler to read the excel and print the values read in the process.
import java.io.File;
import java.net.URL;
public class ReadExcelUsingSaxParserExample {
public static void main(String[] args) throws Exception {
URL url = ReadExcelUsingSaxParserExample.class
.getClassLoader()
.getResource("howtodoinjava_demo.xlsx");
new ExcelReaderHandler().readExcelFile(new File(url.getFile()));
}
}
Check the output that has the cell values from the excel file.
Processing start for sheet : Employee Data
Sheet starts
The header values are at line no. 1 are :{A=ID, B=NAME, C=LASTNAME}
The row values are at line no. 2 are :{A=1, B=Amit, C=Shukla}
The row values are at line no. 3 are :{A=2, B=Lokesh, C=Gupta}
The row values are at line no. 4 are :{A=3, B=John, C=Adwards}
The row values are at line no. 5 are :{A=4, B=Brian, C=Schultz}
Sheet ends
Processing start for sheet : Random Data
Sheet starts
The header values are at line no. 1 are :{A=Key, B=Value}
The row values are at line no. 2 are :{A=1, B=a}
The row values are at line no. 3 are :{A=2, B=b}
The row values are at line no. 4 are :{A=3, B=c}
Sheet ends
5. Conclusion
In this Apache POI tutorial, we learned to read an excel file using the SAX parser. We can use this solution to read huge excel files as well. I will suggest you play with the code for better understanding.
Happy Learning !!
Source Code on Github
Рассказывает автор блога javarevisited.blogspot.ru
Из этой статьи вы сможете узнать о записи и чтении данных из Excel файлов в Java (будет рассмотрен как XLS
, так и XLSX
формат). Мы будем использовать библиотеку Apache POI и сосредоточимся на работе с типами String
и Date
, работа с последним происходит достаточно хитро. Напомню, что работу с числами мы уже рассмотрели в другой статье.
Библиотеку poi-XX.jar
вы можете использовать для всех старых (xls
, doc
, ppt
) файлов Microsoft Office, для новых (xlsx
, docx
, pptx
) вам понадобится poi-ooxml-XX.jar
. Очень важно понимать, что к чему относится, т.к. используемые классы тоже разные — для старых расширений это HSSFWorkbook
, а для новых — XSSFWorkbook
.
Подготовка: загрузка библиотек и зависимостей
Конечно, существует достаточно много открытых библиотек, которые позволяют работать с Excel файлами в Java, например, JXL, но мы будем использовать имеющую самый обширный API и самую популярную — Apache POI. Чтобы её использовать, вам нужно скачать jar
файлы и добавить их через Eclipse вручную, или вы можете предоставить это Maven.
Во втором случае вам нужно просто добавить следующие две зависимости:
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.12</version>
</dependency>
</dependencies>
Самое удобное в Maven — что он загрузит не только указанные poi.jar
и poi-ooxml.jar
, но и все jar файлы, которые используются внутри, то есть xmlbeans-2.6.0.jar
, stax-api-1.0.1.jar
, poi-ooxml-schemas-3.12.jar
и commons-codec-1.9.jar
.
Если вы будете добавлять библиотеки вручную — не забудьте о вышеназванных файлах. Скачать всё можно отсюда. Помните — если вы загрузите только poi-XX.jar
, то ваш код скомпилируется без ошибок, но потом упадёт с java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject
, так как внутри будет вызываться xmlbeans.jar
.
Запись
В этом примере мы запишем в xls
файл следующие данные: в первую ячейку — строку с именем, а во вторую — дату рождения. Вот пошаговая инструкция:
- Создаём объект
HSSFWorkBook
; - Создаём лист, используя на объекте, созданном в предыдущем шаге,
createSheet()
; - Создаём на листе строку, используя
createRow()
; - Создаём в строке ячейку —
createCell()
; - Задаём значение ячейки через
setCellValue();
- Записываем
workbook
вFile
черезFileOutputStream
; - Закрываем
workbook
, вызываяclose()
.
Для записи строк или чисел этого вполне достаточно, но чтобы записать дату, нам понадобится сделать ещё кое-что:
- Создать
DateFormat
; - Создать
CellStyle
; - Записать
DateFormat
вCellStyle
; - Записать
CellStyle
в ячейку; - Теперь в эту ячейку можно записать объект
Date
через всё тот жеsetCellValue
; - Чтобы дата поместилась в ячейку, нам нужно добавить столбцу свойство автоматически менять размер:
sheet.autoSizeColumn(1)
.
Всё вместе это будет выглядеть так:
@SuppressWarnings("deprecation")
public static void writeIntoExcel(String file) throws FileNotFoundException, IOException{
Workbook book = new HSSFWorkbook();
Sheet sheet = book.createSheet("Birthdays");
// Нумерация начинается с нуля
Row row = sheet.createRow(0);
// Мы запишем имя и дату в два столбца
// имя будет String, а дата рождения --- Date,
// формата dd.mm.yyyy
Cell name = row.createCell(0);
name.setCellValue("John");
Cell birthdate = row.createCell(1);
DataFormat format = book.createDataFormat();
CellStyle dateStyle = book.createCellStyle();
dateStyle.setDataFormat(format.getFormat("dd.mm.yyyy"));
birthdate.setCellStyle(dateStyle);
// Нумерация лет начинается с 1900-го
birthdate.setCellValue(new Date(110, 10, 10));
// Меняем размер столбца
sheet.autoSizeColumn(1);
// Записываем всё в файл
book.write(new FileOutputStream(file));
book.close();
}
Чтение
Теперь мы считаем из только что созданного файла то, что мы туда записали.
- Для начала создадим
HSSFWorkBook
, передав в конструкторFileInputStream
; - Получаем лист, передавая в
getSheet()
его номер или название; - Получаем строку, используя
getRow()
; - Получаем ячейку, используя
getCell()
; - Узнаём тип ячейки, используя на ней
getCellType()
; - В зависимости от типа ячейки, читаем её значения, используя
getStringCellValue()
,getNumericCellValue()
илиgetDateCellValue()
; - Закрываем
workbook
используяclose()
.
Напомню, что дату Excel хранит как числа, т.е. тип ячейки всё равно будет CELL_TYPE_NUMERIC
.
В виде кода это будет выглядеть следующим образом:
public static void readFromExcel(String file) throws IOException{
HSSFWorkbook myExcelBook = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet myExcelSheet = myExcelBook.getSheet("Birthdays");
HSSFRow row = myExcelSheet.getRow(0);
if(row.getCell(0).getCellType() == HSSFCell.CELL_TYPE_STRING){
String name = row.getCell(0).getStringCellValue();
System.out.println("name : " + name);
}
if(row.getCell(1).getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
Date birthdate = row.getCell(1).getDateCellValue();
System.out.println("birthdate :" + birthdate);
}
myExcelBook.close();
}
В заключение
Как уже упомналось выше, чтение из xlsx
файлов ничем принципиально не отличается — нужно только вместо HSSFWorkBook
, HSSFSheet
, HSSFRow
(и прочих) из poi-XX.jar
использовать XSSFWorkBook
, XSSFSheet
, XSSFRow
из poi-ooxml-XX.jar
. Это всё, что вам нужно знать для чтения и записи в файлы Excel. Разумеется, с помощью библиотеки Apache POI вы можете сделать гораздо больше, но эта статья должна помочь вам быстрее в ней освоиться.
Перевод статьи «How to Read Write Excel file in Java — POI Example»
- Details
- Written by
- Last Updated on 30 May 2019 | Print Email
In this tutorial, I will share with you how to read Excel files programmatically using Java.
You know, Excel is the very popular file format created by Microsoft. Although it is not an opened file format, Java applications can still read and write Excel files using the Apache POI — the Java API for Microsoft Documents, because the development team uses reverse-engineering to understand the Excel file format. Hence the name POI stands for Poor Obfuscation Implementation.
This tutorial shows you how simple and easy it is to read Excel files using Apache POI’s API.
1. Getting Apache POI library
Apache POI is the pure Java API for reading and writing Excel files in both formats XLS (Excel 2003 and earlier) and XLSX (Excel 2007 and later). To use Apache POI in your Java project:
- For non-Maven projects:
- Download the latest release of the library here: Apache POI — Download Release ArtifactsExtract the zip file and add the appropriate JAR files to your project’s classpath:- If you are reading and writing only Excel 2003 format, only the file poi-VERSION.jar is enough.- If you are reading and writing Excel 2007 format, you have to include the following files:
- poi-ooxml-VERSION.jar
- poi-ooxml-schemas-VERSION.jar
- xmlbeans-VERSION.jar
- Download the latest release of the library here: Apache POI — Download Release ArtifactsExtract the zip file and add the appropriate JAR files to your project’s classpath:- If you are reading and writing only Excel 2003 format, only the file poi-VERSION.jar is enough.- If you are reading and writing Excel 2007 format, you have to include the following files:
- For Maven projects: Add the following dependency to your project’s pom.xml file:
- For Excel 2003 format only:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>VERSION</version> </dependency>
- For Excel 2007 format:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>VERSION</version> </dependency>
The latest stable version of Apache POI is 3.11 (at the time of writing this tutorial).
- For Excel 2003 format only:
2. The Apache POI API Basics
There are two main prefixes which you will encounter when working with Apache POI:
- HSSF: denotes the API is for working with Excel 2003 and earlier.
- XSSF: denotes the API is for working with Excel 2007 and later.
And to get started the Apache POI API, you just need to understand and use the following 4 interfaces:
- Workbook: high level representation of an Excel workbook. Concrete implementations are: HSSFWorkbookand XSSFWorkbook.
- Sheet: high level representation of an Excel worksheet. Typical implementing classes are HSSFSheetand XSSFSheet.
- Row: high level representation of a row in a spreadsheet. HSSFRowand XSSFRoware two concrete classes.
- Cell: high level representation of a cell in a row. HSSFCelland XSSFCellare the typical implementing classes.
Now, let’s walk through some real-life examples.
3. Reading from Excel File Examples
Suppose you want to read an Excel file whose content looks like the following screenshot:
This spreadsheet contains information about books (title, author and price).
A Simple Example to Read Excel File in Java
Here’s a dirty example that reads every cell in the first sheet of the workbook and prints out values in every cell, row by row:
package net.codejava.excel; import java.io.File; 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; /** * A dirty simple program that reads an Excel file. * @author www.codejava.net * */ public class SimpleExcelReaderExample { public static void main(String[] args) throws IOException { String excelFilePath = "Books.xlsx"; FileInputStream inputStream = new FileInputStream(new File(excelFilePath)); Workbook workbook = new XSSFWorkbook(inputStream); Sheet firstSheet = workbook.getSheetAt(0); Iterator<Row> iterator = firstSheet.iterator(); while (iterator.hasNext()) { Row nextRow = iterator.next(); Iterator<Cell> cellIterator = nextRow.cellIterator(); while (cellIterator.hasNext()) { Cell cell = cellIterator.next(); switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: System.out.print(cell.getStringCellValue()); break; case Cell.CELL_TYPE_BOOLEAN: System.out.print(cell.getBooleanCellValue()); break; case Cell.CELL_TYPE_NUMERIC: System.out.print(cell.getNumericCellValue()); break; } System.out.print(" - "); } System.out.println(); } workbook.close(); inputStream.close(); } }
Output:
Head First Java - Kathy Serria - 79.0 - Effective Java - Joshua Bloch - 36.0 - Clean Code - Robert Martin - 42.0 - Thinking in Java - Bruce Eckel - 35.0 -
A More Object-Oriented Example to read Excel File
For nicer and more object-oriented program, let’s create a model class (Book.java) with the following code:
package net.codejava.excel; public class Book { private String title; private String author; private float price; public Book() { } public String toString() { return String.format("%s - %s - %f", title, author, price); } // getters and setters }
Write a method that reads value of a cell as following:
private Object getCellValue(Cell cell) { switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: return cell.getStringCellValue(); case Cell.CELL_TYPE_BOOLEAN: return cell.getBooleanCellValue(); case Cell.CELL_TYPE_NUMERIC: return cell.getNumericCellValue(); } return null; }
Next, implement a method that reads an Excel file and returns a list of books:
public List<Book> readBooksFromExcelFile(String excelFilePath) throws IOException { List<Book> listBooks = new ArrayList<>(); FileInputStream inputStream = new FileInputStream(new File(excelFilePath)); Workbook workbook = new XSSFWorkbook(inputStream); Sheet firstSheet = workbook.getSheetAt(0); Iterator<Row> iterator = firstSheet.iterator(); while (iterator.hasNext()) { Row nextRow = iterator.next(); Iterator<Cell> cellIterator = nextRow.cellIterator(); Book aBook = new Book(); while (cellIterator.hasNext()) { Cell nextCell = cellIterator.next(); int columnIndex = nextCell.getColumnIndex(); switch (columnIndex) { case 1: aBook.setTitle((String) getCellValue(nextCell)); break; case 2: aBook.setAuthor((String) getCellValue(nextCell)); break; case 3: aBook.setPrice((double) getCellValue(nextCell)); break; } } listBooks.add(aBook); } workbook.close(); inputStream.close(); return listBooks; }
And here is the testing code:
public static void main(String[] args) throws IOException { String excelFilePath = "Books.xlsx"; ExcelReaderExample2 reader = new ExcelReaderExample2(); List<Book> listBooks = reader.readBooksFromExcelFile(excelFilePath); System.out.println(listBooks); }
Output:
[Head First Java - Kathy Serria - 79.000000, Effective Java - Joshua Bloch - 36.000000, Clean Code - Robert Martin - 42.000000, Thinking in Java - Bruce Eckel - 35.000000]
How to Read both Excel 2003 and 2007 format in Java
For better supporting both users using Excel 2003 and 2007, it’s recommended to write a separate factory method that returns an XSSFWorkbookor HSSFWorkbookdepending on the file extension of the file (.xls or .xlsx):
private Workbook getWorkbook(FileInputStream inputStream, String excelFilePath) throws IOException { Workbook workbook = null; if (excelFilePath.endsWith("xlsx")) { workbook = new XSSFWorkbook(inputStream); } else if (excelFilePath.endsWith("xls")) { workbook = new HSSFWorkbook(inputStream); } else { throw new IllegalArgumentException("The specified file is not Excel file"); } return workbook; }
And here’s a usage example of this factory method:
String excelFilePath = "Books.xlsx"; // can be .xls or .xlsx FileInputStream inputStream = new FileInputStream(new File(excelFilePath)); Workbook workbook = getWorkbook(inputStream, excelFilePath);
Reading Other Information
- Get a specific sheet:
Sheet thirdSheet = workbook.getSheetAt(2);
- Get sheet name:
String sheetName = sheet.getSheetName();
- Get total number of sheets in the workbook:
int numberOfSheets = workbook.getNumberOfSheets();
- Get all sheet names in the workbook:
int numberOfSheets = workbook.getNumberOfSheets(); for (int i = 0; i < numberOfSheets; i++) { Sheet aSheet = workbook.getSheetAt(i); System.out.println(aSheet.getSheetName()); }
- Get comment of a specific cell:
Comment cellComment = sheet.getCellComment(2, 2); System.out.println("comment: " + cellComment.getString());
For reading other information, see the getXXX() methods of the Workbook, Sheet, Row and Cell interfaces.
That’s how to read Excel files in Java programmatically. I recommend you to take this Java course to fully learn Java programming.
Related Java Excel Tutorials:
- How to Write Excel Files in Java using Apache POI
- Java Example to Read Password-protected Excel Files Using Apache POI
- Java Example to Update Existing Excel Files Using Apache POI
- Working with Formula Cells in Excel using Apache POI
References:
- Apache POI — the Java API for Microsoft Documents
- POI API Documentation (Javadocs)
- Apache POI Quick Guide
- Apache POI HOWTO
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.