Creating excel file java

I’ve created the API «generator-excel» to create an Excel file, below the dependecy:

<dependency>
  <groupId>com.github.bld-commons.excel</groupId>
  <artifactId>generator-excel</artifactId>
  <version>3.1.0</version>
</dependency>

This library can to configure the styles, the functions, the charts, the pivot table and etc. through a series of annotations.
You can write rows by getting data from a datasource trough a query with or without parameters.
Below an example to develop

  1. I created 2 classes that represents the row of the table.
  2. package bld.generator.report.junit.entity;
        
        import java.util.Date;
        
        import org.apache.poi.ss.usermodel.HorizontalAlignment;
        
        import bld.generator.report.excel.RowSheet;
        import bld.generator.report.excel.annotation.ExcelCellLayout;
        import bld.generator.report.excel.annotation.ExcelColumn;
        import bld.generator.report.excel.annotation.ExcelDate;
        import bld.generator.report.excel.annotation.ExcelImage;
        import bld.generator.report.excel.annotation.ExcelRowHeight;
        
        @ExcelRowHeight(height = 3)
        public class UtenteRow implements RowSheet {
            
            @ExcelColumn(columnName = "Id", indexColumn = 0)
            @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.RIGHT)
            private Integer idUtente; 
            @ExcelColumn(columnName = "Nome", indexColumn = 2)
            @ExcelCellLayout
            private String nome; 
            @ExcelColumn(columnName = "Cognome", indexColumn = 1)
            @ExcelCellLayout
            private String cognome;
            @ExcelColumn(columnName = "Data di nascita", indexColumn = 3)
            @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.CENTER)
            @ExcelDate
            private Date dataNascita;
            @ExcelColumn(columnName = "Immagine", indexColumn = 4)
            @ExcelCellLayout
            @ExcelImage(resizeHeight = 0.7, resizeWidth = 0.6)
            private byte[] image;   
            
            @ExcelColumn(columnName = "Path", indexColumn = 5)
            @ExcelCellLayout
            @ExcelImage(resizeHeight = 0.7, resizeWidth = 0.6)
            private String path;    
            
        
            public UtenteRow() {
            }
        
        
            public UtenteRow(Integer idUtente, String nome, String cognome, Date dataNascita) {
                super();
                this.idUtente = idUtente;
                this.nome = nome;
                this.cognome = cognome;
                this.dataNascita = dataNascita;
            }
        
        
            public Integer getIdUtente() {
                return idUtente;
            }
        
        
            public void setIdUtente(Integer idUtente) {
                this.idUtente = idUtente;
            }
        
        
            public String getNome() {
                return nome;
            }
        
        
            public void setNome(String nome) {
                this.nome = nome;
            }
        
        
            public String getCognome() {
                return cognome;
            }
        
        
            public void setCognome(String cognome) {
                this.cognome = cognome;
            }
        
        
            public Date getDataNascita() {
                return dataNascita;
            }
        
        
            public void setDataNascita(Date dataNascita) {
                this.dataNascita = dataNascita;
            }
        
        
            public byte[] getImage() {
                return image;
            }
        
        
            public String getPath() {
                return path;
            }
        
        
            public void setImage(byte[] image) {
                this.image = image;
            }
        
        
            public void setPath(String path) {
                this.path = path;
            }
        
        }
    

    package bld.generator.report.junit.entity;
    
    import org.apache.poi.ss.usermodel.DataConsolidateFunction;
    import org.apache.poi.ss.usermodel.HorizontalAlignment;
    
    import bld.generator.report.excel.RowSheet;
    import bld.generator.report.excel.annotation.ExcelCellLayout;
    import bld.generator.report.excel.annotation.ExcelColumn;
    import bld.generator.report.excel.annotation.ExcelFont;
    import bld.generator.report.excel.annotation.ExcelSubtotal;
    import bld.generator.report.excel.annotation.ExcelSubtotals;
    
    @ExcelSubtotals(labelTotalGroup = "Total",endLabel = "total")
    public class SalaryRow implements RowSheet {
    
        @ExcelColumn(columnName = "Name", indexColumn = 0)
        @ExcelCellLayout
        private String name;
        @ExcelColumn(columnName = "Amount", indexColumn = 1)
        @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.RIGHT)
        @ExcelSubtotal(dataConsolidateFunction = DataConsolidateFunction.SUM,excelCellLayout = @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.RIGHT,font=@ExcelFont(bold = true)))
        private Double amount;
        
        public SalaryRow() {
            super();
        }
        public SalaryRow(String name, Double amount) {
            super();
            this.name = name;
            this.amount = amount;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Double getAmount() {
            return amount;
        }
        public void setAmount(Double amount) {
            this.amount = amount;
        }
        
    }
    
  3. I created 2 class that represents the sheets.
  4. package bld.generator.report.junit.entity;
    
    import javax.validation.constraints.Size;
    
    import bld.generator.report.excel.QuerySheetData;
    import bld.generator.report.excel.annotation.ExcelHeaderLayout;
    import bld.generator.report.excel.annotation.ExcelMarginSheet;
    import bld.generator.report.excel.annotation.ExcelQuery;
    import bld.generator.report.excel.annotation.ExcelSheetLayout;
    
    @ExcelSheetLayout
    @ExcelHeaderLayout
    @ExcelMarginSheet(bottom = 1.5, left = 1.5, right = 1.5, top = 1.5)
    @ExcelQuery(select = "SELECT id_utente, nome, cognome, data_nascita,image,path "
            + "FROM utente "
            + "WHERE cognome=:cognome "
            + "order by cognome,nome")
    public class UtenteSheet extends QuerySheetData<UtenteRow> {
        
    
        public UtenteSheet(@Size(max = 31) String sheetName) {
            super(sheetName);
        }
    
        
    }
    

    package bld.generator.report.junit.entity;
    
    import javax.validation.constraints.Size;
    
    import bld.generator.report.excel.SheetData;
    import bld.generator.report.excel.annotation.ExcelHeaderLayout;
    import bld.generator.report.excel.annotation.ExcelMarginSheet;
    import bld.generator.report.excel.annotation.ExcelSheetLayout;
    @ExcelSheetLayout
    @ExcelHeaderLayout
    @ExcelMarginSheet(bottom = 1.5,left = 1.5,right = 1.5,top = 1.5)
    public class SalarySheet extends SheetData<SalaryRow> {
    
        public SalarySheet(@Size(max = 31) String sheetName) {
            super(sheetName);
        }
    
    }
    
  5. Class test, in the test function there are antoher sheets
  6. package bld.generator.report.junit;
    
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.List;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import bld.generator.report.excel.BaseSheet;
    import bld.generator.report.excel.GenerateExcel;
    import bld.generator.report.excel.data.ReportExcel;
    import bld.generator.report.junit.entity.AutoreLibriSheet;
    import bld.generator.report.junit.entity.CasaEditrice;
    import bld.generator.report.junit.entity.GenereSheet;
    import bld.generator.report.junit.entity.SalaryRow;
    import bld.generator.report.junit.entity.SalarySheet;
    import bld.generator.report.junit.entity.TotaleAutoreLibriRow;
    import bld.generator.report.junit.entity.TotaleAutoreLibriSheet;
    import bld.generator.report.junit.entity.UtenteSheet;
    import bld.generator.report.utils.ExcelUtils;
    
    /**
     * The Class ReportTest.
     */
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ConfigurationProperties
    @ComponentScan(basePackages = {"bld.generator","bld.read"})
    @EnableTransactionManagement
    public class ReportTestJpa {
    
        /** The Constant PATH_FILE. */
        private static final String PATH_FILE = "/mnt/report/";
    
        /** The generate excel. */
        @Autowired
        private GenerateExcel generateExcel;
    
        /**
         * Sets the up.
         *
         * @throws Exception the exception
         */
        @Before
        public void setUp() throws Exception {
        }
    
        /**
         * Test.
         *
         * @throws Exception the exception
         */
        @Test
        public void test() throws Exception {
            List<BaseSheet> listBaseSheet = new ArrayList<>();
            
            UtenteSheet utenteSheet=new UtenteSheet("Utente");
            utenteSheet.getMapParameters().put("cognome", "Rossi");
            listBaseSheet.add(utenteSheet);
            
            CasaEditrice casaEditrice = new CasaEditrice("Casa Editrice","Mondadori", new GregorianCalendar(1955, Calendar.MAY, 10), "Roma", "/home/francesco/Documents/git-project/dev-excel/linux.jpg","Drammatico");
            listBaseSheet.add(casaEditrice);
            
            
            AutoreLibriSheet autoreLibriSheet = new AutoreLibriSheet("Libri d'autore","Test label");
            TotaleAutoreLibriSheet totaleAutoreLibriSheet=new TotaleAutoreLibriSheet();
            totaleAutoreLibriSheet.getListRowSheet().add(new TotaleAutoreLibriRow("Totale"));
            autoreLibriSheet.setSheetFunctionsTotal(totaleAutoreLibriSheet);
            listBaseSheet.add(autoreLibriSheet);
            GenereSheet genereSheet=new GenereSheet("Genere");
            listBaseSheet.add(genereSheet);
            SalarySheet salarySheet=new SalarySheet("salary");
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            listBaseSheet.add(salarySheet);
            ReportExcel excel = new ReportExcel("Mondadori JPA", listBaseSheet);
    
            byte[] byteReport = this.generateExcel.createFileXlsx(excel);
    
            ExcelUtils.writeToFile(PATH_FILE,excel.getTitle(), ".xlsx", byteReport);
    
        }
    
        
    
    }
    
  7. Application yaml
  8. logging:
      level:
        root: WARN
        org:
          springframework:
            web: DEBUG
          hibernate: ERROR
    
    
    
    spring:
      datasource:
        url: jdbc:postgresql://localhost:5432/excel_db
        username: ${EXCEL_USER_DB}
        password: ${EXCEL_PASSWORD_DB}
      jpa:
        show-sql: true
        properties:
          hibernate:
            default_schema: public
            jdbc:
              lob:
                non_contextual_creation: true 
            format_sql: true    
            ddl-auto: auto
        database-platform: org.hibernate.dialect.PostgreSQLDialect
        generate-ddl: true
    

