Downloading excel file in java

Рассказывает автор блога 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»

The Excel file is a spreadsheet file format created by Microsoft for use with Microsoft Excel. You can use the file to create, view, edit, analyse data, charts, budgets and more. In this tutorial, I will show you how to use Spring Boot to download Excel file from a table in MySQL Database using Apache POI.

Related Posts:
– Spring Boot: Upload/Import Excel file data into MySQL Database
– Spring Boot Multipart File upload example
– How to upload multiple files in Java Spring Boot
– Upload/Import CSV file to MySQL Database in Spring Boot

CSV file instead:
Spring Boot Download CSV file from Database example

Deployment:
– Deploy Spring Boot App on AWS – Elastic Beanstalk
– Docker Compose: Spring Boot and MySQL example

Contents

  • Spring Boot Rest API: Download Excel File
  • Technology
  • Project Structure
  • Setup Spring Boot Download Excel File project
  • Configure Spring Datasource, JPA, Hibernate
  • Define Data Model
  • Create Data Repository for working with Database
  • Implement Excel Helper Class
  • Create Excel File Service
  • Create Controller for Excel File Download
  • Run the Spring Boot Download Excel File App
  • Conclusion
  • Further Reading
  • Source Code

Assume that we have a tutorials table in MySQL database like this:

spring-boot-download-excel-file-mysql-example-database-table

We’re gonna create a Spring Boot Application that provides APIs for downloading MySQL table data as Excel file with following content:

spring-boot-download-excel-file-mysql-example-result

If you send request to /api/excel/download, the server will return a response with an Excel file tutorials.xlsx that contains data in MySQL table:

spring-boot-download-excel-file-mysql-example-get-request-excel-file

How to do this?
You need to set the HTTP header:

"Content-disposition" : "attachment; filename=[yourFileName]" 
"Content-Type" : "application/vnd.ms-excel"

We’re gonna apply the information above later in this tutorial.

You can also find how to upload Excel File to the Spring Server & store data in MySQL Database in the post:
Spring Boot: Upload/Import Excel file data into MySQL Database

Technology

  • Java 8
  • Spring Boot 2 (with Spring Web MVC)
  • Maven 3.6.1
  • Apache POI 4.1.2

Project Structure

This is the project directory that we’re gonna build:

spring-boot-download-excel-file-mysql-example-project-structure

ExcelHelper provides functions to write to Excel file.

Tutorial data model class corresponds to entity and table tutorials.
TutorialRepository is an interface that extends JpaRepository for persisting data.

ExcelService uses ExcelHelper and TutorialRepository methods load data to Excel file.

ExcelController calls ExcelService methods and export Rest API for downloading Excel files.

application.properties contains configuration for Spring Data.
pom.xml for Spring Boot, MySQL connector, Apache POI dependencies.

Setup Spring Boot Download Excel File project

Use Spring web tool or your development tool (Spring Tool Suite, Eclipse, Intellij) to create a Spring Boot project.

Then open pom.xml and add these dependencies:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>4.1.2</version>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

Configure Spring Datasource, JPA, Hibernate

Under src/main/resources folder, open application.properties and write these lines.

spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
spring.datasource.username= root
spring.datasource.password= 123456

spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update
  • spring.datasource.username & spring.datasource.password properties are the same as your database installation.
  • Spring Boot uses Hibernate for JPA implementation, we configure MySQL5InnoDBDialect for MySQL database
  • spring.jpa.hibernate.ddl-auto is used for database initialization. We set the value to update value so that a table will be created in the database automatically corresponding to defined data model. Any change to the model will also trigger an update to the table. For production, this property should be validate.

Define Data Model

Our Data model is Tutorial with four fields: id, title, description, published.
In model package, we define Tutorial class.

model/Tutorial.java

package com.bezkoder.spring.files.excel.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tutorials")
public class Tutorial {

  @Id
  @Column(name = "id")
  private long id;

  @Column(name = "title")
  private String title;

  @Column(name = "description")
  private String description;

  @Column(name = "published")
  private boolean published;

  public Tutorial() {

  }

