Create excel apache poi

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

Афоризм

Склероз нельзя вылечить, но о нем можно забыть.

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

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

 • 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;
}
Details
Written by  
Last Updated on 30 May 2019   |   Print  Email

In this tutorial, I’d love to share with you guys some examples of writing data to Excel files using the Apache POI library. If today is the first day you get to know Apache POI and you haven’t written any code snippet to read/write Excel files yet, I recommend you to read the sections 1 and 2 in the tutorial How to Read Excel Files in Java using Apache POI to understand the fundamentals of Apache POI.

Or if you are a kind of person who likes getting your hands-dirty first, let jump directly into the following examples.

 

1. Apache POI API Basics for Writing Excel Files

The fundamental interfaces include Workbook, Sheet, Row and Cell. For basic formatting, use the CellStyle and Font interfaces. Concrete implementing classes include:

  • Excel 2003: HSSFWorkbook, HSSFSheet, HSSFRow, HSSFCell, etc.
  • Excel 2007: XSSFWorkbook, XSSFSheet, XSSFRow, XSSFCell, etc.

But I recommend using the common interfaces for greater flexibility with both Excel formats 2003 (XLS) and 2007(XLSX).

Here are the basic steps for writing an Excel file:

  1. Create a Workbook.
  2. Create a Sheet.
  3. Repeat the following steps until all data is processed:
    1. Create a Row.
    2. Create Cellsin a Row. Apply formatting using CellStyle.
  4. Write to an OutputStream.
  5. Close the output stream.

Now, let’s see some examples that demonstrate writing a list of books to an Excel file.

 

2. A Simple Example to create an Excel file in Java

The following code snippet is a very simple program that demonstrates writing a list of books to an Excel file in the simplest and dirty form:

package net.codejava.excel;

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * A very simple program that writes some data to an Excel file
 * using the Apache POI library.
 * @author www.codejava.net
 *
 */
public class SimpleExcelWriterExample {

	public static void main(String[] args) throws IOException {
		XSSFWorkbook workbook = new XSSFWorkbook();
		XSSFSheet sheet = workbook.createSheet("Java Books");
		
		Object[][] bookData = {
				{"Head First Java", "Kathy Serria", 79},
				{"Effective Java", "Joshua Bloch", 36},
				{"Clean Code", "Robert martin", 42},
				{"Thinking in Java", "Bruce Eckel", 35},
		};

		int rowCount = 0;
		
		for (Object[] aBook : bookData) {
			Row row = sheet.createRow(++rowCount);
			
			int columnCount = 0;
			
			for (Object field : aBook) {
				Cell cell = row.createCell(++columnCount);
				if (field instanceof String) {
					cell.setCellValue((String) field);
				} else if (field instanceof Integer) {
					cell.setCellValue((Integer) field);
				}
			}
			
		}
		
		
		try (FileOutputStream outputStream = new FileOutputStream("JavaBooks.xlsx")) {
			workbook.write(outputStream);
		}
	}

}

This program creates an Excel 2007 document which looks like the following screenshot (File: JavaBooks.xlsx):

Output Excel File

 

3. A More Object-Oriented Example to create an Excel file in Java

