IRONPDF 사용 Create PDF in C# 14: Advanced Guide Using Visual Studio Code in 2025 제이콥 멜러 업데이트됨:1월 21, 2026 다운로드 IronPDF NuGet 다운로드 DLL 다운로드 윈도우 설치 프로그램 무료 체험 시작하기 LLM용 사본 LLM용 사본 LLM용 마크다운 형식으로 페이지를 복사하세요 ChatGPT에서 열기 ChatGPT에 이 페이지에 대해 문의하세요 제미니에서 열기 제미니에게 이 페이지에 대해 문의하세요 Grok에서 열기 Grok에게 이 페이지에 대해 문의하세요 혼란 속에서 열기 Perplexity에게 이 페이지에 대해 문의하세요 공유하다 페이스북에 공유하기 트위터에 공유하기 LinkedIn에 공유하기 URL 복사 이메일로 기사 보내기 Creating PDFs in C# is an essential skill for modern .NET developers, whether you're building financial reports, generating healthcare documents, or producing e-commerce receipts. With the right .NET PDF library, you can transform HTML content into professional PDF documents with just a few lines of code, giving you complete control over document structure and appearance. IronPDF is the simplest, most usable .NET PDF creation library by a long way - with an incredibly easy learning curve that gets you generating PDFs in minutes, not hours. This comprehensive guide will show you exactly how to create PDF documents in C# using IronPDF - a powerful C# PDF generator that produces pixel-perfect results and supports every modern .NET platform, including the upcoming .NET 10 release in November 2025. While this tutorial covers everything from the simplest use cases to the most advanced PDF generation scenarios, don't get intimidated - start from the beginning and work forwards. You'll learn multiple ways to generate PDFs, from simple HTML strings to complex multi-page reports, plus how to troubleshoot common issues and optimize performance for various PDF generation tasks. When you need help, IronPDF's support team consists of actual engineers who understand your challenges. With 24/7 live chat support and typical response times under 30 seconds, you're never stuck waiting for answers. This level of support is why developers consistently rate IronPDF as having the best support in the industry. The support team can help with everything fr# How to Create PDFs in C# - The Complete Guide to PDF Generation in .NET Quick Start: Create Your First PDF in C# (Under 2 Minutes) Want to generate a PDF right now? Let's create a simple but functional PDF document that demonstrates the power of modern PDF generation in .NET. First, install IronPDF via NuGet Package Manager - this single package contains everything you need to start creating PDFs immediately. IronPDF is free for development, so you can experiment with all features before deciding on a license. Install-Package IronPdf Now let's create PDF content using C#: using IronPdf; // Instantiate the PDF generator - this is your gateway to PDF creation var renderer = new ChromePdfRenderer(); // Create a PDF from HTML string - yes, it's really this simple! var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>PDF generated successfully!</p>"); // Save your newly created PDF document pdf.SaveAs("my-first-pdf.pdf"); Console.WriteLine("PDF generated successfully!"); using IronPdf; // Instantiate the PDF generator - this is your gateway to PDF creation var renderer = new ChromePdfRenderer(); // Create a PDF from HTML string - yes, it's really this simple! var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>PDF generated successfully!</p>"); // Save your newly created PDF document pdf.SaveAs("my-first-pdf.pdf"); Console.WriteLine("PDF generated successfully!"); $vbLabelText $csharpLabel That's it! You just created your first PDF document in C#. No need to learn complex PDF APIs, no server dependencies to install, no low-level PDF commands to master. Just HTML in, PDF out - the way PDF generation should be. But this is just the beginning - let's explore why this approach is so powerful and how you can create more sophisticated PDF documents. How to Create a PDF in C#: A Quick Overview To create a PDF in C#, you can utilize third-party libraries like IronPDF, QuestPDF, or PDFsharp. These libraries offer various functionalities, including creating PDFs from scratch, converting HTML to PDF, and more. Here's a general outline of the process: Install a PDF library: Use NuGet Package Manager in Visual Studio to install a suitable library. Create a new PDF document: Instantiate a PDF document object. Add content: Add pages, text, images, and other elements to the document. Save the document: Specify a file path and save the PDF. Here's an example using IronPDF: using IronPdf; public class Example { public static void CreatePdf() { // Create a new PDF document var pdf = new ChromePdfRenderer(); // Add some text string htmlContent = "<h1>Hello, PDF!</h1><p>This is a dynamically created PDF.</p>"; // Render HTML to PDF var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent); // Save the PDF pdfDocument.SaveAs("MyDynamicPdf.pdf"); } } using IronPdf; public class Example { public static void CreatePdf() { // Create a new PDF document var pdf = new ChromePdfRenderer(); // Add some text string htmlContent = "<h1>Hello, PDF!</h1><p>This is a dynamically created PDF.</p>"; // Render HTML to PDF var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent); // Save the PDF pdfDocument.SaveAs("MyDynamicPdf.pdf"); } } $vbLabelText $csharpLabel Now, let's dive deeper into why developers need to create PDFs and explore the many ways IronPDF makes this process simple and powerful. Why Would Developers Need to Create PDFs in C#? Creating PDFs programmatically in C# opens up a world of possibilities for automating document generation and streamlining business processes. IronPDF has been trusted by over 14 million installed developers globally to achieve these tasks because it provides unmatched reliability and ease of use for building PDFs in .NET. In finance, developers use C# to create PDF invoices, statements, and regulatory reports that require precise formatting and security features. Healthcare organizations generate patient records, lab results, and insurance forms as PDFs to ensure document integrity and HIPAA compliance. E-commerce platforms produce PDF receipts, shipping labels, and tickets with QR codes (using tools like IronQR) embedded directly in the PDF. The ability to manipulate PDF documents programmatically means you can create, modify, and secure documents at scale without manual intervention. The beauty of using a modern .NET PDF library like IronPDF is that it seamlessly integrates into your organization's existing workflows. Whether you're converting Word documents from your business users, transforming Markdown documentation from your development team, or generating PDFs from web-based reports, IronPDF handles it all. This organizational flexibility is why companies choose programmatic PDF generation in .NET - it eliminates manual document creation, reduces errors, ensures consistency across all generated PDFs, and saves countless hours of employee time. Instead of learning proprietary PDF syntax or positioning every element manually, you can use HTML and CSS to design your documents. This approach dramatically reduces development time and makes it easy to maintain consistent branding across all your produced PDFs. Whether you're creating a single-page invoice or a complex multi-chapter report, the principles remain the same - design with HTML, generate PDFs with C#. Setting Up IronPDF in Your C# Project Before diving into creating PDFs, let's ensure your development environment is properly configured for optimal PDF generation. IronPDF supports all modern .NET versions, including .NET 8, .NET 9, and is already compliant with the upcoming .NET 10 release scheduled for November 2025 (Iron Software works closely with the .NET Foundation and Microsoft to ensure day-one compatibility). The setup process is straightforward, but understanding your options helps you choose the best approach for your specific needs. Installation Methods Method 1: Visual Studio Package Manager (Recommended for Beginners) The easiest way to get started with IronPDF is through Visual Studio's built-in NuGet Package Manager. This graphical interface makes it simple to browse, install, and manage your PDF generation dependencies: Right-click your project in Solution Explorer Select "Manage NuGet Packages" Click "Browse" and search for "IronPDF" Select the IronPdf package by Iron Software Click Install and accept the license agreement Method 2: Package Manager Console For developers who prefer command-line tools, the Package Manager Console provides a quick way to install IronPDF: Install-Package IronPdf Method 3: .NET CLI (For Cross-Platform Development) If you're working on macOS, Linux, or prefer the .NET CLI, use this command in your project directory: dotnet add package IronPdf Choosing the Right Package IronPDF offers different NuGet packages optimized for various deployment scenarios. Understanding these options helps you minimize deployment size and optimize performance: IronPdf: The standard package that includes everything you need for Windows, macOS, and Linux. Perfect for most applications. IronPdf.Slim: A lightweight base package that downloads platform-specific components at runtime. Ideal for cloud deployments where package size matters. IronPdf.Linux: Optimized specifically for Linux deployments with all required dependencies pre-packaged. IronPdf.MacOs: Tailored for macOS environments with native Apple Silicon support. 참고해 주세요For cloud deployments on Azure, AWS, or Docker, consider using IronPdf.Slim to reduce your container size. The required components will be downloaded automatically on first use. Verifying Your Installation After installation, verify everything is working correctly with this simple test that creates a new document: using IronPdf; using System.IO; // Test your IronPDF installation var renderer = new ChromePdfRenderer(); var testPdf = renderer.RenderHtmlAsPdf("<p>Installation test successful!</p>"); testPdf.SaveAs("test.pdf"); if (File.Exists("test.pdf")) { Console.WriteLine("IronPDF installed and working correctly!"); } using IronPdf; using System.IO; // Test your IronPDF installation var renderer = new ChromePdfRenderer(); var testPdf = renderer.RenderHtmlAsPdf("<p>Installation test successful!</p>"); testPdf.SaveAs("test.pdf"); if (File.Exists("test.pdf")) { Console.WriteLine("IronPDF installed and working correctly!"); } $vbLabelText $csharpLabel What Are the Different Ways to Generate PDFs in C#? IronPDF provides multiple approaches to build PDF documents, each suited to different scenarios and requirements. Understanding these methods helps you choose the most efficient approach for your specific use case when you need to produce PDFs in .NET. Whether you're creating PDFs from scratch with HTML strings, converting existing files, or capturing live web content, IronPDF has you covered as a comprehensive C# PDF generator. Let's explore each method in detail with practical examples that demonstrate real-world applications for PDF creation in C#. 1. Create PDF from HTML String (Most Flexible) Creating PDFs from HTML strings gives you complete control over the content and styling of your final document when you need to convert HTML content to PDF format. This method is perfect for generating dynamic reports, invoices, or any document where the content changes based on data. You can convert HTML content into professional PDFs using modern HTML5 and CSS3 features, including flexbox and grid layouts. The ability to dynamically convert HTML content makes this the most versatile approach for PDF creation in C#: using IronPdf; using System; using System.Linq; var renderer = new ChromePdfRenderer(); // Build dynamic content with data var customerName = "Acme Corporation"; var orderDate = DateTime.Now; var items = new[] { new { Name = "Widget Pro", Price = 99.99m }, new { Name = "Gadget Plus", Price = 149.99m } }; // Create HTML with embedded data and modern CSS var html = $@" <html> <head> <style> body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 40px; color: #333; }} .invoice-header {{ display: flex; justify-content: space-between; border-bottom: 2px solid #0066cc; padding-bottom: 20px; }} .items-table {{ width: 100%; margin-top: 30px; border-collapse: collapse; }} .items-table th {{ background: #f0f0f0; padding: 10px; text-align: left; }} </style> </head> <body> <div class='invoice-header'> <div> <h1>Invoice</h1> <p>Customer: {customerName}</p> </div> <div> <p>Date: {orderDate:yyyy-MM-dd}</p> <p>Invoice #: INV-{orderDate:yyyyMMdd}-001</p> </div> </div> <table class='items-table'> <thead> <tr> <th>Item</th> <th>Price</th> </tr> </thead> <tbody>"; foreach (var item in items) { html += $@" <tr> <td>{item.Name}</td> <td>${item.Price:F2}</td> </tr>"; } html += @" </tbody> </table> </body> </html>"; // Generate the PDF document var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs($"invoice-{orderDate:yyyyMMdd}.pdf"); using IronPdf; using System; using System.Linq; var renderer = new ChromePdfRenderer(); // Build dynamic content with data var customerName = "Acme Corporation"; var orderDate = DateTime.Now; var items = new[] { new { Name = "Widget Pro", Price = 99.99m }, new { Name = "Gadget Plus", Price = 149.99m } }; // Create HTML with embedded data and modern CSS var html = $@" <html> <head> <style> body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 40px; color: #333; }} .invoice-header {{ display: flex; justify-content: space-between; border-bottom: 2px solid #0066cc; padding-bottom: 20px; }} .items-table {{ width: 100%; margin-top: 30px; border-collapse: collapse; }} .items-table th {{ background: #f0f0f0; padding: 10px; text-align: left; }} </style> </head> <body> <div class='invoice-header'> <div> <h1>Invoice</h1> <p>Customer: {customerName}</p> </div> <div> <p>Date: {orderDate:yyyy-MM-dd}</p> <p>Invoice #: INV-{orderDate:yyyyMMdd}-001</p> </div> </div> <table class='items-table'> <thead> <tr> <th>Item</th> <th>Price</th> </tr> </thead> <tbody>"; foreach (var item in items) { html += $@" <tr> <td>{item.Name}</td> <td>${item.Price:F2}</td> </tr>"; } html += @" </tbody> </table> </body> </html>"; // Generate the PDF document var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs($"invoice-{orderDate:yyyyMMdd}.pdf"); $vbLabelText $csharpLabel 2. Generate PDF from URL (Web Page Capture) Sometimes you need to convert existing web pages into PDF documents - perfect for archiving, reporting, or creating offline versions of online content. IronPDF's URL to PDF conversion uses a real Chromium engine, ensuring that complex JavaScript-heavy sites render correctly. This method is invaluable for creating snapshots of dashboards, saving online receipts, or documenting web-based reports: using IronPdf; var renderer = new ChromePdfRenderer(); // Configure rendering options for optimal capture renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; renderer.RenderingOptions.MarginTop = 25; renderer.RenderingOptions.MarginBottom = 25; // Wait for JavaScript to fully load (important for SPAs) renderer.RenderingOptions.RenderDelay = 2000; // 2 seconds // Enable JavaScript execution renderer.RenderingOptions.EnableJavaScript = true; // Capture a web page as PDF var pdf = renderer.RenderUrlAsPdf("https://example.com/dashboard"); pdf.SaveAs("dashboard-capture.pdf"); // For authenticated pages, you can set cookies var cookieManager = renderer.RenderingOptions.CustomCookies; cookieManager["session_id"] = "your-session-token"; // Capture authenticated content var securePdf = renderer.RenderUrlAsPdf("https://app.example.com/private/report"); securePdf.SaveAs("private-report.pdf"); using IronPdf; var renderer = new ChromePdfRenderer(); // Configure rendering options for optimal capture renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; renderer.RenderingOptions.MarginTop = 25; renderer.RenderingOptions.MarginBottom = 25; // Wait for JavaScript to fully load (important for SPAs) renderer.RenderingOptions.RenderDelay = 2000; // 2 seconds // Enable JavaScript execution renderer.RenderingOptions.EnableJavaScript = true; // Capture a web page as PDF var pdf = renderer.RenderUrlAsPdf("https://example.com/dashboard"); pdf.SaveAs("dashboard-capture.pdf"); // For authenticated pages, you can set cookies var cookieManager = renderer.RenderingOptions.CustomCookies; cookieManager["session_id"] = "your-session-token"; // Capture authenticated content var securePdf = renderer.RenderUrlAsPdf("https://app.example.com/private/report"); securePdf.SaveAs("private-report.pdf"); $vbLabelText $csharpLabel 3. Create PDF from HTML File (Template-Based Generation) Template-based PDF generation is ideal when you have complex layouts that designers can maintain separately from your application code. By storing HTML templates as files, you enable a clean separation between design and logic. This approach works exceptionally well for generating consistent documents like certificates, contracts, or standardized reports: using IronPdf; using System.IO; using System; var renderer = new ChromePdfRenderer(); // Basic file conversion var pdf = renderer.RenderHtmlFileAsPdf("Templates/certificate-template.html"); pdf.SaveAs("certificate.pdf"); // Advanced: Using templates with asset directories // Perfect when your HTML references images, CSS, or JavaScript files var basePath = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "Assets"); var pdfWithAssets = renderer.RenderHtmlFileAsPdf( "Templates/report-template.html", basePath // IronPDF will resolve relative paths from here ); // Even better: Template with placeholders var templateHtml = File.ReadAllText("Templates/contract-template.html"); templateHtml = templateHtml .Replace("{{ClientName}}", "Tech Innovations Inc.") .Replace("{{ContractDate}}", DateTime.Now.ToString("MMMM dd, yyyy")) .Replace("{{ContractValue}}", "$50,000"); var contractPdf = renderer.RenderHtmlAsPdf(templateHtml); contractPdf.SaveAs("contract-final.pdf"); using IronPdf; using System.IO; using System; var renderer = new ChromePdfRenderer(); // Basic file conversion var pdf = renderer.RenderHtmlFileAsPdf("Templates/certificate-template.html"); pdf.SaveAs("certificate.pdf"); // Advanced: Using templates with asset directories // Perfect when your HTML references images, CSS, or JavaScript files var basePath = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "Assets"); var pdfWithAssets = renderer.RenderHtmlFileAsPdf( "Templates/report-template.html", basePath // IronPDF will resolve relative paths from here ); // Even better: Template with placeholders var templateHtml = File.ReadAllText("Templates/contract-template.html"); templateHtml = templateHtml .Replace("{{ClientName}}", "Tech Innovations Inc.") .Replace("{{ContractDate}}", DateTime.Now.ToString("MMMM dd, yyyy")) .Replace("{{ContractValue}}", "$50,000"); var contractPdf = renderer.RenderHtmlAsPdf(templateHtml); contractPdf.SaveAs("contract-final.pdf"); $vbLabelText $csharpLabel 4. Convert Markdown to PDF Markdown has become the standard for technical documentation, README files, and content management systems. IronPDF makes it easy to convert Markdown content directly to PDF, preserving formatting while creating professional-looking documents. This feature is particularly valuable for organizations that maintain their documentation in Markdown format - developers can write documentation in their preferred format, and the system can automatically generate PDFs for distribution to clients or stakeholders. using IronPdf; var renderer = new ChromePdfRenderer(); // Convert Markdown string to PDF string markdownContent = @" <h1>Project Documentation</h1> <h2>Overview</h2> This project demonstrates **PDF generation** from _Markdown_ content. <h3>Features</h3> - Easy conversion - Preserves formatting - Supports lists and tables | Feature | Status | |---------|--------| | Markdown Support | | | Table Rendering | | | Code Blocks | | ```csharp // Code blocks are preserved var pdf = RenderMarkdownAsPdf(markdown); \`\`\` "; // Render Markdown as PDF var pdfFromMarkdown = renderer.RenderMarkdownStringAsPdf(markdownContent); pdfFromMarkdown.SaveAs("documentation.pdf"); // Convert Markdown file to PDF var pdfFromFile = renderer.RenderMarkdownFileAsPdf("README.md"); pdfFromFile.SaveAs("readme-pdf.pdf"); using IronPdf; var renderer = new ChromePdfRenderer(); // Convert Markdown string to PDF string markdownContent = @" <h1>Project Documentation</h1> <h2>Overview</h2> This project demonstrates **PDF generation** from _Markdown_ content. <h3>Features</h3> - Easy conversion - Preserves formatting - Supports lists and tables | Feature | Status | |---------|--------| | Markdown Support | | | Table Rendering | | | Code Blocks | | ```csharp // Code blocks are preserved var pdf = RenderMarkdownAsPdf(markdown); \`\`\` "; // Render Markdown as PDF var pdfFromMarkdown = renderer.RenderMarkdownStringAsPdf(markdownContent); pdfFromMarkdown.SaveAs("documentation.pdf"); // Convert Markdown file to PDF var pdfFromFile = renderer.RenderMarkdownFileAsPdf("README.md"); pdfFromFile.SaveAs("readme-pdf.pdf"); $vbLabelText $csharpLabel The Markdown to PDF conversion is particularly useful for organizations that use version control systems like Git. Your entire documentation workflow can be automated - developers update Markdown files, CI/CD pipelines automatically generate PDF documents, and stakeholders receive professionally formatted documentation without any manual intervention. This seamless integration into existing workflows is why many development teams choose IronPDF for their documentation needs. 5. Convert Word Documents (DOCX) to PDF Many businesses have existing Word documents that need to be converted to PDF for distribution or archiving. IronPDF provides seamless DOCX to PDF conversion that preserves formatting, images, and even complex features like mail merge. This capability is transformative for organizations - business users can continue working in familiar Microsoft Word while the system automatically generates PDFs for external distribution. The DOCX to PDF conversion feature bridges the gap between business users who prefer Word and the need for secure, uneditable PDF documents. using IronPdf; using System.Collections.Generic; // Simple DOCX to PDF conversion var docxRenderer = new DocxToPdfRenderer(); var pdfFromDocx = docxRenderer.RenderDocxAsPdf("proposal.docx"); pdfFromDocx.SaveAs("proposal.pdf"); // Advanced: Mail merge functionality for mass document generation var recipients = new List<Dictionary<string, string>> { new() { ["Name"] = "John Smith", ["Company"] = "Tech Corp", ["Date"] = "March 15, 2024" }, new() { ["Name"] = "Jane Doe", ["Company"] = "Innovation Inc", ["Date"] = "March 15, 2024" } }; // Configure mail merge options var options = new DocxPdfRenderOptions { MailMergeDataSource = recipients, MailMergePrintAllInOnePdfDocument = false // Creates separate PDFs }; // Generate personalized PDFs from template foreach (var recipient in recipients) { var personalizedPdf = docxRenderer.RenderDocxAsPdf("letter-template.docx", options); personalizedPdf.SaveAs($"letter-{recipient["Name"].Replace(" ", "-")}.pdf"); } using IronPdf; using System.Collections.Generic; // Simple DOCX to PDF conversion var docxRenderer = new DocxToPdfRenderer(); var pdfFromDocx = docxRenderer.RenderDocxAsPdf("proposal.docx"); pdfFromDocx.SaveAs("proposal.pdf"); // Advanced: Mail merge functionality for mass document generation var recipients = new List<Dictionary<string, string>> { new() { ["Name"] = "John Smith", ["Company"] = "Tech Corp", ["Date"] = "March 15, 2024" }, new() { ["Name"] = "Jane Doe", ["Company"] = "Innovation Inc", ["Date"] = "March 15, 2024" } }; // Configure mail merge options var options = new DocxPdfRenderOptions { MailMergeDataSource = recipients, MailMergePrintAllInOnePdfDocument = false // Creates separate PDFs }; // Generate personalized PDFs from template foreach (var recipient in recipients) { var personalizedPdf = docxRenderer.RenderDocxAsPdf("letter-template.docx", options); personalizedPdf.SaveAs($"letter-{recipient["Name"].Replace(" ", "-")}.pdf"); } $vbLabelText $csharpLabel This DOCX conversion feature is invaluable for automating document workflows within organizations. Consider a sales team that creates proposals in Word - with IronPDF, these proposals can be automatically converted to PDF with watermarks, security settings, and digital signatures applied programmatically. The mail merge functionality enables mass generation of personalized PDF documents - perfect for creating thousands of customized letters, certificates, or contracts without manual intervention. This integration capability is why IronPDF is trusted by enterprises worldwide to handle their document automation needs. 6. Convert Images to PDF Converting images to PDF is essential for creating photo albums, scanned document compilations, or image-based reports. IronPDF supports all major image formats and provides options for controlling layout and quality: using IronPdf; using IronPdf.Imaging; // Install-Package IronPdf using System.IO; var renderer = new ChromePdfRenderer(); // Convert single image to PDF var imagePath = "product-photo.jpg"; var imageHtml = $@" <html> <body style='margin: 0; padding: 0;'> <img src='{imagePath}' style='width: 100%; height: auto;' /> </body> </html>"; var imagePdf = renderer.RenderHtmlAsPdf(imageHtml, Path.GetDirectoryName(imagePath)); imagePdf.SaveAs("product-catalog-page.pdf"); // Create multi-page PDF from multiple images var imageFiles = Directory.GetFiles("ProductImages", "*.jpg"); var catalogHtml = "<html><body style='margin: 0;'>"; foreach (var image in imageFiles) { catalogHtml += $@" <div style='page-break-after: always;'> <img src='{Path.GetFileName(image)}' style='width: 100%; height: auto;' /> <p style='text-align: center;'>{Path.GetFileNameWithoutExtension(image)}</p> </div>"; } catalogHtml += "</body></html>"; var catalogPdf = renderer.RenderHtmlAsPdf(catalogHtml, "ProductImages"); catalogPdf.SaveAs("product-catalog.pdf"); using IronPdf; using IronPdf.Imaging; // Install-Package IronPdf using System.IO; var renderer = new ChromePdfRenderer(); // Convert single image to PDF var imagePath = "product-photo.jpg"; var imageHtml = $@" <html> <body style='margin: 0; padding: 0;'> <img src='{imagePath}' style='width: 100%; height: auto;' /> </body> </html>"; var imagePdf = renderer.RenderHtmlAsPdf(imageHtml, Path.GetDirectoryName(imagePath)); imagePdf.SaveAs("product-catalog-page.pdf"); // Create multi-page PDF from multiple images var imageFiles = Directory.GetFiles("ProductImages", "*.jpg"); var catalogHtml = "<html><body style='margin: 0;'>"; foreach (var image in imageFiles) { catalogHtml += $@" <div style='page-break-after: always;'> <img src='{Path.GetFileName(image)}' style='width: 100%; height: auto;' /> <p style='text-align: center;'>{Path.GetFileNameWithoutExtension(image)}</p> </div>"; } catalogHtml += "</body></html>"; var catalogPdf = renderer.RenderHtmlAsPdf(catalogHtml, "ProductImages"); catalogPdf.SaveAs("product-catalog.pdf"); $vbLabelText $csharpLabel 7. Generate PDF from ASP.NET Pages For web applications, generating PDFs from your existing views provides a seamless way to create downloadable versions of web content. This integration capability is crucial for organizations that need to create PDFs from their web applications - whether it's customer portals generating statements, admin dashboards producing reports, or e-learning platforms creating certificates. IronPDF works with all ASP.NET technologies including MVC, Razor Pages, and Blazor, making it the perfect choice for organizations already invested in the Microsoft ecosystem: // Namespace: Microsoft.AspNetCore.Mvc using Microsoft.AspNetCore.Mvc; // Namespace: IronPdf using IronPdf; // Namespace: System.Threading.Tasks using System.Threading.Tasks; // Namespace: System.IO using System.IO; // Namespace: System using System; // ASP.NET Core MVC Controller public class ReportController : Controller { private readonly ChromePdfRenderer _pdfRenderer; public ReportController() { _pdfRenderer = new ChromePdfRenderer(); } public async Task<IActionResult> DownloadReport(int reportId) { // Get your report data var reportData = await GetReportData(reportId); // Render view to HTML string var html = await RenderViewToStringAsync("Reports/MonthlyReport", reportData); // Convert HTML content to PDF var pdf = _pdfRenderer.RenderHtmlAsPdf(html); // Return as file download return File( pdf.BinaryData, "application/pdf", $"report-{reportId}-{DateTime.Now:yyyy-MM}.pdf" ); } private async Task<string> RenderViewToStringAsync(string viewName, object model) { ViewData.Model = model; using var sw = new StringWriter(); var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); var viewContext = new ViewContext( ControllerContext, viewResult.View, ViewData, TempData, sw, new HtmlHelperOptions() ); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } // Namespace: Microsoft.AspNetCore.Mvc using Microsoft.AspNetCore.Mvc; // Namespace: IronPdf using IronPdf; // Namespace: System.Threading.Tasks using System.Threading.Tasks; // Namespace: System.IO using System.IO; // Namespace: System using System; // ASP.NET Core MVC Controller public class ReportController : Controller { private readonly ChromePdfRenderer _pdfRenderer; public ReportController() { _pdfRenderer = new ChromePdfRenderer(); } public async Task<IActionResult> DownloadReport(int reportId) { // Get your report data var reportData = await GetReportData(reportId); // Render view to HTML string var html = await RenderViewToStringAsync("Reports/MonthlyReport", reportData); // Convert HTML content to PDF var pdf = _pdfRenderer.RenderHtmlAsPdf(html); // Return as file download return File( pdf.BinaryData, "application/pdf", $"report-{reportId}-{DateTime.Now:yyyy-MM}.pdf" ); } private async Task<string> RenderViewToStringAsync(string viewName, object model) { ViewData.Model = model; using var sw = new StringWriter(); var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); var viewContext = new ViewContext( ControllerContext, viewResult.View, ViewData, TempData, sw, new HtmlHelperOptions() ); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } $vbLabelText $csharpLabel How Can I Make My PDFs Look Professional? Creating PDFs is one thing - making them look professional is what sets your application apart when you generate PDFs in .NET. Professional PDF documents require attention to detail in layout, typography, and branding consistency to create the right impression. With IronPDF's comprehensive styling options and advanced PDF features, you can create documents that match your corporate identity perfectly using this powerful C# PDF generator. The HTML to PDF conversion capabilities ensure your styled documents maintain their visual appeal when produced as PDFs. Let's explore the features that transform basic PDFs into polished, professional documents that impress clients and stakeholders. Headers, Footers, and Page Numbers Professional documents need consistent headers and footers that provide context and navigation. IronPDF offers both simple text-based and complex HTML-based options for headers and footers. This flexibility is why organizations choose IronPDF when they need to create branded PDF documents at scale. You can include dynamic content like page numbers, dates, and document titles - ensuring every generated PDF maintains professional standards: using IronPdf; using System; var renderer = new ChromePdfRenderer(); // Simple text header and footer with page numbers renderer.RenderingOptions.TextHeader = new TextHeaderFooter { Text = "Confidential Report - {date}", DrawDividerLine = true, Font = "Arial", FontSize = 12 }; renderer.RenderingOptions.TextFooter = new TextHeaderFooter { Text = "Page {page} of {total-pages}", DrawDividerLine = true, Font = "Arial", FontSize = 10, CenterText = true }; // HTML headers for complex layouts with logos renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter { Html = @" <div style='display: flex; justify-content: space-between; align-items: center; padding: 10px 40px;'> <img src='logo.png' style='height: 40px;' /> <div style='text-align: center;'> ## Annual Report 2024 <p style='margin: 0; font-size: 12px; color: #666;'>Confidential</p> </div> <div style='text-align: right; font-size: 11px; color: #666;'> Generated: {date}<br/> Department: Finance </div> </div>", Height = 80, LoadStylesAndCSSFromMainHtmlDocument = true }; // Create your PDF with professional headers/footers var html = @"<h1>Financial Overview</h1><p>Report content here...</p>"; var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("professional-report.pdf"); using IronPdf; using System; var renderer = new ChromePdfRenderer(); // Simple text header and footer with page numbers renderer.RenderingOptions.TextHeader = new TextHeaderFooter { Text = "Confidential Report - {date}", DrawDividerLine = true, Font = "Arial", FontSize = 12 }; renderer.RenderingOptions.TextFooter = new TextHeaderFooter { Text = "Page {page} of {total-pages}", DrawDividerLine = true, Font = "Arial", FontSize = 10, CenterText = true }; // HTML headers for complex layouts with logos renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter { Html = @" <div style='display: flex; justify-content: space-between; align-items: center; padding: 10px 40px;'> <img src='logo.png' style='height: 40px;' /> <div style='text-align: center;'> ## Annual Report 2024 <p style='margin: 0; font-size: 12px; color: #666;'>Confidential</p> </div> <div style='text-align: right; font-size: 11px; color: #666;'> Generated: {date}<br/> Department: Finance </div> </div>", Height = 80, LoadStylesAndCSSFromMainHtmlDocument = true }; // Create your PDF with professional headers/footers var html = @"<h1>Financial Overview</h1><p>Report content here...</p>"; var pdf = renderer.RenderHtmlAsPdf(html); pdf.SaveAs("professional-report.pdf"); $vbLabelText $csharpLabel These header and footer options enable organizations to maintain brand consistency across all generated PDFs. Whether you're creating financial reports or technical documentation, professional headers and footers ensure your documents meet corporate standards. Advanced Page Setup and Layout Control Control over page layout is crucial for creating documents that print correctly and look professional on all devices. IronPDF provides extensive options for page setup, including custom sizes, orientations, and margins: var renderer = new ChromePdfRenderer(); // Configure page setup for professional printing renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait; // Set margins in millimeters for precise control renderer.RenderingOptions.MarginTop = 25; renderer.RenderingOptions.MarginBottom = 25; renderer.RenderingOptions.MarginLeft = 20; renderer.RenderingOptions.MarginRight = 20; // Enable background colors and images (important for branding) renderer.RenderingOptions.PrintHtmlBackgrounds = true; // Use screen media type for vibrant colors renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen; // Custom page size for special documents renderer.RenderingOptions.SetCustomPaperSizeinMilimeters(210, 297); // A4 // Enable high-quality rendering renderer.RenderingOptions.RenderQuality = 100; // 0-100 scale var renderer = new ChromePdfRenderer(); // Configure page setup for professional printing renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait; // Set margins in millimeters for precise control renderer.RenderingOptions.MarginTop = 25; renderer.RenderingOptions.MarginBottom = 25; renderer.RenderingOptions.MarginLeft = 20; renderer.RenderingOptions.MarginRight = 20; // Enable background colors and images (important for branding) renderer.RenderingOptions.PrintHtmlBackgrounds = true; // Use screen media type for vibrant colors renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen; // Custom page size for special documents renderer.RenderingOptions.SetCustomPaperSizeinMilimeters(210, 297); // A4 // Enable high-quality rendering renderer.RenderingOptions.RenderQuality = 100; // 0-100 scale $vbLabelText $csharpLabel Working with Fonts and Typography Typography plays a crucial role in document professionalism. IronPDF supports web fonts, custom fonts, and advanced typography features: var renderer = new ChromePdfRenderer(); // HTML with custom fonts and typography var html = @" <html> <head> <link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'> <style> @font-face { font-family: 'CustomBrand'; src: url('BrandFont.ttf') format('truetype'); } body { font-family: 'Roboto', Arial, sans-serif; font-size: 11pt; line-height: 1.6; color: #333; } h1 { font-family: 'CustomBrand', Georgia, serif; font-size: 28pt; color: #0066cc; letter-spacing: -0.5px; } .quote { font-style: italic; font-size: 14pt; color: #666; border-left: 4px solid #0066cc; padding-left: 20px; margin: 20px 0; } </style> </head> <body> # Professional Document <p>This document demonstrates professional typography.</p> <div class='quote'> "Excellence in typography enhances readability and professionalism." </div> </body> </html>"; var pdf = renderer.RenderHtmlAsPdf(html, "Assets/Fonts"); pdf.SaveAs("typography-demo.pdf"); var renderer = new ChromePdfRenderer(); // HTML with custom fonts and typography var html = @" <html> <head> <link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'> <style> @font-face { font-family: 'CustomBrand'; src: url('BrandFont.ttf') format('truetype'); } body { font-family: 'Roboto', Arial, sans-serif; font-size: 11pt; line-height: 1.6; color: #333; } h1 { font-family: 'CustomBrand', Georgia, serif; font-size: 28pt; color: #0066cc; letter-spacing: -0.5px; } .quote { font-style: italic; font-size: 14pt; color: #666; border-left: 4px solid #0066cc; padding-left: 20px; margin: 20px 0; } </style> </head> <body> # Professional Document <p>This document demonstrates professional typography.</p> <div class='quote'> "Excellence in typography enhances readability and professionalism." </div> </body> </html>"; var pdf = renderer.RenderHtmlAsPdf(html, "Assets/Fonts"); pdf.SaveAs("typography-demo.pdf"); $vbLabelText $csharpLabel Real-World Example: How Do I Generate an Invoice PDF? Let's create a complete, production-ready invoice generator that demonstrates best practices for creating PDF documents in real-world applications. This example showcases why thousands of businesses choose IronPDF as their C# PDF generator for invoice generation needs - it combines data binding, professional styling, and proper document structure in a way that's both powerful and maintainable. Similar implementations are used by e-commerce platforms to generate millions of invoices monthly, demonstrating the scalability of programmatic PDF generation in .NET. You can adapt this code for your own PDF creation tasks: using IronPdf; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; public class InvoiceGenerator { private readonly ChromePdfRenderer _renderer; public InvoiceGenerator() { _renderer = new ChromePdfRenderer(); ConfigureRenderer(); } private void ConfigureRenderer() { // Professional page setup _renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; _renderer.RenderingOptions.MarginTop = 25; _renderer.RenderingOptions.MarginBottom = 25; _renderer.RenderingOptions.MarginLeft = 25; _renderer.RenderingOptions.MarginRight = 25; _renderer.RenderingOptions.PrintHtmlBackgrounds = true; // Add footer with page numbers _renderer.RenderingOptions.TextFooter = new TextHeaderFooter { Text = "Page {page} of {total-pages} | Invoice generated on {date}", FontSize = 9, Font = "Arial", CenterText = true }; } public void CreateInvoice(Invoice invoice) { var html = GenerateInvoiceHtml(invoice); var pdf = _renderer.RenderHtmlAsPdf(html); // Add metadata to the final document pdf.MetaData.Title = $"Invoice {invoice.Number}"; pdf.MetaData.Author = "Your Company Name"; pdf.MetaData.Subject = $"Invoice for {invoice.CustomerName}"; pdf.MetaData.Keywords = "invoice, billing, payment"; pdf.MetaData.CreationDate = DateTime.Now; // Save the PDF document var fileName = $"Invoice-{invoice.Number}.pdf"; pdf.SaveAs(fileName); Console.WriteLine($"PDF generated successfully: {fileName}"); } private string GenerateInvoiceHtml(Invoice invoice) { var itemsHtml = string.Join("", invoice.Items.Select(item => $@" <tr> <td style='padding: 12px; border-bottom: 1px solid #eee;'>{item.Description}</td> <td style='padding: 12px; border-bottom: 1px solid #eee; text-align: center;'>{item.Quantity}</td> <td style='padding: 12px; border-bottom: 1px solid #eee; text-align: right;'>${item.UnitPrice:F2}</td> <td style='padding: 12px; border-bottom: 1px solid #eee; text-align: right;'>${item.Total:F2}</td> </tr>")); return $@" <html> <head> <style> * {{ box-sizing: border-box; }} body {{ font-family: 'Segoe UI', Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 0; }} .invoice-container {{ max-width: 800px; margin: 0 auto; padding: 40px; }} .invoice-header {{ display: flex; justify-content: space-between; margin-bottom: 40px; padding-bottom: 20px; border-bottom: 3px solid #0066cc; }} .company-details {{ flex: 1; }} .company-details h1 {{ color: #0066cc; margin: 0 0 10px 0; font-size: 28px; }} .invoice-details {{ flex: 1; text-align: right; }} .invoice-details h2 {{ margin: 0 0 10px 0; color: #666; font-size: 24px; }} .invoice-number {{ font-size: 18px; color: #0066cc; font-weight: bold; }} .billing-section {{ display: flex; justify-content: space-between; margin-bottom: 40px; }} .billing-box {{ flex: 1; padding: 20px; background: #f8f9fa; border-radius: 8px; margin-right: 20px; }} .billing-box:last-child {{ margin-right: 0; }} .billing-box h3 {{ margin: 0 0 15px 0; color: #0066cc; font-size: 16px; text-transform: uppercase; letter-spacing: 1px; }} .items-table {{ width: 100%; border-collapse: collapse; margin-bottom: 40px; }} .items-table th {{ background: #0066cc; color: white; padding: 12px; text-align: left; font-weight: 600; }} .items-table th:last-child {{ text-align: right; }} .totals-section {{ display: flex; justify-content: flex-end; margin-bottom: 40px; }} .totals-box {{ width: 300px; }} .total-row {{ display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #eee; }} .total-row.final {{ border-bottom: none; border-top: 2px solid #0066cc; margin-top: 10px; padding-top: 15px; font-size: 20px; font-weight: bold; color: #0066cc; }} .payment-terms {{ background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px; }} .payment-terms h3 {{ margin: 0 0 10px 0; color: #0066cc; }} .footer-note {{ text-align: center; color: #666; font-size: 14px; margin-top: 40px; padding-top: 20px; border-top: 1px solid #eee; }} </style> </head> <body> <div class='invoice-container'> <div class='invoice-header'> <div class='company-details'> # {invoice.CompanyName} <p>{invoice.CompanyAddress}<br> {invoice.CompanyCity}, {invoice.CompanyState} {invoice.CompanyZip}<br> Phone: {invoice.CompanyPhone}<br> Email: {invoice.CompanyEmail}</p> </div> <div class='invoice-details'> ## INVOICE <p class='invoice-number'>#{invoice.Number}</p> <p><strong>Date:</strong> {invoice.Date:MMMM dd, yyyy}<br> <strong>Due Date:</strong> {invoice.DueDate:MMMM dd, yyyy}</p> </div> </div> <div class='billing-section'> <div class='billing-box'> ### Bill To <p><strong>{invoice.CustomerName}</strong><br> {invoice.CustomerAddress}<br> {invoice.CustomerCity}, {invoice.CustomerState} {invoice.CustomerZip}<br> {invoice.CustomerEmail}</p> </div> <div class='billing-box'> ### Payment Information <p><strong>Payment Terms:</strong> {invoice.PaymentTerms}<br> <strong>Invoice Status:</strong> <span style='color: #ff6b6b;'>Unpaid</span><br> <strong>Amount Due:</strong> ${invoice.Total:F2}</p> </div> </div> <table class='items-table'> <thead> <tr> <th>Description</th> <th style='text-align: center;'>Quantity</th> <th style='text-align: right;'>Unit Price</th> <th style='text-align: right;'>Total</th> </tr> </thead> <tbody> {itemsHtml} </tbody> </table> <div class='totals-section'> <div class='totals-box'> <div class='total-row'> <span>Subtotal:</span> <span>${invoice.Subtotal:F2}</span> </div> <div class='total-row'> <span>Tax ({invoice.TaxRate:F0}%):</span> <span>${invoice.Tax:F2}</span> </div> <div class='total-row final'> <span>Total Due:</span> <span>${invoice.Total:F2}</span> </div> </div> </div> <div class='payment-terms'> ### Payment Terms & Conditions <p>Payment is due within {invoice.PaymentTerms}. Late payments are subject to a 1.5% monthly service charge. Please make checks payable to {invoice.CompanyName} or pay online at {invoice.CompanyWebsite}.</p> </div> <div class='footer-note'> <p>Thank you for your business! This invoice was generated automatically using our C# PDF generation system.</p> <p>Questions? Contact us at {invoice.CompanyEmail} or {invoice.CompanyPhone}</p> </div> </div> </body> </html>"; } } // Invoice model classes public class Invoice { public string Number { get; set; } public DateTime Date { get; set; } public DateTime DueDate { get; set; } public string CompanyName { get; set; } public string CompanyAddress { get; set; } public string CompanyCity { get; set; } public string CompanyState { get; set; } public string CompanyZip { get; set; } public string CompanyPhone { get; set; } public string CompanyEmail { get; set; } public string CompanyWebsite { get; set; } public string CustomerName { get; set; } public string CustomerAddress { get; set; } public string CustomerCity { get; set; } public string CustomerState { get; set; } public string CustomerZip { get; set; } public string CustomerEmail { get; set; } public string PaymentTerms { get; set; } public List<InvoiceItem> Items { get; set; } public decimal Subtotal => Items.Sum(i => i.Total); public decimal TaxRate { get; set; } public decimal Tax => Subtotal * (TaxRate / 100); public decimal Total => Subtotal + Tax; } public class InvoiceItem { public string Description { get; set; } public int Quantity { get; set; } public decimal UnitPrice { get; set; } public decimal Total => Quantity * UnitPrice; } // Usage example var generator = new InvoiceGenerator(); var invoice = new Invoice { Number = "INV-2024-001", Date = DateTime.Now, DueDate = DateTime.Now.AddDays(30), CompanyName = "Your Company Name", CompanyAddress = "123 Business Street", CompanyCity = "New York", CompanyState = "NY", CompanyZip = "10001", CompanyPhone = "(555) 123-4567", CompanyEmail = "billing@yourcompany.com", CompanyWebsite = "www.yourcompany.com", CustomerName = "Acme Corporation", CustomerAddress = "456 Client Avenue", CustomerCity = "Los Angeles", CustomerState = "CA", CustomerZip = "90001", CustomerEmail = "accounts@acmecorp.com", PaymentTerms = "Net 30", TaxRate = 8.5m, Items = new List<InvoiceItem> { new() { Description = "Professional Services - March 2024", Quantity = 40, UnitPrice = 125.00m }, new() { Description = "Software License (Annual)", Quantity = 1, UnitPrice = 2400.00m }, new() { Description = "Technical Support", Quantity = 10, UnitPrice = 150.00m } } }; generator.CreateInvoice(invoice); using IronPdf; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; public class InvoiceGenerator { private readonly ChromePdfRenderer _renderer; public InvoiceGenerator() { _renderer = new ChromePdfRenderer(); ConfigureRenderer(); } private void ConfigureRenderer() { // Professional page setup _renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; _renderer.RenderingOptions.MarginTop = 25; _renderer.RenderingOptions.MarginBottom = 25; _renderer.RenderingOptions.MarginLeft = 25; _renderer.RenderingOptions.MarginRight = 25; _renderer.RenderingOptions.PrintHtmlBackgrounds = true; // Add footer with page numbers _renderer.RenderingOptions.TextFooter = new TextHeaderFooter { Text = "Page {page} of {total-pages} | Invoice generated on {date}", FontSize = 9, Font = "Arial", CenterText = true }; } public void CreateInvoice(Invoice invoice) { var html = GenerateInvoiceHtml(invoice); var pdf = _renderer.RenderHtmlAsPdf(html); // Add metadata to the final document pdf.MetaData.Title = $"Invoice {invoice.Number}"; pdf.MetaData.Author = "Your Company Name"; pdf.MetaData.Subject = $"Invoice for {invoice.CustomerName}"; pdf.MetaData.Keywords = "invoice, billing, payment"; pdf.MetaData.CreationDate = DateTime.Now; // Save the PDF document var fileName = $"Invoice-{invoice.Number}.pdf"; pdf.SaveAs(fileName); Console.WriteLine($"PDF generated successfully: {fileName}"); } private string GenerateInvoiceHtml(Invoice invoice) { var itemsHtml = string.Join("", invoice.Items.Select(item => $@" <tr> <td style='padding: 12px; border-bottom: 1px solid #eee;'>{item.Description}</td> <td style='padding: 12px; border-bottom: 1px solid #eee; text-align: center;'>{item.Quantity}</td> <td style='padding: 12px; border-bottom: 1px solid #eee; text-align: right;'>${item.UnitPrice:F2}</td> <td style='padding: 12px; border-bottom: 1px solid #eee; text-align: right;'>${item.Total:F2}</td> </tr>")); return $@" <html> <head> <style> * {{ box-sizing: border-box; }} body {{ font-family: 'Segoe UI', Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 0; }} .invoice-container {{ max-width: 800px; margin: 0 auto; padding: 40px; }} .invoice-header {{ display: flex; justify-content: space-between; margin-bottom: 40px; padding-bottom: 20px; border-bottom: 3px solid #0066cc; }} .company-details {{ flex: 1; }} .company-details h1 {{ color: #0066cc; margin: 0 0 10px 0; font-size: 28px; }} .invoice-details {{ flex: 1; text-align: right; }} .invoice-details h2 {{ margin: 0 0 10px 0; color: #666; font-size: 24px; }} .invoice-number {{ font-size: 18px; color: #0066cc; font-weight: bold; }} .billing-section {{ display: flex; justify-content: space-between; margin-bottom: 40px; }} .billing-box {{ flex: 1; padding: 20px; background: #f8f9fa; border-radius: 8px; margin-right: 20px; }} .billing-box:last-child {{ margin-right: 0; }} .billing-box h3 {{ margin: 0 0 15px 0; color: #0066cc; font-size: 16px; text-transform: uppercase; letter-spacing: 1px; }} .items-table {{ width: 100%; border-collapse: collapse; margin-bottom: 40px; }} .items-table th {{ background: #0066cc; color: white; padding: 12px; text-align: left; font-weight: 600; }} .items-table th:last-child {{ text-align: right; }} .totals-section {{ display: flex; justify-content: flex-end; margin-bottom: 40px; }} .totals-box {{ width: 300px; }} .total-row {{ display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #eee; }} .total-row.final {{ border-bottom: none; border-top: 2px solid #0066cc; margin-top: 10px; padding-top: 15px; font-size: 20px; font-weight: bold; color: #0066cc; }} .payment-terms {{ background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px; }} .payment-terms h3 {{ margin: 0 0 10px 0; color: #0066cc; }} .footer-note {{ text-align: center; color: #666; font-size: 14px; margin-top: 40px; padding-top: 20px; border-top: 1px solid #eee; }} </style> </head> <body> <div class='invoice-container'> <div class='invoice-header'> <div class='company-details'> # {invoice.CompanyName} <p>{invoice.CompanyAddress}<br> {invoice.CompanyCity}, {invoice.CompanyState} {invoice.CompanyZip}<br> Phone: {invoice.CompanyPhone}<br> Email: {invoice.CompanyEmail}</p> </div> <div class='invoice-details'> ## INVOICE <p class='invoice-number'>#{invoice.Number}</p> <p><strong>Date:</strong> {invoice.Date:MMMM dd, yyyy}<br> <strong>Due Date:</strong> {invoice.DueDate:MMMM dd, yyyy}</p> </div> </div> <div class='billing-section'> <div class='billing-box'> ### Bill To <p><strong>{invoice.CustomerName}</strong><br> {invoice.CustomerAddress}<br> {invoice.CustomerCity}, {invoice.CustomerState} {invoice.CustomerZip}<br> {invoice.CustomerEmail}</p> </div> <div class='billing-box'> ### Payment Information <p><strong>Payment Terms:</strong> {invoice.PaymentTerms}<br> <strong>Invoice Status:</strong> <span style='color: #ff6b6b;'>Unpaid</span><br> <strong>Amount Due:</strong> ${invoice.Total:F2}</p> </div> </div> <table class='items-table'> <thead> <tr> <th>Description</th> <th style='text-align: center;'>Quantity</th> <th style='text-align: right;'>Unit Price</th> <th style='text-align: right;'>Total</th> </tr> </thead> <tbody> {itemsHtml} </tbody> </table> <div class='totals-section'> <div class='totals-box'> <div class='total-row'> <span>Subtotal:</span> <span>${invoice.Subtotal:F2}</span> </div> <div class='total-row'> <span>Tax ({invoice.TaxRate:F0}%):</span> <span>${invoice.Tax:F2}</span> </div> <div class='total-row final'> <span>Total Due:</span> <span>${invoice.Total:F2}</span> </div> </div> </div> <div class='payment-terms'> ### Payment Terms & Conditions <p>Payment is due within {invoice.PaymentTerms}. Late payments are subject to a 1.5% monthly service charge. Please make checks payable to {invoice.CompanyName} or pay online at {invoice.CompanyWebsite}.</p> </div> <div class='footer-note'> <p>Thank you for your business! This invoice was generated automatically using our C# PDF generation system.</p> <p>Questions? Contact us at {invoice.CompanyEmail} or {invoice.CompanyPhone}</p> </div> </div> </body> </html>"; } } // Invoice model classes public class Invoice { public string Number { get; set; } public DateTime Date { get; set; } public DateTime DueDate { get; set; } public string CompanyName { get; set; } public string CompanyAddress { get; set; } public string CompanyCity { get; set; } public string CompanyState { get; set; } public string CompanyZip { get; set; } public string CompanyPhone { get; set; } public string CompanyEmail { get; set; } public string CompanyWebsite { get; set; } public string CustomerName { get; set; } public string CustomerAddress { get; set; } public string CustomerCity { get; set; } public string CustomerState { get; set; } public string CustomerZip { get; set; } public string CustomerEmail { get; set; } public string PaymentTerms { get; set; } public List<InvoiceItem> Items { get; set; } public decimal Subtotal => Items.Sum(i => i.Total); public decimal TaxRate { get; set; } public decimal Tax => Subtotal * (TaxRate / 100); public decimal Total => Subtotal + Tax; } public class InvoiceItem { public string Description { get; set; } public int Quantity { get; set; } public decimal UnitPrice { get; set; } public decimal Total => Quantity * UnitPrice; } // Usage example var generator = new InvoiceGenerator(); var invoice = new Invoice { Number = "INV-2024-001", Date = DateTime.Now, DueDate = DateTime.Now.AddDays(30), CompanyName = "Your Company Name", CompanyAddress = "123 Business Street", CompanyCity = "New York", CompanyState = "NY", CompanyZip = "10001", CompanyPhone = "(555) 123-4567", CompanyEmail = "billing@yourcompany.com", CompanyWebsite = "www.yourcompany.com", CustomerName = "Acme Corporation", CustomerAddress = "456 Client Avenue", CustomerCity = "Los Angeles", CustomerState = "CA", CustomerZip = "90001", CustomerEmail = "accounts@acmecorp.com", PaymentTerms = "Net 30", TaxRate = 8.5m, Items = new List<InvoiceItem> { new() { Description = "Professional Services - March 2024", Quantity = 40, UnitPrice = 125.00m }, new() { Description = "Software License (Annual)", Quantity = 1, UnitPrice = 2400.00m }, new() { Description = "Technical Support", Quantity = 10, UnitPrice = 150.00m } } }; generator.CreateInvoice(invoice); $vbLabelText $csharpLabel What Advanced PDF Features Does IronPDF Offer? IronPDF goes beyond basic PDF creation in C# to offer sophisticated features that enable complex document workflows and enterprise-grade functionality. These advanced capabilities allow you to create interactive forms, secure sensitive documents, and manipulate existing PDFs with precision when you build PDFs in .NET. These features are why over 14 million developers worldwide trust IronPDF for their mission-critical PDF generation needs. Understanding these features helps you build comprehensive PDF solutions that meet even the most demanding requirements - from creating fillable forms to implementing enterprise-grade security in your C# PDF creation projects. Generate Interactive PDF Forms Creating fillable PDF forms programmatically opens up possibilities for automating data collection and document workflows. IronPDF can transform HTML forms into interactive PDF forms that users can fill out in any PDF reader: // Namespace: IronPdf using IronPdf; // Namespace: System using System; var renderer = new ChromePdfRenderer(); // Enable form creation from HTML renderer.RenderingOptions.CreatePdfFormsFromHtml = true; // Create an interactive form with various input types var formHtml = @" <html> <head> <style> body { font-family: Arial, sans-serif; padding: 40px; } .form-group { margin-bottom: 20px; } label { display: block; margin-bottom: 5px; font-weight: bold; } input[type='text'], input[type='email'], select, textarea { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; } .checkbox-group { margin: 10px 0; } .submit-section { margin-top: 30px; padding-top: 20px; border-top: 2px solid #0066cc; } </style> </head> <body> # Application Form <form> <div class='form-group'> <label for='fullName'>Full Name:</label> <input type='text' id='fullName' name='fullName' required /> </div> <div class='form-group'> <label for='email'>Email Address:</label> <input type='email' id='email' name='email' required /> </div> <div class='form-group'> <label for='department'>Department:</label> <select id='department' name='department'> <option value=''>Select Department</option> <option value='sales'>Sales</option> <option value='marketing'>Marketing</option> <option value='engineering'>Engineering</option> <option value='hr'>Human Resources</option> </select> </div> <div class='form-group'> <label>Interests:</label> <div class='checkbox-group'> <label><input type='checkbox' name='interests' value='training' /> Professional Training</label> <label><input type='checkbox' name='interests' value='conferences' /> Industry Conferences</label> <label><input type='checkbox' name='interests' value='certification' /> Certification Programs</label> </div> </div> <div class='form-group'> <label for='comments'>Additional Comments:</label> <textarea id='comments' name='comments' rows='4'></textarea> </div> <div class='submit-section'> <p><em>Please save this form and email to hr@company.com</em></p> </div> </form> </body> </html>"; // Create the PDF with form fields var formPdf = renderer.RenderHtmlAsPdf(formHtml); // Optionally pre-fill form fields programmatically formPdf.Form.FindFormField("fullName").Value = "John Smith"; formPdf.Form.FindFormField("email").Value = "john.smith@example.com"; formPdf.Form.FindFormField("department").Value = "engineering"; // Save the interactive form formPdf.SaveAs("application-form.pdf"); // You can also read and process submitted forms var submittedPdf = PdfDocument.FromFile("submitted-form.pdf"); var name = submittedPdf.Form.FindFormField("fullName").Value; var email = submittedPdf.Form.FindFormField("email").Value; Console.WriteLine($"Form submitted by: {name} ({email})"); // Namespace: IronPdf using IronPdf; // Namespace: System using System; var renderer = new ChromePdfRenderer(); // Enable form creation from HTML renderer.RenderingOptions.CreatePdfFormsFromHtml = true; // Create an interactive form with various input types var formHtml = @" <html> <head> <style> body { font-family: Arial, sans-serif; padding: 40px; } .form-group { margin-bottom: 20px; } label { display: block; margin-bottom: 5px; font-weight: bold; } input[type='text'], input[type='email'], select, textarea { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; } .checkbox-group { margin: 10px 0; } .submit-section { margin-top: 30px; padding-top: 20px; border-top: 2px solid #0066cc; } </style> </head> <body> # Application Form <form> <div class='form-group'> <label for='fullName'>Full Name:</label> <input type='text' id='fullName' name='fullName' required /> </div> <div class='form-group'> <label for='email'>Email Address:</label> <input type='email' id='email' name='email' required /> </div> <div class='form-group'> <label for='department'>Department:</label> <select id='department' name='department'> <option value=''>Select Department</option> <option value='sales'>Sales</option> <option value='marketing'>Marketing</option> <option value='engineering'>Engineering</option> <option value='hr'>Human Resources</option> </select> </div> <div class='form-group'> <label>Interests:</label> <div class='checkbox-group'> <label><input type='checkbox' name='interests' value='training' /> Professional Training</label> <label><input type='checkbox' name='interests' value='conferences' /> Industry Conferences</label> <label><input type='checkbox' name='interests' value='certification' /> Certification Programs</label> </div> </div> <div class='form-group'> <label for='comments'>Additional Comments:</label> <textarea id='comments' name='comments' rows='4'></textarea> </div> <div class='submit-section'> <p><em>Please save this form and email to hr@company.com</em></p> </div> </form> </body> </html>"; // Create the PDF with form fields var formPdf = renderer.RenderHtmlAsPdf(formHtml); // Optionally pre-fill form fields programmatically formPdf.Form.FindFormField("fullName").Value = "John Smith"; formPdf.Form.FindFormField("email").Value = "john.smith@example.com"; formPdf.Form.FindFormField("department").Value = "engineering"; // Save the interactive form formPdf.SaveAs("application-form.pdf"); // You can also read and process submitted forms var submittedPdf = PdfDocument.FromFile("submitted-form.pdf"); var name = submittedPdf.Form.FindFormField("fullName").Value; var email = submittedPdf.Form.FindFormField("email").Value; Console.WriteLine($"Form submitted by: {name} ({email})"); $vbLabelText $csharpLabel Secure Your Generated PDFs Security is paramount when dealing with sensitive documents. IronPDF provides comprehensive security features to protect your PDFs from unauthorized access or modification: // Namespace: IronPdf using IronPdf; // Namespace: IronPdf.Editing using IronPdf.Editing; var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential Document</h1><p>Sensitive information...</p>"); // Apply password protection pdf.SecuritySettings.UserPassword = "user123"; // Required to open pdf.SecuritySettings.OwnerPassword = "owner456"; // Required to modify // Set detailed permissions pdf.SecuritySettings.AllowUserCopyPasteContent = false; pdf.SecuritySettings.AllowUserAnnotations = false; pdf.SecuritySettings.AllowUserFormData = true; pdf.SecuritySettings.AllowUserPrinting = PrintPermissions.LowQualityPrint; // Add digital signature for authenticity pdf.SignWithFile( certificatePath: "certificate.pfx", certificatePassword: "certpass123", signingReason: "Document Approval", signingLocation: "New York, NY", signatureImage: new Signature("signature.png") { Width = 150, Height = 50 } ); // Apply redaction to hide sensitive information pdf.RedactTextOnPage( pageIndex: 0, searchText: "SSN: ***-**-****", replacementText: "[REDACTED]", caseSensitive: false ); // Save the secured PDF pdf.SaveAs("secure-confidential.pdf"); // Namespace: IronPdf using IronPdf; // Namespace: IronPdf.Editing using IronPdf.Editing; var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential Document</h1><p>Sensitive information...</p>"); // Apply password protection pdf.SecuritySettings.UserPassword = "user123"; // Required to open pdf.SecuritySettings.OwnerPassword = "owner456"; // Required to modify // Set detailed permissions pdf.SecuritySettings.AllowUserCopyPasteContent = false; pdf.SecuritySettings.AllowUserAnnotations = false; pdf.SecuritySettings.AllowUserFormData = true; pdf.SecuritySettings.AllowUserPrinting = PrintPermissions.LowQualityPrint; // Add digital signature for authenticity pdf.SignWithFile( certificatePath: "certificate.pfx", certificatePassword: "certpass123", signingReason: "Document Approval", signingLocation: "New York, NY", signatureImage: new Signature("signature.png") { Width = 150, Height = 50 } ); // Apply redaction to hide sensitive information pdf.RedactTextOnPage( pageIndex: 0, searchText: "SSN: ***-**-****", replacementText: "[REDACTED]", caseSensitive: false ); // Save the secured PDF pdf.SaveAs("secure-confidential.pdf"); $vbLabelText $csharpLabel Merge and Split PDFs Combining multiple PDFs or extracting specific pages is essential for document management workflows: // Namespace: IronPdf using IronPdf; // Namespace: System using System; // Merge multiple PDFs into one document var coverPage = new ChromePdfRenderer().RenderHtmlAsPdf("<h1>Annual Report 2024</h1>"); var introduction = PdfDocument.FromFile("introduction.pdf"); var financials = PdfDocument.FromFile("financials.pdf"); var appendix = PdfDocument.FromFile("appendix.pdf"); // Merge all documents var completeReport = PdfDocument.Merge(coverPage, introduction, financials, appendix); // Add page numbers to the merged document for (int i = 0; i < completeReport.PageCount; i++) { completeReport.AddTextFooterToPage(i, $"Page {i + 1} of {completeReport.PageCount}", IronPdf.Font.FontTypes.Arial, 10); } completeReport.SaveAs("annual-report-complete.pdf"); // Extract specific pages var executiveSummary = completeReport.CopyPages(0, 4); // First 5 pages executiveSummary.SaveAs("executive-summary.pdf"); // Split a large PDF into chapters var sourcePdf = PdfDocument.FromFile("large-document.pdf"); var chaptersPerFile = 50; for (int i = 0; i < sourcePdf.PageCount; i += chaptersPerFile) { var endPage = Math.Min(i + chaptersPerFile - 1, sourcePdf.PageCount - 1); var chapter = sourcePdf.CopyPages(i, endPage); chapter.SaveAs($"chapter-{(i / chaptersPerFile) + 1}.pdf"); } // Namespace: IronPdf using IronPdf; // Namespace: System using System; // Merge multiple PDFs into one document var coverPage = new ChromePdfRenderer().RenderHtmlAsPdf("<h1>Annual Report 2024</h1>"); var introduction = PdfDocument.FromFile("introduction.pdf"); var financials = PdfDocument.FromFile("financials.pdf"); var appendix = PdfDocument.FromFile("appendix.pdf"); // Merge all documents var completeReport = PdfDocument.Merge(coverPage, introduction, financials, appendix); // Add page numbers to the merged document for (int i = 0; i < completeReport.PageCount; i++) { completeReport.AddTextFooterToPage(i, $"Page {i + 1} of {completeReport.PageCount}", IronPdf.Font.FontTypes.Arial, 10); } completeReport.SaveAs("annual-report-complete.pdf"); // Extract specific pages var executiveSummary = completeReport.CopyPages(0, 4); // First 5 pages executiveSummary.SaveAs("executive-summary.pdf"); // Split a large PDF into chapters var sourcePdf = PdfDocument.FromFile("large-document.pdf"); var chaptersPerFile = 50; for (int i = 0; i < sourcePdf.PageCount; i += chaptersPerFile) { var endPage = Math.Min(i + chaptersPerFile - 1, sourcePdf.PageCount - 1); var chapter = sourcePdf.CopyPages(i, endPage); chapter.SaveAs($"chapter-{(i / chaptersPerFile) + 1}.pdf"); } $vbLabelText $csharpLabel Add Watermarks and Stamps Watermarking PDFs is crucial for document control and branding. IronPDF supports both text and image watermarks: // Namespace: IronPdf using IronPdf; // Namespace: System using System; var pdf = PdfDocument.FromFile("document.pdf"); // Add text watermark pdf.ApplyWatermark( html: "<h1 style='color: #ff0000; opacity: 0.5; font-size: 100px;'>DRAFT</h1>", rotation: 45, opacity: 50, verticalAlignment: VerticalAlignment.Middle, horizontalAlignment: HorizontalAlignment.Center ); // Add image watermark (company logo) pdf.ApplyWatermark( html: "<img src='logo-watermark.png' style='width: 300px;' />", rotation: 0, opacity: 30, verticalAlignment: VerticalAlignment.Bottom, horizontalAlignment: HorizontalAlignment.Right ); // Add stamps for document status pdf.StampHtml( Html: @"<div style='border: 3px solid green; padding: 10px; background: white; font-weight: bold; color: green;'> APPROVED<br/> " + DateTime.Now.ToString("MM/dd/yyyy") + @" </div>", X: 400, Y: 100, Width: 150, Height: 60, PageIndex: 0 ); pdf.SaveAs("watermarked-document.pdf"); // Namespace: IronPdf using IronPdf; // Namespace: System using System; var pdf = PdfDocument.FromFile("document.pdf"); // Add text watermark pdf.ApplyWatermark( html: "<h1 style='color: #ff0000; opacity: 0.5; font-size: 100px;'>DRAFT</h1>", rotation: 45, opacity: 50, verticalAlignment: VerticalAlignment.Middle, horizontalAlignment: HorizontalAlignment.Center ); // Add image watermark (company logo) pdf.ApplyWatermark( html: "<img src='logo-watermark.png' style='width: 300px;' />", rotation: 0, opacity: 30, verticalAlignment: VerticalAlignment.Bottom, horizontalAlignment: HorizontalAlignment.Right ); // Add stamps for document status pdf.StampHtml( Html: @"<div style='border: 3px solid green; padding: 10px; background: white; font-weight: bold; color: green;'> APPROVED<br/> " + DateTime.Now.ToString("MM/dd/yyyy") + @" </div>", X: 400, Y: 100, Width: 150, Height: 60, PageIndex: 0 ); pdf.SaveAs("watermarked-document.pdf"); $vbLabelText $csharpLabel How Can I Optimize Performance When Generating PDFs at Scale? When generating PDFs at scale, performance becomes critical. Whether you're creating thousands of invoices or processing large batch jobs, optimizing your PDF generation code can dramatically improve throughput and reduce resource consumption. Modern applications require efficient PDF creation in C# that doesn't block threads or consume excessive memory. Here are proven strategies for maximizing performance in your various PDF generation tasks when you need to produce PDFs in .NET efficiently. Async PDF Generation Modern applications require non-blocking operations to maintain responsiveness. IronPDF provides async methods for all major operations: // Namespace: IronPdf using IronPdf; // Namespace: System.Threading.Tasks using System.Threading.Tasks; // Namespace: System.Collections.Generic using System.Collections.Generic; // Namespace: System.Linq using System.Linq; // Namespace: System using System; // Namespace: System.Threading using System.Threading; public class AsyncPdfService { private readonly ChromePdfRenderer _renderer; public AsyncPdfService() { _renderer = new ChromePdfRenderer(); // Configure renderer once for reuse _renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; } public async Task<byte[]> GeneratePdfAsync(string html) { // Non-blocking PDF generation var pdf = await _renderer.RenderHtmlAsPdfAsync(html); return pdf.BinaryData; } public async Task GenerateBatchAsync(List<string> htmlDocuments) { // Process multiple PDFs concurrently var tasks = htmlDocuments.Select(async (html, index) => { var pdf = await _renderer.RenderHtmlAsPdfAsync(html); await pdf.SaveAsAsync($"document-{index}.pdf"); }); await Task.WhenAll(tasks); } // Async with cancellation support public async Task<PdfDocument> GenerateWithTimeoutAsync(string html, int timeoutSeconds) { using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds)); try { return await _renderer.RenderHtmlAsPdfAsync(html, cts.Token); } catch (OperationCanceledException) { throw new TimeoutException("PDF generation exceeded timeout"); } } } // Namespace: IronPdf using IronPdf; // Namespace: System.Threading.Tasks using System.Threading.Tasks; // Namespace: System.Collections.Generic using System.Collections.Generic; // Namespace: System.Linq using System.Linq; // Namespace: System using System; // Namespace: System.Threading using System.Threading; public class AsyncPdfService { private readonly ChromePdfRenderer _renderer; public AsyncPdfService() { _renderer = new ChromePdfRenderer(); // Configure renderer once for reuse _renderer.RenderingOptions.PaperSize = PdfPaperSize.A4; } public async Task<byte[]> GeneratePdfAsync(string html) { // Non-blocking PDF generation var pdf = await _renderer.RenderHtmlAsPdfAsync(html); return pdf.BinaryData; } public async Task GenerateBatchAsync(List<string> htmlDocuments) { // Process multiple PDFs concurrently var tasks = htmlDocuments.Select(async (html, index) => { var pdf = await _renderer.RenderHtmlAsPdfAsync(html); await pdf.SaveAsAsync($"document-{index}.pdf"); }); await Task.WhenAll(tasks); } // Async with cancellation support public async Task<PdfDocument> GenerateWithTimeoutAsync(string html, int timeoutSeconds) { using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds)); try { return await _renderer.RenderHtmlAsPdfAsync(html, cts.Token); } catch (OperationCanceledException) { throw new TimeoutException("PDF generation exceeded timeout"); } } } $vbLabelText $csharpLabel Batch Processing Best Practices When processing multiple PDFs, proper resource management and parallel processing can significantly improve performance: using IronPdf; using System.Threading.Tasks.Dataflow; public class BatchPdfProcessor { private readonly ChromePdfRenderer _renderer; private readonly ActionBlock<PdfJob> _processingBlock; public BatchPdfProcessor(int maxConcurrency = 4) { _renderer = new ChromePdfRenderer(); // Create a processing pipeline with controlled concurrency _processingBlock = new ActionBlock<PdfJob>( async job => await ProcessPdfAsync(job), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = maxConcurrency, BoundedCapacity = maxConcurrency * 2 }); } private async Task ProcessPdfAsync(PdfJob job) { try { var pdf = await _renderer.RenderHtmlAsPdfAsync(job.Html); await pdf.SaveAsAsync(job.OutputPath); job.OnSuccess?.Invoke(); } catch (Exception ex) { job.OnError?.Invoke(ex); } } public async Task<bool> QueuePdfAsync(PdfJob job) { return await _processingBlock.SendAsync(job); } public async Task CompleteAsync() { _processingBlock.Complete(); await _processingBlock.Completion; } } public class PdfJob { public string Html { get; set; } public string OutputPath { get; set; } public Action OnSuccess { get; set; } public Action<Exception> OnError { get; set; } } using IronPdf; using System.Threading.Tasks.Dataflow; public class BatchPdfProcessor { private readonly ChromePdfRenderer _renderer; private readonly ActionBlock<PdfJob> _processingBlock; public BatchPdfProcessor(int maxConcurrency = 4) { _renderer = new ChromePdfRenderer(); // Create a processing pipeline with controlled concurrency _processingBlock = new ActionBlock<PdfJob>( async job => await ProcessPdfAsync(job), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = maxConcurrency, BoundedCapacity = maxConcurrency * 2 }); } private async Task ProcessPdfAsync(PdfJob job) { try { var pdf = await _renderer.RenderHtmlAsPdfAsync(job.Html); await pdf.SaveAsAsync(job.OutputPath); job.OnSuccess?.Invoke(); } catch (Exception ex) { job.OnError?.Invoke(ex); } } public async Task<bool> QueuePdfAsync(PdfJob job) { return await _processingBlock.SendAsync(job); } public async Task CompleteAsync() { _processingBlock.Complete(); await _processingBlock.Completion; } } public class PdfJob { public string Html { get; set; } public string OutputPath { get; set; } public Action OnSuccess { get; set; } public Action<Exception> OnError { get; set; } } $vbLabelText $csharpLabel Memory Optimization Techniques For large PDFs or high-volume processing, memory management is crucial: using IronPdf; public class MemoryEfficientPdfGenerator { private readonly ChromePdfRenderer _renderer; public MemoryEfficientPdfGenerator() { _renderer = new ChromePdfRenderer(); // Optimize for memory usage _renderer.RenderingOptions.RenderQuality = 90; // Slightly lower quality for smaller size _renderer.RenderingOptions.ImageQuality = 85; // Compress images } // Stream large PDFs instead of loading into memory public async Task GenerateLargePdfToStreamAsync(string html, Stream outputStream) { var pdf = await _renderer.RenderHtmlAsPdfAsync(html); // Write directly to stream without keeping in memory using (pdf) { var bytes = pdf.BinaryData; await outputStream.WriteAsync(bytes, 0, bytes.Length); } } // Process large HTML in chunks public async Task<PdfDocument> GenerateFromChunksAsync(List<string> htmlChunks) { var pdfs = new List<PdfDocument>(); try { // Generate each chunk separately foreach (var chunk in htmlChunks) { var chunkPdf = await _renderer.RenderHtmlAsPdfAsync(chunk); pdfs.Add(chunkPdf); } // Merge all chunks return PdfDocument.Merge(pdfs.ToArray()); } finally { // Ensure all temporary PDFs are disposed foreach (var pdf in pdfs) { pdf?.Dispose(); } } } } using IronPdf; public class MemoryEfficientPdfGenerator { private readonly ChromePdfRenderer _renderer; public MemoryEfficientPdfGenerator() { _renderer = new ChromePdfRenderer(); // Optimize for memory usage _renderer.RenderingOptions.RenderQuality = 90; // Slightly lower quality for smaller size _renderer.RenderingOptions.ImageQuality = 85; // Compress images } // Stream large PDFs instead of loading into memory public async Task GenerateLargePdfToStreamAsync(string html, Stream outputStream) { var pdf = await _renderer.RenderHtmlAsPdfAsync(html); // Write directly to stream without keeping in memory using (pdf) { var bytes = pdf.BinaryData; await outputStream.WriteAsync(bytes, 0, bytes.Length); } } // Process large HTML in chunks public async Task<PdfDocument> GenerateFromChunksAsync(List<string> htmlChunks) { var pdfs = new List<PdfDocument>(); try { // Generate each chunk separately foreach (var chunk in htmlChunks) { var chunkPdf = await _renderer.RenderHtmlAsPdfAsync(chunk); pdfs.Add(chunkPdf); } // Merge all chunks return PdfDocument.Merge(pdfs.ToArray()); } finally { // Ensure all temporary PDFs are disposed foreach (var pdf in pdfs) { pdf?.Dispose(); } } } } $vbLabelText $csharpLabel Caching and Template Optimization Reduce rendering time by caching common elements and optimizing templates: using IronPdf; using Microsoft.Extensions.Caching.Memory; public class CachedPdfService { private readonly ChromePdfRenderer _renderer; private readonly IMemoryCache _cache; private readonly Dictionary<string, string> _compiledTemplates; public CachedPdfService(IMemoryCache cache) { _renderer = new ChromePdfRenderer(); _cache = cache; _compiledTemplates = new Dictionary<string, string>(); // Pre-compile common templates PrecompileTemplates(); } private void PrecompileTemplates() { // Load and cache common CSS var commonCss = File.ReadAllText("Templates/common.css"); _compiledTemplates["commonCss"] = commonCss; // Cache logo as Base64 var logoBytes = File.ReadAllBytes("Assets/logo.png"); var logoBase64 = Convert.ToBase64String(logoBytes); _compiledTemplates["logoData"] = $"data:image/png;base64,{logoBase64}"; } public async Task<byte[]> GenerateInvoicePdfAsync(string invoiceId, InvoiceData data) { // Check cache first var cacheKey = $"invoice_{invoiceId}"; if (_cache.TryGetValue<byte[]>(cacheKey, out var cachedPdf)) { return cachedPdf; } // Generate PDF with cached templates var html = BuildHtmlWithCache(data); var pdf = await _renderer.RenderHtmlAsPdfAsync(html); var pdfBytes = pdf.BinaryData; // Cache for 1 hour _cache.Set(cacheKey, pdfBytes, TimeSpan.FromHours(1)); return pdfBytes; } private string BuildHtmlWithCache(InvoiceData data) { return $@" <html> <head> <style>{_compiledTemplates["commonCss"]}</style> </head> <body> <img src='{_compiledTemplates["logoData"]}' /> </body> </html>"; } } using IronPdf; using Microsoft.Extensions.Caching.Memory; public class CachedPdfService { private readonly ChromePdfRenderer _renderer; private readonly IMemoryCache _cache; private readonly Dictionary<string, string> _compiledTemplates; public CachedPdfService(IMemoryCache cache) { _renderer = new ChromePdfRenderer(); _cache = cache; _compiledTemplates = new Dictionary<string, string>(); // Pre-compile common templates PrecompileTemplates(); } private void PrecompileTemplates() { // Load and cache common CSS var commonCss = File.ReadAllText("Templates/common.css"); _compiledTemplates["commonCss"] = commonCss; // Cache logo as Base64 var logoBytes = File.ReadAllBytes("Assets/logo.png"); var logoBase64 = Convert.ToBase64String(logoBytes); _compiledTemplates["logoData"] = $"data:image/png;base64,{logoBase64}"; } public async Task<byte[]> GenerateInvoicePdfAsync(string invoiceId, InvoiceData data) { // Check cache first var cacheKey = $"invoice_{invoiceId}"; if (_cache.TryGetValue<byte[]>(cacheKey, out var cachedPdf)) { return cachedPdf; } // Generate PDF with cached templates var html = BuildHtmlWithCache(data); var pdf = await _renderer.RenderHtmlAsPdfAsync(html); var pdfBytes = pdf.BinaryData; // Cache for 1 hour _cache.Set(cacheKey, pdfBytes, TimeSpan.FromHours(1)); return pdfBytes; } private string BuildHtmlWithCache(InvoiceData data) { return $@" <html> <head> <style>{_compiledTemplates["commonCss"]}</style> </head> <body> <img src='{_compiledTemplates["logoData"]}' /> </body> </html>"; } } $vbLabelText $csharpLabel What Are Common Issues When Creating PDFs and How Do I Fix Them? Even with a robust .NET PDF library like IronPDF, you may encounter challenges during development or deployment when you build PDFs in C#. Understanding common issues and their solutions helps you quickly resolve problems and maintain smooth PDF generation operations. The good news is that with over 14 million developers using IronPDF as their C# PDF generator, most issues have been encountered and solved before. This troubleshooting guide covers the most frequent issues developers face when they create PDFs in .NET and provides practical solutions based on real-world experience. Remember, 24/7 support is always available if you need immediate assistance with your PDF creation challenges. Issue 1: Failed Rendering or Blank PDFs One of the most common issues is PDFs that appear blank or fail to render properly. This typically occurs when assets don't load in time or when there are JavaScript timing issues: // Namespace: IronPdf using IronPdf; // Namespace: System.IO using System.IO; // Namespace: System using System; // Problem: PDF is blank or missing content var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(complexHtml); // Results in blank PDF // Solution 1: Add render delay for JavaScript-heavy content renderer.RenderingOptions.RenderDelay = 3000; // Wait 3 seconds renderer.RenderingOptions.EnableJavaScript = true; // Solution 2: Wait for specific elements renderer.RenderingOptions.WaitFor = new WaitFor() { JavaScriptQuery = "document.querySelector('#chart-loaded') !== null", WaitForType = WaitForType.JavaScript, Timeout = 30000 // 30 second timeout }; // Solution 3: Use base path for local assets var basePath = Path.GetFullPath("Assets"); var pdf = renderer.RenderHtmlAsPdf(htmlWithImages, basePath); // Solution 4: Embed assets as Base64 var imageBase64 = Convert.ToBase64String(File.ReadAllBytes("logo.png")); var htmlWithEmbedded = $@"<img src='data:image/png;base64,{imageBase64}' />"; // Namespace: IronPdf using IronPdf; // Namespace: System.IO using System.IO; // Namespace: System using System; // Problem: PDF is blank or missing content var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(complexHtml); // Results in blank PDF // Solution 1: Add render delay for JavaScript-heavy content renderer.RenderingOptions.RenderDelay = 3000; // Wait 3 seconds renderer.RenderingOptions.EnableJavaScript = true; // Solution 2: Wait for specific elements renderer.RenderingOptions.WaitFor = new WaitFor() { JavaScriptQuery = "document.querySelector('#chart-loaded') !== null", WaitForType = WaitForType.JavaScript, Timeout = 30000 // 30 second timeout }; // Solution 3: Use base path for local assets var basePath = Path.GetFullPath("Assets"); var pdf = renderer.RenderHtmlAsPdf(htmlWithImages, basePath); // Solution 4: Embed assets as Base64 var imageBase64 = Convert.ToBase64String(File.ReadAllBytes("logo.png")); var htmlWithEmbedded = $@"<img src='data:image/png;base64,{imageBase64}' />"; $vbLabelText $csharpLabel For persistent rendering issues, enable logging to diagnose the problem: // Enable detailed logging IronPdf.Logging.Logger.EnableDebugging = true; IronPdf.Logging.Logger.LogFilePath = "IronPdf.log"; IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All; // Enable detailed logging IronPdf.Logging.Logger.EnableDebugging = true; IronPdf.Logging.Logger.LogFilePath = "IronPdf.log"; IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All; $vbLabelText $csharpLabel Learn more about troubleshooting rendering issues Issue 2: Slow Initial Render The first PDF generation can be slower due to initialization overhead. IronPDF's initial render may take 2-3 seconds to execute, which is normal start-up time similar to Chrome opening on a desktop environment: // Problem: First PDF takes too long to generate public class PdfService { private ChromePdfRenderer _renderer; // Solution 1: Initialize renderer at startup public void Initialize() { _renderer = new ChromePdfRenderer(); // Warm up the renderer _ = _renderer.RenderHtmlAsPdf("<p>Warm up</p>"); } // Solution 2: Use IronPdf.Native packages for faster initialization // Install-Package IronPdf.Native.Windows.X64 // This includes pre-loaded binaries for your platform // Solution 3: For cloud deployments, use appropriate packages // For Linux: Install-Package IronPdf.Linux // For Docker: Use IronPdf.Linux with proper dependencies } // Solution 4: Skip initialization checks in production IronPdf.Installation.SkipInitialization = true; // Use only with persistent storage // Problem: First PDF takes too long to generate public class PdfService { private ChromePdfRenderer _renderer; // Solution 1: Initialize renderer at startup public void Initialize() { _renderer = new ChromePdfRenderer(); // Warm up the renderer _ = _renderer.RenderHtmlAsPdf("<p>Warm up</p>"); } // Solution 2: Use IronPdf.Native packages for faster initialization // Install-Package IronPdf.Native.Windows.X64 // This includes pre-loaded binaries for your platform // Solution 3: For cloud deployments, use appropriate packages // For Linux: Install-Package IronPdf.Linux // For Docker: Use IronPdf.Linux with proper dependencies } // Solution 4: Skip initialization checks in production IronPdf.Installation.SkipInitialization = true; // Use only with persistent storage $vbLabelText $csharpLabel Read more about optimizing startup performance Issue 3: Deployment Issues on Linux/Docker IronPDF requires specific Linux dependencies that may not be present in minimal Docker images. Here's how to resolve common deployment issues: # Dockerfile for IronPDF on Linux FROM mcr.microsoft.com/dotnet/aspnet:8.0 # Install required dependencies RUN apt-get update && apt-get install -y \ libglib2.0-0 \ libnss3 \ libatk1.0-0 \ libatk-bridge2.0-0 \ libcups2 \ libxkbcommon0 \ libxcomposite1 \ libxdamage1 \ libxrandr2 \ libgbm1 \ libpango-1.0-0 \ libcairo2 \ libasound2 \ libxshmfence1 \ libx11-xcb1 # Copy and run your application WORKDIR /app COPY . . ENTRYPOINT ["dotnet", "YourApp.dll"] For Google Cloud Run specifically: // Use 2nd generation execution environment // Deploy with: gcloud run deploy --execution-environment gen2 // In your code, ensure compatibility IronPdf.Installation.LinuxAndDockerDependenciesAutoConfig = true; IronPdf.Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled; // Use 2nd generation execution environment // Deploy with: gcloud run deploy --execution-environment gen2 // In your code, ensure compatibility IronPdf.Installation.LinuxAndDockerDependenciesAutoConfig = true; IronPdf.Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled; $vbLabelText $csharpLabel Learn more about Docker deployment Issue 4: Memory and Performance Issues For high-volume PDF generation, optimize memory usage and performance: // Problem: High memory usage or slow batch processing public class OptimizedPdfService { private readonly ChromePdfRenderer _renderer; public OptimizedPdfService() { _renderer = new ChromePdfRenderer(); // Optimize for performance _renderer.RenderingOptions.RenderQuality = 90; _renderer.RenderingOptions.ImageQuality = 85; // Disable features you don't need _renderer.RenderingOptions.EnableJavaScript = false; // If not needed _renderer.RenderingOptions.RenderDelay = 0; // If content is static } // Solution 1: Process large documents in chunks public async Task<PdfDocument> GenerateLargeReportAsync(List<ReportSection> sections) { var pdfs = new List<PdfDocument>(); foreach (var section in sections) { var sectionHtml = GenerateSectionHtml(section); var sectionPdf = await _renderer.RenderHtmlAsPdfAsync(sectionHtml); pdfs.Add(sectionPdf); // Force garbage collection after each section if (pdfs.Count % 10 == 0) { GC.Collect(); GC.WaitForPendingFinalizers(); } } return PdfDocument.Merge(pdfs.ToArray()); } // Solution 2: Use streaming for large files public async Task StreamLargePdfAsync(string html, HttpResponse response) { response.ContentType = "application/pdf"; response.Headers.Add("Content-Disposition", "attachment; filename=report.pdf"); var pdf = await _renderer.RenderHtmlAsPdfAsync(html); var bytes = pdf.BinaryData; await response.Body.WriteAsync(bytes, 0, bytes.Length); await response.Body.FlushAsync(); } } // Problem: High memory usage or slow batch processing public class OptimizedPdfService { private readonly ChromePdfRenderer _renderer; public OptimizedPdfService() { _renderer = new ChromePdfRenderer(); // Optimize for performance _renderer.RenderingOptions.RenderQuality = 90; _renderer.RenderingOptions.ImageQuality = 85; // Disable features you don't need _renderer.RenderingOptions.EnableJavaScript = false; // If not needed _renderer.RenderingOptions.RenderDelay = 0; // If content is static } // Solution 1: Process large documents in chunks public async Task<PdfDocument> GenerateLargeReportAsync(List<ReportSection> sections) { var pdfs = new List<PdfDocument>(); foreach (var section in sections) { var sectionHtml = GenerateSectionHtml(section); var sectionPdf = await _renderer.RenderHtmlAsPdfAsync(sectionHtml); pdfs.Add(sectionPdf); // Force garbage collection after each section if (pdfs.Count % 10 == 0) { GC.Collect(); GC.WaitForPendingFinalizers(); } } return PdfDocument.Merge(pdfs.ToArray()); } // Solution 2: Use streaming for large files public async Task StreamLargePdfAsync(string html, HttpResponse response) { response.ContentType = "application/pdf"; response.Headers.Add("Content-Disposition", "attachment; filename=report.pdf"); var pdf = await _renderer.RenderHtmlAsPdfAsync(html); var bytes = pdf.BinaryData; await response.Body.WriteAsync(bytes, 0, bytes.Length); await response.Body.FlushAsync(); } } $vbLabelText $csharpLabel Read the complete performance optimization guide Issue 5: Font and Encoding Issues When dealing with international content or custom fonts: // Problem: Fonts not rendering correctly var renderer = new ChromePdfRenderer(); // Solution 1: Install fonts on the server // For Linux/Docker, add to Dockerfile: // RUN apt-get install -y fonts-liberation fonts-noto // Solution 2: Embed fonts in HTML var html = @" <html> <head> <style> @font-face { font-family: 'CustomFont'; src: url('data:font/woff2;base64,[base64-encoded-font]') format('woff2'); } body { font-family: 'CustomFont', Arial, sans-serif; } </style> </head> <body> <p>Content with custom font</p> </body> </html>"; // Solution 3: Use web fonts var htmlWithWebFont = @" <html> <head> <link href='https://fonts.googleapis.com/css2?family=Noto+Sans+JP' rel='stylesheet'> <style> body { font-family: 'Noto Sans JP', sans-serif; } </style> </head> <body> <p>日本語のテキスト</p> </body> </html>"; // Ensure proper encoding renderer.RenderingOptions.InputEncoding = Encoding.UTF8; // Problem: Fonts not rendering correctly var renderer = new ChromePdfRenderer(); // Solution 1: Install fonts on the server // For Linux/Docker, add to Dockerfile: // RUN apt-get install -y fonts-liberation fonts-noto // Solution 2: Embed fonts in HTML var html = @" <html> <head> <style> @font-face { font-family: 'CustomFont'; src: url('data:font/woff2;base64,[base64-encoded-font]') format('woff2'); } body { font-family: 'CustomFont', Arial, sans-serif; } </style> </head> <body> <p>Content with custom font</p> </body> </html>"; // Solution 3: Use web fonts var htmlWithWebFont = @" <html> <head> <link href='https://fonts.googleapis.com/css2?family=Noto+Sans+JP' rel='stylesheet'> <style> body { font-family: 'Noto Sans JP', sans-serif; } </style> </head> <body> <p>日本語のテキスト</p> </body> </html>"; // Ensure proper encoding renderer.RenderingOptions.InputEncoding = Encoding.UTF8; $vbLabelText $csharpLabel Getting Help If you encounter issues not covered here, IronPDF provides excellent support resources: 24/7 Live Chat Support - Talk to engineers in real-time with 30-second response time Comprehensive Documentation - Detailed API references and guides Knowledge Base - Solutions to common problems Code Examples - Ready-to-use code snippets When requesting support, include: IronPDF version .NET version and platform Minimal code example reproducing the issue Log files (if available) Stack trace or error messages Which Platforms Support IronPDF for PDF Generation? IronPDF's cross-platform support ensures your PDF generation code works consistently across different environments. Whether you're deploying to Windows servers, Linux containers, or cloud platforms, IronPDF provides the flexibility and reliability needed for production deployments of your C# PDF generator. This universal compatibility is one reason why organizations across 50+ countries rely on IronPDF to generate millions of PDFs daily. From Fortune 500 companies creating financial reports to startups producing customer invoices, IronPDF scales to meet any demand for PDF creation in .NET. Understanding platform-specific considerations helps ensure smooth deployments across your infrastructure - whether that's on-premise servers or cloud environments where you need to build PDFs with C#. .NET Version Compatibility IronPDF supports all modern .NET versions and is continuously updated to support the latest releases: .NET 8 - Full support with all features .NET 9 - Fully supported (current latest version) .NET 10 - Pre-release support available (IronPDF is already compliant for the November 2025 release) .NET 7, 6, 5 - Fully supported .NET Core 3.1+ - Supported with all features .NET Framework 4.6.2+ - Legacy support maintained Operating System Support Deploy your PDF generation solution on any major operating system: Windows Windows 11, 10, 8, 7 Windows Server 2022, 2019, 2016, 2012 Linux Ubuntu 20.04, 22.04, 24.04 Debian 10, 11, 12 CentOS 7, 8 Red Hat Enterprise Linux Alpine Linux (with additional configuration) macOS macOS 13 (Ventura) and newer Apple Silicon (M1/M2/M3) native support Intel-based Macs fully supported Cloud Platform Deployment IronPDF works seamlessly on all major cloud platforms: Microsoft Azure // Azure App Service configuration // Use at least B1 tier for optimal performance // Enable 64-bit platform in Configuration settings // For Azure Functions public static class PdfFunction { [FunctionName("GeneratePdf")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req) { var renderer = new ChromePdfRenderer(); var html = await new StreamReader(req.Body).ReadToEndAsync(); var pdf = await renderer.RenderHtmlAsPdfAsync(html); return new FileContentResult(pdf.BinaryData, "application/pdf"); } } // Azure App Service configuration // Use at least B1 tier for optimal performance // Enable 64-bit platform in Configuration settings // For Azure Functions public static class PdfFunction { [FunctionName("GeneratePdf")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req) { var renderer = new ChromePdfRenderer(); var html = await new StreamReader(req.Body).ReadToEndAsync(); var pdf = await renderer.RenderHtmlAsPdfAsync(html); return new FileContentResult(pdf.BinaryData, "application/pdf"); } } $vbLabelText $csharpLabel Amazon Web Services (AWS) // AWS Lambda configuration // Use custom runtime or container deployment // Ensure Lambda has at least 512MB memory public class PdfLambdaFunction { private readonly ChromePdfRenderer _renderer; public PdfLambdaFunction() { _renderer = new ChromePdfRenderer(); // Configure for Lambda environment IronPdf.Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled; } public async Task<APIGatewayProxyResponse> FunctionHandler( APIGatewayProxyRequest request, ILambdaContext context) { var pdf = await _renderer.RenderHtmlAsPdfAsync(request.Body); return new APIGatewayProxyResponse { StatusCode = 200, Headers = new Dictionary<string, string> { { "Content-Type", "application/pdf" } }, Body = Convert.ToBase64String(pdf.BinaryData), IsBase64Encoded = true }; } } // AWS Lambda configuration // Use custom runtime or container deployment // Ensure Lambda has at least 512MB memory public class PdfLambdaFunction { private readonly ChromePdfRenderer _renderer; public PdfLambdaFunction() { _renderer = new ChromePdfRenderer(); // Configure for Lambda environment IronPdf.Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled; } public async Task<APIGatewayProxyResponse> FunctionHandler( APIGatewayProxyRequest request, ILambdaContext context) { var pdf = await _renderer.RenderHtmlAsPdfAsync(request.Body); return new APIGatewayProxyResponse { StatusCode = 200, Headers = new Dictionary<string, string> { { "Content-Type", "application/pdf" } }, Body = Convert.ToBase64String(pdf.BinaryData), IsBase64Encoded = true }; } } $vbLabelText $csharpLabel Google Cloud Platform # app.yaml for App Engine runtime: aspnetcore env: flex # Use 2nd generation for Cloud Run # Deploy with: gcloud run deploy --execution-environment gen2 # app.yaml for App Engine runtime: aspnetcore env: flex # Use 2nd generation for Cloud Run # Deploy with: gcloud run deploy --execution-environment gen2 YAML Container Deployment (Docker/Kubernetes) IronPDF is container-ready with full Docker and Kubernetes support: # Multi-stage Dockerfile for optimal size FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["YourApp.csproj", "./"] RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app/publish FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final WORKDIR /app # Install IronPDF dependencies RUN apt-get update && apt-get install -y \ libglib2.0-0 libnss3 libatk1.0-0 libatk-bridge2.0-0 \ libcups2 libxkbcommon0 libxcomposite1 libxdamage1 \ libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2 COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "YourApp.dll"] Desktop Application Support IronPDF works with all major .NET desktop frameworks: WPF (Windows Presentation Foundation) public partial class MainWindow : Window { private async void GeneratePdfButton_Click(object sender, RoutedEventArgs e) { var renderer = new ChromePdfRenderer(); var html = HtmlEditor.Text; var pdf = await renderer.RenderHtmlAsPdfAsync(html); var saveDialog = new SaveFileDialog { Filter = "PDF files (*.pdf)|*.pdf", DefaultExt = "pdf" }; if (saveDialog.ShowDialog() == true) { pdf.SaveAs(saveDialog.FileName); MessageBox.Show("PDF saved successfully!"); } } } public partial class MainWindow : Window { private async void GeneratePdfButton_Click(object sender, RoutedEventArgs e) { var renderer = new ChromePdfRenderer(); var html = HtmlEditor.Text; var pdf = await renderer.RenderHtmlAsPdfAsync(html); var saveDialog = new SaveFileDialog { Filter = "PDF files (*.pdf)|*.pdf", DefaultExt = "pdf" }; if (saveDialog.ShowDialog() == true) { pdf.SaveAs(saveDialog.FileName); MessageBox.Show("PDF saved successfully!"); } } } $vbLabelText $csharpLabel Windows Forms public partial class PdfGeneratorForm : Form { private void btnGeneratePdf_Click(object sender, EventArgs e) { var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(txtHtml.Text); using (var saveDialog = new SaveFileDialog()) { saveDialog.Filter = "PDF files|*.pdf"; if (saveDialog.ShowDialog() == DialogResult.OK) { pdf.SaveAs(saveDialog.FileName); MessageBox.Show($"PDF saved to {saveDialog.FileName}"); } } } } public partial class PdfGeneratorForm : Form { private void btnGeneratePdf_Click(object sender, EventArgs e) { var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(txtHtml.Text); using (var saveDialog = new SaveFileDialog()) { saveDialog.Filter = "PDF files|*.pdf"; if (saveDialog.ShowDialog() == DialogResult.OK) { pdf.SaveAs(saveDialog.FileName); MessageBox.Show($"PDF saved to {saveDialog.FileName}"); } } } } $vbLabelText $csharpLabel MAUI (Multi-platform App UI) public partial class MainPage : ContentPage { public async Task GeneratePdfAsync() { var renderer = new ChromePdfRenderer(); var pdf = await renderer.RenderHtmlAsPdfAsync(HtmlContent); // Save to app's document directory var documentsPath = FileSystem.Current.AppDataDirectory; var filePath = Path.Combine(documentsPath, "output.pdf"); await File.WriteAllBytesAsync(filePath, pdf.BinaryData); await DisplayAlert("Success", $"PDF saved to {filePath}", "OK"); } } public partial class MainPage : ContentPage { public async Task GeneratePdfAsync() { var renderer = new ChromePdfRenderer(); var pdf = await renderer.RenderHtmlAsPdfAsync(HtmlContent); // Save to app's document directory var documentsPath = FileSystem.Current.AppDataDirectory; var filePath = Path.Combine(documentsPath, "output.pdf"); await File.WriteAllBytesAsync(filePath, pdf.BinaryData); await DisplayAlert("Success", $"PDF saved to {filePath}", "OK"); } } $vbLabelText $csharpLabel Getting Started with PDF Creation Ready to start creating PDFs in your C# application? Follow this step-by-step guide to go from installation to your first generated PDF. IronPDF makes it easy to get started, with comprehensive resources and support available every step of the way. Step 1: Install IronPDF Choose the installation method that works best for your development environment: Visual Studio Package Manager** (Recommended) Open your project in Visual Studio Right-click on your project in Solution Explorer Select "Manage NuGet Packages" Search for "IronPDF" Click Install on the IronPdf package by Iron Software Package Manager Console** Install-Package IronPdf .NET CLI dotnet add package IronPdf The NuGet package includes everything needed for PDF generation on Windows, Linux, and macOS. For specialized deployments, consider these platform-specific packages that optimize size and performance: IronPdf.Linux - Optimized for Linux environments IronPdf.MacOs - Native Apple Silicon support IronPdf.Slim - Minimal package that downloads dependencies at runtime Step 2: Create Your First PDF Start with a simple example to verify everything is working: using IronPdf; class Program { static void Main() { // Create a new PDF generator instance var renderer = new ChromePdfRenderer(); // Generate PDF from HTML var pdf = renderer.RenderHtmlAsPdf(@" # Welcome to IronPDF! <p>This is your first generated PDF document.</p> <p>Created on: " + DateTime.Now + "</p>" ); // Save the PDF pdf.SaveAs("my-first-pdf.pdf"); Console.WriteLine("PDF created successfully!"); } } using IronPdf; class Program { static void Main() { // Create a new PDF generator instance var renderer = new ChromePdfRenderer(); // Generate PDF from HTML var pdf = renderer.RenderHtmlAsPdf(@" # Welcome to IronPDF! <p>This is your first generated PDF document.</p> <p>Created on: " + DateTime.Now + "</p>" ); // Save the PDF pdf.SaveAs("my-first-pdf.pdf"); Console.WriteLine("PDF created successfully!"); } } $vbLabelText $csharpLabel Step 3: Explore Examples and Tutorials IronPDF provides extensive resources to help you master PDF generation: Code Examples - Ready-to-use code snippets for common scenarios Tutorials - Step-by-step guides for specific features How-To Guides - Practical solutions to real-world problems API Reference - Comprehensive documentation of all classes and methods Step 4: Get Help When Needed IronPDF offers multiple support channels to ensure your success: 24/7 Live Chat Support - Chat with engineers in real-time for immediate assistance Email Support - Get detailed responses to complex questions Stack Overflow - Community support and solutions Step 5: Development and Deployment Free Development License IronPDF is free for development and testing. You can explore all features without any limitations during development. Watermarks appear on generated PDFs in development mode but don't affect functionality. Production Deployment Options When you're ready to deploy to production, IronPDF offers flexible licensing: Free Trial - Get a 30-day trial license to test in production without watermarks Commercial Licenses - Starting at $799 for single-project deployment Enterprise Solutions - Custom packages for large organizations To apply a license in your code: IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"; IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"; $vbLabelText $csharpLabel Step 6: Stay Updated Keep your PDF generation capabilities current: Subscribe to Updates - Get notified about new features and improvements Follow the Blog - Learn about best practices and new techniques Check the Changelog - See what's new in each release Regular updates ensure compatibility with the latest .NET versions and include performance improvements, new features, and security updates. Why Choose IronPDF for PDF Generation in C#? After exploring various approaches to create PDFs in C#, you might wonder what makes IronPDF the preferred choice for many developers. It's not just about features - it's about the entire developer experience, from initial implementation to long-term maintenance when you need to generate PDFs in .NET. With over 14 million developers using IronPDF globally as their C# PDF generator, it has become the de facto standard for PDF generation in .NET applications. Let's examine why developers choose IronPDF for their PDF creation in C# needs. Pixel-Perfect Rendering Unlike other PDF libraries that produce approximations of your HTML designs, IronPDF uses a real Chromium engine to ensure your PDFs look exactly like they would in a modern web browser. This pixel-perfect rendering capability is why financial institutions trust IronPDF to generate regulatory reports where precision matters. Your CSS Grid layouts, flexbox designs, and JavaScript-rendered content all work perfectly. No more fighting with proprietary layout engines or accepting "close enough" results when you create PDF documents. Developer-Friendly API IronPDF's API is designed by developers, for developers. The simplicity of the API is why startups can get their PDF generation working in hours, not days. Instead of learning complex PDF specifications, you work with familiar concepts: using IronPdf; // Other libraries might require this: // document.Add(new Paragraph("Hello World")); // document.Add(new Table(3, 2)); // cell.SetBackgroundColor(ColorConstants.LIGHT_GRAY); // With IronPDF, just use HTML: var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(@" # Hello World <table> <tr style='background: lightgray;'> <td>Simple</td> <td>Intuitive</td> </tr> </table> "); using IronPdf; // Other libraries might require this: // document.Add(new Paragraph("Hello World")); // document.Add(new Table(3, 2)); // cell.SetBackgroundColor(ColorConstants.LIGHT_GRAY); // With IronPDF, just use HTML: var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderHtmlAsPdf(@" # Hello World <table> <tr style='background: lightgray;'> <td>Simple</td> <td>Intuitive</td> </tr> </table> "); $vbLabelText $csharpLabel Enterprise-Ready Features IronPDF includes features that enterprise applications demand, which is why Fortune 500 companies rely on it for mission-critical document generation: Security: Encryption, digital signatures, and permission controls protect sensitive documents Compliance: PDF/A and PDF/UA support ensures your generated PDFs meet regulatory requirements Performance: Async operations and batch processing handle millions of documents efficiently Reliability: Extensive error handling and logging help maintain uptime in production Outstanding Support When you need help, IronPDF's support team consists of actual engineers who understand your challenges. With 24/7 live chat support and typical response times under 30 seconds, you're never stuck waiting for answers. This level of support is why developers consistently rate IronPDF as having the best support in the industry. The support team can help with everything from basic questions to complex implementation challenges, ensuring your PDF generation projects succeed. Transparent Pricing No hidden fees, no surprise costs, no per-server licensing complications. IronPDF's straightforward licensing model means you know exactly what you're paying for. Development is always free, and production licenses are perpetual - you own them forever. This transparency is refreshing in an industry known for complex licensing schemes. Active Development IronPDF is continuously improved with monthly updates that add features, enhance performance, and ensure compatibility with the latest .NET releases. The team actively monitors customer feedback and implements requested features regularly. Recent additions include enhanced form handling, improved PDF editing capabilities, and optimizations for cloud deployments. Real-World Success Stories Thousands of companies across industries trust IronPDF for mission-critical PDF generation: Finance: Banks generate millions of statements and reports monthly using IronPDF's secure document features Healthcare: Hospitals create patient records and lab results with HIPAA-compliant security settings E-commerce: Online retailers produce invoices and shipping labels at scale, handling peak loads effortlessly Government: Agencies generate official documents and forms with digital signatures and encryption These organizations choose IronPDF because it delivers consistent results at scale - whether generating a single invoice or processing millions of documents daily. How Does IronPDF Compare to Other C# PDF Libraries? Choosing the right PDF library is crucial for your project's success when you need to generate PDFs in C#. Let's look at how IronPDF compares to other popular options in the .NET ecosystem for PDF creation. This comparison is based on real-world usage, developer feedback, and technical capabilities for those looking to build PDFs in .NET. Understanding these differences helps you choose the best C# PDF generator for your specific needs. Comparison Table Feature IronPDF wkhtmltopdf QuestPDF iText 7 PdfSharp Syncfusion Aspose.PDF HTML to PDF Quality Pixel-Perfect Print-Style N/A Limited No HTML Good Good HTML5/CSS3 Support Full Outdated Code-Only Partial None Full Full JavaScript Support Full No No Limited No Limited Limited Ease of Use 3 Lines CLI Only Code-First Complex Low-Level Good Complex Server Dependencies None Executable None None None None None Performance Fast + Async Slow Fast Fast Fast Fast Fast Active Development Very Active Abandoned Active Active Minimal Active Active License Type Commercial Open Source MIT→Commercial* AGPL/Commercial MIT Commercial Commercial Starting Price $799 Free $599+* $2,399+ Free $2,995+ $2,499+ *Note: QuestPDF recently changed from MIT to commercial licensing Detailed Comparisons IronPDF vs wkhtmltopdf wkhtmltopdf is free but was abandoned in 2020 and produces dated-looking PDFs Requires platform-specific executables that complicate deployment No JavaScript support means modern web apps won't render correctly IronPDF offers modern rendering with no external dependencies IronPDF vs QuestPDF QuestPDF requires building PDFs entirely in C# code with no HTML support Good for programmatic PDF creation but time-consuming for complex layouts Recently switched from MIT to commercial licensing IronPDF lets you use HTML/CSS skills you already have IronPDF vs iText 7 iText has AGPL licensing that can "infect" your codebase Commercial licenses start at $1,999 with complex pricing Limited HTML to PDF capabilities with poor CSS support IronPDF provides superior HTML rendering at a lower price point IronPDF vs PdfSharp PdfSharp is great for low-level PDF manipulation but has zero HTML support Requires manually positioning every element on the page Free and open source but very limited in features IronPDF handles both high-level HTML and low-level PDF operations IronPDF vs Syncfusion/Aspose.PDF Both are enterprise options with good features but higher pricing Syncfusion starts at $2,995, Aspose at $2,499 Neither achieves the same pixel-perfect HTML rendering as IronPDF IronPDF offers better value with comparable enterprise features Migration Paths Many developers switch to IronPDF from other libraries. Here's why: From wkhtmltopdf "We were tired of dealing with platform-specific binaries and outdated rendering" "IronPDF gave us modern CSS support and eliminated our Docker headaches" From iTextSharp/iText 7 "The learning curve was killing our productivity - IronPDF let us use HTML instead" "AGPL licensing was a deal-breaker for our commercial product" From PdfSharp "We needed HTML to PDF conversion, which PdfSharp simply doesn't do" "Manually positioning every element was taking forever" From QuestPDF "Building layouts in C# code was tedious compared to using HTML/CSS" "The recent license change made us reconsider our options" Conclusion Creating PDFs in C# doesn't have to be complicated. With IronPDF, you can generate professional PDF documents using the HTML and CSS skills you already have. Whether you're building simple reports or complex documents with charts and forms, IronPDF handles the heavy lifting so you can focus on your application logic. Join the 14 million developers worldwide who trust IronPDF as their C# PDF generator to produce PDFs reliably and efficiently. Throughout this guide, we've explored how to create PDF documents using multiple approaches - from HTML strings and URLs to converting existing files like Word documents and Markdown. We've seen how IronPDF's modern Chromium-based rendering engine produces pixel-perfect results that actually look like your web designs, not dated printer output. The ability to manipulate PDF documents programmatically, add security features, and optimize performance makes IronPDF a complete solution for all your PDF generation tasks in .NET. What sets IronPDF apart is its developer-first approach. With just three lines of code, you can generate your first PDF. The intuitive API means you spend less time learning proprietary PDF syntax and more time building features. Combined with excellent support from real engineers, transparent pricing, and continuous updates (including pre-release support for .NET 10), IronPDF gives you confidence that your PDF creation in C# will work today and in the future. Start creating PDFs today - get your free trial license and see how easy PDF generation in .NET can be in your applications. With IronPDF, you'll be generating professional PDFs in minutes, not hours. Ready to build your first PDF? Get started with IronPDF - it's free for development, and you'll be creating PDFs with C# in minutes. 참고해 주세요Aspose, iText, wkhtmltopdf, QuestPDF, PdfSharp and SyncFusion are registered trademarks of their respective owners. This site is not affiliated with, endorsed by, or sponsored by Aspose, iText, wkhtmltopdf, QuestPDF, PdfSharp, or SyncFusion. All product names, logos, and brands are the property of their respective owners. Comparisons are provided for informational purposes only and are based on publicly available information at the time of writing. 자주 묻는 질문 C#으로 HTML 콘텐츠로 PDF를 만들려면 어떻게 해야 하나요? IronPDF의 RenderHtmlAsPdf 메서드를 사용하여 C#의 HTML 콘텐츠로 PDF를 만들 수 있습니다. 이를 통해 HTML 문자열이나 URL을 PDF 문서로 직접 쉽게 변환할 수 있습니다. 무료 PDF 라이브러리보다 상용 PDF 라이브러리를 사용하면 어떤 이점이 있나요? IronPDF와 같은 상용 PDF 라이브러리는 JavaScript, CSS3 및 반응형 레이아웃에 대한 완벽한 지원과 같은 강력한 기능을 제공합니다. 안정적인 성능, 정기적인 업데이트, 포괄적인 지원을 제공하며 고품질 PDF를 만드는 데 최적화되어 있습니다. IronPDF를 사용하여 ASP.NET MVC 애플리케이션에서 PDF를 생성할 수 있나요? 예, ASP.NET MVC 애플리케이션에서 IronPDF를 사용하여 Razor 뷰 또는 HTML 템플릿을 PDF로 변환할 수 있으므로 PDF 생성을 웹 애플리케이션에 원활하게 통합할 수 있습니다. C#을 사용하여 이미지와 CSS를 PDF 문서에 통합하려면 어떻게 해야 하나요? IronPDF를 사용하면 이미지와 CSS를 PDF 문서에 쉽게 통합할 수 있습니다. HTML 콘텐츠에 이미지 태그와 CSS 스타일을 포함시킨 후 IronPDF의 렌더링 기능을 사용하여 PDF로 변환하면 됩니다. C#으로 PDF에 머리글, 바닥글, 페이지 번호를 추가할 수 있나요? 예, IronPDF는 PDF 문서에 머리글, 바닥글 및 페이지 번호 매기기를 추가할 수 있는 고급 기능을 제공합니다. HTML 콘텐츠를 렌더링하기 전에 PDF 설정을 구성하면 이 작업을 수행할 수 있습니다. C#으로 PDF를 생성할 때 XML 데이터를 어떻게 처리할 수 있나요? IronPDF를 사용하면 XML을 HTML로 변환하거나 XSLT를 사용하여 XML에 스타일을 지정하여 XML 데이터를 처리한 다음 IronPDF의 RenderHtmlAsPdf 메서드를 사용하여 PDF 문서로 변환할 수 있습니다. C#으로 PDF를 생성할 때 흔히 겪는 어려움은 무엇인가요? 일반적인 과제에는 레이아웃 일관성 유지, 복잡한 CSS 및 JavaScript 처리, 웹 기술의 정확한 렌더링 보장 등이 포함됩니다. IronPDF는 최신 Chromium 엔진과 HTML5 및 CSS3 표준에 대한 광범위한 지원으로 이러한 문제를 해결합니다. C#으로 대용량 PDF를 효율적으로 생성하려면 어떻게 해야 하나요? IronPDF는 대용량 PDF 생성을 효율적으로 처리하도록 설계되었습니다. 고성능 렌더링 엔진을 사용하며 비동기 작업을 지원하여 대용량 문서를 쉽게 관리할 수 있습니다. 상업용 라이선스 없이 IronPDF를 테스트할 수 있나요? 예, IronPDF는 개발 및 테스트 목적으로 무료 라이선스를 제공하므로 프로덕션용으로 상용 라이선스를 구매하기 전에 기능을 평가할 수 있습니다. .NET 10 호환성: .NET 10에서 IronPDF를 사용할 수 있으며 특별히 고려해야 할 사항이 있나요? 예, IronPDF는 .NET 10과 완벽하게 호환됩니다. Windows, Linux, 컨테이너화된 환경 및 웹 프레임워크를 대상으로 하는 프로젝트를 포함하여 .NET 10을 즉시 지원합니다. 특별한 구성이 필요하지 않습니다. 최신 IronPDF NuGet 패키지를 설치하기만 하면 .NET 10과 원활하게 작동합니다. 제이콥 멜러 지금 바로 엔지니어링 팀과 채팅하세요 최고기술책임자 제이콥 멜러는 Iron Software의 최고 기술 책임자(CTO)이자 C# PDF 기술을 개척한 선구적인 엔지니어입니다. Iron Software의 핵심 코드베이스를 최초로 개발한 그는 창립 초기부터 회사의 제품 아키텍처를 설계해 왔으며, CEO인 캐머런 리밍턴과 함께 회사를 NASA, 테슬라, 그리고 전 세계 정부 기관에 서비스를 제공하는 50명 이상의 직원을 보유한 기업으로 성장시켰습니다. 제이콥은 맨체스터 대학교에서 토목공학 학사 학위(BEng)를 최우등으로 취득했습니다(1998~2001). 1999년 런던에서 첫 소프트웨어 회사를 설립하고 2005년 첫 .NET 컴포넌트를 개발한 후, 마이크로소프트 생태계 전반에 걸쳐 복잡한 문제를 해결하는 데 전문성을 발휘해 왔습니다. 그의 대표 제품인 IronPDF 및 Iron Suite .NET 라이브러리는 전 세계적으로 3천만 건 이상의 NuGet 설치 수를 기록했으며, 그의 핵심 코드는 전 세계 개발자들이 사용하는 다양한 도구에 지속적으로 활용되고 있습니다. 25년의 실무 경험과 41년의 코딩 전문성을 바탕으로, 제이콥은 차세대 기술 리더들을 양성하는 동시에 기업 수준의 C#, Java, Python PDF 기술 혁신을 주도하는 데 주력하고 있습니다. 관련 기사 업데이트됨 1월 22, 2026 How to Create PDF Documents in .NET with IronPDF: Complete Guide Discover effective methods to create PDF files in C# for developers. Enhance your coding skills and streamline your projects. Read the article now! 더 읽어보기 업데이트됨 1월 21, 2026 How to Merge PDF Files in VB.NET: Complete Tutorial Merge PDF VB NET with IronPDF. Learn to combine multiple PDF files into one document using simple VB.NET code. Step-by-step examples included. 더 읽어보기 업데이트됨 1월 21, 2026 C# PDFWriter Tutorial: Create PDF Documents in .NET Learn to create PDFs efficiently using C# PDFWriter with this step-by-step guide for developers. Read the article to enhance your skills today! 더 읽어보기 .NET Core PDF Libraryx509certificate2 Add Digital Signat...
업데이트됨 1월 22, 2026 How to Create PDF Documents in .NET with IronPDF: Complete Guide Discover effective methods to create PDF files in C# for developers. Enhance your coding skills and streamline your projects. Read the article now! 더 읽어보기
업데이트됨 1월 21, 2026 How to Merge PDF Files in VB.NET: Complete Tutorial Merge PDF VB NET with IronPDF. Learn to combine multiple PDF files into one document using simple VB.NET code. Step-by-step examples included. 더 읽어보기
업데이트됨 1월 21, 2026 C# PDFWriter Tutorial: Create PDF Documents in .NET Learn to create PDFs efficiently using C# PDFWriter with this step-by-step guide for developers. Read the article to enhance your skills today! 더 읽어보기