TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2879 2.46K
День 2393. #ЗаметкиНаПолях
PDF из HTML в .NET (бесплатно). Продолжение

Начало. Создание шаблона

3. Рендеринг шаблона
Мы используем Handlebars для компиляции шаблона с данными, а затем PuppeteerSharp для рендеринга в PDF.

Сначала прочитаем файл шаблона, скомпилируем его с помощью Handlebars и заполним данными:
var tmplt = File.ReadAllText(
"Templates/InvoiceTemplate.html");

var data = new {
IssuedDate = new DateOnly(2025, 08, 19),
Number = 12345,
…
LineItems = new[] {
new { Name = "Software License", Price = 99d },
new { Name = "Support Plan", Price = 49d }
}
};

// ... регистрируем вспомогательные функции Handlebars до вызова компиляции ...

var compiledTmplt = Handlebars.Compile(tmplt);

var html = compiledTmplt(data);

Это даст нам финальный HTML-код, в котором все заместители заменены реальными данными.

Примечание: не обязательно использовать Handlebars. Можно использовать любой шаблонизатор, например, Razor или Scriban.

4. Преобразование в PDF
Мы запустим браузер без UI, установим получившийся HTML код как его контент и сгенерируем PDF-файл:
// Скачиваем бинарные файлы браузера 
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();

// Запускаем браузер и создаём страницу
using var browser = await Puppeteer.LaunchAsync(
new LaunchOptions { Headless = true });
using var page = await browser.NewPageAsync();

// Устанавливаем контент страницы
await page.SetContentAsync(html);

// Не обязательно: ждём загрузки шрифтов
await page.EvaluateExpressionHandleAsync(
"document.fonts.ready");

// Настраиваем PDF
byte[] pdf = await page.PdfDataAsync(
new PdfOptions {
Format = PaperFormat.A4,
PrintBackground = true,
MarginOptions = new MarginOptions
{
Top = "50px",
Right = "20px",
Bottom = "50px",
Left = "20px"
}
});

В начале нам нужно скачать движок Chromium для рендеринга HTML страницы. PuppeteerSharp требует загрузки исполняемых файлов браузера Chromium во время выполнения. Это можно сделать, вызвав BrowserFetcher.DownloadAsync(). Это займёт какое-то время в первый раз, далее PuppeteerSharp будет использовать скачанные бинарные файлы.

В итоге в переменной pdf мы получим массив байтов, содержащий данные PDF-файла. Вы можете сохранить его в файл или вернуть из конечной точки API. Например, так:
return Results.File(pdf, "application/pdf", "invoice.pdf");


Окончание следует…

Источник:
https://www.milanjovanovic.tech/blog/pdf-reporting-in-dotnet-with-html-templates-and-puppeteersharp
  • 👍 7
More from @netdeveloperdiary
  1. Oct 2, 2026День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пос…
  2. Oct 1, 2026Post #3357
  3. Sep 30, 2026Post #3356
  4. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  5. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  6. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →