Генерация PDF на сервере: FastReport, QuestPDF, шаблоны
↑ 5.6 Генерация документов и отчётов · → Следующая
Зачем это на собесе
Практический кейс: счета, акты, справки. Спрашивают, чем генерировать и как не положить сервис нагрузкой.
Объяснение
| Подход | Плюсы | Минусы |
|---|---|---|
| QuestPDF (код на C#, fluent API) | типобезопасно, тесты, без внешних зависимостей | вёрстка кодом; лицензия для коммерции (Community — до порога дохода) |
| FastReport / отчёты по шаблонам | дизайнер шаблонов, бизнес правит сам | коммерческая лицензия, движок тяжёлее |
| HTML → PDF (Chromium/Playwright, wkhtmltopdf) | вёрстка HTML/CSS, знакомо фронтендерам | тяжёлый браузер, потребление памяти |
| iText / PDFsharp | низкоуровневый контроль | больше кода, AGPL у iText |
| Word/ODT → PDF (LibreOffice) | шаблоны в Word | медленно, внешний процесс |
Document.Create(c => c.Page(page =>
{
page.Size(PageSizes.A4); page.Margin(30);
page.Header().Text($"Счёт № {inv.Number}").FontSize(20).Bold();
page.Content().Table(t =>
{
t.ColumnsDefinition(cd => { cd.RelativeColumn(4); cd.RelativeColumn(); cd.RelativeColumn(); });
foreach (var i in inv.Items) { t.Cell().Text(i.Title); t.Cell().Text(i.Qty.ToString()); t.Cell().Text(i.Total.ToString("N2")); }
});
page.Footer().AlignCenter().Text(x => { x.CurrentPageNumber(); x.Span(" / "); x.TotalPages(); });
})).GeneratePdf(stream);Архитектура:
- Генерация тяжёлая (CPU/память): выносите в фоновый воркер, очередь задач, ограничивайте параллелизм.
- Результат сохраняйте в объектное хранилище и отдавайте по ссылке (см. Хранение и отдача файлов через MinIO).
- Шаблон и данные разделены: данные собираются отдельной моделью (view model).
- Шрифты со встроенной кириллицей включайте явно.
Нюансы и подводные камни
- Кириллица и шрифты: без встроенного шрифта в контейнере вместо букв «квадратики».
- Генерация в HTTP-запросе на большом документе блокирует пул и вызывает таймауты.
- Повторная генерация одного документа: кэшируйте по хэшу данных и версии шаблона.
- PDF/A для архивного хранения, подписи и ЭЦП — отдельные требования.
- Тестируйте визуально (снимки страниц) и по тексту.
Практика
- Сгенерируйте счёт через QuestPDF со шрифтом с кириллицей.
- Вынесите генерацию в фоновый воркер и статус задачи в API.
- Сравните время и память QuestPDF и HTML→PDF на 500 страницах.
Вопросы с ответами
Чем генерировать PDF в .NET?
QuestPDF (код), FastReport (шаблоны), HTML→PDF через браузерный движок; выбор по требованиям к шаблонам и лицензиям.
Почему PDF нельзя генерировать в HTTP-обработчике?
Долго и тяжело: блокирует потоки и приводит к таймаутам; лучше очередь и отдача по готовности.
Как избежать проблем с кириллицей?
Встроить нужные шрифты в образ и явно указать их в документе.