  public Tutorial(String title, String description, boolean published) {
    this.title = title;
    this.description = description;
    this.published = published;
  }

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public boolean isPublished() {
    return published;
  }

  public void setPublished(boolean isPublished) {
    this.published = isPublished;
  }

  @Override
  public String toString() {
    return "Tutorial [id=" + id + ", title=" + title + ", desc=" + description + ", published=" + published + "]";
  }
}

@Entity annotation indicates that the class is a persistent Java class.
@Table annotation provides the table that maps this entity.
@Id annotation is for the primary key.
@Column annotation is used to define the column in database that maps annotated field.

Create Data Repository for working with Database

Let’s create a repository to interact with Tutorials from the database.
In repository package, create TutorialRepository interface that extends JpaRepository.

repository/TutorialRepository.java

package com.bezkoder.spring.files.excel.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.bezkoder.spring.files.excel.model.Tutorial;

public interface TutorialRepository extends JpaRepository<Tutorial, Long> {
}

Now we can use JpaRepository’s methods: save(), findOne(), findById(), findAll(), count(), delete(), deleteById()… without implementing these methods.

The quantity of rows in Excel file (also tutorials table) could be large, so you may want to get only several at once by modifying this Repository to work with Pagination, the instruction can be found at:
Spring Boot Pagination & Filter example | Spring JPA, Pageable

Implement Excel Helper Class

We’re gonna use Apache POI classes such as: Workbook, Sheet, Row, Cell.
Let me summarize the steps for writing to Excel file:

  • create a new Workbook
  • create a new Sheet using Workbook.createSheet()
  • iterate over tutorials list
  • for each Tutorial, create a Row using Sheet.createRow()
  • create Cell using Row.createCell(), then use Cell.setCellValue()
  • use Workbook.write() to write out ByteArrayOutputStream
Workbook workbook = new XSSFWorkbook();
Sheet sheet = Workbook.createSheet(SHEET);

for (Tutorial tutorial : tutorials) {
  Row row = sheet.createRow(rowIdx++);

  row.createCell(0).setCellValue(tutorial.getId());
  row.createCell(1).setCellValue(tutorial.getTitle());
  row.createCell(2).setCellValue(tutorial.getDescription());
  row.createCell(3).setCellValue(tutorial.isPublished());
}

ByteArrayOutputStream out = new ByteArrayOutputStream();
workbook.write(out);
return new ByteArrayInputStream(out.toByteArray());

Under helper package, we create ExcepHelper class with tutorialsToExcel() method which processes a list of Tutorials, return a ByteArrayInputStream for Excel file later.

Here is full code of helper/ExcelHelper.java:

package com.bezkoder.spring.files.excel.helper;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

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;

import com.bezkoder.spring.files.excel.model.Tutorial;

public class ExcelHelper {
  public static String TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  static String[] HEADERs = { "Id", "Title", "Description", "Published" };
  static String SHEET = "Tutorials";

  public static ByteArrayInputStream tutorialsToExcel(List<Tutorial> tutorials) {

    try (Workbook workbook = new XSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
      Sheet sheet = workbook.createSheet(SHEET);

      // Header
      Row headerRow = sheet.createRow(0);

      for (int col = 0; col < HEADERs.length; col++) {
        Cell cell = headerRow.createCell(col);
        cell.setCellValue(HEADERs[col]);
      }

      int rowIdx = 1;
      for (Tutorial tutorial : tutorials) {
        Row row = sheet.createRow(rowIdx++);

        row.createCell(0).setCellValue(tutorial.getId());
        row.createCell(1).setCellValue(tutorial.getTitle());
        row.createCell(2).setCellValue(tutorial.getDescription());
        row.createCell(3).setCellValue(tutorial.isPublished());
      }

      workbook.write(out);
      return new ByteArrayInputStream(out.toByteArray());
    } catch (IOException e) {
      throw new RuntimeException("fail to import data to Excel file: " + e.getMessage());
    }
  }
}

Create Excel File Service

ExcelService class will be annotated with @Service annotation, it uses ExcelHelper and TutorialRepository in load() method which read data from database and return ByteArrayInputStream.

service/ExcelService.java

package com.bezkoder.spring.files.excel.service;

