Khi phát triển ứng dụng .NET yêu cầu xuất nội dung HTML dưới dạng ảnh (PNG/JPEG) hoặc tài liệu PDF, nhiều lựa chọn khả thi tồn tại — từ các thành phần tích hợp hệ thống đến thư viện mã nguồn mở và giải pháp thương mại. Dưới đây là phân tích kỹ thuật về bốn phương án phổ biến, tập trung vào tính khả thi triển khai, độ ổn định, khả năng hỗ trợ CSS/JS và mức độ kiểm soát đầu ra.
1. WebBrowser (WinForms) – Giải pháp thuần .NET nhưng giới hạn nghiêm trọng
Thành phần System.Windows.Forms.WebBrowser cho phép render HTML bằng engine MSHTML (Internet Explorer), sau đó chụp toàn bộ vùng hiển thị vào Bitmap. Không cần cài đặt phụ trợ hay package bên ngoài, nên rất nhẹ về mặt cấu hình:
public static async Task<byte[]> RenderHtmlToPngAsync(string htmlContent, int width = 1200, int height = 800)
{
var tcs = new TaskCompletionSource<byte[]>();
// Chạy trên STA thread bắt buộc
await Task.Run(() =>
{
using var app = new Application();
using var browser = new WebBrowser { Width = width, Height = height };
browser.ScrollBarsEnabled = false;
browser.DocumentCompleted += (_, _) =>
{
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
var bitmap = new Bitmap(width, height);
browser.DrawToBitmap(bitmap, new Rectangle(0, 0, width, height));
using var ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Png);
tcs.SetResult(ms.ToArray());
}
};
browser.DocumentText = htmlContent;
while (browser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
});
return await tcs.Task;
}
Tuy nhiên, giải pháp này gặp nhiều vấn đề thực tế: không hoạt động trên môi trường non-UI (.NET Core console, ASP.NET Core), dễ treo khi xử lý HTML phức tạp hoặc có script nặng, không hỗ trợ modern CSS (Flexbox, Grid), font nhúng thường bị thay thế, và không đảm bảo tính nhất quán giữa các phiên bản Windows. Không phù hợp cho production.
2. wkhtmltopdf/wkhtmltoimage – Công cụ dòng lệnh dựa trên WebKit
Đây là công cụ mã nguồn mở được viết bằng C++, sử dụng WebKit để render — mang lại chất lượng đầu ra tốt hơn WebBrowser, đặc biệt với layout CSS3 và font vector. Cách tích hợp trong .NET là gọi tiến trình con:
public static async Task<bool> ConvertUrlToPdfAsync(string url, string outputPath, bool landscape = true)
{
var startInfo = new ProcessStartInfo
{
FileName = "wkhtmltopdf.exe",
Arguments = $"--no-stop-slow-scripts --quiet {(landscape ? "--orientation landscape" : "")} \"{url}\" \"{outputPath}\"",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true
};
using var proc = Process.Start(startInfo);
await proc.WaitForExitAsync();
return proc.ExitCode == 0;
}
Ưu điểm: ổn định, hỗ trợ header/footer, watermark, page numbering, và tùy chỉnh qua CSS @page. Nhược điểm: phải cài đặt binary riêng trên mỗi máy chủ, khó quản lý phiên bản, không hỗ trợ JavaScript động đầy đủ (do WebKit cũ), và không chạy được trên môi trường không có X11 (Linux headless cần thêm xvfb).
3. PuppeteerSharp – Giao diện .NET cho Chromium Headless
PuppeteerSharp là bản port chính thức của Puppeteer (Node.js) sang .NET, dùng Chromium làm nền tảng render — do đó đạt độ tương thích cao nhất với HTML/CSS/JS hiện đại. Nó tự động tải và quản lý phiên bản Chromium tương thích:
public static async Task<byte[]> CapturePageAsPngAsync(string url, bool fullPage = true, int? viewportWidth = null, int? viewportHeight = null)
{
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
Args = new[] { "--no-sandbox", "--disable-gpu", "--font-render-hinting=none" }
});
await using var page = await browser.NewPageAsync();
if (viewportWidth.HasValue && viewportHeight.HasValue)
await page.SetViewportAsync(new ViewPortOptions { Width = viewportWidth.Value, Height = viewportHeight.Value });
await page.GoToAsync(url, new NavigationOptions { WaitUntil = new[] { WaitUntilNavigation.NetworkIdle0 } });
return await page.ScreenshotDataAsync(new ScreenshotOptions { FullPage = fullPage });
}
Tính năng nổi bật: hỗ trợ service workers, WebGL, canvas, đánh giá JS đồng bộ/dị bộ, emulation thiết bị di động, chặn/ghi log network request, và debug qua DevTools Protocol. Nhược điểm duy nhất là kích thước triển khai lớn (Chromium ~250MB), nên khuyến nghị triển khai dưới dạng microservice độc lập hoặc container hóa.
4. IronPdf – Thư viện thương mại với API đơn giản và tích hợp sâu
IronPdf là giải pháp đóng gói, hỗ trợ cả .NET Framework và .NET Core, không yêu cầu binary bên ngoài — vì nó nhúng một phiên bản tối ưu hóa của Chromium (không cần download runtime). Cách dùng trực quan và ít lỗi:
public static byte[] GeneratePdfFromHtml(string html, bool enableJs = true)
{
var renderer = new HtmlToPdf
{
RenderingOptions = {
EnableJavaScript = enableJs,
PaperSize = PdfPrintOptions.PaperSize.A4,
MarginTop = 10,
MarginBottom = 10
}
};
return renderer.RenderHtmlAsPdf(html).ToArray();
}
Ngoài chuyển đổi HTML → PDF/PNG, IronPdf còn hỗ trợ chỉnh sửa PDF (thêm watermark, merge, split), chèn hình ảnh/vector, đọc metadata, và xuất từ URL hoặc stream. Phiên bản miễn phí cho phép dùng trong môi trường dev/test với watermark "Evaluation License". Ưu điểm rõ rệt: không cần quản lý binary, hỗ trợ đa nền tảng ngay lập tức, tài liệu chi tiết và ví dụ phong phú.