below the link of the project on github:

  • https://github.com/bld-commons/dev-excel

В прошлых двух статьях мы познакомились с библиотекой Apache POI, а также разобрались со считыванием данных из Excel документов в форматах .xls и .xlsx. Сегодня мы продолжим изучение возможностей этой библиотеки и попробуем создать новый Excel файл с формулами и стилями. Скачать проект Вы сможете в конце статьи.

Если Вы еще не знакомы с Apache POI, то рекомендую вкратце ознакомится с ее возможностями и способами ее подключения в проект по этой ссылке.

Внимание, код не очень красив и оптимизирован. Я хотел просто продемонстрировать возможности этой удобной библиотеки.

Для начала давайте создадим простой xls файл и запишем в него какие-то данные. А далее будем применять к нему стили и добавлять формулы.

Для удобной работы с данными нам потребуется дополнительный класс, который будет представлять собой модель данных, которую мы будем записывать в файл:

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

package ua.com.prologistic.model;

public class DataModel {

    private String name;

    private String surname;

    private String city;

    private Double salary;

    public DataModel() {

    }

    public DataModel(String name, String surname, String city, Double salary) {

        this.name = name;

        this.surname = surname;

        this.city = city;

        this.salary = salary;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getSurname() {

        return surname;

    }

    public void setSurname(String surname) {

        this.surname = surname;

    }

    public String getCity() {

        return city;

    }

    public void setCity(String city) {

        this.city = city;

    }

    public Double getSalary() {

        return salary;

    }

    public void setSalary(Double salary) {

        this.salary = salary;

    }

}

Как видим, это простой класс с полями для имени, фамилии, города и зарплаты какого-то человека.

Ниже представлен листинг класса, в котором создается сам Excel файл:

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

60

61

62

63

64

65

66

67

68

69

70

71

package ua.com.prologistic.excel;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.ss.usermodel.Row;

import ua.com.prologistic.model.DataModel;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.text.ParseException;

import java.util.ArrayList;

import java.util.List;

public class ExcelWorker {