import java.io.ByteArrayInputStream;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bezkoder.spring.files.excel.helper.ExcelHelper;
import com.bezkoder.spring.files.excel.model.Tutorial;
import com.bezkoder.spring.files.excel.repository.TutorialRepository;

@Service
public class ExcelService {
  @Autowired
  TutorialRepository repository;

  public ByteArrayInputStream load() {
    List<Tutorial> tutorials = repository.findAll();

    ByteArrayInputStream in = ExcelHelper.tutorialsToExcel(tutorials);
    return in;
  }

}

Create Controller for Excel File Download

In controller package, we create ExcelController class for Rest Apis.
@CrossOrigin is for configuring allowed origins.
@Controller annotation indicates that this is a controller.
@GetMappinggetFile() method.
– We also use @Autowired to inject implementation of ExcelService bean to local variable.

controller/ExcelController.java

package com.bezkoder.spring.files.excel.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.bezkoder.spring.files.excel.service.ExcelService;

@CrossOrigin("http://localhost:8081")
@Controller
@RequestMapping("/api/excel")
public class ExcelController {

  @Autowired
  ExcelService fileService;

  @GetMapping("/download")
  public ResponseEntity<Resource> getFile() {
    String filename = "tutorials.xlsx";
    InputStreamResource file = new InputStreamResource(fileService.load());

    return ResponseEntity.ok()
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename)
        .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
        .body(file);
  }

}

Run the Spring Boot Download Excel File App

Run Spring Boot application with command: mvn spring-boot:run.

Conclusion

Today we’ve built a Rest API using Spring Boot to download Excel file that contains table data in MySQL database.

We also see how to use Apache POI to write data to Excel Sheet, JpaRepository to retrieve items in database table without need of boilerplate code.

If you want to add Pagination to this Spring project, you can find the instruction at:
Spring Boot Pagination & Filter example | Spring JPA, Pageable

You can also find how to upload Excel File to the Spring Server & store data in MySQL Database in the post:
Spring Boot: Upload/Import Excel file data into MySQL Database

For CSV file instead:
Spring Boot Download CSV file from Database example

Happy learning! See you again.

Further Reading

  • Spring Data JPA Reference Documentation
  • https://github.com/apache/poi

Deployment:
– Deploy Spring Boot App on AWS – Elastic Beanstalk
– Docker Compose: Spring Boot and MySQL example

Source Code

You can find the complete source code for this tutorial on Github.

5.1. Books

Create Book POJO:

src/main/java/example/micronaut/Book.java

package example.micronaut;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Introspected;

import javax.validation.constraints.NotBlank;

@Introspected
public class Book {
    @NonNull
    @NotBlank
    private final String isbn;

    @NonNull
    @NotBlank
    private final String name;

    public Book(@NonNull @NotBlank String isbn, @NonNull @NotBlank String name) {
        this.isbn = isbn;
        this.name = name;
    }

    @NonNull
    public String getIsbn() {
        return isbn;
    }

    @NonNull
    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Book book = (Book) o;

        if (!isbn.equals(book.isbn)) return false;
        return name.equals(book.name);
    }

    @Override
    public int hashCode() {
        int result = isbn.hashCode();
        result = 31 * result + name.hashCode();
        return result;
    }
}

Create an interface to encapsulate Book retrieval.

src/main/java/example/micronaut/BookRepository.java

package example.micronaut;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.context.annotation.DefaultImplementation;

import java.util.List;

@DefaultImplementation(BookRepositoryImpl.class)
public interface BookRepository {

    @NonNull
    List<Book> findAll();
}

Create a bean which implements the previous interface:

src/main/java/example/micronaut/BookRepositoryImpl.java

package example.micronaut;

import io.micronaut.core.annotation.NonNull;
import jakarta.inject.Singleton;

import java.util.Arrays;
import java.util.List;

@Singleton (1)
public class BookRepositoryImpl implements BookRepository {

    @NonNull
    @Override
    public List<Book> findAll() {
        return Arrays.asList(
                new Book("1491950358", "Building Microservices"),
                new Book("1680502395", "Release It!"),
                new Book("0321601912", "Continuous Delivery:"));
    }
}
1 Use jakarta.inject.Singleton to designate a class as a singleton.