The following code snippets demonstrate a nicer program that focuses on OOP approach. That makes the program more flexible and easy to extend or upgrade in the future.

  • Create the model class (Book.java):
    package net.codejava.excel;
    
    public class Book {
    	private String title;
    	private String author;
    	private float price;
    
    	public Book() {
    	}
    
    	public Book(String title, String author, double price) {
    		this.title = title;
    		this.author = author;
    		this.price = price;
    	}
    
    	// getters and setters
    }
  • The method that writes a list of books to an Excel file (in 2003 format):
    public void writeExcel(List<Book> listBook, String excelFilePath) throws IOException {
    	Workbook workbook = new HSSFWorkbook();
    	Sheet sheet = workbook.createSheet();
    
    	int rowCount = 0;
    
    	for (Book aBook : listBook) {
    		Row row = sheet.createRow(++rowCount);
    		writeBook(aBook, row);
    	}
    
    	try (FileOutputStream outputStream = new FileOutputStream(excelFilePath)) {
    		workbook.write(outputStream);
    	}
    }
  • The method that writes information of a book to cells:
    private void writeBook(Book aBook, Row row) {
    	Cell cell = row.createCell(1);
    	cell.setCellValue(aBook.getTitle());
    
    	cell = row.createCell(2);
    	cell.setCellValue(aBook.getAuthor());
    
    	cell = row.createCell(3);
    	cell.setCellValue(aBook.getPrice());
    }
  • The following method creates some dummy data (a list of books):
    private List<Book> getListBook() {
    	Book book1 = new Book("Head First Java", "Kathy Serria", 79);
    	Book book2 = new Book("Effective Java", "Joshua Bloch", 36);
    	Book book3 = new Book("Clean Code", "Robert Martin", 42);
    	Book book4 = new Book("Thinking in Java", "Bruce Eckel", 35);
    
    	List<Book> listBook = Arrays.asList(book1, book2, book3, book4);
    
    	return listBook;
    }
  • And the following code snippet is for testing:
    NiceExcelWriterExample excelWriter = new NiceExcelWriterExample();
    
    List<Book> listBook = excelWriter.getListBook();
    String excelFilePath = "NiceJavaBooks.xls";
    
    excelWriter.writeExcel(listBook, excelFilePath);

 

4. Formatting Cells of the Excel file

Of course you may need to format the Excel file to make it looks nicely and professionally. Formatting is diversity and quite complex so in this introductory tutorial, I just show you how to format the basics like setting font style. Here are the steps:

  • Create a CellStyle object what holds formatting information:
    CellStyle cellStyle = sheet.getWorkbook().createCellStyle();
  • Invoke the appropriate setters to apply the formatting you want. For example:
    cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
    cellStyle.setFont(font);
    cellStyle.setWrapText(true);

For example, the following method writes a header row for the document with font style bold and size is 16:

private void createHeaderRow(Sheet sheet) {

	CellStyle cellStyle = sheet.getWorkbook().createCellStyle();
	Font font = sheet.getWorkbook().createFont();
	font.setBold(true);
	font.setFontHeightInPoints((short) 16);
	cellStyle.setFont(font);

	Row row = sheet.createRow(0);
	Cell cellTitle = row.createCell(1);

	cellTitle.setCellStyle(cellStyle);
	cellTitle.setCellValue("Title");

	Cell cellAuthor = row.createCell(2);
	cellAuthor.setCellStyle(cellStyle);
	cellAuthor.setCellValue("Author");

	Cell cellPrice = row.createCell(3);
	cellPrice.setCellStyle(cellStyle);
	cellPrice.setCellValue("Price");
}

You can see the complete program (FormattedExcelWriterExample.java) which can be found in the source code attached to this article.

 

5. Writing both Excel 2003 and Excel 2007 formats in Java

For better flexibility (supporting both common Excel formats), I recommend writing a factory method that either returns a HSSFWorkbook or XSSFWorkbook, depending on the extension of the file (.xls or .xlsx). Here’s the method:

private Workbook getWorkbook(String excelFilePath)
		throws IOException {
	Workbook workbook = null;

	if (excelFilePath.endsWith("xlsx")) {
		workbook = new XSSFWorkbook();
	} else if (excelFilePath.endsWith("xls")) {
		workbook = new HSSFWorkbook();
	} else {
		throw new IllegalArgumentException("The specified file is not Excel file");
	}

	return workbook;
}

You can see the complete program (FlexibleExcelWriterExample.java) which can be found in the source code attached to this article.

That’s how to read Excel files in Java programmatically. To learn more in-depth about Java programming, this Java software developers course would be good choice.

Related Java Excel Tutorials:

  • How to Read 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

The Apache POI is a popular open source library used to read, write, and manipulate MS Office and Open Office files by using Java code. The library is one of the many open source products maintained by Apache Software Foundation (ASF) contributed to the Java community. The library contains classes and methods to decode file formats based on Open Office XML standards and Microsoft OLE2. Although the library is capable of manipulating Word, Excel spreadsheet and PowerPoint files, this article mainly focuses on spreadsheet documents, only to make it brief.

Learn JAVA and Start your Free Trial today!