    public static void main(String[] args) throws ParseException {

        // создание самого excel файла в памяти

        HSSFWorkbook workbook = new HSSFWorkbook();

        // создание листа с названием «Просто лист»

        HSSFSheet sheet = workbook.createSheet(«Просто лист»);

        // заполняем список какими-то данными

        List<DataModel> dataList = fillData();

        // счетчик для строк

        int rowNum = 0;

        // создаем подписи к столбцам (это будет первая строчка в листе Excel файла)

        Row row = sheet.createRow(rowNum);

        row.createCell(0).setCellValue(«Имя»);

        row.createCell(1).setCellValue(«Фамилия»);

        row.createCell(2).setCellValue(«Город»);

        row.createCell(3).setCellValue(«Зарплата»);

        // заполняем лист данными

        for (DataModel dataModel : dataList) {

            createSheetHeader(sheet, ++rowNum, dataModel);

        }

        // записываем созданный в памяти Excel документ в файл

        try (FileOutputStream out = new FileOutputStream(new File(«F:\Apache POI Excel File.xls»))) {

            workbook.write(out);

        } catch (IOException e) {

            e.printStackTrace();

        }

        System.out.println(«Excel файл успешно создан!»);

    }

    // заполнение строки (rowNum) определенного листа (sheet)

    // данными  из dataModel созданного в памяти Excel файла

    private static void createSheetHeader(HSSFSheet sheet, int rowNum, DataModel dataModel) {

        Row row = sheet.createRow(rowNum);

        row.createCell(0).setCellValue(dataModel.getName());

        row.createCell(1).setCellValue(dataModel.getSurname());

        row.createCell(2).setCellValue(dataModel.getCity());

        row.createCell(3).setCellValue(dataModel.getSalary());

    }

    // заполняем список рандомными данными

    // в реальных приложениях данные будут из БД или интернета