5.2. Spreadsheet Builder

Spreadsheet builder provides convenient way how to read and create MS Excel OfficeOpenXML Documents (XSLX) focus not only on content side but also on easy styling.

pom.xml

<dependency>
    <groupId>builders.dsl</groupId>
    <artifactId>spreadsheet-builder-poi:2.2.1</artifactId>
    <scope>compile</scope>
</dependency>

5.3. Excel Creation

Create a interface to encapsulate Excel generation:

src/main/java/example/micronaut/BookExcelService.java

package example.micronaut;

import java.util.List;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.context.annotation.DefaultImplementation;
import io.micronaut.http.server.types.files.SystemFile;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

@DefaultImplementation(BookExcelServiceImpl.class)
public interface BookExcelService {
    String SHEET_NAME = "Books";
    String HEADER_ISBN = "Isbn";
    String HEADER_NAME = "Name";
    String HEADER_EXCEL_FILE_SUFIX = ".xlsx";
    String HEADER_EXCEL_FILE_PREFIX = "books";
    String HEADER_EXCEL_FILENAME = HEADER_EXCEL_FILE_PREFIX + HEADER_EXCEL_FILE_SUFIX;

    @NonNull
    SystemFile excelFileFromBooks(@NonNull @NotNull List<@Valid Book> bookList); (1)
}
1 SystemFile is specified as the return type of a route execution to indicate the given file should be downloaded by the client instead of displayed.

Externalize your styles configuration into a class implementing builders.dsl.spreadsheet.builder.api.Stylesheet interface to maximize code reuse.

src/main/java/example/micronaut/BookExcelStylesheet.java

package example.micronaut;

import builders.dsl.spreadsheet.api.FontStyle;
import builders.dsl.spreadsheet.builder.api.CanDefineStyle;
import builders.dsl.spreadsheet.builder.api.Stylesheet;

public class BookExcelStylesheet implements Stylesheet {
    public static final String STYLE_HEADER = "header";

    @Override
    public void declareStyles(CanDefineStyle stylable) {
        stylable.style(STYLE_HEADER, st -> {
            st.font(f -> f.style(FontStyle.BOLD));
        });
    }
}

Create a bean which generates the Excel file.

src/main/java/example/micronaut/BookExcelServiceImpl.java

package example.micronaut;

import builders.dsl.spreadsheet.builder.poi.PoiSpreadsheetBuilder;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
import io.micronaut.http.server.types.files.SystemFile;
import jakarta.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Stream;

@Singleton (1)
public class BookExcelServiceImpl implements BookExcelService {

    private static final Logger LOG = LoggerFactory.getLogger(BookExcelServiceImpl.class);

    @NonNull
    public SystemFile excelFileFromBooks(@NonNull @NotNull List<@Valid Book> bookList) {
        try {
            File file = File.createTempFile(HEADER_EXCEL_FILE_PREFIX, HEADER_EXCEL_FILE_SUFIX);
            PoiSpreadsheetBuilder.create(file).build(w -> {
                w.apply(BookExcelStylesheet.class);
                w.sheet(SHEET_NAME, s -> {
                    s.row(r -> Stream.of(HEADER_ISBN, HEADER_NAME)
                            .forEach(header -> r.cell(cd -> {
                                    cd.value(header);
                                    cd.style(BookExcelStylesheet.STYLE_HEADER);
                                })
                            ));
                    for (Book book : bookList) {
                        s.row(r -> {
                            r.cell(book.getIsbn());
                            r.cell(book.getName());
                        });
                    }
                });
            });
            return new SystemFile(file).attach(HEADER_EXCEL_FILENAME);
        } catch (IOException e) {
            LOG.error("File not found exception raised when generating excel file");
        }
        throw new HttpStatusException(HttpStatus.SERVICE_UNAVAILABLE, "error generating excel file");
    }
}
1 Use jakarta.inject.Singleton to designate a class as a singleton.

5.4. Controller

5.5. Views

Although the Micronaut framework is primarily designed around message encoding / decoding, there are occasions where it is convenient to render a view on the server side.

