1. Обзор
Когда дело доходит до файлов Microsoft Excel, чтение значений из разных ячеек может быть немного сложным. Файлы Excel
представляют собой электронные таблицы, организованные в строки и ячейки, которые могут содержать значения типа String, Numeric, Date, Boolean и даже Formula
. Apache POI — это библиотека, предлагающая полный набор инструментов для работы с различными файлами Excel и типами значений .
В этом руководстве мы сосредоточимся на том, чтобы научиться обрабатывать файлы Excel, перебирать строки и ячейки и использовать правильный способ чтения каждого типа значения ячейки.
2. Зависимость от Maven
Начнем с добавления зависимости Apache POI в pom.xml
:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.0</version>
</dependency>
Последние версии poi-ooxml
можно найти на Maven Central.
3. Обзор POI Apache
Иерархия начинается с рабочей книги, которая представляет весь файл Excel. Каждый файл может содержать один или несколько рабочих листов, представляющих собой наборы строк и ячеек. В зависимости от версии файла Excel HSSF является префиксом классов, представляющих старые файлы Excel ( .xls
), тогда как XSSF используется для новейших версий ( .xlsx
). Поэтому у нас есть:
Классы XSSFWorkbook
иHSSFWorkbook
представляют книгу Excel.Интерфейс листа
представляет рабочие листы Excel- Интерфейс
Row
представляет строки - Интерфейс
Cell
представляет ячейки
3.1. Работа с файлами Excel
Сначала мы открываем файл, который хотим прочитать, и конвертируем его в FileInputStream
для дальнейшей обработки. Конструктор FileInputStream генерирует исключение
java.io.FileNotFoundException
, поэтому нам нужно обернуть его вокруг блока try-catch и закрыть поток в конце:
public static void readExcel(String filePath) {
File file = new File(filePath);
try {
FileInputStream inputStream = new FileInputStream(file);
...
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
3.2. Итерация по файлу Excel
После того, как мы успешно открыли InputStream
, пришло время создать XSSFWorkbook
и выполнить итерацию по строкам и ячейкам каждого листа. Если мы знаем точное количество листов или имя конкретного листа, мы можем использовать методы getSheetAt(int index)
и getSheet(String sheetName)
XSSFWorkbook
соответственно .
Поскольку мы хотим прочитать любой файл Excel, мы пройдемся по всем листам, используя три вложенных цикла for, один для листов, один для строк каждого листа и, наконец, один для ячеек каждого листа .
Ради этого урока мы будем печатать данные только на консоли:
FileInputStream inputStream = new FileInputStream(file);
Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
for (Sheet sheet : baeuldungWorkBook) {
...
}
Затем, чтобы перебрать строки листа, нам нужно найти индекс первой строки и последней строки, которые мы получаем из объекта листа:
int firstRow = sheet.getFirstRowNum();
int lastRow = sheet.getLastRowNum();
for (int index = firstRow + 1; index <= lastRow; index++) {
Row row = sheet.getRow(index);
}
Наконец, мы делаем то же самое для ячеек. Кроме того, при доступе к каждой ячейке мы можем дополнительно передать MissingCellPolicy
, которая в основном сообщает POI, что возвращать, когда значение ячейки пустое или нулевое. Перечисление MissingCellPolicy
содержит три перечисляемых значения:
RETURN_NULL_AND_BLANK
RETURN_BLANK_AS_NULL
CREATE_NULL_AS_BLANK
;
Код для итерации ячейки выглядит следующим образом:
for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
...
}
3.3. Чтение значений ячеек в Excel
Как мы упоминали ранее, ячейки Microsoft Excel могут содержать разные типы значений, поэтому важно уметь отличать один тип значения ячейки от другого и использовать соответствующий метод для извлечения значения. Ниже приведен список всех типов значений:
НИКТО
ЦИФРОВОЙ
НИТЬ
ФОРМУЛА
ПУСТОЙ
логическое значение
ОШИБКА
Мы сосредоточимся на четырех основных типах значений ячеек: Numeric, String, Boolean и Formula
, где последний содержит вычисляемое значение первых трех типов.
Давайте создадим вспомогательный метод, который в основном будет проверять каждый тип значения и на основе этого будет использовать соответствующий метод для доступа к значению. Также можно обрабатывать значение ячейки как строку и извлекать ее с помощью соответствующего метода.
Стоит отметить две важные вещи. Во- первых, значения Date
хранятся как числовые
значения, а также, если тип значения ячейки — FORMULA
, нам нужно использовать метод getCachedFormulaResultType()
вместо метода getCellType()
, чтобы проверить результат вычисления формулы :
public static void printCellValue(Cell cell) {
CellType cellType = cell.getCellType().equals(CellType.FORMULA)
? cell.getCachedFormulaResultType() : cell.getCellType();
if (cellType.equals(CellType.STRING)) {
System.out.print(cell.getStringCellValue() + " | ");
}
if (cellType.equals(CellType.NUMERIC)) {
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(cell.getDateCellValue() + " | ");
} else {
System.out.print(cell.getNumericCellValue() + " | ");
}
}
if (cellType.equals(CellType.BOOLEAN)) {
System.out.print(cell.getBooleanCellValue() + " | ");
}
}
Теперь все, что нам нужно сделать, это вызвать метод printCellValue
внутри цикла ячеек, и все готово. Вот фрагмент полного кода:
...
for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
printCellValue(cell);
}
...
4. Вывод
В этой статье мы показали пример проекта для чтения файлов Excel и доступа к различным значениям ячеек с помощью Apache POI.
Полный исходный код можно найти на GitHub .