    private static List<DataModel> fillData() {

        List<DataModel> dataModels = new ArrayList<>();

        dataModels.add(new DataModel(«Howard», «Wolowitz», «Massachusetts», 90000.0));

        dataModels.add(new DataModel(«Leonard», «Hofstadter», «Massachusetts», 95000.0));

        dataModels.add(new DataModel(«Sheldon», «Cooper», «Massachusetts», 120000.0));

        return dataModels;

    }

}

Обратите внимание, что мы использовали try with resources — одну из особенностей Java 7. А это значит, что нам не нужно беспокоится о закрытии файла вручную. В Java 7 конструкцию try-catch-finally можно не использовать, так как ей на смену пришла try with resources, которая сама закрывает открытые файлы или потоки без вашего вмешательства.

После запуска приведенной выше программы, в корне проекта создастся файл с названием Apache POI Excel File.xls. Давайте посмотрим на его содержимое:

Apache POI Excel File.xls

Лист Excel файла называется «Просто лист», как мы и называли, а данные расположены правильно.

Добавление стилей в Excel документ на Java

Теперь давайте поупражняемся с обновлением файла, а именно добавлением стилей. Например, выделим имя столбцов из первой строки жирным.

Для этого нам понадобится еще один метод setBoldStyle():

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

private static void setBoldStyle() throws IOException {

        // получаем файл с диска

        FileInputStream file = new FileInputStream(new File(«F:\Apache POI Excel File.xls»));

        // считываем его в память

        HSSFWorkbook workbook = new HSSFWorkbook(file);

        // говорим, что хотим работать с первым листом

        HSSFSheet sheet = workbook.getSheetAt(0);

        // создаем шрифт

        HSSFFont font = workbook.createFont();

        // указываем, что хотим его видеть жирным

        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // создаем стиль для ячейки

        HSSFCellStyle style = workbook.createCellStyle();

        // и применяем к этому стилю жирный шрифт

        style.setFont(font);

        // получаем первую строку листа excel файла

        Row row = sheet.getRow(0);

        // проходим по всем ячейкам этой строки

        for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {

            // применяем созданный выше стиль к каждой ячейке

            row.getCell(i).setCellStyle(style);

        }

        // получаем доступ к excel файлу и обновляем его

        try (FileOutputStream out = new FileOutputStream(new File(«F:\Apache POI Excel File.xls»))) {

            workbook.write(out);

        } catch (IOException e) {

            e.printStackTrace();

        }

        System.out.println(«Excel файл успешно обновлен!»);

    }

Как видите, мы просто обходим все ячейки первой строки и применяем к ней стиль BOLD.

Результат выполнения этого кода представлен ниже:

excel file updated

С помощью Apache POI это делается быстро и удобно.

Добавление формул в Excel документ на Java

Теперь попробуем разобраться с добавлением формул с помощью Apache POI.

Apache POI не позволяет устанавливать в ячейки значения из знаком равно: «=».

Пример:

Можно делать так:

cell.setCellFormula(«D2+D3+D4»);

и вот так:

cell.setCellFormula(«SUM(D2:D4)»);

Но если Вы попробуете написать так:

cell.setCellFormula(«=D2*D3*D4»);

то вылетит exception с сообщением о недопустимой операции. Apache POI не позволяет работать с формулами таким образом.

И так, в теории мы подкованы, теперь добавим простую формулу. Для этого напишем еще один метод setFormula():

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

private static void setFormula() throws IOException {

        // получаем файл с диска

        FileInputStream file = new FileInputStream(new File(«F:\Apache POI Excel File.xls»));

        // считываем его в память

        HSSFWorkbook workbook = new HSSFWorkbook(file);

        // говорим, что хотим работать с первым листом

        HSSFSheet sheet = workbook.getSheetAt(0);

        // создаем 5ю строку листа excel файла

        // (сейчас она null, так как в ней нет никаких данных)

        Row row = sheet.createRow(4);

        // идем в 4ю ячейку строки и устанавливаем

        // формулу подсчета зарплат (столбец D)

        Cell sum = row.createCell(3);

        sum.setCellFormula(«D2+D3+D4»);

        // создаем шрифт

        HSSFFont font = workbook.createFont();

        // указываем, что хотим его видеть красным

        font.setColor(Font.COLOR_RED);

        // создаем стиль для ячейки

        HSSFCellStyle style = workbook.createCellStyle();

        // и применяем к этому стилю жирный шрифт

        style.setFont(font);

        sum.setCellStyle(style);

        // получаем доступ к excel файлу и обновляем его

        try (FileOutputStream out = new FileOutputStream(new File(«F:\Apache POI Excel File.xls»))) {

            workbook.write(out);

        } catch (IOException e) {

            e.printStackTrace();

        }

        System.out.println(«Excel файл успешно обновлен!»);

    }

В нем мы открываем файл, добавляем к нему еще одну строку с ячейкой для подсчета суммы зарплаты физиков. И да, выделяем ее красным цветом.

Результат выполнения представленного выше метода:

excel file updated with formula

Урок по созданию нового Excel файла в Java с помощью Apache POI подошел к концу. Скачать рабочий проект можно по этой ссылке.

Подробнее о считывании Excel файлов Вы найдете здесь.

Подписывайтесь на обновления и получайте новые уроки по Java и Android сразу на почту!

In Java, read excel file and write excel file is a bit tricky because excel worksheet has cells to store data. Java does not provide direct API to read or write Microsoft Excel or Word documents. We have to rely on the third-party library that is Apache POI. In this section, we will learn how to create an excel file in Java and how to write or insert data in the excel file using the Apache POI Java library.

Java Apache POI Library

Apache POI (Poor Obfuscation Implementation) is a Java API for reading and writing Microsoft Documents. It contains classes and interfaces. The Apache POI library provides two implementations for reading or writing 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.

Throughout this section, we have used HSSF implementation.

Create Excel File in Java

Follow the steps given below to create an excel file in Java.

Step 1: Create a Java project in eclipse. We have created a Java project with the name CreateExcelEile.

Step 2: Create a class with the name CreateExcelFileExample1 and write the code that we have written in CreateExcelFileExample1.java file.

Step 3: Download the Apache POI library (poi-3.17.jar).

Step 4: Add the Apache POI to the project. Right-click on the project -> Build Path -> Configure Build Path. It opens the Properties window for the current project.

Step 5: In the Properties window, click on the Add External JARs button.

Java Create Excel File

Step 6: Go to the path where the poi-3.17.jar file is located. Select the JAR file and click on the Open button. It adds the JAR file to the project. After that, click on the Apply and Close button to apply the changes.

Java Create Excel File

When we have done with all the above steps, the project structure looks like the following:

Java Create Excel File

Let’s understand the following code.

In the following program, we have used the Apache POI library to create an excel file. The library provides the class named HSSFWorkbook defined in the org.apache.poi.hssf.usermodel package.

CreateExcelFileExample1.java

Output:

Java Create Excel File

It creates a blank excel file at the specified location.

Java Create Excel File

Let’s create another Java program that creates an excel file.

CreateExcelFileExample2.java

Output:

Java Create Excel File

It creates a blank excel file at the specified location.

Java Create Excel File

Insert Data in the Excel File

Still, we have created a blank excel file. But it is not always necessary that create a blank excel file only. Some times we need to insert some data in the worksheet. Let’s see how to insert data in an excel file through a Java program.

CreateExcelFileExample3.java

Output:

Java Create Excel File

It creates an excel file at the specified location with the values that we have inserted using the setCellValue() method.

Java Create Excel File


In this tutorial, we will explore the Java spreadsheet support and learn how to create Microsoft Excel .xlsx spreadsheet files using java program. For handling Excel files, we need to make use of the well known Apache POI library. This tutorial has been updated for Java 17 and work with Apache POI modules.

Add Apache POI library into your project

The first step is adding the Apache POI library into your project.

If you are using Gradle, add the following dependency into your build.gradle file.

// https://mvnrepository.com/artifact/org.apache.poi/poi
implementation group: 'org.apache.poi', name: 'poi', version: '5.2.2'

If you are using Maven, add the following dependency into your pom.xml file.

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.2</version>
</dependency>

Issue with Java modules

Q. I am getting the exception “java.lang.module.FindException: Module SparseBitSet not found, required by org.apache.poi.poi”. How can I fix it?
Another similar exception you might come across is: “java.lang.module.FindException: Module commons.math3 not found, required by org.apache.poi.poi”.

Since you are using Java 9+ with modules, you need to set the module configuration correctly. First, make sure that your module-info.java contains the following lines to have your application access the org.apache.poi.poi module.

requires org.apache.poi.poi;

Then, we must allow the Apache poi module to access two if its dependencies. This needs to be added as a JVM argument. Add the following JVM argument into your project.

--add-opens=org.apache.poi.poi/com.zaxxer=ALL-UNNAMED 
--add-opens=org.apache.poi.poi/org.apache.commons.math3=ALL-UNNAMED"

Create Excel Workbook

The first thing to do when creating a spreadsheet file is creating a workbook. We will create an org.apache.poi.hssf.usermodel.HSSFWorkbook and then save it as an .xlsx file.

import java.io.File;
import java.io.OutputStream;
import java.nio.file.Files;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;

public class ExcelTutorial {

