phronCare/Transversal/Services/PuppeteerPdfGeneratorService.cs
Leandro Hernan Rojas fa5b51dc40
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 25m21s
Update PuppeteerPdfGeneratorService for Local USE
2026-01-12 16:22:19 -03:00

86 lines
3.3 KiB
C#

using System.Runtime.InteropServices;
using Microsoft.Extensions.Configuration;
using PuppeteerSharp;
using PuppeteerSharp.Media;
using Transversal.Interfaces;
using Transversal.Models;
namespace Transversal.Services
{
public class PuppeteerPdfGeneratorService : IPdfGeneratorService, IAsyncDisposable
{
private readonly Browser _browser;
public PuppeteerPdfGeneratorService(IConfiguration config)
{
string? executablePath = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/usr/bin/chromium" // Docker/Linux (NO TOCAR)
: ResolveWindowsBrowserPath(config); // Windows local
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
if (string.IsNullOrWhiteSpace(executablePath) || !File.Exists(executablePath))
throw new InvalidOperationException(
$"No se encontró un navegador. Verifique Puppeteer:ExecutablePath. Path evaluado: '{executablePath}'.");
}
_browser = Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
ExecutablePath = executablePath,
Args = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? new[] { "--no-sandbox", "--disable-setuid-sandbox" }
: Array.Empty<string>()
}).GetAwaiter().GetResult();
}
private static string? ResolveWindowsBrowserPath(IConfiguration config)
{
// 1) appsettings: "Puppeteer:ExecutablePath"
var configured = config["Puppeteer:ExecutablePath"];
if (!string.IsNullOrWhiteSpace(configured))
return configured;
// 2) fallbacks típicos (Chrome/Edge)
var candidates = new[]
{
@"C:\Program Files\Google\Chrome\Application\chrome.exe",
@"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
@"C:\Program Files\Microsoft\Edge\Application\msedge.exe",
@"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",
};
return candidates.FirstOrDefault(File.Exists);
}
public async Task<byte[]> 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();
}
}
}