using Transversal.Interfaces; using Transversal.Models; using PuppeteerSharp; using PuppeteerSharp.Media; namespace Transversal.Services { public class PuppeteerPdfGeneratorService : IPdfGeneratorService, IAsyncDisposable { private readonly Browser _browser; public PuppeteerPdfGeneratorService() { // Descargar Chromium si no está new BrowserFetcher().DownloadAsync().GetAwaiter().GetResult(); // Lanzar Chromium persistente _browser = Puppeteer.LaunchAsync(new LaunchOptions { Headless = true, ExecutablePath = "/usr/bin/chromium", Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" } }).GetAwaiter().GetResult(); } public async Task GeneratePdfFromHtmlAsync(string htmlContent, PdfGenerationOptions options = null) { options ??= new PdfGenerationOptions(); using var page = await _browser.NewPageAsync(); await page.SetContentAsync(htmlContent); var pdfOptions = new PdfOptions { Format = options.Format, Landscape = options.Landscape, PrintBackground = options.PrintBackground, Scale = options.Scale, MarginOptions = options.Margins ?? new MarginOptions(), DisplayHeaderFooter = !string.IsNullOrEmpty(options.HeaderTemplate) || !string.IsNullOrEmpty(options.FooterTemplate), HeaderTemplate = options.HeaderTemplate, FooterTemplate = options.FooterTemplate }; return await page.PdfDataAsync(pdfOptions); } public async ValueTask DisposeAsync() { if (_browser != null) await _browser.CloseAsync(); } } }