  public static void main(String[] args) throws Exception {
    ExcelTutorial excelTutorial = new ExcelTutorial();
    excelTutorial.createWorkbook();
  }

  private void createWorkbook() throws Exception {
    //Create a workbook
    try (Workbook wb = new HSSFWorkbook()) {
      //Add two sheets into the workbook
      wb.createSheet("My Excel Sheet 1");
      wb.createSheet("My Excel Sheet 2");
      //Save the workbook to a file
      try (OutputStream fileOut = Files.newOutputStream(new File("my_first_java_spreadsheet.xlsx").toPath())) {
        wb.write(fileOut);
      }
    }
  }

This will create a new file Excel file. We can open it on the MS Excel or any compatible spreadsheet program you have installed, including LibreOffice Calc, Google Sheet, etc. The following screenshot shows the Excel file opened with LibreOffice.

Java Excel Workbook

Excel workbook we have created with two sheets

Create Excel spreadsheet with actual data

Now that we have learned how to create Excel spreadsheet with sheets, let’s learn how to add tabular data into the sheets.

We can add rows into the sheets using the method sheet.createRow(rowIndex);. For each row, we can then set the value for each cell using the setCellValue(String); function. Let’s understand this better with the following example code.

import java.io.File;
import java.io.OutputStream;
import java.nio.file.Files;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.ss.usermodel.Workbook;

public class ExcelTutorial {

  public static void main(String[] args) throws Exception {
    ExcelTutorial excelTutorial = new ExcelTutorial();
    excelTutorial.createEmployeeSheet();
  }

