Генерация больших Excel отчетов без таймаутов: опыт внедрения Spring Batch

20 марта 2026

Как организовать пакетную генерацию Excel отчетов на Java, чтобы пользователи могли запускать десятки и сотни документов за раз без зависаний и таймаутов? Разбираем архитектуру решения на Spring Batch, схему обработки, расчет прогресса и интеграцию с фронтендом.

Проблема генерации больших Excel отчетов

В одном из реализованных нами продуктов, предназначенном для автоматизации бизнес-процессов ремонта авиационных двигателей, нам регулярно нужно переводить бизнес сущности в физический формат. Речь идет о рабочих картах с пошаговыми инструкциями и маршрутных листах, которые формируются в Excel или PDF и далее распечатываются на производстве.

На практике пользователи могут запускать печать десятков или сотен документов одновременно. Если обрабатывать большой объем данных синхронно в рамках одного HTTP запроса, система неизбежно упирается в таймауты. Браузер ждет ответ, сервер удерживает соединение, ресурсы блокируются.

На Python бэкенде для подобных задач используется Celery с Redis в роли брокера и оркестратора. Для Java сервиса мы выбрали Spring Batch — фреймворк, предназначенный для пакетной обработки данных с поддержкой чанков, хранения состояния и восстановления после сбоев.

Архитектура Spring Batch: Job, Step, Tasklet

Spring Batch строится вокруг трех ключевых понятий (подробнее в официальной документации или в более коротком туториале на Baeldung):

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

Step — логически завершенный этап внутри Job.Step может быть:

  • chunk oriented — чтение, обработка и запись порциями 
  • tasklet based — выполнение одной атомарной операции 

Tasklet — интерфейс для шага, который выполняет одно действие и завершает работу.

Такое разделение позволяет разбить процесс генерации Excel отчетов на независимые этапы и управлять ими централизованно.

Разбиение процесса генерации Excel на шаги

В нашем случае шаги выглядят так:

Picture   2026 03 20 T153128.448

Шаг 1. PRINT — генерация Excel

На вход Step поступает подготовленный список данных. Конфигурация Spring Batch разбивает его на чанки по 10 элементов.

Каждый чанк проходит через:

  • reader — получает порцию данных 
  • processor — конвертирует их в Excel файл 
  • writer — сохраняет результат на диск 

@Bean

@JobScope

public Step printTrpTagsStep(

        ItemReader<TrpTagForPrintModel> excelTrpTagItemReader,

        ItemProcessor<TrpTagForPrintModel, ExcelItem> excelTrpTagItemProcessor,

        ItemWriter<ExcelItem> excelTrpTagItemWriter

) {

    return new StepBuilder(BatchExcelPrintStep.PRINT.getCode(), jobRepository)

 

    .<TrpTagForPrintModel, ExcelItem>chunk(10)

            .transactionManager(transactionManager)

            .reader(excelTrpTagItemReader)

            .processor(excelTrpTagItemProcessor)

            .writer(excelTrpTagItemWriter)

            .build();

}

Spring Batch автоматически ведет счетчик writeCount. Это позволяет отслеживать прогресс генерации и не держать все файлы в памяти одновременно.

Структура временных файлов после завершения шага PRINT:

/tmp/engine/{timestamp}/

├── models.json

└── zip/

    ├── kitting-list-1/

    │   ├── Off_Tag_FERRULE.xlsx

    │   └── Off_Tag_FERRULE (1).xlsx

    └── kitting-list-2/

        └── Off_Tag_BLADE.xlsx

Шаг 2. ZIP — архивирование

После завершения генерации отдельный Tasklet проходит по директории и упаковывает все файлы в единый ZIP архив стандартными средствами Java.

Шаг 3. UPLOAD — загрузка в S3

Готовый архив загружается в S3. Ссылка на файл сохраняется в ExecutionContext.

Шаг 4. CLEAN_UP — очистка временных файлов

После успешной загрузки временные файлы удаляются из каталога /tmp пода.

Если Job завершится с ошибкой до этапа очистки, используется JobExecutionListener. В нем проверяется статус выполнения, и при необходимости запускается логика удаления временных данных.

Параллельная генерация Excel документов

Spring Batch поддерживает параллельное выполнение шагов. В нашем случае этого не потребовалось. Для масштабирования мы используем Thread Pool и запускаем несколько Job параллельно.

Это позволяет обрабатывать несколько запросов пользователей одновременно без усложнения внутренней логики одного Job.

Отображение прогресса генерации на фронтенде

