QuestPDF силен, когда граница продукта — C#
QuestPDF заслуживает уважительного сравнения. Это современная библиотека генерации PDF для C#-разработчиков: fluent API, строгая типизация, большая документация, Companion App для предпросмотра и отладки, а также необычно понятная для PDF SDK модель лицензирования.
Вопрос не в том, какой продукт умеет создавать PDF. Оба умеют. Полезный вопрос — где должна проходить граница PDF: внутри .NET-приложения, которое владеет макетом, байтами и жизненным циклом, или на уровне инфраструктурного сервиса, к которому обращаются разные продукты и языки программирования.
Быстрый выбор
- Выбирайте QuestPDF, если C# является источником истины для документа, приложение должно работать офлайн или нужны локальные операции над существующими PDF.
- Выбирайте gPdf, если один PDF-слой должен обслуживать Node, Python, Go, .NET, фоновые задачи и региональные системы через один HTTP API.
- Выбирайте gPdf, если изменения макета должны быть версиями шаблона, а не пересборкой C# и повторным развертыванием сервиса.
Одна семья документов, разные модели владения
С QuestPDF приложение владеет генерацией PDF — это сильная сторона: C# находится рядом с доменной моделью, все запускается и отлаживается локально, без вызова внешнего API во время выполнения.
Компромисс в том, что команда владеет и всем боевым контуром:
- CPU и памятью для рендера.
- Поиском шрифтов и цепочками подстановки в каждой среде развертывания.
- Интеграцией библиотеки штрихкодов и проверкой печати.
- Нативными пакетами и вопросами развертывания для графиков или пользовательской графики.
- Мониторингом, повторами и обработкой отказов.
- Региональным развертыванием, если пользователи или склады распределены по миру.
- Выпусками при каждом изменении макета документа.
С gPdf эта область выносится наружу: приложение отправляет DocumentRequest или template_id + data, а сервис отвечает за рендерер, среду выполнения на edge, шрифты, примитивы штрихкодов, вывод PDF/A и упаковку электронных счетов. Это менее привлекательно, если вы хотите держать каждую деталь в C#, но лучше подходит, когда генерация PDF должна быть общим служебным слоем, вызываемым из любого стека.
Три компромисса, на которые хостинговый API должен отвечать честно
Большинство сравнений библиотеки и API обходят три вопроса, которые .NET-архитектор задает первыми. Честное сравнение проговаривает их напрямую.
1. Куда уходят данные документа. Эта страница в основном про счета, выписки и электронные счета — документы с именами, адресами, налоговыми идентификаторами и суммами. В QuestPDF эти байты создаются внутри вашего процесса и не покидают его. Публичный API gPdf передает тело запроса рендереру, но рендерер работает без хранения: JSON запроса находится в V8-изоляте Cloudflare Workers только во время рендера (обычно ~4 ms) и освобождается после завершения ответа — не сохраняется, не логируется, не попадает в выборки и не используется для обучения; операционные логи ограничены HTTP-статусом и длительностью (security, DPA). Выбор размещения данных в ЕС / глобально и enterprise on-prem / частное развертывание дополнительно сужают или закрывают внешний контур. Тем не менее генерация внутри процесса без настройки — вполне законная, иногда решающая причина, по которой финансовая или государственная команда выбирает QuestPDF.
2. Режим отказа. У библиотеки нет третьей стороны, которая может упасть; генерация может сломаться только на инфраструктуре, которой вы уже владеете. Хостинговый API добавляет зависимость от доступности поставщика, которую вы не контролируете. Правильный способ внедрять gPdf — относиться к вызовам рендера как к любому внешнему вызову: таймаут, повтор, очередь и, в идеале, деградированный резервный путь. Если генерация документов стоит на критическом синхронном пути, сравнивайте “эксплуатировать самим” с “зависеть от доступности поставщика”.
3. Профиль задержки. Генерация внутри процесса — это вызов функции без сети. Размещенный вызов — сетевой обмен туда-обратно. Для пакетных и асинхронных задач это шум. Для сценария “пользователь нажал кнопку, PDF должен появиться сейчас” генерация внутри процесса структурно быстрее; edge PoPs gPdf делают переход небольшим, но это все равно TLS плюс сетевой обмен, тогда как QuestPDF — вызов метода.
Это не делает gPdf неправильным выбором; это определяет, когда он правильный — для команд, чьи данные документов могут покидать процесс, чьи процессы выдерживают сетевой переход и которым выгоднее зависеть от доступности поставщика, чем самим эксплуатировать парк рендереров.
Лицензирование и модель цены
Публичная страница лицензирования QuestPDF говорит, что коммерческая лицензия требуется только компаниям с годовой валовой выручкой выше 1 млн USD. Уровень Community бесплатен по MIT-условиям для подходящих частных лиц, open-source-проектов, некоммерческих организаций и компаний ниже этого порога. На той же странице указаны два бессрочных коммерческих уровня: Professional за 999 USD плюс местные налоги для команд до 10 разработчиков и Enterprise за 2 999 USD плюс местные налоги на всю организацию без подсчета разработчиков. Оба тарифа включают один год обновлений и неограниченные проекты, серверы и развертывания, а лицензия не истекает для последней полученной версии.
Модель контроля тоже необычно легкая. Лицензия задается одной строкой — QuestPDF.Settings.License = LicenseType.Community; — без лицензионного ключа, сервера активации и, согласно собственной странице конфигурации QuestPDF, без сетевых вызовов и без вывода данных с машины. Это модель на доверии: вы выбираете уровень, на который имеете право. Нет счета поставщика за каждый документ, а платная лицензия работает где угодно, включая полностью офлайн.
gPdf тарифицирует сам сервис рендера. Публичный Basic plan начинается с 5 USD/мес. за 100 000 страниц, перерасход — от 0,00005 USD за страницу. Это счет поставщика, но он также убирает отдельный проект по эксплуатации генерации PDF: без кластера рендера, без пути развертывания NuGet, без регионального теплого пула, без пакета шрифтов для каждого приложения и без PDF-сервиса, который нужно патчить.
Поэтому сравнение стоимости — не “999 USD против 5 USD”; лицензия — малая строка. Реальное сравнение такое:
Стоимость QuestPDF = лицензия (разовая) + ваш хостинг + время инженеров + дежурства
Стоимость gPdf = счет за страницы (инфраструктура, шрифты, масштабирование и edge включены)
По публичной постраничной модели gPdf перерасход стоит 0,05 USD за 1 000 страниц (50 USD за 1 млн, 500 USD за 10 млн). Разовая лицензия Enterprise за 2 999 USD сравняется с этим счетом только примерно на 60 млн страницах — и этот расчет не учитывает хостинг QuestPDF и инженерные месяцы, которые сдвигают реальную точку пересечения дальше в пользу gPdf, если у вас уже нет почти бесплатной инфраструктуры рендера. Практическое правило: если ради библиотеки нужно построить и укомплектовать сервис рендера, gPdf обычно выигрывает по полной стоимости задолго до того, как постраничный счет догонит лицензию; если эта инфраструктура уже есть и почти бесплатна, бессрочная лицензия выигрывает на масштабе.
Процесс разработки: Fluent C# против шаблонов
Fluent API QuestPDF хорошо подходит, когда разработчики владеют формой документа. Строгая типизация, цепочки методов, переиспользуемые C# компоненты, рефакторинг в IDE и Companion App логичны, если PDF является частью кодовой базы приложения.
gPdf подходит другому процессу. Разработчики могут писать JSON напрямую, но боевые системы обычно переходят к шаблонам. Дизайнер, операционный специалист или инженер настраивает макет в gPdf Studio. Утвержденный макет становится шаблоном, а бэкенд продолжает рендерить через template_id + data.
Эта разница важна, когда документ часто меняется. Если меняется этикетка перевозчика, счет, упаковочный лист или макет выписки, gPdf может оставить среду выполнения стабильной и изменить только шаблон. В QuestPDF макет — это C# код, поэтому обычный путь: изменение кода, тест, сборка, развертывание и план отката.
Ни один процесс не лучше всегда: QuestPDF оптимизирован для C# разработчиков, которым нужен документ как код; gPdf — для операционных шаблонов, общих для нескольких систем.
Соответствие требованиям: оба продукта серьезные
Это не сравнение, где gPdf выигрывает заявлением, что у конкурента нет функций соответствия требованиям. Текущие публичные материалы QuestPDF перечисляют сильную поддержку стандартов, включая PDF/A, PDF/UA-1 и электронные счета EN 16931 через пример ZUGFeRD 2.1 / Factur-X на базе UN/CEFACT Cross Industry Invoice (CII). Этот пример включает PdfA = true, встраивает тело factur-x.xml через AddAttachment(), дополняет документ XMP-метаданными и валидирует результат через veraPDF (для PDF/A-3b) и Mustang Project (для ZUGFeRD). Это полный и честный рецепт — и ваш процесс владеет каждым его шагом.
gPdf упаковывает те же стандарты как API-контракт. JSON Render открывает шесть профилей PDF/A (1b, 2b, 3b, 4, 2u, 3u) плюс PDF/UA-1 через settings.profile, Template Render переиспользует ту же модель документа, а E-Invoice Render дает выделенный эндпоинт POST /api/v1/e-invoice/render, который создает пакеты Factur-X / ZUGFeRD PDF/A-3b со встроенным EN 16931 CII XML. Отличие от рецепта QuestPDF в том, что сервис делает за вас: gPdf выполняет PDF/A-3b и валидацию электронного счета на сервере, поддерживает синхронную выдачу в ответе или доставку через опрашиваемый объект и предлагает резидентность данных в ЕС или глобально как параметры запроса, а не как шаги, которые вы собираете и эксплуатируете. QuestPDF подходит, когда валидация должна жить внутри вашего .NET-процесса; gPdf — когда это должен быть хостинговый контракт, общий для многих систем.
Шрифты и штрихкоды: главное — усилия интеграции
У QuestPDF сильная модель шрифтов. Он поставляет Lato 2.015 по умолчанию, автоматически загружает системные шрифты и шрифты из каталога развертывания, позволяет регистрировать пользовательские шрифты через FontManager и поддерживает цепочки подстановки. Это дает разработчикам контроль. Но та же документация честно описывает проблему: “in most cloud deployments, few or no fonts are available, which may lead to unexpected results” и рекомендует отключать шрифты окружения и явно регистрировать нужные. Иначе говоря, в контейнере или бессерверной среде шрифтовое окружение — ваша зона планирования, упаковки и тестирования; отсутствующий глиф станет символом-заглушкой или, если включить CheckIfAllTextGlyphsAreAvailable, исключением.
gPdf делает шрифты частью границы сервиса. Рендерер включает набор для многих письменностей — латиницы, греческого, кириллицы, арабского, иврита, бенгальского, тамильского, тайского, вьетнамского, моноширинного текста и CJK с подстановкой по письменности на Noto KR / JP / SC. Он решает неявный выбор шрифта через авто-выбор, а явный выбор — через prefer или strict. Вызывающим приложениям не нужно отправлять CJK-шрифт, регистрировать ресурсы Noto в .NET-приложении или настраивать подстановку для каждой среды развертывания. Они отправляют данные; рендерер владеет шрифтовым окружением, одинаковым в каждом регионе.
Сравнение штрихкодов имеет похожую форму. Документация QuestPDF по штрихкодам показывает добротный подход с ZXing.Net, который рендерится как векторный SVG, и прямо отмечает, что ZXing.Net не входит в пакет QuestPDF — его устанавливают из NuGet и подключают отдельно:
// QuestPDF: add the separate ZXing.Net package, encode, render to SVG, embed.
// dotnet add package ZXing.Net
var writer = new ZXing.BarcodeWriterSvg {
Format = ZXing.BarcodeFormat.CODE_128,
Options = new ZXing.Common.EncodingOptions { Width = 320, Height = 80 }
};
string svg = writer.Write("INV-2026-001").Content;
container.Svg(svg);
// GS1-128 with Application Identifiers and FNC1 framing is hand-wired on top.
В gPdf генерация штрихкодов — полноценный элемент схемы. Запрос объявляет формат, содержимое, физический размер и опциональную человекочитаемую строку; форматы GS1 нативные, поэтому идентификаторы применения идут прямо в content:
{
"type": "barcode",
"format": "gs1_128",
"content": "(01)00012345678905(21)SN12345",
"layout": {
"left": 12,
"top": 60
},
"width": 80,
"height": 18,
"barcode_text": {
"enabled": true,
"position": "bottom"
}
}
Для одного .NET приложения установить ZXing.Net и протестировать вывод может быть легко. Для многих сервисов и шаблонов — особенно в логистике и рознице, где нужны GS1-128, SSCC, GTIN, GS1 DataMatrix или GS1 QR с человекочитаемой строкой интерпретации — проще поддерживать поведение штрихкодов внутри API документов, чем заново подключать ZXing в каждом сервисе.
Где QuestPDF явно выигрывает
Офлайн-работу и хранение данных документа внутри вашего периметра мы уже рассмотрели. Когда PDF-код является частью продукта и команде нужно проверять, расширять и контролировать путь рендера, QuestPDF также предлагает более широкие возможности в двух областях:
- Операции с существующими PDF. QuestPDF может загружать существующие файлы и объединять их, выбирать / переставлять / разворачивать / фильтровать страницы, накладывать оверлеи, добавлять вложения, задавать XMP-метаданные, линеаризовать для web-доставки, а также шифровать и расшифровывать с безопасностью 40/128/256-bit. gPdf может ставить пароль и ограничивать права для PDF, которые он генерирует, но не открывает, не объединяет и не расшифровывает файлы, созданные не им.
- Произвольные графики, карты и пользовательская графика. У gPdf теперь есть нативный векторный элемент
chartдля Bar, Line, Area, Combo, Pie и Donut с двумя осями значений, режимами накопления, четырьмя пресетами, градиентами и паттернами для печати. Однако QuestPDF предлагает более широкий выбор, если документу нужны другие типы графиков из ScottPlot / LiveCharts / Microcharts, карты Mapbox или неограниченное рисование через SkiaSharp.
Где gPdf явно выигрывает
gPdf выигрывает, когда организация не хочет, чтобы каждая продуктовая команда владела собственным PDF-сервисом: стеки на нескольких языках программирования, глобальные процессы и ERP / OMS / WMS / ecommerce / fintech / ticketing-системы, которые рендерят документы из структурированных данных, с шаблонами, меняющимися независимо от кода. В таких условиях локальная библиотека часто начинается дешево, а затем превращается в парк: один сервис на язык программирования, один путь развертывания на регион, один план шрифтов на контейнер, один набор регрессий штрихкодов на команду. gPdf превращает этот парк в один HTTP-контракт.
Бессерверная архитектура делает границу особенно явной. На AWS Lambda, Cloud Run или Azure Functions QuestPDF все равно работает внутри приложения — команда пакует среду выполнения .NET, шрифты, нативные зависимости и достаточно CPU / памяти для пиковых PDF-задач, а также отвечает за холодные старты. gPdf уже является сервисом рендера: функция отправляет небольшой запрос template_id + data на edge и получает PDF-байты обратно, без рендерера, который нужно прогревать, и без воркера в каждом регионе, который нужно масштабировать.
Как выглядит миграция
Миграция с QuestPDF на gPdf — не построчная перепись. Это смена границы: C# код, строящий PDF, становится либо JSON-запросом документа, либо опубликованным шаблоном.
До / после — C# вызов сборки документа сводится к одному HTTP POST (нажмите, чтобы раскрыть)
- // Before: generate the PDF inside a .NET application.
- Document.Create(container =>
- {
- container.Page(page =>
- {
- page.Size(PageSizes.A4);
- page.Margin(30);
- page.Header().Text("Invoice").FontSize(24).SemiBold();
- page.Content().Column(column =>
- {
- column.Item().Text($"Invoice number: {invoice.Number}");
- column.Item().Text($"Total: {invoice.Total:C}");
- });
- });
- })
- .GeneratePdf("invoice.pdf");
+
+ // After: render through the shared gPdf template from C#.
+ using System.Net.Http.Headers;
+ using System.Net.Http.Json;
+
+ using var client = new HttpClient();
+ client.DefaultRequestHeaders.Authorization =
+ new AuthenticationHeaderValue("Bearer", key);
+
+ var response = await client.PostAsJsonAsync(
+ "https://api.gpdf.com/api/v1/template-render",
+ new {
+ template_id = "invoice-v2",
+ data = new {
+ invoice_number = invoice.Number,
+ total = invoice.Total,
+ currency = invoice.Currency
+ }
+ });
+
+ response.EnsureSuccessStatusCode();
+ byte[] pdfBytes = await response.Content.ReadAsByteArrayAsync();
Когда эта граница переносится, изменения макета могут стать версиями шаблона вместо развертываний приложения. Приложение по-прежнему владеет бизнес-данными и решениями процесса; gPdf владеет рендерингом.
Примечание о ценах и источниках
Информация о QuestPDF на этой странице проверена 2026-06-02 по официальным источникам QuestPDF: License and Pricing, License configuration, Features Overview, Companion App features, Barcodes, Font management и ZUGFeRD example. Цены и страницы возможностей могут меняться; закупочным командам стоит перепроверить страницу поставщика перед решением о покупке. QuestPDF и связанные обозначения принадлежат их владельцам, это сравнение ими не одобрено.
Связанные сценарии генерации PDF
Если вы сравниваете QuestPDF и gPdf, рядом обычно возникают задачи API JSON в PDF, PDF счетов, API транспортных этикеток, GS1-128 и штрихкодов в PDF, API PDF/A, API Factur-X и генерации PDF без эксплуатации собственного сервиса рендера. Также полезно посмотреть отдельный разбор стоимости транспортных этикеток на iText и gPdf, если ваш сценарий ближе к логистике.
FAQ
Заменяет ли gPdf QuestPDF?
Нет. gPdf заменяет необходимость эксплуатировать сервис генерации PDF для структурированных бизнес-документов. QuestPDF остается сильной локальной C# библиотекой, когда PDF должен генерироваться внутри приложения.
QuestPDF бесплатен?
Публичная страница лицензирования QuestPDF говорит, что уровень Community бесплатен по MIT-условиям для подходящих частных лиц, open-source-проектов, некоммерческих организаций и компаний с годовой валовой выручкой ниже 1 млн USD. Компаниям выше этого порога нужна бессрочная коммерческая лицензия: Professional за 999 USD плюс местные налоги для команд до 10 разработчиков или Enterprise за 2 999 USD плюс местные налоги на всю организацию, каждый вариант включает один год обновлений.
Может ли gPdf генерировать графики или карты как QuestPDF?
Для распространенных отчетных графиков — да. Нативный векторный элемент chart в gPdf напрямую строит из JSON Bar, Line, Area, Combo, Pie и Donut; для однотипных графиков и Combo доступны две оси значений, обычное и процентное накопление, четыре пресета, градиенты и паттерны для печати. gPdf не предоставляет движок карт или универсальный API рисования. QuestPDF лучше подходит, если нужны другие библиотеки построения графиков для .NET, Mapbox или произвольное рисование через SkiaSharp; если нативного типа графика недостаточно, gPdf по-прежнему может встроить экспортированные ими SVG / PNG.
Какой продукт дешевле?
Зависит от границы. QuestPDF может быть дешевле для .NET-команд, которые подходят под условия Community или уже эксплуатируют инфраструктуру рендера. gPdf может быть дешевле, когда альтернатива — построить, разместить и обслуживать PDF-сервис для нескольких продуктов или регионов.
Хранит или логирует ли gPdf данные моих документов?
Нет. JSON, который вы отправляете, и PDF, который возвращает gPdf, не сохраняются. Каждый запрос рендерится внутри одного V8-изолята Cloudflare Workers, держится в памяти только во время рендера — обычно около 4 ms — и освобождается после завершения потока ответа; gPdf не сохраняет, не логирует, не берет выборки и не обучается на содержимом DocumentRequest. Операционные логи хранят только HTTP-статус и длительность 30 дней и не содержат тел запросов. См. security policy, privacy policy и DPA. Для нагрузок, которые вообще не могут передавать данные наружу, on-prem / частное развертывание удерживает их внутри вашего периметра.
Может ли QuestPDF работать без доступа к интернету?
Да. Страница конфигурации лицензии QuestPDF говорит, что лицензионный ключ и сервер активации не нужны, а вычисления выполняются локально. Это одна из самых ясных причин выбрать QuestPDF.
Может ли gPdf рендерить произвольные C# макеты QuestPDF?
Нет. gPdf не выполняет C# код макета. Миграция означает перевод формы документа в gPdf JSON-запрос или сохраненный gPdf шаблон.