To use the Thymeleaf Java template engine to render views in a Micronaut application, add the following dependency on your classpath.

pom.xml

<dependency>
    <groupId>io.micronaut.views</groupId>
    <artifactId>micronaut-views-thymeleaf</artifactId>
    <scope>compile</scope>
</dependency>

Create a controller:

src/main/java/example/micronaut/HomeController.java

package example.micronaut;

import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.server.types.files.SystemFile;
import io.micronaut.views.View;

import java.util.HashMap;
import java.util.Map;

@Controller (1)
public class HomeController {

    private final BookRepository bookRepository;
    private final BookExcelService bookExcelService;

    public HomeController(BookRepository bookRepository,  (2)
                          BookExcelService bookExcelService) {
        this.bookRepository = bookRepository;
        this.bookExcelService = bookExcelService;
    }

    @View("index") (3)
    @Get
    public Map<String, String> index() {
        return new HashMap<>();
    }

    @Produces(value = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    @Get("/excel") (4)
    public SystemFile excel() { (5)
        return bookExcelService.excelFileFromBooks(bookRepository.findAll());
    }
}
1 The class is defined as a controller with the @Controller annotation mapped to the path /.
2 Constructor injection
3 Use @View annotation to specify which template to use to render the response.
4 You can specify the HTTP verb that a controller action responds to. To respond to a GET request, use io.micronaut.http.annotation.Get
5 SystemFile is specified as the return type of a route execution to indicate the given file should be downloaded by the client instead of displayed.

The previous controller index method renders a simple view with a link to download the Excel file:

src/main/resources/views/index.html

<!DOCTYPE html>
<html>
<head>
    <title>Micronaut</title>
</head>
<body>
<p><a href="/excel">Excel</a></p>
</body>
</html>

5.6. Tests

Often, file transfers remain untested in many applications. In this section, you will see how easy is to test that the
file downloads but also that the downloaded file contents match our expectations.

Create a test to verify the Excel file is downloaded and the content matches our expectations.

src/test/java/example/micronaut/DownloadExcelTest.java

package example.micronaut;

import builders.dsl.spreadsheet.query.api.SpreadsheetCriteria;
import builders.dsl.spreadsheet.query.api.SpreadsheetCriteriaResult;
import builders.dsl.spreadsheet.query.poi.PoiSpreadsheetCriteria;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import jakarta.inject.Inject;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import static org.junit.jupiter.api.Assertions.assertEquals;

@MicronautTest (1)
class DownloadExcelTest {

    @Inject
    @Client("/")
    HttpClient client; (2)

    @Test
    public void booksCanBeDownloadedAsAnExcelFile() throws FileNotFoundException {
        HttpRequest<?> request = HttpRequest.GET("/excel")
                .accept("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); (3)
        HttpResponse<byte[]> response = client.toBlocking().exchange(request, byte[].class);

        assertEquals(HttpStatus.OK, response.getStatus());

        InputStream inputStream = new ByteArrayInputStream(response.body()); (4)
        SpreadsheetCriteria query = PoiSpreadsheetCriteria.FACTORY.forStream(inputStream);
        SpreadsheetCriteriaResult result = query.query(workbookCriterion -> {
            workbookCriterion.sheet(BookExcelService.SHEET_NAME, sheetCriterion ->
                    sheetCriterion.row(rowCriterion ->
                            rowCriterion.cell(cellCriterion -> cellCriterion.value("Building Microservices"))));
        });

        assertEquals(1, result.getCells().size());
    }
}
1 Annotate the class with @MicronautTest so the Micronaut framework will initialize the application context and the embedded server. More info.
2 Inject the HttpClient bean and point it to the embedded server.
3 Creating HTTP Requests is easy thanks to the Micronaut framework fluid API.
4 Use .body() to retrieve the excel bytes.

Learn to read excel, write excel, evaluate formula cells and apply custom formatting to the generated excel files using Apache POI library with examples.

If we are building software for the HR or Finance domain, there is usually a requirement for generating excel reports across management levels. Apart from reports, we can also expect some input data for the applications coming in the form of excel sheets and the application is expected to support this requirement.

Apache POI is a well-trusted library among many other open-source libraries to handle such usecases involving excel files. Please note that, in addition, we can read and write MS Word and MS PowerPoint files also using the Apache POI library.

This Apache POI tutorial will discuss some everyday excel operations in real-life applications.