The Apache POI Library

Intriguingly, in the name Apache POI, the POI stands for “Poor Obfuscation Implementation” and the goal of the library is to provide Java APIs for manipulating various file formats based upon the Office Open XML standards (OOXML) and Microsoft’s OLE 2 Compound Document format (OLE2). In short, this enables one to read and write MS Excel, MS Word, and MS PowerPoint files by using Java code. Most Microsoft Office files—such as XLS, DOC, PPT, and MFC serialization API-based file formats—are based on OLE2 standard. The OLE, basically, is a proprietary technique developed by Microsoft, and provides the format for linking objects and embedding objects within container documents. The first format is called OLE1.0 format where the linked object and the embedded object data is laid out as a sequence of bytes within the container document. The second version, the OLE2.0 format, leverages OLE Compound File Technology (MS-CFB) where the linked object or embedded object data is contained in this storage in the form of OLE Compound File Stream objects. Refer to OLE1.0 and OLE2.0 Formats for more details on this. The Apache POI library provides library APIs for the OLE2 file system called POIFS and OLE2 Document Properties called HPSF.

Apache POI Components

The Apache POI library provides classes and methods to work with OLE2 Compound Documents of MS Office. Here is a brief overview of the most commonly used ones:

  • POIFS for OLE2 Documents: The POIFS stands for Poor Obfuscation Implementation File System. This is the basic POI element implemented in the library to port OLE2 Compound Document. It supports read and write functionality for the non-XML binary Microsoft Office format. All APIs of the POI library are built upon this.
  • HSSF and XSSF: The HSSF stands for Horrible Spread Sheet Format. It is a Java implementation port for the Excel 97 file format or for .xls files. XSSF stands for XML Spread Sheet Format and it is a port for the OOXML file format or .xlsx file format.
  • HWPF and XWPF: The HWPF stands for Horrible Word Processor Format. It is a limited read-only port for the older Word 6 or Word 95 file format. The XWPF stands for XML Word Processor Format. It is a Java implementation port for the Word 2007 .docx file format. Both implementations support limited functionality.
  • HSLF and XSLF: The HSLF stands for Horrible Slide Layout Format. The XSLF stands for XML Slide Layout Format. Both of these provide read, write, create, and modify capability of PowerPoint presentations whereas HSLF supports the PowerPoint 97 format and XSLF supports later versions.
  • HPSF: The HPSF stands for Horrible Property Set Format. It is particularly used to work with document properties such as setting the title, category, author, date of modification and so forth of a document
  • HDGF and XDGF: The HDGF stands for Horrible Diagram Format. This component contains classes to work with the Visio binary file format. It provides low-level, read-only APIs to access Visio Documents and VSD files. The XDGF stands for XML Diagram Format. It is for the Visio XML file format or VSDX files.
  • HPBF: The HPBF stands for Horrible Publisher Format. It is a limited Java port to work with the MS Publisher file format.

The acronyms sound humorous because these file systems were supposed to be closed and Microsoft did their best to obfuscate the code so that they are not only difficult to understand but also hard to reverse engineer. But, the developers at Apache hacked it with ease and reverse engineered it successfully. Perhaps, as a mark of rejoice or utter condemnation of closed system, they jocularly named them as such.

Working with HSSF and XSSF Files

The HSSF and XSSF components of the Apache library provides three models of accessing a spreadsheet document as per the HSSF and XSSF Documentation. They are:

  • Low-level structures for special needs
  • The eventmodel APIs for read-only access to Excel documents
  • The usermodel APIs for creating, reading, and modifying Excel files

The limited eventmodel APIs may be used for only reading spreadsheet data. These APIs are located in the org.apache.poi.hssf.eventusermodel package and org.apache.poi.xssf.eventusermodel package, where the first one is used to read data from the .xls file format and the second is used to read data from the .xlsx file format.

The usermodel is much more flexible and easier to use; it can read, write, create, and modify an Excel spreadsheet document. But, it has a much higher memory footprint than the low-level eventmodel.

Also, accessing and manipulating the newer OOXML-based file format with XSSF has a much higher memory footprint than the old HSSF supported binary files.