  private void createEmployeeSheet() throws Exception {
    try (Workbook wb = new HSSFWorkbook()) {
      Sheet sheet = wb.createSheet("Building#1");
      //Create table header
      Row headerRow = sheet.createRow(0); //First row - Heading
      headerRow.createCell(0).setCellValue("Employee No.");
      headerRow.createCell(1).setCellValue("Name");
      headerRow.createCell(2).setCellValue("Department");
      headerRow.createCell(3, CellType.BOOLEAN).setCellValue("Promoted");
      //Add first employee
      Row firstEmployee = sheet.createRow(1); //Second row
      firstEmployee.createCell(0).setCellValue(1); //Giving numeric value to cell
      firstEmployee.createCell(1).setCellValue("Genuine Coder");
      firstEmployee.createCell(2).setCellValue("IT");
      firstEmployee.createCell(3).setCellValue(false); //Giving a boolean value to the cell
      //Add second employee
      Row secondEmployee = sheet.createRow(2); //Third row
      secondEmployee.createCell(0).setCellValue(2);
      secondEmployee.createCell(1).setCellValue("Anya");
      secondEmployee.createCell(2).setCellValue("IT");
      secondEmployee.createCell(3).setCellValue(true); //Giving a boolean value to the cell

      //Write workbook into file
      try (OutputStream fileOut = Files.newOutputStream(new File("employee_data.xlsx").toPath())) {
        wb.write(fileOut);
      }
    }
  }
}

We have created a new Excel file with the name employee_data.xlsx and two employees. For each employee, we have given numeric, string and boolean cell data. You can see the generated file in the below screenshot.

Java Excel Workbook with data

Java Excel Workbook With Worksheet and Data

Q. How to set background color of a row with Apache POI?

Now, let’s say we want to set the background color of the title. We need to set background color and text color for the entire first row.
Let’s see how we can do the styling per-cell for the entire header row. This way, in future if you would like to have customization within a row itself, it will be much easier.

private void applyStyleForRow(Row row) {
  //Create new style for the row
  CellStyle cellStyle = row.getSheet().getWorkbook().createCellStyle();
  //Configure single solid color fill
  cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  //Set font color
  cellStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
  //Set background color
  cellStyle.setFillBackgroundColor(IndexedColors.WHITE.getIndex());
  //Apply style for each cell
  row.forEach(cell -> cell.setCellStyle(cellStyle));
}

Java Spreadsheet with customized header

Spreadsheet with customized header

Q. How to change font with Apache POI?

Often we would want to change the font for particular rows or cells. This is also easily achievable with Apache POI. We can set font family, font weight and of course font size with style attribute. Let’s see how we can do that with a code example.

private void applyFontForRow(Row row) {
  Workbook workbook = row.getSheet().getWorkbook();

  //Create and style font
  Font font = workbook.createFont();
  //Set bold
  font.setBold(true);
  //Set font family
  font.setFontName("Roboto");
  //Set font size
  font.setFontHeightInPoints((short) 20);

  //Apply style for each cell
  CellStyle cellStyle = workbook.createCellStyle();
  cellStyle.setFont(font); //Attach font to style
  row.forEach(cell -> cell.setCellStyle(cellStyle));
}

We have customized the header font by using Bold Roboto Font of 20pt size. The generated file looks as shown below.

Java Spreadsheet with customized font

Spreadsheet with customized fonts

Conclusion

In this tutorial, we have learned how to create Excel spreadsheets in Java. We have seen how to create workbook with multiple sheets, adding contents to sheets, customizing font and background style of cells and rows. If you have liked this article, you might want to check some of my other tutorial articles given below.

  • Create desktop app using flutter
  • Using WebP images in Java

Афоризм

— Почему Вы не сделаете пластическую операцию?
— А толку! Фасад обновишь, а канализация все равно старая!

Фаина Раневская

Поддержка проекта

Если Вам сайт понравился и помог, то будем признательны за Ваш «посильный» вклад в его поддержку и развитие

 • Yandex.Деньги
  410013796724260

 • Webmoney
  R335386147728
  Z369087728698

Свойства и методы взаимодействия Java приложений с файлами Excel представлены на странице
библиотеки Apache POI. Здесь рассматриваются примеры использования
Apache POI для создания файлов Excel 2007 или более поздней версии. Если необходимо создать
Excel 1997-2003, то следует использовать классы, наименования которых начинаются с символа ‘H’.
Использование библиотеки Apache POI для чтения файлов Excel с примером рассмотрен
здесь.

Создание книги Excel

// Создание книги Excel
XSSFWorkbook book = new XSSFWorkbook();
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");

// создания страниц
// создание строк
// создание и форматирование ячеек
// запись информации в ячейки

// Закрытие
book.write(fileOut);
fileOut.close();

Создание страницы

XSSFSheet sheet2 = book.createSheet("Sheet 1");
XSSFSheet sheet3 = book.createSheet("Страница 2");

Наименование страницы не должно превышать 31 символ. Следующие символы недопустимы в
наименовании страницы :

