Статьи Генератор паролей UUID MD5 Unix-время URL-encode Base64 Форматирование XML Ваш внешний IP Число прописью


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

Вернуться назад Исходники

10 февраля 2020

Тэги: 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"));

    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.setCellStyle(style);

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

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

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

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

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