Асинхронная генерация Excel отчётов требует прозрачного механизма отслеживания статуса.

API для отслеживания статуса

После запуска Job клиент получает jobExecutionId. Фронтенд периодически опрашивает endpoint статуса и получает актуальные данные о выполнении.

POST /trp-tag/print/excel/batch/start → { jobExecutionId: 12345 }

GET  /trp-tag/print/excel/batch/12345 → { status, progressPercentage, downloadUrl, ... }

Расчет прогресса

Шаги имеют разную продолжительность. Генерация Excel занимает около 90 процентов времени, архивирование, загрузка и очистка — оставшиеся 10 процентов.

Для шага PRINT прогресс рассчитывается пропорционально через writeCount — встроенный счетчик Spring Batch, который увеличивается после каждого чанка.

Для остальных шагов используется бинарная логика: либо этап не выполнен, либо выполнен полностью.

Фронтенд получает все необходимое, чтобы пользователь видел понятный прогресс:

  • progressPercentage — значение для прогресс-бара 
  • currentStepNumber и totalStepsNumber — текстовый индикатор шага 
  • status — STARTED, COMPLETED или FAILED 
  • downloadUrl — ссылку на скачивание архива 
  • failureDetails — описание ошибки при сбое 
  • durationMillis — общее время выполнения 

Что дало внедрение Spring Batch

Асинхронность.

Пользователь мгновенно получает идентификатор задачи, а не ждет завершения генерации. Это принципиально изменило UX: вместо зависшего экрана — прогресс-бар с процентом выполнения.

Прозрачность и контроль.

Spring Batch автоматически сохраняет данные о Job и Step Execution в PostgreSQL. Мы получили историю запусков, длительность выполнения, счетчики обработанных элементов и информацию об ошибках без дополнительной инфраструктуры.

Управление состоянием.

Фреймворк берет на себя транзакционность, персистентность состояния и корректное завершение шагов. При использовании простых асинхронных методов такую логику пришлось бы реализовывать вручную при использовании простых @Async-методов. 

Итог

Spring Batch оказался оптимальным решением для пакетной генерации больших Excel отчетов в Java сервисе. Он позволяет обрабатывать сотни документов без таймаутов, контролировать прогресс в реальном времени и сохранять устойчивость системы при сбоях.

Если перед вами стоит задача массовой генерации документов, архивирования и загрузки в файловое хранилище, архитектура на базе Spring Batch дает управляемость, масштабируемость и прозрачность на уровне продакшена.

Недавние публикации

Еще по теме

Похожие бизнес-задачи и решения, которые мы нашли, проверили и внедрили

Система удаленного мониторинга и управления нефтяными скважинами

Работа со скважинами предъявляет высокие требования не только к оборудованию, но и к программному обеспечению. Оно должно стабильно работать при нестабильной связи, поддерживать оборудование разных производителей, безопасно передавать данные и помогать инженерам принимать решения на основе актуальной информации.

В этом кейсе рассказываем, как совместная команда специалистов заказчика и True Engineering разработали систему удаленного мониторинга и управления нефтяными скважинами.

Корпоративное приложение для 150 000 сотрудников сети быстрого питания: как мы спроектировали единую экосистему сервисов

Как объединить 150 000 сотрудников, если у большинства нет доступа к корпоративным системам с рабочего компьютера? Для сети ресторанов быстрого питания мы спроектировали мобильную экосистему, которая собрала в одном окне ключевые HR-сервисы, коммуникации, льготы и инструменты поддержки с учетом высокой нагрузки, требований безопасности и сценариев использования на личных устройствах.

S7 Airlines: автоматизировали 90% кассовых операций и перевели всю сеть офисов на новую систему за сутки — без потери данных и остановки продаж

Централизованная аутентификация и SSO на базе Keycloak для корпоративных систем

Крупная сеть ресторанов столкнулась с типичной проблемой растущей IT-инфраструктуры: десятки систем с разными механизмами авторизации, множественные интеграции и отсутствие единого управления доступами. Мы построили централизованную систему аутентификации на базе Keycloak, объединив офисные и ресторанные системы в единую точку входа.

Опросы без Google Forms: как построить корпоративный сервис сбора данных под задачи бизнеса

В корпоративной среде обратную связь приходится собирать регулярно - от сотрудников, клиентов, партнеров. Публичные инструменты вроде Google Forms и «Яндекс Форм» удобны для простых задач, но часто не подходят компаниям с высокими требованиями к безопасности и множеством интеграций. Мы рассказываем, как создали сервис опросов, который стал частью корпоративной экосистемы.