   0x0 — нулевое значение;
   ‘:’ — двоеточие;
   » — обратный слэш;
   ‘/’ — прямой слэш;
   ‘*’ — «звездочка»;
   ‘?’ — вопросительный знак;
   ‘[‘ — открывающаяся квадратная скобка;
   ‘]’ — закрывающаяся квадратная скобка.

Можно использовать утилиту WorkbookUtil для получения наименования страницы книги. Метод
createSafeSheetName данной утилиты заменит «неправильные» символы на пробелы (‘ ‘).

import org.apache.poi.ss.util.WorkbookUtil;

String caption  = "[O'Brien's sales*?]";
String safeName = WorkbookUtil.createSafeSheetName(caption);

// safeName = " O'Brien's sales   ";
XSSFSheet sheet3 = book.createSheet(safeName);

Определение размера колонки

При определении размера колонки необходимо учитывать максимальное количество символов в колонке,
коэффициент размера символа для заданного шрифта (для «Sans Sherif» равен 1.14388) и коэффициент
EXCEL_COLUMN_WIDTH_FACTOR, равный 256. Метод autoSizeColumn(idx_column) позволяет автоматически
установить размер колонки по максимальному значению.

// Определение размера колонки
int width = (int) (6 * 1.14388) * 256; // 1757;
sheet.setColumnWidth(0, width);

// Автоматическая настройка размера колонки
sheet.autoSizeColumn(1);

Метод setColumnWidth(column, width) в качестве параметров принимает номер колонки (отсчет от 0) и
размер колонки. Методу autoSizeColumn(column) необходимо передать только номер колонки.

Создание строки

При создании строки в метод createRow в качестве параметра необходимо передать номер строки
(отсчет от 0). Для определения размера строки можно использовать методы setHeight (short) и
setHeightInPoints (float). При использовании метода setHeight также, как и с определением размера колонки,
необходимо учитывать коэффициенты. Поэтому метод setHeightInPoints оказывается более предпочтительным.

XSSFRow row = sheet.createRow((short)0);
row.setHeightInPoints(80.0f);

Создание ячейки, определение типа значения

В следующем примере создаются ячейки, устанавливается их тип и записываются значения.

XSSFCell cell = row.createCell(0);
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(1.2);

cell = row.createCell(1);
cell.setCellType(CellType.STRING);
cell.setCellValue("Строковое представление");

cell = row.createCell(2);
cell.setCellType(CellType.FORMULA);
cell.setCellValue("SUM(B3:B5)");

Класс CellType включает свойства [_NONE, BLANK, BOOLEAN, ERROR, FORMULA, NUMERIC, STRING],
которые можно использовать для определения типа значения ячейки.

Определение формата даты ячейки

В следующем примере создаются две ячейки с записью текущей даты. Вторая ячейка форматируется.

CreationHelper createHelper = book.getCreationHelper();

XSSFCellStyle cellStyle = book.createCellStyle();
cellStyle.setDataFormat(createHelper
                       .createDataFormat()
                       .getFormat("m/d/yy h:mm"));
XSSFCell cell = row.createCell(0);
cell.setCellValue(new Date());

cell = row.createCell(1);
cell.setCellStyle(cellStyle);
cell.setCellValue(new Date());

Слияние ячеек

Для слияния ячеек используется метод addMergedRegion.

// Создание строки
XSSFRow row = sheet.createRow((short) 1);

// Создание ячейки
XSSFCell cell = row.createCell((short) 1);
cell.setCellValue("This is a test of merging");

// Слияние 2-х ячеек в одной строке
sheet.addMergedRegion(
        new CellRangeAddress(1, // первая строка
                             1, // последняя строка
                             1, // первая колонка
                             2) // последняя колонка
);

Определение шрифта

// Создание шрифта
XSSFFont font = book.createFont();

font.setFontHeightInPoints((short)24);
font.setFontName("Courier New");
font.setItalic(true);
font.setStrikeout(true);
// цвет шрифта
font.setColor(new XSSFColor(new java.awt.Color(16,64,255)));

// Создание стиля с определением в нем шрифта
XSSFCellStyle style = book.createCellStyle();
style.setFont(font);

// Создание ячейки с определением ее стиля
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(1);
cell.setCellValue("Тестовый шрифт");
cell.setCellStyle(style);

Помните, что максимальное количество создаваемых шрифтов ограничено значением 32767. Необходимо
использовать объекты шрифтов/стилей.

// Неправильно
for (int i = 0; i < 100; i++) {
    XSSFRow row = sheet.createRow(i);
    for (int j = 0; j < 100; j++) {
        XSSFCell cell = row.createCell((short) j);

        XSSFCellStyle style = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setBold(true);
        style.setFont(font);
        cell.setCellStyle(style);
    }
}

// Правильно
XSSFFont font = workbook.createFont();
font.setBold(true);

XSSFCellStyle style = workbook.createCellStyle();
style.setFont(font);

for (int i = 0; i < 100; i++) {
    XSSFRow row = sheet.createRow(i);
    for (int j = 0; j < 100; j++) {
        XSSFCell cell = row.createCell((short) 0);
        cell.setCellStyle(style);
    }
}

Определение цвета фона ячейки

Color COLOR_light_gray  = new java.awt.Color(232, 232, 232);

XSSFCellStyle style = book.createCellStyle();

style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

style.setFillForegroundColor(new XSSFColor(COLOR_light_gray));

ПРИМЕЧАНИЕ : для выделения цвета значения настраивайте шрифт (см. выше).

Выравнивание значения

В следующем примере создаются ячейки с различным выравниванием значений по горизонтали и
вертикали.

createCell(wb, row, (short) 0, CellStyle.ALIGN_CENTER, 
                               CellStyle.VERTICAL_BOTTOM);
createCell(wb, row, (short) 1, CellStyle.ALIGN_CENTER_SELECTION,
                               CellStyle.VERTICAL_BOTTOM);
createCell(wb, row, (short) 2, CellStyle.ALIGN_FILL,
                               CellStyle.VERTICAL_CENTER);
createCell(wb, row, (short) 3, CellStyle.ALIGN_GENERAL,
                               CellStyle.VERTICAL_CENTER);
createCell(wb, row, (short) 4, CellStyle.ALIGN_JUSTIFY,
                               CellStyle.VERTICAL_JUSTIFY);
createCell(wb, row, (short) 5, CellStyle.ALIGN_LEFT,
                               CellStyle.VERTICAL_TOP);
createCell(wb, row, (short) 6, CellStyle.ALIGN_RIGHT,
                               CellStyle.VERTICAL_TOP);

/**
 * Creates a cell and aligns it a certain way.
 *
 * @param book   книга Excel
 * @param row    строка
 * @param column колонка
 * @param halign горизонтальное выравнивание
 * @param valign вертикальное выравнивание
 */
private void createCell(Workbook book,
                        Row row, short column,
                        short halign, short valign)
{
    XSSFCell cell = row.createCell(column);
    cell.setCellValue("Значение");
    // Определение стиля
    XSSFCellStyle cellStyle = book.createCellStyle();
    // Настройка выравнивания стиля
    cellStyle.setAlignment(halign);
    cellStyle.setVerticalAlignment(valign);
    // Стиль ячейки
    cell.setCellStyle(cellStyle);
}

Границы ячейки, Border

// Создание строки
XSSFRow row = sheet.createRow(1);
// Создание ячейки
XSSFCell cell = row.createCell(1);
cell.setCellValue("Значение");

// Создание стиля
XSSFCellStyle style = book.createCellStyle();

// Определение граничных значений стиля
style.setBorderTop   (CellStyle.BORDER_MEDIUM_DASHED);
style.setBorderRight (CellStyle.BORDER_THIN         );
style.setBorderBottom(CellStyle.BORDER_THIN         );
style.setBorderLeft  (CellStyle.BORDER_THIN         );
// Определение цвета граничных значений стиля
style.setTopBorderColor   (IndexedColors.BLACK.getIndex());
style.setRightBorderColor (IndexedColors.BLUE.getIndex ());
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setLeftBorderColor  (IndexedColors.GREEN.getIndex());

// Определение стиля ячейки
cell.setCellStyle(style);

Многострочные ячейки

Для фиксированного разделения/переноса текста в ячейке необходимо в стиле определить
свойство WrapText=true, и в тексте установить разделители ‘n’.

String text = "Фиксированное n разделение n текста";

XSSFCellStyle style = book.createCellStyle();
style.setWrapText(true);

XSSFRow row = sheet.createRow(2);
XSSFCell cell = row.createCell(2);
cell.setCellValue(text);
cell.setCellStyle(style);

Использование формулы

Создадим две ячейки. В первую ячейку cell1 запишем сумму значений колонки, а во второй ячейке
cell2 разместим формулу «СУММА()». Для вычисления значения первой ячейки дополнительно используются
методы getColsSummary и getCellValue.

int row = 5;
int summa = getColsSummary (1, 2, row);
XSSFCell cell1 = row.createCell(2);
if (summa > 0)
    cell1.setCellValue(summa);

XSSFCell cell2 = row.createCell(2);
String formula = String.format("SUM(B3:B%d)", row);
cell2.setCellFormula(formula);
//-------------------------------------------------------
private int getCellValue (final int cl, final int rw)
{
    XSSFRow  row  = sheet.getRow(rw);
    XSSFCell cell = row.getCell(cl);

    return (int)cell.getNumericCellValue(); 
}
//-------------------------------------------------------
private int getColsSummary (int col, int row1, int row2)
{
    int summary = 0;
    for (int i = row1; i < row2; i++)
        summary += getCellValue (col, i);
    return summary;
}

Like this post? Please share to your friends:
  • Creating excel file in python
  • Creating emails in word
  • Creating designs in word
  • Creating dates in excel
  • Creating database with excel