Интеграция электронных таблиц MS Excel и Java.
Описание:
В современном мире очень много случаев, при которых необходимо интегрировать MS
Excel с Java. Например, при разработке Enterprise-приложения в некой финансовой
сфере, вам необходимо предоставить счет для заинтересованных лиц, а проще всего
выставлять счет на MS Excel.
Обзор существующих API MS Excel для Java:
Рассмотрим основные API:
-
Docx4j — это API с открытым исходным кодом, для создания и манипулирования документами формата Microsoft Open XML, к которым отросятся Word docx, Powerpoint pptx, Excel xlsx файлы. Он очень похож на Microsoft OpenXML SDK, но реализован на языке Java. Docx4j использует JAXB архитектуру для создания представления объекта в памяти. Docx4j акцентирует свое внимание на всесторонней поддержке заявленного формата, но от пользователя данного API требуется знание и понимание технологии JAXB и структуры Open XML.
-
Apache POI — это набор API с открытым исходным кодом, который предлагает определенные функции для чтения и записи различных документов, базирующихся на Office Open XML стандартах (OOXML) и Microsoft OLE2 форматe документов (OLE2). OLE2 файлы включают большинство Microsoft Office форматов, таких как doc, xls, ppt. Office Open XML формат это новый стандарт базирующийся на XML разметке, и используется в файлах Microsoft office 2007 и старше.
-
Aspose for Java — набор платных Java APIs, которые помогают разработчикам в работе с популярными форматами бизнес файлов, такими как документы Microsoft Word, таблицы Microsoft Excel, презентации Microsoft PowerPoint, PDF файлы Adobe Acrobat, emails, изображения, штрих-коды и оптические распознавания символов.
Каждое API проектируется для того, чтобы выполнять широкий спектр создания документов, различные манипуляции и преобразования быстро и легко, экономя время и позволяя разработчикам успешно программировать. Ни один API с открытым исходным кодом не имеет одной и той же комплексной поддержки функций.
Все Aspose’s APIs используют простую объектную модель документа, а одно API предназначено для работы с набором связанных форматов. Aspose’s Microsoft Office APIs, Aspose.Cells, Aspose.Words, Aspose.Slides, Aspose.Email, и Aspose.Tasks легки в работе, эффективны, надежны и независимы от других библиотек.
Преимуществом APIs с открытым исходным кодом является то, что они бесплатны и каждый может настроить их под свои задачи и цели. Это очень удобно, если у пользователя есть достаточно времени и ресурсов. Однако данные APIs не всегда имеют поддержку или документацию, и поддерживают небольшое количество функций и вариантов. Этот недостаток стоит разработчикам времени, и сокращает надежность их приложений. К преимуществам проприетарных (коммерческих) API можно отнести комплексную поддержку функционала с подробной документацией, регулярное обновление, гарантию отсутствия ошибок и обратную связь с разработчиками APIs.
В данной программе будем использовать Apache POI
Ссылки на полезные ресурсы
- https://habr.com/post/56817/
- https://poi.apache.org/apidocs/index.html — официальная документация
- http://java-online.ru/java-excel.xhtml
Задание:
В данной работе вы должны реализовать следующее:
-
Чтение с ячейки MS Excel в Java
-
Запись с Java в MS Excel
Инструкция
- Для обращения к MS Excel версии до 2003 включительно года с Java используется класс
HSSFWorkbook
- Для обращения к MS Excel версии 2007 и позднее с Java используется класс
XSSFWorkbook
- При операциях Обновление или Запись необходимо, чтобы MS Excel был закрыт.
Чтение ячейки с MS Excel
Чтобы считать данные с xlsx
необходимо исполнить следующие шаги:
//filePath - это путь до MS Excel Workbook book = new XSSFWorkbook(new FileInputStream(filePath); //считывается лист по индексу sheet_index. sheet_index начинается с 0 Sheet sheet = book.getSheetAt(sheet_index); //считывается row по индексу row_index. row_index начинается с 0 Row row = sheet.getRow(row_index); //считывается cell по индексу cell_index. cell_index начинается с 0 Cell cell = sheet.getCell(cell_index);
Запись в ячейку MS Excel
Workbook book = new XSSFWorkbook(); //name - имя листа Sheet sheet = book.createSheet(name); Row row = sheet.createRow(i); Cell cell = row.createCell(j); FileInputStream fileOut = new FileInputStream(filePath); book.write(fileOut); fileOut.close();
Обновление ячейки в существующем листе MS Excel
Workbook workbook = new XSSFWorkbook(new FileInputStream(filePath)); Sheet sheet = workbook.getSheetAt(i); Row row = sheet.getRow(j); Cell cell = row.getCell(k); cell.setCellValue(value);
Подготовка: загрузка библиотек и зависимостей
Конечно, существует достаточно много открытых библиотек, которые позволяют работать с Excel файлами в Java, например, JXL, но мы будем использовать имеющую самый обширный API и самую популярную — Apache POI. Чтобы её использовать, вам нужно скачать jar файлы и добавить их через Eclipse вручную, или вы можете предоставить это Maven.
Во втором случае вам нужно просто добавить следующие две зависимости:
<dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.12</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.12</version> </dependency> </dependencies>
Самое удобное в Maven — что он загрузит не только указанные poi.jar и poi-ooxml.jar, но и все jar файлы, которые используются внутри, то есть xmlbeans-2.6.0.jar,
stax-api-1.0.1.jar, poi-ooxml-schemas-3.12.jar и commons-codec-1.9.jar
Выполнение:
-
Создать проект на java с помощью maven.
-
Следовать инструкции «Подготовка:…» описанная выше.
-
Создать Excel файл в корневой папке проекта.
-
Записать в A1 и A2 любые целые числа.
-
В папке src/main/java создать класс IOCell
- Создать поле
- Создать конструктор
IOCell(String filePath) { this.filePath = new File(filePath)}
- Создать метод для чтения c Excel в Java
public Cell getCell(int sheet, int row, int column) { Workbook workbook = null; try (FileInputStream file = new FileInputStream(filePath)) { workbook = new XSSFWorkbook(file); } catch (FileNotFoundException e) { System.out.println("file is not exists"); } catch (IOException e) { e.printStackTrace(); } return workbook.getSheetAt(sheet).getRow(row).getCell(column); }
- Создать метод для записи с Java в Excel
public void setCell(int row, int column, double val) { Workbook workbook = null; try (FileInputStream file = new FileInputStream(filePath)) { workbook = new XSSFWorkbook(file); Sheet sheet = workbook.getSheetAt(0); sheet.getRow(row).getCell(column).setCellValue(val); } catch (IOException e) { e.printStackTrace(); } try (OutputStream fileOut = new FileOutputStream(filePath)) { workbook.write(fileOut); } catch (FileNotFoundException e) { System.out.println("file is not exist AAAA"); } catch (IOException e) { e.printStackTrace(); } }
-
В папке src/main/java создать класс Main
- Создать поле
private static final String filePath = "NAME_OF_EXCEL_FILE";
- Создать метод
public static void main(String[] args) { IOCell ioCell = new IOCell(filePath); Cell x = ioCell.getCell(0, 1, 0); Cell y = ioCell.getCell(0, 1, 1); System.out.println("first number: " + x.toString()); System.out.println("second number: " + y.toString()); //Write x * y ioCell.setCell(4, 0, x.getNumericCellValue() * y.getNumericCellValue()); //Write x + y ioCell.setCell(4, 1, x.getNumericCellValue() + y.getNumericCellValue()); System.out.println("Interactions is complete successfully"); }
-
Запускаем приложение и смотрим в консоль.
Рассказывает автор блога javarevisited.blogspot.ru
Из этой статьи вы сможете узнать о записи и чтении данных из Excel файлов в Java (будет рассмотрен как XLS
, так и XLSX
формат). Мы будем использовать библиотеку Apache POI и сосредоточимся на работе с типами String
и Date
, работа с последним происходит достаточно хитро. Напомню, что работу с числами мы уже рассмотрели в другой статье.
Библиотеку poi-XX.jar
вы можете использовать для всех старых (xls
, doc
, ppt
) файлов Microsoft Office, для новых (xlsx
, docx
, pptx
) вам понадобится poi-ooxml-XX.jar
. Очень важно понимать, что к чему относится, т.к. используемые классы тоже разные — для старых расширений это HSSFWorkbook
, а для новых — XSSFWorkbook
.
Подготовка: загрузка библиотек и зависимостей
Конечно, существует достаточно много открытых библиотек, которые позволяют работать с Excel файлами в Java, например, JXL, но мы будем использовать имеющую самый обширный API и самую популярную — Apache POI. Чтобы её использовать, вам нужно скачать jar
файлы и добавить их через Eclipse вручную, или вы можете предоставить это Maven.
Во втором случае вам нужно просто добавить следующие две зависимости:
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.12</version>
</dependency>
</dependencies>
Самое удобное в Maven — что он загрузит не только указанные poi.jar
и poi-ooxml.jar
, но и все jar файлы, которые используются внутри, то есть xmlbeans-2.6.0.jar
, stax-api-1.0.1.jar
, poi-ooxml-schemas-3.12.jar
и commons-codec-1.9.jar
.
Если вы будете добавлять библиотеки вручную — не забудьте о вышеназванных файлах. Скачать всё можно отсюда. Помните — если вы загрузите только poi-XX.jar
, то ваш код скомпилируется без ошибок, но потом упадёт с java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject
, так как внутри будет вызываться xmlbeans.jar
.
Запись
В этом примере мы запишем в xls
файл следующие данные: в первую ячейку — строку с именем, а во вторую — дату рождения. Вот пошаговая инструкция:
- Создаём объект
HSSFWorkBook
; - Создаём лист, используя на объекте, созданном в предыдущем шаге,
createSheet()
; - Создаём на листе строку, используя
createRow()
; - Создаём в строке ячейку —
createCell()
; - Задаём значение ячейки через
setCellValue();
- Записываем
workbook
вFile
черезFileOutputStream
; - Закрываем
workbook
, вызываяclose()
.
Для записи строк или чисел этого вполне достаточно, но чтобы записать дату, нам понадобится сделать ещё кое-что:
- Создать
DateFormat
; - Создать
CellStyle
; - Записать
DateFormat
вCellStyle
; - Записать
CellStyle
в ячейку; - Теперь в эту ячейку можно записать объект
Date
через всё тот жеsetCellValue
; - Чтобы дата поместилась в ячейку, нам нужно добавить столбцу свойство автоматически менять размер:
sheet.autoSizeColumn(1)
.
Всё вместе это будет выглядеть так:
@SuppressWarnings("deprecation")
public static void writeIntoExcel(String file) throws FileNotFoundException, IOException{
Workbook book = new HSSFWorkbook();
Sheet sheet = book.createSheet("Birthdays");
// Нумерация начинается с нуля
Row row = sheet.createRow(0);
// Мы запишем имя и дату в два столбца
// имя будет String, а дата рождения --- Date,
// формата dd.mm.yyyy
Cell name = row.createCell(0);
name.setCellValue("John");
Cell birthdate = row.createCell(1);
DataFormat format = book.createDataFormat();
CellStyle dateStyle = book.createCellStyle();
dateStyle.setDataFormat(format.getFormat("dd.mm.yyyy"));
birthdate.setCellStyle(dateStyle);
// Нумерация лет начинается с 1900-го
birthdate.setCellValue(new Date(110, 10, 10));
// Меняем размер столбца
sheet.autoSizeColumn(1);
// Записываем всё в файл
book.write(new FileOutputStream(file));
book.close();
}
Чтение
Теперь мы считаем из только что созданного файла то, что мы туда записали.
- Для начала создадим
HSSFWorkBook
, передав в конструкторFileInputStream
; - Получаем лист, передавая в
getSheet()
его номер или название; - Получаем строку, используя
getRow()
; - Получаем ячейку, используя
getCell()
; - Узнаём тип ячейки, используя на ней
getCellType()
; - В зависимости от типа ячейки, читаем её значения, используя
getStringCellValue()
,getNumericCellValue()
илиgetDateCellValue()
; - Закрываем
workbook
используяclose()
.
Напомню, что дату Excel хранит как числа, т.е. тип ячейки всё равно будет CELL_TYPE_NUMERIC
.
В виде кода это будет выглядеть следующим образом:
public static void readFromExcel(String file) throws IOException{
HSSFWorkbook myExcelBook = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet myExcelSheet = myExcelBook.getSheet("Birthdays");
HSSFRow row = myExcelSheet.getRow(0);
if(row.getCell(0).getCellType() == HSSFCell.CELL_TYPE_STRING){
String name = row.getCell(0).getStringCellValue();
System.out.println("name : " + name);
}
if(row.getCell(1).getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
Date birthdate = row.getCell(1).getDateCellValue();
System.out.println("birthdate :" + birthdate);
}
myExcelBook.close();
}
В заключение
Как уже упомналось выше, чтение из xlsx
файлов ничем принципиально не отличается — нужно только вместо HSSFWorkBook
, HSSFSheet
, HSSFRow
(и прочих) из poi-XX.jar
использовать XSSFWorkBook
, XSSFSheet
, XSSFRow
из poi-ooxml-XX.jar
. Это всё, что вам нужно знать для чтения и записи в файлы Excel. Разумеется, с помощью библиотеки Apache POI вы можете сделать гораздо больше, но эта статья должна помочь вам быстрее в ней освоиться.
Перевод статьи «How to Read Write Excel file in Java — POI Example»
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;
public
class
GFG {
public
static
void
main(String[] args)
{
XSSFWorkbook workbook =
new
XSSFWorkbook();
XSSFSheet sheet
= workbook.createSheet(
"student Details"
);
Map<String, Object[]> data
=
new
TreeMap<String, Object[]>();
data.put(
"1"
,
new
Object[] {
"ID"
,
"NAME"
,
"LASTNAME"
});
data.put(
"2"
,
new
Object[] {
1
,
"Pankaj"
,
"Kumar"
});
data.put(
"3"
,
new
Object[] {
2
,
"Prakashni"
,
"Yadav"
});
data.put(
"4"
,
new
Object[] {
3
,
"Ayan"
,
"Mondal"
});
data.put(
"5"
,
new
Object[] {
4
,
"Virat"
,
"kohli"
});
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
{
FileOutputStream out =
new
FileOutputStream(
new
File(
"gfgcontribute.xlsx"
));
workbook.write(out);
out.close();
System.out.println(
"gfgcontribute.xlsx written successfully on disk."
);
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
Афоризм
«Нахал!» – совсем не значит «Прекратите».
Наталья Резник
Поддержка проекта
Если Вам сайт понравился и помог, то будем признательны за Ваш «посильный» вклад в его поддержку и развитие
• Yandex.Деньги
410013796724260
• Webmoney
R335386147728
Z369087728698
На странице описания библиотеки Apache POI представлены свойства
и методы взаимодействия Java приложений с файлами Excel. Здесь рассматривается пример использования
Apache POI для чтения файлов Excel 2007 или более поздней версии. Если необходимо обрабатывать
Excel 1997-2003, то следует использовать классы, наименования которых начинаются с символа ‘H’
(см. наименование классов на странице описания Apache POI).
Открытие книги Excel
Чтобы «открыть» файл Excel как HSSFWorkbook (.xls), так и XSSFWorkbook (.xlsx) можно использовать либо
File, либо InputStream. При использовании InputStream требуется больше
памяти для загрузки файла в буффер.
Метод openBook демонстрирует использование WorkbookFactory для открытия Excel файла. Строки
использования InputStream закомментированы.
private XSSFWorkbook book; ... private void openBook(final String path) { try { File file = new File(path); book = (XSSFWorkbook) WorkbookFactory.create(file); // InputStream is = new FileInputStream(FILE); // book = (XSSFWorkbook) WorkbookFactory.create(is); // is.close(); } catch (FileNotFoundException e1) { e.printStackTrace(); } catch (EncryptedDocumentException e) { e.printStackTrace(); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
Если нужно обойти использование WorkbookFactory, т.е. использовать XSSFWorkbook (HSSFWorkbook)
напрямую, то следует использовать OPCPackage (.xlsx) или NPOIFSFileSystem (.xls).
private XSSFWorkbook book; ... private void openBookDirectly(final String path) { File file = new File(path); try { OPCPackage pkg = OPCPackage.open(file); book = new XSSFWorkbook(pkg); pkg.close(); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
Открытие страницы
При открытии страницы слеудет использовать метод getSheet с указанием в качестве параметра наименования
страницы. Здесь необходимо быть внимательным, поскольку наименования страницы по умолчанию могут быть как
«Sheet», так и «Лист», в зависимости от локализации операционной системы и Excel.
XSSFSheet sheet = book.getSheet("Лист1");
Перебор строк и ячеек
Чтобы «пройтись» по всем страницам книги и перебрать все значения в ячейках можно использовать
итераторы. Следующий код показывает использование итераторов
для перебора всех ячеек страницы.
import java.util.Iterator; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Cell; ... Iterator<Row> ri = sheet.rowIterator(); while(ri.hasNext()) { XSSFRow row = (XSSFRow) ri.next(); Iterator<Cell> ci = row.cellIterator(); while(ci.hasNext()) { XSSFCell cell = (XSSFCell) ci.next(); // код } }
Итераторы доступны по вызовам workbook.sheetIterator(), sheet.rowIterator() и row.cellIterator().
Но необходимо помнить, что rowIterator и cellIterator перебирают только строки и ячейки, которые созданы,
пропуская пустые строки и ячейки.
Если необходимо проверить все строки и все ячейки определенной области, то можно воспользоваться
следующим кодом.
private void readCells() { // Определение граничных строк обработки int rowStart = Math.min( 0, sheet.getFirstRowNum()); int rowEnd = Math.max(100, sheet.getLastRowNum ()); for (int rw = rowStart; rw < rowEnd; rw++) { XSSFRow row = sheet.getRow(rw); if (row == null) { // System.out.println( // "row '" + rw + "' is not created"); continue; } short minCol = row.getFirstCellNum(); short maxCol = row.getLastCellNum(); for(short col = minCol; col < maxCol; col++) { XSSFCell cell = row.getCell(col); if (cell == null) { // System.out.println( // "cell '" + col + "' is not created"); continue; } printCell(row, cell); } } }
В представленном коде для чтения ячейки был использован метод getCell(int). Можно использовать
метод getCell(int, MissingCellPolicy), где
MissingCellPolicy, определяет условие возвращения пустых и
отсутствующих ячеек. Однако IDE Eclipse, где работоспособность кода проверялась, показывает, что
MissingCellPolicy упразднена (deprecated), а метод getCell(int) для ячейки типа XSSFCell
вернул правильные значения. Определение значений ячеек выполнялось в методе printCell(row, cell).
Чтение содержимого ячейки
Чтобы получить значение ячейки, необходимо знать тип её значения. Полагаю, что Вы не раз сталкивались
с числовым представлением значения даты. Если у текстовой ячейки попытаться получить числовое значение,
то будет вызвано NumberFormatException. Поэтому, необходимо первоначально определиться с типом, чтобы
использовать соответствующий метод.
Следующий код в цикле проходит по ячейкам в строке и выводит в консоль ссылочную информацию на ячейку
(например $A$3) и содержимое ячейки. Причем, сначала отображается значение, полученное методом
formatCellValue класса DataFormatter, а после символа слеша ‘/’ отображается значение,
получаемое методами getRichStringCellValue(), getDateCellValue(), getNumericCellValue(), getBooleanCellValue()
и getCellFormula() класса XSSFCell.
private void printCell(XSSFRow row, XSSFCell cell) { DataFormatter formatter = new DataFormatter(); CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex()); System.out.print(cellRef.formatAsString()); System.out.print(" : "); // get the text that appears in the cell by getting // the cell value and applying any data formats // (Date, 0.00, 1.23e9, $1.23, etc) String text = formatter.formatCellValue(cell); System.out.print(text + " / "); // Вывод значения в консоль switch (cell.getCellTypeEnum()) { case STRING: System.out.println(cell.getRichStringCellValue() .getString()); break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) System.out.println(cell.getDateCellValue()); else System.out.println(cell.getNumericCellValue()); break; case BOOLEAN: System.out.println(cell.getBooleanCellValue()); break; case FORMULA: System.out.println(cell.getCellFormula()); break; case BLANK: System.out.println(); break; default: System.out.println(); } }
Пример чтения файла Excel
Работоспособность представленного на странице кода (методов), была проверена в примере,
структура которого изображена на следующем скриншоте. Это проект Eclipse, включающий
перечень необходимых библиотек для чтения файла Excel. Основной класс ExcelRead реализует
все представленные выше методы.
На следующем скриншоте представлена страница простенького файла Excel, содержащая ячейки
со значениями типа Date, String, Numeric и ячейки с формулами.
Результат чтения файла
Значения ячеек книги Excel в примере отображаются в консоли. Обратите внимание на
отличия значений до слеша и после него для типов Date и Numeric. При необходимости можно
использовать в приложении переменные соответствующего типа (Date, Integer) и должным образом
отформатировать значения.
Книга Excel открыта Страница открыта $A$1 : Закупки / Закупки $B$1 : 1/20/17 / Fri Jan 20 00:00:00 MSK 2017 $A$3 : Наименование / Наименование $B$3 : Цена / Цена $C$3 : Количество / Количество $D$3 : Стоимость / Стоимость $A$4 : Сахар / Сахар $B$4 : 50 / 50.0 $C$4 : 2 / 2.0 $D$4 : B4*C4 / B4*C4 $A$5 : Рис / Рис $B$5 : 45 / 45.0 $C$5 : 4 / 4.0 $D$5 : B5*C5 / B5*C5 $A$7 : Итого : / Итого : $D$7 : SUM(D4:D6) / SUM(D4:D6)
Скачать примеры
Исходный пример, рассмотренный в тексте страницы, можно скачать
здесь (11.7 Мб).
import
java.io.File;
import
org.apache.poi.ss.usermodel.Cell;
import
org.apache.poi.xssf.usermodel.XSSFRow;
import
org.apache.poi.xssf.usermodel.XSSFSheet;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook;
import
java.io.FileOutputStream;
import
java.util.Map;
import
java.util.Set;
import
java.util.TreeMap;
public
class
WriteDataToExcel {
public
static
void
main(String[] args)
throws
Exception
{
XSSFWorkbook workbook =
new
XSSFWorkbook();
XSSFSheet spreadsheet
= workbook.createSheet(
" Student Data "
);
XSSFRow row;
Map<String, Object[]> studentData
=
new
TreeMap<String, Object[]>();
studentData.put(
"1"
,
new
Object[] {
"Roll No"
,
"NAME"
,
"Year"
});
studentData.put(
"2"
,
new
Object[] {
"128"
,
"Aditya"
,
"2nd year"
});
studentData.put(
"3"
,
new
Object[] {
"129"
,
"Narayana"
,
"2nd year"
});
studentData.put(
"4"
,
new
Object[] {
"130"
,
"Mohan"
,
"2nd year"
});
studentData.put(
"5"
,
new
Object[] {
"131"
,
"Radha"
,
"2nd year"
});
studentData.put(
"6"
,
new
Object[] {
"132"
,
"Gopal"
,
"2nd year"
});
Set<String> keyid = studentData.keySet();
int
rowid =
0
;
for
(String key : keyid) {
row = spreadsheet.createRow(rowid++);
Object[] objectArr = studentData.get(key);
int
cellid =
0
;
for
(Object obj : objectArr) {
Cell cell = row.createCell(cellid++);
cell.setCellValue((String)obj);
}
}
FileOutputStream out =
new
FileOutputStream(
new
File(
"C:/savedexcel/GFGsheet.xlsx"
));
workbook.write(out);
out.close();
}
}
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. Maven Dependency
- 2. Important Classes in POI Library
- 3. Writing an Excel File
- 4. Reading an Excel File
- 5. Add and Evaluate Formula Cells
- 6. Formatting the Cells
- 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
-
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.
-
Row and Cell
Apart from the above classes, Row and Cell interact with a particular row and a particular cell in an excel sheet.
-
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.
-
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:
- Create a workbook
- Create a sheet in workbook
- Create a row in sheet
- Add cells to sheet
- 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();
}
}
}
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.
- Create workbook instance from an excel sheet
- Get to the desired sheet
- Increment row number
- iterate over all cells in a row
- 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
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);
}
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)");
}
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)");
}
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");
}
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