From POI 3.5 onwards, the HSSF and XSSF model has been clubbed into the SS model, rather tweaked to work for both the models. It is more of tweak of name than a real change. In a way, we can say that SS=HSSF+XSSF.

Migrating Database Table Data to an Excel Spreadsheet

Here, we’ll create a simple utility program to migrate some database data into an Excel sheet. This also can be tweaked to work with other ways, such as migrating Excel data to a database table. This is left as an exercise for the reader. The program is simple and self-explanatory. Visit the Apache POI Documentation for detailed information on any classes or methods. To try the following example, what we have used is as follows:

  • JDK 8
  • MS Excel 2007
  • Intellij IDEA IDE
  • Apache POI 3.17
  • Apache Derby 10.14

Visit the appropriate documents and help files for setting up the project. Here are the contents for the Maven pom.xml file we have used.

<project 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.mano.examples</groupId>
   <artifactId>apache-poi-demo</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>apache-poi-demo</name>
   <url>http://maven.apache.org</url>

   <properties>
      <project.build.sourceEncoding>
         UTF-8
      </project.build.sourceEncoding>
   </properties>

   <build>
      <plugins>
         <plugin>
            <artifactId>
               maven-compiler-plugin
            </artifactId>
            <version>3.7.0</version>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
            </configuration>
         </plugin>
      </plugins>
   </build>

   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>

      <!-- https://mvnrepository.com/artifact
         /org.apache.maven.plugins/maven-compiler-plugin -->
      <dependency>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.7.0</version>
      </dependency>

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

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

      <!-- https://mvnrepository.com/artifact/
         org.apache.derby/derby -->
      <dependency>
         <groupId>org.apache.derby</groupId>
         <artifactId>derby</artifactId>
         <version>10.14.1.0</version>
         <scope>test</scope>
      </dependency>

      <!-- https://mvnrepository.com/artifact/
         org.apache.derby/derbyclient -->
      <dependency>
         <groupId>org.apache.derby</groupId>
         <artifactId>derbyclient</artifactId>
         <version>10.14.1.0</version>
      </dependency>

   </dependencies>
</project>

Listing 1: pom.xml

A database table is created with some dummy records prior to running the utility program. Here is the code of that file.

package com.mano.examples;

import java.sql.*;


public class DummyDatabase {

