Статьи
YouTube-канал

Сохранение данных в формате Excel

Исходники

9 февраля 2020

Тэги: Apache, Excel, Java, Java 10, файлы.

Ранее мы рассматривали пример на тему Чтение данных из Excel. А сегодня узнаем, как можно сохранять данные в формате Excel. Для работы нам потребуются всё те же зависимости от Apache POI. Пример проекта на github прилагается.

Добавим необходимые зависимости в pom.xml.

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

Предположим, у нас есть такая структура данных для хранения имени клиента и его даты рождения:

public class ClientInfo {

    private final String name;
    private final LocalDate birthDate;

    // далее идут конструктор и геттеры для этих полей...

Теперь разберёмся, как создать файл Excel и записать туда данные. Причём в каждой строке Excel у нас будет не по 2, а по 3 ячейки. В третьей ячейке мы будем вычислять средствами Excel текущий возраст клиента.

Сначала создаём объект, представляющий книгу (файл) Excel с помощью класса XSSFWorkbook. Затем создаём лист в этой книге с помощью метода createSheet(). Затем первой строкой на лист добавляем заголовок, в котором будут указаны названия колонок в таблице (метод createHeader()). После этого построчно создаём ячейки с помощью метода createCells(). В конце создаём файловый поток вывода FileOutputStream, связанный с именем файла, который мы планируем создать. В конструкции try-with-resources сохраняем данные в этот файл (метод write()) и конце завершаем работу с книгой (метод close()).

public void write(String filename) throws IOException {
    var workbook = new XSSFWorkbook();
    var sheet = createSheet(workbook);
    createHeader(workbook, sheet);
    createCells(workbook, sheet);
    try (var outputStream = new FileOutputStream(filename)) {
        workbook.write(outputStream);
    }
    workbook.close();
}

Создание листа заключается в том, что мы создаём сам объект листа, а также задаём имя этого листа (отображается в Excel внизу листа). Для каждой колонки указываем её ширину в некоторых безразмерных единицах с помощью метода setColumnWidth().

private Sheet createSheet(XSSFWorkbook workbook) {
    var sheet = workbook.createSheet("Клиенты");
    sheet.setColumnWidth(0, 4000);
    sheet.setColumnWidth(1, 6000);
    sheet.setColumnWidth(2, 4000);
    return sheet;
}

Создаём заголовок и задаём стиль для него (метод createCellStyle()). В данном примере мы для фона заголовка задаём серый цвет. Также зададим шрифт для заголовка, отличный от стандартного. В данном случае мы выбираем жирный шрифт Arial размером в 14 пунктов (методы createFont(), setFontName(), setFontHeightInPoints(), setBold()).

private void createHeader(XSSFWorkbook workbook, Sheet sheet) {
    var header = sheet.createRow(0);

    var headerStyle = workbook.createCellStyle();
    headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

    var font = workbook.createFont();
    font.setFontName("Arial");
    font.setFontHeightInPoints((short) 14);
    font.setBold(true);
    headerStyle.setFont(font);

    var headerCell = header.createCell(0);
    headerCell.setCellValue("Имя");
    headerCell.setCellStyle(headerStyle);

    headerCell = header.createCell(1);
    headerCell.setCellValue("Дата рождения");
    headerCell.setCellStyle(headerStyle);

    headerCell = header.createCell(2);
    headerCell.setCellValue("Возраст");
    headerCell.setCellStyle(headerStyle);
}

Затем создаём три ячейки (createCell() c указанием номера ячейки), из которых будет состоять наш заголовок. Текст для ячейки задаём с помощью метода setCellValue(), а ранее созданный стиль - с помощью setCellStyle().

Теперь перейдём к созданию ячеек с данными.

private void createCells(XSSFWorkbook workbook, Sheet sheet) {
    var style = workbook.createCellStyle();
    style.setWrapText(true);
    var createHelper = workbook.getCreationHelper();
    style.setDataFormat(createHelper.createDataFormat().getFormat("dd.mm.yyyy"));
    sheet.setDefaultColumnStyle(1, style);

    for (var i = 0; i < CLIENTS.size(); i++) {
        var client = CLIENTS.get(i);
        var row = sheet.createRow(i + 1);

        var cell = row.createCell(0);
        cell.setCellValue(client.getName());

        cell = row.createCell(1);
        cell.setCellValue(client.getBirthDate());

        cell = row.createCell(2);
        cell.setCellFormula(String.format("TEXT(DATEDIF(B%s,NOW(),\"Y\"), \"0\")", i + 2));
    }
}

Создаём стиль для ячеек (метод createCellStyle()). Также для этого стиля определяем формат для ячеек с датами. В этом нам поможет вспомогательный класс, возвращаемый методом getCreationHelper(). Дни рождения клиентов будем отображать в формате dd.mm.yyyy. Теперь мы можем задать стиль по умолчанию для всей колонки. Дни рождения содержатся во второй колонке, поэтому вызываем метод setDefaultColumnStyle() с индексом 1. Важно задать стиль по умолчанию до начала заполнения самих ячеек данными. Мы могли бы также для задания стиля ячеек использовать и setCellStyle(), рассмотренный выше, но при большом количестве ячеек можно израсходовать лимит стилей, который допускает Excel.

Затем в цикле проходимся по списку, содержащему объекты ClientInfo. На каждой итерации создаём новую строку с указанием её порядкового номера, прибавляя 1, т.к. 0 строка - это заголовок таблицы. Обычные значение указываем с помощью метода setCellValue(). Третья колонка нашей таблицы будет содержать текущий возраст клиентов, динамически вычисляемый средствами Excel. Поэтому мы задаём не фиксированное значение, а формулу с помощью метода setCellFormula(). В формуле мы ссылаемся на колонку B, т.е. туда, где содержится дата рождения клиента. Затем в формуле вычисляется разница между текущей датой и датой рождения клиента в годах. После этого преобразуем полученное значение в текст для удобства отображения.

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


Облако тэгов

Kotlin, Java, Java 16, Java 11, Java 10, Java 9, Java 8, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Linux, Hibernate, Collections, Stream API, многопоточность, файлы, Nginx, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.

Последние статьи


Комментарии

20.04.2021 22:48 molochko

всем сердцем благодарю 🐥🧚🏻‍♂️ очень понятно и полезно

17.09.2021 16:05 Андрей

Скинь пожалуйста скриншоты того, что должно получится, дай например вывод и записи в Exel.

18.07.2022 21:32 Дмитрий

большое спасибо, просто, наглядно, работает!!!

Добавить комментарий

×

devmark.ru