  1. 1. Maven Dependency
  2. 2. Important Classes in POI Library
  3. 3. Writing an Excel File
  4. 4. Reading an Excel File
  5. 5. Add and Evaluate Formula Cells
  6. 6. Formatting the Cells
  7. 7. Conclusion

1. Maven Dependency

If we are working on a maven project, we can include the Apache POI dependencies in pom.xml file using this:

<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. Important Classes in POI Library

  1. HSSF, XSSF and XSSF classes

    Apache POI main classes usually start with either HSSF, XSSF or SXSSF.

    • HSSF – is the POI Project’s pure Java implementation of the Excel 97(-2007) file format. e.g., HSSFWorkbook, HSSFSheet.
    • XSSF – is the POI Project’s pure Java implementation of the Excel 2007 OOXML (.xlsx) file format. e.g., XSSFWorkbook, XSSFSheet.
    • SXSSF (since 3.8-beta3) – is an API-compatible streaming extension of XSSF to be used when huge spreadsheets have to be produced and heap space is limited. e.g., SXSSFWorkbook, SXSSFSheet. SXSSF achieves its low memory footprint by limiting access to the rows within a sliding window, while XSSF gives access to all rows in the document.
  2. Row and Cell

    Apart from the above classes, Row and Cell interact with a particular row and a particular cell in an excel sheet.

  3. Styling Related Classes

    A wide range of classes like CellStyle, BuiltinFormats, ComparisonOperator, ConditionalFormattingRule, FontFormatting, IndexedColors, PatternFormatting, SheetConditionalFormatting etc. are used when you have to add formatting to a sheet, primarily based on some rules.

  4. FormulaEvaluator

    Another helpful class FormulaEvaluator is used to evaluate the formula cells in an excel sheet.

3. Writing an Excel File

I am taking this example first so we can reuse the excel sheet created by this code in further examples.

Writing excel using POI is very simple and involves the following steps:

  1. Create a workbook
  2. Create a sheet in workbook
  3. Create a row in sheet
  4. Add cells to sheet
  5. Repeat steps 3 and 4 to write more data

It seems very simple, right? Let’s have a look at the code doing these steps.

Java program to write an excel file using Apache POI library.

package com.howtodoinjava.demo.poi;
//import statements
public class WriteExcelDemo 
{
    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)
        {
            Row row = sheet.createRow(rownum++);
            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("howtodoinjava_demo.xlsx"));
            workbook.write(out);
            out.close();
            System.out.println("howtodoinjava_demo.xlsx written successfully on disk.");
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }
}
poi-demo-write-file

See Also: Appending Rows to Excel

4. Reading an Excel File

Reading an excel file using POI is also very simple if we divide this into steps.

  1. Create workbook instance from an excel sheet
  2. Get to the desired sheet
  3. Increment row number
  4. iterate over all cells in a row
  5. repeat steps 3 and 4 until all data is read

Let’s see all the above steps in code. I am writing the code to read the excel file created in the above example. It will read all the column names and the values in it – cell by cell.

Java program to read an excel file using Apache POI library.