   public static void createDummyDatabase()
         throws SQLException {
      Connection con=DriverManager.getConnection
         ("jdbc:derby:D:/temp/dummy;create=true");
      Statement stmt=con.createStatement();
      stmt.executeUpdate("drop table semester2");
      stmt.executeUpdate("CREATE TABLE semester2(STUDENT_ID int,
         CARCH INT, DCE INT, WEBTECH INT, JAVA INT, SAD_MIS INT,
         PRIMARY KEY(STUDENT_ID))");

      // Insert 2 rows
      stmt.executeUpdate("insert into semester2
         values (23567932,56,78,97,58,85)");
      stmt.executeUpdate("insert into semester2
         values (47250001,96,34,75,68,12)");
      stmt.executeUpdate("insert into semester2
         values (99568955,45,68,69,78,29)");
      stmt.executeUpdate("insert into semester2
         values (89376473,75,23,56,89,47)");
      stmt.executeUpdate("insert into semester2
         values (29917740,85,78,55,15,48)");
      stmt.executeUpdate("insert into semester2
         values (85776649,23,56,78,25,69)");
      stmt.executeUpdate("insert into semester2
         values (38846455,68,95,78,53,48)");
      stmt.executeUpdate("insert into semester2
         values (40028826,63,56,48,59,75)");
      stmt.executeUpdate("insert into semester2
         values (83947759,85,54,69,36,89)");
      stmt.executeUpdate("insert into semester2
         values (92884775,78,59,25,48,69)");
      stmt.executeUpdate("insert into semester2
         values (24947389,12,10,14,54,68)");
      stmt.executeUpdate("insert into semester2
         values (77399465,44,33,26,88,77)");

      // Query
      ResultSet rs = stmt.executeQuery
      ("SELECT * FROM semester2");

      // Print out query result
      while (rs.next()) {
         System.out.printf
               ("%dt%dt%dt%dt%dt%dn",
            rs.getLong("STUDENT_ID"),
            rs.getInt("CARCH"),
            rs.getInt("DCE"),
            rs.getInt("WEBTECH"),
            rs.getInt("JAVA"),
            rs.getInt("SAD_MIS"));
      }
      stmt.close();
      con.close();
   }
}

Listing 2: DummyDatabase.java.

This is the utility program we are talking about. The code was written in big hurry and the structure not very elegant. However, it works. Restructure or tweak it as you deem fit.

package com.mano.examples;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.*;

public class SSFile {

   private static String[] header={"STUDENT_ID",
      "CARCH", "DCE", "WEBTECH", "JAVA",
      "SAD_MIS", "TOTAL", "AVERAGE"};

   public static void databaseToExcel(File file)
         throws IOException, SQLException {
      Workbook workbook = null;
      if (file.getName().endsWith(".xls"))
         workbook = new HSSFWorkbook();
      else if (file.getName().endsWith(".xlsx"))
         workbook = new XSSFWorkbook();
      else {
         System.out.println("Invalid filename!");
         return;
      }
      Sheet sheet = workbook.createSheet();
      Connection con = DriverManager.getConnection
         ("jdbc:derby:D:/temp/dummy;create=true");
      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT * FROM semester2");



      Row rr = sheet.createRow(0);
      for(int i=0;i<header.length;i++){
         createHeaderCell(rr, (short) i, header[i]);
      }

      int i = 1;
      while (rs.next()) {
         rr = sheet.createRow(i++);
         for(int j=0;j<header.length-2;j++){
            createDataCell(rr, (short) j,
               rs.getLong(header[j]));
         }
      }
      rr = sheet.getRow(1);
      Cell total = rr.createCell(6);
      total.setCellType(CellType.FORMULA);
      total.setCellFormula("SUM(B2:F2)");
      Cell avg = rr.createCell(7);
      avg.setCellType(CellType.FORMULA);
      avg.setCellFormula("AVERAGE(B2:F2)");

      FileOutputStream outFile = new
         FileOutputStream(file);
      workbook.write(outFile);
      outFile.flush();
      outFile.close();
      stmt.close();
      con.close();
   }

   private static void createHeaderCell(Row row,
         short col, String cellValue) {
      Cell c = row.createCell(col);
      c.setCellValue(cellValue);
   }

   private static void createDataCell(Row row,
         short col, Number cellValue) {
      Cell c = row.createCell(col);
      c.setCellType(CellType.NUMERIC);
      c.setCellValue(cellValue.doubleValue());
   }
}

Listing 3: SSFile.java

This is the control panel from which the utility program is invoked.

package com.mano.examples;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;

public class App
{
   public static void main( String[] args )
         throws IOException,SQLException{
      // DummyDatabase.createDummyDatabase();
      SSFile.databaseToExcel(new
         File("d://temp//test1.xls"));
   }
}

Listing 4: App.java

Before Running…

Make sure that the test1.xls or test1.xlsx files do not exist in the d://temp directory prior to running the program because the program neither overwrites nor checks the file with the same name in the directory where the file is supposed to be created. Make sure of this every time the program is run; otherwise, the code gives a nasty error message. However, you may tweak the code to put some checking.

Conclusion

There is another alternative to working with spreadsheets, as the Apache POI Documentation suggests via the Cocoon serializer, although it still uses HSSF indirectly. Cocoon can serialize any XML data source by applying the style sheet and designating the serializer. The HSSF and XSSF model is quite powerful and provides a number of classes and methods to deal with different aspects of an Excel document. This article tried to give a glimpse of what we can do with Apache POI. We often need to write a utility program to bridge between an open and closed system. Apache POI can definitely serve our purpose as one of its kind.

References

  • Apache POI – the Java API for Microsoft Documents
  • POI-HSSF and POI-XSSF – Java API to Access Microsoft Excel Format Files

В прошлых двух статьях мы познакомились с библиотекой 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 сразу на почту!

Понравилась статья? Поделить с друзьями:
  • Create database with excel
  • Create database from excel table
  • Create database for excel
  • Create data table microsoft excel
  • Create data range excel