package com.howtodoinjava.demo.poi;
//import statements
public class ReadExcelDemo 
{
    public static void main(String[] args) 
    {
        try
        {
            FileInputStream file = new FileInputStream(new File("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();
        }
    }
}

Program Output:

ID      NAME        LASTNAME
1.0     Amit        Shukla  
2.0     Lokesh      Gupta   
3.0     John        Adwards 
4.0     Brian       Schultz 

See Also: Apache POI – Read an Excel File using SAX Parser

5. Add and Evaluate Formula Cells

When working on complex excel sheets, we encounter many cells with formulas to calculate their values. These are formula cells. Apache POI also has excellent support for adding formula cells and evaluating already present formula cells.

Let’s see one example of how to add formula cells in excel?

The sheet has four cells in a row and the fourth one in the multiplication of all the previous 3 rows. So the formula will be: A2*B2*C2 (in the second row)

Java program to add formula in an excel file using Apache POI library.

public static void main(String[] args) 
{
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("Calculate Simple Interest");
  
    Row header = sheet.createRow(0);
    header.createCell(0).setCellValue("Pricipal");
    header.createCell(1).setCellValue("RoI");
    header.createCell(2).setCellValue("T");
    header.createCell(3).setCellValue("Interest (P r t)");
      
    Row dataRow = sheet.createRow(1);
    dataRow.createCell(0).setCellValue(14500d);
    dataRow.createCell(1).setCellValue(9.25);
    dataRow.createCell(2).setCellValue(3d);
    dataRow.createCell(3).setCellFormula("A2*B2*C2");
      
    try {
        FileOutputStream out =  new FileOutputStream(new File("formulaDemo.xlsx"));
        workbook.write(out);
        out.close();
        System.out.println("Excel with foumula cells written successfully");
          
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Similarly, we want to read a file with formula cells and use the following logic to evaluate formula cells.

Java program to evaluate formula in an excel file using Apache POI library.

public static void readSheetWithFormula()
{
    try
    {
        FileInputStream file = new FileInputStream(new File("formulaDemo.xlsx"));
 
        //Create Workbook instance holding reference to .xlsx file
        XSSFWorkbook workbook = new XSSFWorkbook(file);
 
        FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
         
        //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 after eveluating formulae
                //If it is formula cell, it will be evaluated otherwise no change will happen
                switch (evaluator.evaluateInCell(cell).getCellType()) 
                {
                    case Cell.CELL_TYPE_NUMERIC:
                        System.out.print(cell.getNumericCellValue() + "tt");
                        break;
                    case Cell.CELL_TYPE_STRING:
                        System.out.print(cell.getStringCellValue() + "tt");
                        break;
                    case Cell.CELL_TYPE_FORMULA:
                        //Not again
                        break;
                }
            }
            System.out.println("");
        }
        file.close();
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
}

Program Output:

Pricipal        RoI         T       Interest (P r t)        
14500.0         9.25        3.0     402375.0  
poi-demo-write-formula

6. Formatting the Cells

So far we have seen examples of reading/writing and excel files using Apache POI. But, when creating a report in an excel file, it is essential to add formatting on cells that fit into any pre-determined criteria.

This formatting can be a different coloring based on a specific value range, expiry date limit etc.

In the below examples, we are taking a couple of such cell formatting examples for various purposes.

6.1. Cell value in a specific range

This code will color any cell in a range whose value is between a configured range. [e.g., between 50 and 70]

static void basedOnValue(Sheet sheet) 
{
    //Creating some random values
    sheet.createRow(0).createCell(0).setCellValue(84);
    sheet.createRow(1).createCell(0).setCellValue(74);
    sheet.createRow(2).createCell(0).setCellValue(50);
    sheet.createRow(3).createCell(0).setCellValue(51);
    sheet.createRow(4).createCell(0).setCellValue(49);
    sheet.createRow(5).createCell(0).setCellValue(41);
 
    SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
 
    //Condition 1: Cell Value Is   greater than  70   (Blue Fill)
    ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.GT, "70");
    PatternFormatting fill1 = rule1.createPatternFormatting();
    fill1.setFillBackgroundColor(IndexedColors.BLUE.index);
    fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
 
    //Condition 2: Cell Value Is  less than      50   (Green Fill)
    ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.LT, "50");
    PatternFormatting fill2 = rule2.createPatternFormatting();
    fill2.setFillBackgroundColor(IndexedColors.GREEN.index);
    fill2.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
 
    CellRangeAddress[] regions = {
            CellRangeAddress.valueOf("A1:A6")
    };
 
    sheetCF.addConditionalFormatting(regions, rule1, rule2);
}
poi-demo-formatting-1

6.2. Highlight Duplicate Values

Highlight all cells which have duplicate values in observed cells.

static void formatDuplicates(Sheet sheet) {
    sheet.createRow(0).createCell(0).setCellValue("Code");
    sheet.createRow(1).createCell(0).setCellValue(4);
    sheet.createRow(2).createCell(0).setCellValue(3);
    sheet.createRow(3).createCell(0).setCellValue(6);
    sheet.createRow(4).createCell(0).setCellValue(3);
    sheet.createRow(5).createCell(0).setCellValue(5);
    sheet.createRow(6).createCell(0).setCellValue(8);
    sheet.createRow(7).createCell(0).setCellValue(0);
    sheet.createRow(8).createCell(0).setCellValue(2);
    sheet.createRow(9).createCell(0).setCellValue(8);
    sheet.createRow(10).createCell(0).setCellValue(6);
 
    SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
 
    // Condition 1: Formula Is   =A2=A1   (White Font)
    ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($A$2:$A$11,A2)>1");
    FontFormatting font = rule1.createFontFormatting();
    font.setFontStyle(false, true);
    font.setFontColorIndex(IndexedColors.BLUE.index);
 
    CellRangeAddress[] regions = {
            CellRangeAddress.valueOf("A2:A11")
    };
 
    sheetCF.addConditionalFormatting(regions, rule1);
 
    sheet.getRow(2).createCell(1).setCellValue("<== Duplicates numbers in the column are highlighted.  " +
            "Condition: Formula Is =COUNTIF($A$2:$A$11,A2)>1   (Blue Font)");
}
poi-demo-formatting-2

6.3. Alternate Color Rows in Different Colors

A simple code to color each alternate row in a different color.

static void shadeAlt(Sheet sheet) {
    SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
 
    // Condition 1: Formula Is   =A2=A1   (White Font)
    ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("MOD(ROW(),2)");
    PatternFormatting fill1 = rule1.createPatternFormatting();
    fill1.setFillBackgroundColor(IndexedColors.LIGHT_GREEN.index);
    fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
 
    CellRangeAddress[] regions = {
            CellRangeAddress.valueOf("A1:Z100")
    };
 
    sheetCF.addConditionalFormatting(regions, rule1);
 
    sheet.createRow(0).createCell(1).setCellValue("Shade Alternating Rows");
    sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is  =MOD(ROW(),2)   (Light Green Fill)");
}
poi-demo-formatting-3

6.4. Color amounts that are going to expire in the next 30 days

A handy code for financial projects which keeps track of deadlines.

static void expiryInNext30Days(Sheet sheet) 
{
    CellStyle style = sheet.getWorkbook().createCellStyle();
    style.setDataFormat((short)BuiltinFormats.getBuiltinFormat("d-mmm"));
 
    sheet.createRow(0).createCell(0).setCellValue("Date");
    sheet.createRow(1).createCell(0).setCellFormula("TODAY()+29");
    sheet.createRow(2).createCell(0).setCellFormula("A2+1");
    sheet.createRow(3).createCell(0).setCellFormula("A3+1");
 
    for(int rownum = 1; rownum <= 3; rownum++) sheet.getRow(rownum).getCell(0).setCellStyle(style);
 
    SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
 
    // Condition 1: Formula Is   =A2=A1   (White Font)
    ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("AND(A2-TODAY()>=0,A2-TODAY()<=30)");
    FontFormatting font = rule1.createFontFormatting();
    font.setFontStyle(false, true);
    font.setFontColorIndex(IndexedColors.BLUE.index);
 
    CellRangeAddress[] regions = {
            CellRangeAddress.valueOf("A2:A4")
    };
 
    sheetCF.addConditionalFormatting(regions, rule1);
 
    sheet.getRow(0).createCell(1).setCellValue("Dates within the next 30 days are highlighted");
}
poi-demo-formatting-4

I am ending this apache poi tutorial here to keep the post within a limit.

7. Conclusion

In this tutorial, we learned to read excel, write excel, set and evaluate formula cells, and format the cells with color codings using the Apache POI library.

Happy Learning !!

Source Code on Github

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 
  • 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).

 

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:

Books Excel File

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.

Add comment

Понравилась статья? Поделить с друзьями:
  • Download excel and word for free
  • Download excel 2016 for windows 10
  • Download excel 2013 free download
  • Downloading data into excel
  • Download excel 2010 for windows 10