C# 14 PDF生成器 – 全面指南 (2025版)
在C#中建立PDF是現代.NET開發人員的基本技能,不論您是在建立財務報告、生成醫療文件或產生電子商務收據。使用合適的.NET PDF程式庫,您只需幾行程式碼即可將HTML內容轉換為專業的PDF文件,讓您對文件結構和外觀有完全的控制權。
IronPDF 是目前最簡單、最易用的.NET PDF 建立程式庫 - 它擁有非常易於學習的曲線,讓您在幾分鐘內生成PDF,而非數小時。 這份綜合指南將向您展示如何使用 IronPDF - 一個強大的C# PDF生成器 - 在 C# 中準確地建立PDF文件。這個生成器能夠產生像素完美的結果,並支持所有現代.NET平台,包括即將於2025年11月發佈的.NET 10版本。雖然本教程涵蓋了從最簡單的使用案例到最先進的PDF生成方案,但不要感到害怕 - 從頭開始逐步學習。 您將學習多種生成PDF的方法,從簡單的HTML字串到複雜的多頁面報告,還有如何排除常見問題並優化各種PDF生成任務的性能。
您將學習到什麼
快速入門:在C#中建立您的首個PDF(不到2分鐘)
想立即生成PDF文档吗? 讓我們建立一個簡單但功能齊全的PDF文件來展示現代.NET PDF生成的威力。 首先,通過NuGet包管理器安裝 IronPDF - 這個單一的包包含了一切您開始建立PDF所需的東西。 IronPDF是免費開發使用,因此您可以在決定購買授權之前試用所有功能。
Install-Package IronPdf
現在讓我們使用C#建立PDF內容:
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!");
Imports IronPdf
' Instantiate the PDF generator - this is your gateway to PDF creation
Private renderer = New ChromePdfRenderer()
' Create a PDF from HTML string - yes, it's really this simple!
Private 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!")
就是這樣! 您已經
如何在C#中建立PDF:快速概覽
要在C#中建立PDF,您可以使用像IronPDF、QuestPDF或PDFSharp等第三方程式庫。這些程式庫提供了各種功能,包括從頭開始建立PDF、將HTML轉換為PDF等等。
這是過程的一個大致輪廓:
- 安裝PDF程式庫:使用Visual Studio中的NuGet包管理器以安裝合適的程式庫。
- 建立一個新的PDF文件:實例化一個PDF文件物件。
- 新增內容:向文件中新增頁面、文字、圖片和其他元素。
- 保存文件:指定一個文件路徑並保存PDF。
這是一個使用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");
}
}
Imports IronPdf
Public Class Example
Public Shared Sub CreatePdf()
' Create a new PDF document
Dim pdf = New ChromePdfRenderer()
' Add some text
Dim htmlContent As String = "<h1>Hello, PDF!</h1><p>This is a dynamically created PDF.</p>"
' Render HTML to PDF
Dim pdfDocument = pdf.RenderHtmlAsPdf(htmlContent)
' Save the PDF
pdfDocument.SaveAs("MyDynamicPdf.pdf")
End Sub
End Class
現在,讓我們深入探討為什麼開發人員需要建立PDF,以及IronPDF是如何使這一過程變簡單而強大的。
開發人員為什麼需要在C#中建立PDF?
程式化建立PDF在C#中開啟了自動化文件生成和簡化業務流程的可能性。 IronPDF受到全球超過1,400萬安裝的開發者的信賴來完成這些任務,因為它提供了無與倫比的可靠性和易用性以在.NET中構建PDF。 在金融領域,開發人員使用C# 建立PDF發票、報表和需要精確格式和安全特性的合規報告。 醫療機構**生成患者記錄、實驗室結果和保險表格以PDF形式,來確保文件完整性和HIPAA合規性。 電子商務平台生成PDF收據、運送標籤和帶有QR碼的票證(使用像IronQR這樣的工具)嵌入在PDF中。 能夠程式化地操作PDF文件**意味著您可以建立、修改和安全地操作文件,而不用手動介入。
使用像IronPDF這樣的現代.NET PDF程式庫的美妙之處在於它無縫地融入組織的現有工作流程中。 無論是從業務使用者轉換Word文件,從開發團隊轉換Markdown文件,還是從<a發佈>產生網頁報告,IronPDF都能應對得來。 這種組織靈活性是公司選擇使用程式化.NET中的PDF生成的原因之一 - 它排除了手動文件建立,減少了錯誤,確保了所有生成的PDF的一致性,並節省大量員工工時。您無需學習專有PDF語法或手動定位每個元素,您可以使用HTML和CSS來設計文件。 這種方法大大減少了開發時間,並使得保持所有已生成的PDF的一致品牌變得簡單。 無論您是在建立單頁發票還是複雜的多章節報告,原則是不變的 - 使用HTML設計,使用C#生成PDF。
在C#專案中設置IronPDF
在建立PDF之前,讓我們確保您的開發環境
安裝方法
方法 1:Visual Studio 套件管理器(推薦初學者使用)
最簡便的方式是透過Visual Studio內建的NuGet包管理器開始使用IronPDF。 這個圖形化介面簡化了瀏覽、安裝和管理您的PDF生成依賴項:
- 在解決方案資源管理器中右鍵按您的專案
- 選擇"管理 NuGet 包"
- 點選"瀏覽"並搜尋" IronPDF"
- 選擇Iron Software 提供的 IronPDF 套件
- 點選安裝並接受授權協議
方法 2:套件管理控制台
對於喜歡命令行工具的開發者,可以使用套件管理控制台快速安裝 IronPDF:
Install-Package IronPdf
方法 3:.NET CLI(適用於跨平台開發)
如果您正在 macOS、Linux 上開發或偏好使用.NET CLI,請在您的專案目錄中使用這個命令:
dotnet add package IronPdf
選擇正確的包
IronPDF 整備了不同的NuGet包以優化各種部署場景。 了解這些選項可幫助您最小化部署大小和優化效能:
IronPdf: 標準包,包括Windows、macOS 和 Linux 需求的一切。 適合大多數應用。IronPdf.Slim: 一個輕量的基礎包,在運行時下載特定於平臺的元件。非常適合雲端部署,其中包的大小很重要。IronPdf.Linux: 專為Linux部署優化,所有必要依賴項皆已打包。IronPdf.MacOs: 專為macOS環境量身訂制,支援原生Apple Silicon。
驗證安裝
安裝後,請透過這個簡單的測試建立一個新文件來驗證一切是否正常運作:
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!");
}
Imports IronPdf
Imports System.IO
' Test your IronPDF installation
Private renderer = New ChromePdfRenderer()
Private testPdf = renderer.RenderHtmlAsPdf("<p>Installation test successful!</p>")
testPdf.SaveAs("test.pdf")
If File.Exists("test.pdf") Then
Console.WriteLine("IronPDF installed and working correctly!")
End If
在C#中生成PDF的不同方法是什麼?
IronPDF 提供了 多種方法來構建PDF文件,適合不同的情況和需求。 了解這些方法有助於您在需要
1. 從HTML字串建立PDF (最靈活)
從HTML字串建立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");
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");
Imports IronPdf
Imports System
Imports System.Linq
Dim renderer = New ChromePdfRenderer()
' Build dynamic content with data
Dim customerName = "Acme Corporation"
Dim orderDate = DateTime.Now
Dim items = New() {
New With {.Name = "Widget Pro", .Price = 99.99D},
New With {.Name = "Gadget Plus", .Price = 149.99D}
}
' Create HTML with embedded data and modern CSS
Dim 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>"
For Each item In items
html += $"
<tr>
<td>{item.Name}</td>
<td>${item.Price:F2}</td>
</tr>"
Next
html += "
</tbody>
</table>
</body>
</html>"
' Generate the PDF document
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs($"invoice-{orderDate:yyyyMMdd}.pdf")
2. 從URL生成PDF (網頁捕捉)
有時您需要將現有的網頁轉換為PDF文件 - 非常適合歸檔、報告或建立在線內容的離線版本。 IronPDF的URL到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");
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");
Imports IronPdf
Private 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
Dim pdf = renderer.RenderUrlAsPdf("https://example.com/dashboard")
pdf.SaveAs("dashboard-capture.pdf")
' For authenticated pages, you can set cookies
Dim cookieManager = renderer.RenderingOptions.CustomCookies
cookieManager("session_id") = "your-session-token"
' Capture authenticated content
Dim securePdf = renderer.RenderUrlAsPdf("https://app.example.com/private/report")
securePdf.SaveAs("private-report.pdf")
3. 從HTML文件建立PDF (基於範本的生成)
基於範本的PDF生成非常適合當您擁有設計師可維護的複雜佈局,而不需要從您的應用程式程式碼中進行維護。 通過將HTML範本作為文件保存,您啟用了一種設計與邏輯的清晰分離。 這種方法非常適合生成如證書、合同或標準化報告等一致的文件:
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");
Imports IronPdf
Imports System.IO
Imports System
Private renderer = New ChromePdfRenderer()
' Basic file conversion
Private 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
Dim basePath = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "Assets")
Dim pdfWithAssets = renderer.RenderHtmlFileAsPdf("Templates/report-template.html", basePath)
' Even better: Template with placeholders
Dim 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")
Dim contractPdf = renderer.RenderHtmlAsPdf(templateHtml)
contractPdf.SaveAs("contract-final.pdf")
4. 將Markdown轉換為PDF
Markdown已經成為技術文件、README文件和內容管理系統的標準。 IronPDF使得您
using IronPdf;
var renderer = new ChromePdfRenderer();
// Convert Markdown string to PDF
string markdownContent = @"
# Project Documentation
## Overview
This project demonstrates **PDF generation** from _Markdown_ content.
### Features
- 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 = @"
# Project Documentation
## Overview
This project demonstrates **PDF generation** from _Markdown_ content.
### Features
- 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");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
' Convert Markdown string to PDF
Dim markdownContent As String = "
# Project Documentation
## Overview
This project demonstrates **PDF generation** from _Markdown_ content.
### Features
- 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
Dim pdfFromMarkdown = renderer.RenderMarkdownStringAsPdf(markdownContent)
pdfFromMarkdown.SaveAs("documentation.pdf")
' Convert Markdown file to PDF
Dim pdfFromFile = renderer.RenderMarkdownFileAsPdf("README.md")
pdfFromFile.SaveAs("readme-pdf.pdf")
Markdown轉PDF的轉換對於使用像Git這樣的版本控制系統的組織特別有用。 您可以自動化整個文檔工作流 - 開發人員更新Markdown文件,CI/CD管道自動生成PDF文檔,利益相關者領取專業格式的文檔,而無需任何手動介入。 這種無縫的整合到現有工作流程是為什麼許多開發團隊選擇 IronPDF 作為他們的文檔需求。
5. 將Word文件轉換 (DOCX) 到PDF
許多企業擁有需要轉換為PDF以分發或存檔的現有Word文件。 IronPDF 提供
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");
}
Imports IronPDF
Imports System.Collections.Generic
' Simple DOCX to PDF conversion
Dim docxRenderer As New DocxToPdfRenderer()
Dim pdfFromDocx = docxRenderer.RenderDocxAsPdf("proposal.docx")
pdfFromDocx.SaveAs("proposal.pdf")
' Advanced: Mail merge functionality for mass document generation
Dim recipients As New List(Of Dictionary(Of String, String)) From {
New Dictionary(Of String, String) From {{"Name", "John Smith"}, {"Company", "Tech Corp"}, {"Date", "March 15, 2024"}},
New Dictionary(Of String, String) From {{"Name", "Jane Doe"}, {"Company", "Innovation Inc"}, {"Date", "March 15, 2024"}}
}
' Configure mail merge options
Dim options As New DocxPdfRenderOptions With {
.MailMergeDataSource = recipients,
.MailMergePrintAllInOnePdfDocument = False ' Creates separate PDFs
}
' Generate personalized PDFs from template
For Each recipient In recipients
Dim personalizedPdf = docxRenderer.RenderDocxAsPdf("letter-template.docx", options)
personalizedPdf.SaveAs($"letter-{recipient("Name").Replace(" ", "-")}.pdf")
Next
這個DOCX轉換功能對於組織內部自動化文件工作流程是無價的。 考慮一個銷售團隊在Word中創建提案 - 有了IronPDF,這些提案可以被自動轉換為帶有浮水印、安全設定及數位簽章的PDF,程序化應用。 郵件合併功能允許批量
6. 將圖像轉換為PDF
將圖像轉換為PDF對於製作相冊、掃描的文件集合或基於圖像的報告是必需的。 IronPDF支持所有主要圖像格式,並提供控制佈局和質量的選項:
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");
Imports IronPDF
Imports IronPdf.Imaging ' `Install-Package IronPdf`
Imports System.IO
Dim renderer As New ChromePdfRenderer()
' Convert single image to PDF
Dim imagePath As String = "product-photo.jpg"
Dim imageHtml As String = "
<html>
<body style='margin: 0; padding: 0;'>
<img src='" & imagePath & "' style='width: 100%; height: auto;' />
</body>
</html>"
Dim imagePdf = renderer.RenderHtmlAsPdf(imageHtml, Path.GetDirectoryName(imagePath))
imagePdf.SaveAs("product-catalog-page.pdf")
' Create multi-page PDF from multiple images
Dim imageFiles = Directory.GetFiles("ProductImages", "*.jpg")
Dim catalogHtml As String = "<html><body style='margin: 0;'>"
For Each 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>"
Next
catalogHtml &= "</body></html>"
Dim catalogPdf = renderer.RenderHtmlAsPdf(catalogHtml, "ProductImages")
catalogPdf.SaveAs("product-catalog.pdf")
7. 從ASP.NET頁面生成PDF
對於Web應用程序,
// 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();
}
}
Imports Microsoft.AspNetCore.Mvc
Imports IronPDF
Imports System.Threading.Tasks
Imports System.IO
Imports System
Public Class ReportController
Inherits Controller
Private ReadOnly _pdfRenderer As ChromePdfRenderer
Public Sub New()
_pdfRenderer = New ChromePdfRenderer()
End Sub
Public Async Function DownloadReport(reportId As Integer) As Task(Of IActionResult)
' Get your report data
Dim reportData = Await GetReportData(reportId)
' Render view to HTML string
Dim html = Await RenderViewToStringAsync("Reports/MonthlyReport", reportData)
' Convert HTML content to PDF
Dim pdf = _pdfRenderer.RenderHtmlAsPdf(html)
' Return as file download
Return File(pdf.BinaryData, "application/pdf", $"report-{reportId}-{DateTime.Now:yyyy-MM}.pdf")
End Function
Private Async Function RenderViewToStringAsync(viewName As String, model As Object) As Task(Of String)
ViewData.Model = model
Using sw As New StringWriter()
Dim viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName)
Dim viewContext = New ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw, New HtmlHelperOptions())
viewResult.View.Render(viewContext, sw)
Return sw.GetStringBuilder().ToString()
End Using
End Function
End Class
如何使PDF看起來專業?
創建PDF是其中一方面 - 讓它們看起來專業是當您
頁眉、頁腳和頁碼
專業文檔需要一致的頁眉和頁腳以提供上下文和導航功能。 IronPDF提供簡單的基於文本和複雜的基於HTML的頁眉和頁腳選項。 這種靈活性是為什麼當組織需要在規模上
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;'>
<h2 style='margin: 0; color: #333;'>Annual Report 2024</h2>
<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;'>
<h2 style='margin: 0; color: #333;'>Annual Report 2024</h2>
<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");
Imports IronPDF
Imports System
Dim renderer As New ChromePdfRenderer()
' Simple text header and footer with page numbers
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.Text = "Confidential Report - {date}",
.DrawDividerLine = True,
.Font = "Arial",
.FontSize = 12
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.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 With {
.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;'>
<h2 style='margin: 0; color: #333;'>Annual Report 2024</h2>
<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
Dim html As String = "<h1>Financial Overview</h1><p>Report content here...</p>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("professional-report.pdf")
這些頁眉和頁腳選項使組織能夠保持所有
進階頁面設置和佈局控制
對頁面佈局的控制對於創建能夠正確打印並在所有設備上看起來專業的文件至關重要。 IronPDF 提供了豐富的頁面設置選項,包括自訂大小、方向及邊距:
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
Dim 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
處理字體和排版
字體排版在文件的專業性中起著關鍵作用。 IronPDF 支援Web字體,自定字體和先進的排版功能:
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");
Imports System
Dim renderer = New ChromePdfRenderer()
' HTML with custom fonts and typography
Dim 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>"
Dim pdf = renderer.RenderHtmlAsPdf(html, "Assets/Fonts")
pdf.SaveAs("typography-demo.pdf")
現實範例:我怎樣生成發票PDF?
讓我們創建一個
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'>
<h1>{invoice.CompanyName}</h1>
<p>{invoice.CompanyAddress}<br>
{invoice.CompanyCity}, {invoice.CompanyState} {invoice.CompanyZip}<br>
Phone: {invoice.CompanyPhone}<br>
Email: {invoice.CompanyEmail}</p>
</div>
<div class='invoice-details'>
<h2>INVOICE</h2>
<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'>
<h3>Bill To</h3>
<p><strong>{invoice.CustomerName}</strong><br>
{invoice.CustomerAddress}<br>
{invoice.CustomerCity}, {invoice.CustomerState} {invoice.CustomerZip}<br>
{invoice.CustomerEmail}</p>
</div>
<div class='billing-box'>
<h3>Payment Information</h3>
<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'>
<h3>Payment Terms & Conditions</h3>
<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'>
<h1>{invoice.CompanyName}</h1>
<p>{invoice.CompanyAddress}<br>
{invoice.CompanyCity}, {invoice.CompanyState} {invoice.CompanyZip}<br>
Phone: {invoice.CompanyPhone}<br>
Email: {invoice.CompanyEmail}</p>
</div>
<div class='invoice-details'>
<h2>INVOICE</h2>
<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'>
<h3>Bill To</h3>
<p><strong>{invoice.CustomerName}</strong><br>
{invoice.CustomerAddress}<br>
{invoice.CustomerCity}, {invoice.CustomerState} {invoice.CustomerZip}<br>
{invoice.CustomerEmail}</p>
</div>
<div class='billing-box'>
<h3>Payment Information</h3>
<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'>
<h3>Payment Terms & Conditions</h3>
<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);
Imports IronPDF
Imports System
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Linq
Public Class InvoiceGenerator
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
ConfigureRenderer()
End Sub
Private Sub 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 With {
.Text = "Page {page} of {total-pages} | Invoice generated on {date}",
.FontSize = 9,
.Font = "Arial",
.CenterText = True
}
End Sub
Public Sub CreateInvoice(invoice As Invoice)
Dim html = GenerateInvoiceHtml(invoice)
Dim 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
Dim fileName = $"Invoice-{invoice.Number}.pdf"
pdf.SaveAs(fileName)
Console.WriteLine($"PDF generated successfully: {fileName}")
End Sub
Private Function GenerateInvoiceHtml(invoice As Invoice) As String
Dim itemsHtml = String.Join("", invoice.Items.Select(Function(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'>
<h1>{invoice.CompanyName}</h1>
<p>{invoice.CompanyAddress}<br>
{invoice.CompanyCity}, {invoice.CompanyState} {invoice.CompanyZip}<br>
Phone: {invoice.CompanyPhone}<br>
Email: {invoice.CompanyEmail}</p>
</div>
<div class='invoice-details'>
<h2>INVOICE</h2>
<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'>
<h3>Bill To</h3>
<p><strong>{invoice.CustomerName}</strong><br>
{invoice.CustomerAddress}<br>
{invoice.CustomerCity}, {invoice.CustomerState} {invoice.CustomerZip}<br>
{invoice.CustomerEmail}</p>
</div>
<div class='billing-box'>
<h3>Payment Information</h3>
<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'>
<h3>Payment Terms & Conditions</h3>
<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>"
End Function
End Class
' Invoice model classes
Public Class Invoice
Public Property Number As String
Public Property [Date] As DateTime
Public Property DueDate As DateTime
Public Property CompanyName As String
Public Property CompanyAddress As String
Public Property CompanyCity As String
Public Property CompanyState As String
Public Property CompanyZip As String
Public Property CompanyPhone As String
Public Property CompanyEmail As String
Public Property CompanyWebsite As String
Public Property CustomerName As String
Public Property CustomerAddress As String
Public Property CustomerCity As String
Public Property CustomerState As String
Public Property CustomerZip As String
Public Property CustomerEmail As String
Public Property PaymentTerms As String
Public Property Items As List(Of InvoiceItem)
Public ReadOnly Property Subtotal As Decimal
Get
Return Items.Sum(Function(i) i.Total)
End Get
End Property
Public Property TaxRate As Decimal
Public ReadOnly Property Tax As Decimal
Get
Return Subtotal * (TaxRate / 100)
End Get
End Property
Public ReadOnly Property Total As Decimal
Get
Return Subtotal + Tax
End Get
End Property
End Class
Public Class InvoiceItem
Public Property Description As String
Public Property Quantity As Integer
Public Property UnitPrice As Decimal
Public ReadOnly Property Total As Decimal
Get
Return Quantity * UnitPrice
End Get
End Property
End Class
' Usage example
Dim generator As New InvoiceGenerator()
Dim invoice As New Invoice With {
.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.5D,
.Items = New List(Of InvoiceItem) From {
New InvoiceItem With {.Description = "Professional Services - March 2024", .Quantity = 40, .UnitPrice = 125.0D},
New InvoiceItem With {.Description = "Software License (Annual)", .Quantity = 1, .UnitPrice = 2400.0D},
New InvoiceItem With {.Description = "Technical Support", .Quantity = 10, .UnitPrice = 150.0D}
}
}
generator.CreateInvoice(invoice)
IronPDF 提供什麼先進的PDF功能?
IronPDF 不僅限於基礎
生成互動式PDF表單
程式化創建可填充的PDF表單開啟了自動數據收集和文件工作流程的可能性。 IronPDF可以將HTML表單轉變成
// 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})");
Imports IronPDF
Imports System
Dim renderer As New ChromePdfRenderer()
' Enable form creation from HTML
renderer.RenderingOptions.CreatePdfFormsFromHtml = True
' Create an interactive form with various input types
Dim formHtml As String = "
<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
Dim 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
Dim submittedPdf = PdfDocument.FromFile("submitted-form.pdf")
Dim name = submittedPdf.Form.FindFormField("fullName").Value
Dim email = submittedPdf.Form.FindFormField("email").Value
Console.WriteLine($"Form submitted by: {name} ({email})")
保護您生成的PDF
當涉及敏感文件時,安全性是首要考慮。 IronPDF 提供了全面的安全功能來保護您的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");
// 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");
Imports IronPDF
Imports IronPdf.Editing
Dim renderer As New ChromePdfRenderer()
Dim 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") With {
.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")
合併和拆分PDF
合併多個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");
}
// 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");
}
Imports IronPDF
Imports System
' Merge multiple PDFs into one document
Dim coverPage = New ChromePdfRenderer().RenderHtmlAsPdf("<h1>Annual Report 2024</h1>")
Dim introduction = PdfDocument.FromFile("introduction.pdf")
Dim financials = PdfDocument.FromFile("financials.pdf")
Dim appendix = PdfDocument.FromFile("appendix.pdf")
' Merge all documents
Dim completeReport = PdfDocument.Merge(coverPage, introduction, financials, appendix)
' Add page numbers to the merged document
For i As Integer = 0 To completeReport.PageCount - 1
completeReport.AddTextFooterToPage(i, $"Page {i + 1} of {completeReport.PageCount}", IronPdf.Font.FontTypes.Arial, 10)
Next
completeReport.SaveAs("annual-report-complete.pdf")
' Extract specific pages
Dim executiveSummary = completeReport.CopyPages(0, 4) ' First 5 pages
executiveSummary.SaveAs("executive-summary.pdf")
' Split a large PDF into chapters
Dim sourcePdf = PdfDocument.FromFile("large-document.pdf")
Dim chaptersPerFile As Integer = 50
For i As Integer = 0 To sourcePdf.PageCount - 1 Step chaptersPerFile
Dim endPage = Math.Min(i + chaptersPerFile - 1, sourcePdf.PageCount - 1)
Dim chapter = sourcePdf.CopyPages(i, endPage)
chapter.SaveAs($"chapter-{(i \ chaptersPerFile) + 1}.pdf")
Next
添加浮水印和印章
將浮水印添加到PDF對於文件控制和品牌塑造至關重要。 IronPDF 支持文本和圖像浮水印:
// 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");
Imports IronPDF
Imports System
Dim 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")
如何在規模上優化PDF生成的性能?
當
非同步PDF生成
現代應用需要非阻塞操作來保持響應度。 IronPDF 為所有主要操作提供非同步方法:
// 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");
}
}
}
Imports IronPDF
Imports System.Threading.Tasks
Imports System.Collections.Generic
Imports System.Linq
Imports System
Imports System.Threading
Public Class AsyncPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
' Configure renderer once for reuse
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
' Non-blocking PDF generation
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Function
Public Async Function GenerateBatchAsync(htmlDocuments As List(Of String)) As Task
' Process multiple PDFs concurrently
Dim tasks = htmlDocuments.Select(Async Function(html, index)
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Await pdf.SaveAsAsync($"document-{index}.pdf")
End Function)
Await Task.WhenAll(tasks)
End Function
' Async with cancellation support
Public Async Function GenerateWithTimeoutAsync(html As String, timeoutSeconds As Integer) As Task(Of PdfDocument)
Using cts As New CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds))
Try
Return Await _renderer.RenderHtmlAsPdfAsync(html, cts.Token)
Catch ex As OperationCanceledException
Throw New TimeoutException("PDF generation exceeded timeout")
End Try
End Using
End Function
End Class
批處理的最佳實踐
當處理多個PDF時,適當的資源管理和並行處理能大幅提高性能:
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; }
}
Imports IronPDF
Imports System.Threading.Tasks.Dataflow
Public Class BatchPdfProcessor
Private ReadOnly _renderer As ChromePdfRenderer
Private ReadOnly _processingBlock As ActionBlock(Of PdfJob)
Public Sub New(Optional maxConcurrency As Integer = 4)
_renderer = New ChromePdfRenderer()
' Create a processing pipeline with controlled concurrency
_processingBlock = New ActionBlock(Of PdfJob)(
Async Function(job) Await ProcessPdfAsync(job),
New ExecutionDataflowBlockOptions With {
.MaxDegreeOfParallelism = maxConcurrency,
.BoundedCapacity = maxConcurrency * 2
})
End Sub
Private Async Function ProcessPdfAsync(job As PdfJob) As Task
Try
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(job.Html)
Await pdf.SaveAsAsync(job.OutputPath)
job.OnSuccess?.Invoke()
Catch ex As Exception
job.OnError?.Invoke(ex)
End Try
End Function
Public Async Function QueuePdfAsync(job As PdfJob) As Task(Of Boolean)
Return Await _processingBlock.SendAsync(job)
End Function
Public Async Function CompleteAsync() As Task
_processingBlock.Complete()
Await _processingBlock.Completion
End Function
End Class
Public Class PdfJob
Public Property Html As String
Public Property OutputPath As String
Public Property OnSuccess As Action
Public Property OnError As Action(Of Exception)
End Class
記憶體優化技術
對於大型PDF或高容量處理,記憶管理至關重要:
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();
}
}
}
}
Imports IronPDF
Public Class MemoryEfficientPdfGenerator
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
' Optimize for memory usage
_renderer.RenderingOptions.RenderQuality = 90 ' Slightly lower quality for smaller size
_renderer.RenderingOptions.ImageQuality = 85 ' Compress images
End Sub
' Stream large PDFs instead of loading into memory
Public Async Function GenerateLargePdfToStreamAsync(html As String, outputStream As Stream) As Task
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
' Write directly to stream without keeping in memory
Using pdf
Dim bytes = pdf.BinaryData
Await outputStream.WriteAsync(bytes, 0, bytes.Length)
End Using
End Function
' Process large HTML in chunks
Public Async Function GenerateFromChunksAsync(htmlChunks As List(Of String)) As Task(Of PdfDocument)
Dim pdfs = New List(Of PdfDocument)()
Try
' Generate each chunk separately
For Each chunk In htmlChunks
Dim chunkPdf = Await _renderer.RenderHtmlAsPdfAsync(chunk)
pdfs.Add(chunkPdf)
Next
' Merge all chunks
Return PdfDocument.Merge(pdfs.ToArray())
Finally
' Ensure all temporary PDFs are disposed
For Each pdf In pdfs
pdf?.Dispose()
Next
End Try
End Function
End Class
快取和範本優化
將渲染時間減到最短可以通過快取常用元素和優化範本來減少:
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>";
}
}
Imports IronPDF
Imports Microsoft.Extensions.Caching.Memory
Imports System.IO
Imports System.Threading.Tasks
Public Class CachedPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Private ReadOnly _cache As IMemoryCache
Private ReadOnly _compiledTemplates As Dictionary(Of String, String)
Public Sub New(cache As IMemoryCache)
_renderer = New ChromePdfRenderer()
_cache = cache
_compiledTemplates = New Dictionary(Of String, String)()
' Pre-compile common templates
PrecompileTemplates()
End Sub
Private Sub PrecompileTemplates()
' Load and cache common CSS
Dim commonCss As String = File.ReadAllText("Templates/common.css")
_compiledTemplates("commonCss") = commonCss
' Cache logo as Base64
Dim logoBytes As Byte() = File.ReadAllBytes("Assets/logo.png")
Dim logoBase64 As String = Convert.ToBase64String(logoBytes)
_compiledTemplates("logoData") = $"data:image/png;base64,{logoBase64}"
End Sub
Public Async Function GenerateInvoicePdfAsync(invoiceId As String, data As InvoiceData) As Task(Of Byte())
' Check cache first
Dim cacheKey As String = $"invoice_{invoiceId}"
Dim cachedPdf As Byte() = Nothing
If _cache.TryGetValue(cacheKey, cachedPdf) Then
Return cachedPdf
End If
' Generate PDF with cached templates
Dim html As String = BuildHtmlWithCache(data)
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Dim pdfBytes As Byte() = pdf.BinaryData
' Cache for 1 hour
_cache.Set(cacheKey, pdfBytes, TimeSpan.FromHours(1))
Return pdfBytes
End Function
Private Function BuildHtmlWithCache(data As InvoiceData) As String
Return $"
<html>
<head>
<style>{_compiledTemplates("commonCss")}</style>
</head>
<body>
<img src='{_compiledTemplates("logoData")}' />
</body>
</html>"
End Function
End Class
生成PDF時有哪些常見問題,我該如何解決它們?
即使使用像IronPDF這樣強大的.NET PDF程式庫,您可能會在在C#中構建PDF時遇到發展或部署過程中的挑戰。 理解
問題 1:渲染失敗或空白PDF
最常見的問題之一是PDF看起來空白或未能正確渲染。 通常這發生在資產沒有及時加載或出現
// 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}' />";
Imports IronPDF
Imports System.IO
Imports System
' Problem: PDF is blank or missing content
Dim renderer As New ChromePdfRenderer()
Dim 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() With {
.JavaScriptQuery = "document.querySelector('#chart-loaded') !== null",
.WaitForType = WaitForType.JavaScript,
.Timeout = 30000 ' 30 second timeout
}
' Solution 3: Use base path for local assets
Dim basePath As String = Path.GetFullPath("Assets")
pdf = renderer.RenderHtmlAsPdf(htmlWithImages, basePath)
' Solution 4: Embed assets as Base64
Dim imageBase64 As String = Convert.ToBase64String(File.ReadAllBytes("logo.png"))
Dim htmlWithEmbedded As String = $"<img src='data:image/png;base64,{imageBase64}' />"
對於持續的渲染問題,啟用記續日誌以診斷問題:
// 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;
' Enable detailed logging
IronPdf.Logging.Logger.EnableDebugging = True
IronPdf.Logging.Logger.LogFilePath = "IronPdf.log"
IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All
問題 2:初始渲染速度慢
由於初始化開銷,第一個PDF生成可能會更慢。 IronPDF的首次渲染可能需要2-3秒執行,這是正常的啟動時間,類似於桌面環境中的Chrome開啟:
// 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
Imports IronPdf
' Problem: First PDF takes too long to generate
Public Class PdfService
Private _renderer As ChromePdfRenderer
' Solution 1: Initialize renderer at startup
Public Sub Initialize()
_renderer = New ChromePdfRenderer()
' Warm up the renderer
Dim unused = _renderer.RenderHtmlAsPdf("<p>Warm up</p>")
End Sub
' 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
End Class
' Solution 4: Skip initialization checks in production
IronPdf.Installation.SkipInitialization = True ' Use only with persistent storage
問題 3:Linux/Docker上的部署問題
IronPDF 需要特定的 Linux 依賴項,這些在最小的Docker映像中可能不存在。 以下是如何解決常見的部署問題:
# 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 [".NET", "YourApp.dll"]
專為Google Cloud運行:
// 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;
' 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
問題 4:記憶和性能問題
當進行高容量的PDF生成時,優化記憶使用和性能:
// 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();
}
}
' Problem: High memory usage or slow batch processing
Public Class OptimizedPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_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
End Sub
' Solution 1: Process large documents in chunks
Public Async Function GenerateLargeReportAsync(ByVal sections As List(Of ReportSection)) As Task(Of PdfDocument)
Dim pdfs = New List(Of PdfDocument)()
For Each section In sections
Dim sectionHtml = GenerateSectionHtml(section)
Dim sectionPdf = Await _renderer.RenderHtmlAsPdfAsync(sectionHtml)
pdfs.Add(sectionPdf)
' Force garbage collection after each section
If pdfs.Count Mod 10 = 0 Then
GC.Collect()
GC.WaitForPendingFinalizers()
End If
Next section
Return PdfDocument.Merge(pdfs.ToArray())
End Function
' Solution 2: Use streaming for large files
Public Async Function StreamLargePdfAsync(ByVal html As String, ByVal response As HttpResponse) As Task
response.ContentType = "application/pdf"
response.Headers.Add("Content-Disposition", "attachment; filename=report.pdf")
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Dim bytes = pdf.BinaryData
Await response.Body.WriteAsync(bytes, 0, bytes.Length)
Await response.Body.FlushAsync()
End Function
End Class
問題 5:字體和編碼問題
當處理國際內容或自定字體時:
// 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;
' Problem: Fonts not rendering correctly
Dim 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
Dim 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
Dim 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
獲得幫助
如果遇到這裡未涵蓋的問題,IronPDF 提供優異的支援資源:
- 24/7 即時聊天支援 - 與工程師實時交談,反應時間為30秒
- 全面的文獻記錄 - 詳細的API參考和指南
- 知識庫 - 常見問題的解決方案
- 代碼範例 - 可即時使用的代碼片段
當要求支援時,請包括:
- IronPDF版本
- .NET版本和平台
- 最小代碼範例重現問題
- 記錄檔(如有)
- 堆疊追蹤或錯誤消息
哪個平台支持 IronPDF 進行 PDF 生成?
IronPDF的跨平台支持確保您的PDF生成代碼能在不同環境中穩定運行。 無論您是部署到Windows伺服器、Linux容器或雲端平台,IronPDF 都提供了生產部署所需的靈活性和可靠性,讓您的C# PDF生成器正常運行。 這種通用的兼容性是為什麼全世界50多個國家的組織每天依賴IronPDF生成數百萬張PDF。 從財富500強公司創建財務報告到初創公司生成客戶發票,IronPDF擴展到任何需求的
.NET 版本兼容性
IronPDF支持所有的現代.NET版本,並且持續更新以支持最新釋出的版本:
- .NET 8 - 所有功能全支持
- .NET 9 - 完全支持(最新版本)
- .NET 10 - 可用的預發布支持(IronPDF已經合規於2025年11月發布)
- .NET 7, 6, 5 - 全面支持
- .NET Core 3.1+ - 全功能支持
- .NET Framework 4.6.2+ - 保持的遺產支持
操作系統支持
在任何主流操作系統上部署您的PDF生成解決方案:
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(需要額外配置)
macOS
- macOS 13(Ventura)及更新版本
- 原生支援Apple Silicon(M1/M2/M3)
- 完全支援Intel基礎的Mac
雲端平台部署
IronPDF可以在所有主要的雲端平台上無縫運作:
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");
}
}
' Azure App Service configuration
' Use at least B1 tier for optimal performance
' Enable 64-bit platform in Configuration settings
' For Azure Functions
Public Module PdfFunction
<FunctionName("GeneratePdf")>
Public Async Function Run(<HttpTrigger(AuthorizationLevel.Function, "post")> ByVal req As HttpRequest) As Task(Of IActionResult)
Dim renderer = New ChromePdfRenderer()
Dim html = Await (New StreamReader(req.Body)).ReadToEndAsync()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return New FileContentResult(pdf.BinaryData, "application/pdf")
End Function
End Module
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
};
}
}
Imports System.Collections.Generic
Imports System.Threading.Tasks
Imports Amazon.Lambda.APIGatewayEvents
Imports Amazon.Lambda.Core
Imports IronPdf
' AWS Lambda configuration
' Use custom runtime or container deployment
' Ensure Lambda has at least 512MB memory
Public Class PdfLambdaFunction
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
' Configure for Lambda environment
IronPdf.Installation.ChromeGpuMode = IronPdf.Engines.Chrome.ChromeGpuModes.Disabled
End Sub
Public Async Function FunctionHandler(
request As APIGatewayProxyRequest,
context As ILambdaContext) As Task(Of APIGatewayProxyResponse)
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(request.Body)
Return New APIGatewayProxyResponse With {
.StatusCode = 200,
.Headers = New Dictionary(Of String, String) From {
{"Content-Type", "application/pdf"}
},
.Body = Convert.ToBase64String(pdf.BinaryData),
.IsBase64Encoded = True
}
End Function
End Class
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
容器部署(Docker/Kubernetes)
IronPDF已準備好容器化,並全面支援Docker和Kubernetes:
# Multi-stage Dockerfile for optimal size
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["YourApp.csproj", "./"]
RUN .NET restore
COPY . .
RUN .NET 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 [".NET", "YourApp.dll"]
桌面應用支援
IronPDF支援所有主要的.NET桌面框架:
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!");
}
}
}
Partial Public Class MainWindow
Inherits Window
Private Async Sub GeneratePdfButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim renderer = New ChromePdfRenderer()
Dim html = HtmlEditor.Text
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Dim saveDialog = New SaveFileDialog With {
.Filter = "PDF files (*.pdf)|*.pdf",
.DefaultExt = "pdf"
}
If saveDialog.ShowDialog() = True Then
pdf.SaveAs(saveDialog.FileName)
MessageBox.Show("PDF saved successfully!")
End If
End Sub
End Class
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}");
}
}
}
}
Partial Public Class PdfGeneratorForm
Inherits Form
Private Sub btnGeneratePdf_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(txtHtml.Text)
Using saveDialog = New SaveFileDialog()
saveDialog.Filter = "PDF files|*.pdf"
If saveDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
pdf.SaveAs(saveDialog.FileName)
MessageBox.Show($"PDF saved to {saveDialog.FileName}")
End If
End Using
End Sub
End Class
MAUI(多平台應用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");
}
}
Partial Public Class MainPage
Inherits ContentPage
Public Async Function GeneratePdfAsync() As Task
Dim renderer = New ChromePdfRenderer()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(HtmlContent)
' Save to app's document directory
Dim documentsPath = FileSystem.Current.AppDataDirectory
Dim filePath = Path.Combine(documentsPath, "output.pdf")
Await File.WriteAllBytesAsync(filePath, pdf.BinaryData)
Await DisplayAlert("Success", $"PDF saved to {filePath}", "OK")
End Function
End Class
開始使用PDF創建
準備好在您的C#應用中開始創建PDF了嗎? 遵循這個逐步指南,從安裝到生成您的第一個PDF。 IronPDF讓您容易上手,每一步都有全面的資源和支援。
步驟1:安裝IronPDF
選擇最適合您開發環境的安裝方法:
Visual Studio套件管理器**(推薦)
- 在Visual Studio中打開您的專案
- 在解決方案總管中右鍵點擊您的專案
- 選擇"管理NuGet套件"
- 搜尋"IronPDF"
- 點擊Iron Software的IronPdf套件的安裝按鈕
套件管理器控制台**
Install-Package IronPdf
.NET CLI
.NET add package IronPDF
NuGet套件包含Windows、Linux和macOS上PDF生成所需的一切。 針對專門部署,考慮這些平台特定的套件來優化大小和性能:
IronPdf.Linux- 最適化於Linux環境IronPdf.MacOs- 原生支援Apple SiliconIronPdf.Slim- 最小化套件,在運行時下載依賴項
步驟2:創建您的第一個PDF
從一個簡單的例子開始,驗證一切正常運作:
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!");
}
}
Imports IronPDF
Class Program
Shared Sub Main()
' Create a new PDF generator instance
Dim renderer = New ChromePdfRenderer()
' Generate PDF from HTML
Dim 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!")
End Sub
End Class
步驟3:探索示例和教程
IronPDF提供廣泛的資源幫助您掌握PDF生成:
步驟4:需要時獲得幫助
IronPDF提供多種支援渠道以確保您的成功:
- 24/7 即時聊天支援 - 與工程師實時聊天以獲得即時幫助
- 電子郵件支援 - 獲得複雜問題的詳細回應
- Stack Overflow - 社群支持和解決方案
步驟5:開發與部署
免費開發授權
IronPDF在開發和測試時免費使用。 在開發階段,您可以無限制地探索所有功能。 在開發模式下生成的PDF會出現水印,但不影響功能。
生產部署選項
當您準備好部署到生產環境時,IronPDF提供靈活的授權:
在您的代碼中申請授權的方法:
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
步驟6:保持更新
保持您的PDF生成能力與時俱進:
定期更新以確保與最新的.NET版本兼容,並包括性能改進、新功能和安全更新。
為什麼選擇IronPDF作為在C#中生成PDF的工具?
在探索多種在C#中創建PDF的方法後,您可能會懷疑IronPDF為什麼成為許多開發者的首選。 這不僅僅是因為功能,而是因為擁有從最初實施到需要時長期維護的整體開發者體驗,以便在.NET中生成PDF。 全球超過1400萬開發人員將IronPDF用作其C# PDF生成器,它已成為.NET應用中PDF生成的事實標準。 讓我們來看看為什麼開發者選擇IronPDF滿足其C#中創建PDF的需求。
像素級精確渲染
與其他PDF程式庫生成的HTML設計近似結果不同,IronPDF使用真正的Chromium引擎來確保您的PDF看起來精確無誤,如同在現代網頁瀏覽器中一樣。 正是這種像素級精確渲染功能,使金融機構信賴IronPDF來生成精確度至關重要的監管報告。 您的CSS網格佈局、Flexbox設計和JavaScript渲染內容都能完美運作。 在您創建PDF文件時不再需要為專有佈局引擎或接受"差不多"的結果而鬥爭。
開發者友好的API
IronPDF的API是由開發者為開發者設計的。 API的簡潔性使初創公司在數小時內而非數天內就能讓其PDF生成正常運行。 不用學習複雜的PDF規範,而是用熟悉的概念:
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>
");
### 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](/how-to/pdfa/) and [PDF/UA](/how-to/pdfua/) 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](/examples/form-data/), improved [PDF editing capabilities](/examples/editing-pdfs/), 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
<style>
.comparison-platform-pricing-table *,.comparison-platform-pricing-table *::before,.comparison-platform-pricing-table *::after{box-sizing:border-box;margin:0;padding:0;}
.comparison-platform-pricing-table{font-family:var(--ff-gotham);background:#f4f5f7;margin:24px 0;-webkit-font-smoothing:antialiased;}
.comparison-platform-pricing-table .card{
width:100%;max-width:1380px;
background:#fff;
border:1px solid #e2e5ea;
border-radius:10px;
overflow:hidden;
box-shadow:0 1px 3px rgba(0,0,0,.04),0 4px 16px rgba(0,0,0,.04);
}
.comparison-platform-pricing-table .scroll{overflow-x:auto;}
.comparison-platform-pricing-table ::-webkit-scrollbar{height:3px;}
.comparison-platform-pricing-table ::-webkit-scrollbar-track{background:#f0f0f0;}
.comparison-platform-pricing-table ::-webkit-scrollbar-thumb{background:#c7cdd6;border-radius:2px;}
.comparison-platform-pricing-table table{
border-collapse:collapse;
width:max-content;min-width:100%;
table-layout:fixed;
}
.comparison-platform-pricing-table col.c0{width:196px;}
.comparison-platform-pricing-table col.c1{width:140px;}
.comparison-platform-pricing-table col.cx{width:110px;}
.comparison-platform-pricing-table .s0{position:sticky;left:0;z-index:20;}
.comparison-platform-pricing-table .s1{position:sticky;left:196px;z-index:20;}
.comparison-platform-pricing-table thead th{
position:sticky;top:0;z-index:30;
padding:14px 12px 12px;
text-align:center;
border-bottom:1px solid #e2e5ea;
background:#fff;
vertical-align:bottom;
}
.comparison-platform-pricing-table thead th.s0{text-align:left;z-index:40;padding-left:18px;}
.comparison-platform-pricing-table thead th.s1{z-index:40;background:#f0f5ff;border-bottom:2px solid #2563eb;}
.comparison-platform-pricing-table .th-inner{display:flex;flex-direction:column;align-items:center;gap:5px;}
.comparison-platform-pricing-table .th-badge{
display:inline-block;
font-family:'JetBrains Mono',monospace;
font-size:7px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
background:#2563eb;color:#fff;
padding:2px 7px;border-radius:2px;
}
.comparison-platform-pricing-table .th-name{
font-size:12.5px;font-weight:700;
color:#1e2b3c;line-height:1.25;
}
.comparison-platform-pricing-table .th-name-comp{font-size:11px;font-weight:600;color:#374151;line-height:1.3;text-align:center;}
.comparison-platform-pricing-table .th-pct{
font-family:'JetBrains Mono',monospace;
font-size:11px;font-weight:600;
color:#2563eb;
}
.comparison-platform-pricing-table .th-pct-comp{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;color:#9ca3af;}
.comparison-platform-pricing-table .th-bar{width:48px;height:2px;background:#e5e7eb;border-radius:1px;overflow:hidden;margin:0 auto;}
.comparison-platform-pricing-table .th-bar-fill{height:100%;border-radius:1px;}
.comparison-platform-pricing-table .feat-label-row td.s0{background:#fff;}
.comparison-platform-pricing-table .feat-label{
font-size:12.5px;font-weight:600;
color:#1e2b3c;line-height:1.35;
padding:11px 18px;
}
.comparison-platform-pricing-table .sec-row td{
background:#f9fafb;
border-top:1px solid #e2e5ea;
border-bottom:1px solid #e8eaed;
padding:7px 18px;
}
.comparison-platform-pricing-table .sec-row td.s1{
background:#edf3ff;
border-left:2px solid #2563eb;
border-right:2px solid #2563eb;
}
.comparison-platform-pricing-table .sec-label{
font-family:'JetBrains Mono',monospace;
font-size:8.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
color:#9ca3af;
display:flex;align-items:center;gap:8px;
}
.comparison-platform-pricing-table .sec-label::after{content:'';flex:1;height:1px;background:#e5e7eb;}
.comparison-platform-pricing-table .data-row td{
border-bottom:1px solid #f0f1f3;
padding:10px 12px;
text-align:center;
vertical-align:middle;
background:#fff;
}
.comparison-platform-pricing-table .data-row:last-of-type td{border-bottom:none;}
.comparison-platform-pricing-table .data-row td.s0{background:#fff;text-align:left;}
.comparison-platform-pricing-table .data-row td.s1{
background:#f5f9ff;
border-left:2px solid #2563eb;
border-right:2px solid #2563eb;
}
.comparison-platform-pricing-table .data-row:hover td{background:#fafbfc!important;}
.comparison-platform-pricing-table .data-row:hover td.s1{background:#eef5ff!important;}
.comparison-platform-pricing-table .data-row:hover td.s0{background:#fafbfc!important;}
.comparison-platform-pricing-table .cell{
display:inline-flex;flex-direction:column;align-items:center;gap:2px;
max-width:100%;
}
.comparison-platform-pricing-table .chip{
font-family:'JetBrains Mono',monospace;
font-size:9.5px;font-weight:500;
padding:3px 9px;border-radius:100px;
border:1px solid transparent;
white-space:nowrap;line-height:1.45;
}
.comparison-platform-pricing-table .chip-sub{
font-family:'JetBrains Mono',monospace;
font-size:7.5px;color:#9ca3af;
text-align:center;line-height:1.4;max-width:96px;
}
.comparison-platform-pricing-table .chip-best{
font-family:'JetBrains Mono',monospace;
font-size:7px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
background:#dbeafe;color:#1d4ed8;border:1px solid #bfdbfe;
padding:1px 6px;border-radius:2px;
}
.comparison-platform-pricing-table .yes{background:#f0fdf4;color:#15803d;border-color:#bbf7d0;}
.comparison-platform-pricing-table .no{background:#fafafa;color:#9ca3af;border-color:#e5e7eb;}
.comparison-platform-pricing-table .part{background:#fffbeb;color:#b45309;border-color:#fde68a;}
.comparison-platform-pricing-table .best{background:#eff6ff;color:#1d4ed8;border-color:#bfdbfe;}
.comparison-platform-pricing-table .warn{background:#fff7ed;color:#c2410c;border-color:#fed7aa;}
.comparison-platform-pricing-table .neu{background:#f3f4f6;color:#374151;border-color:#e5e7eb;}
</style>
<div class='comparison-platform-pricing-table'>
<div class="card">
<div class="scroll">
<table id="t">
<colgroup>
<col class="c0"/>
<col class="c1"/>
<col class="cx"/><col class="cx"/><col class="cx"/>
<col class="cx"/><col class="cx"/><col class="cx"/>
<col class="cx"/><col class="cx"/><col class="cx"/>
<col class="cx"/>
</colgroup>
<thead id="thead"></thead>
<tbody id="tbody"></tbody>
</table>
</div>
</div>
<script>
// ── Competitors from ironpdf.com/features/create/ ─────────────────────────────
const COMPS = [
{k:"wkhtml", l:"wkhtmltopdf"},
{k:"itext", l:"iText 7"},
{k:"aspose", l:"Aspose.PDF"},
{k:"sync", l:"Syncfusion"},
{k:"apryse", l:"Apryse"},
{k:"select", l:"SelectPdf"},
{k:"spire", l:"Spire.PDF"},
{k:"pdfsharp",l:"PDFsharp"},
{k:"quest", l:"QuestPDF"},
{k:"itext7j", l:"iText 7 (Java)"},
];
// pill builders
const Y = (s,sub) => ({t:"yes", s,sub});
const N = (s) => ({t:"no", s:s||"No"});
const P = (s,sub) => ({t:"part", s,sub});
const B = (s,sub) => ({t:"best", s,sub,best:true});
const W = (s,sub) => ({t:"warn", s,sub});
const NU= (s,sub) => ({t:"neu", s,sub});
// ── Rows ─────────────────────────────────────────────────────────────────────
const sections = [
{
label:"Create PDF from Scratch",
rows:[
{name:"Create Blank PDF",
iron:B("Yes","Native API"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Add Texts & Images",
iron:B("Yes","HTML + Direct API"),
wkhtml:P("HTML Only"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Add Headers / Footers",
iron:B("HTML / Text / Image","Best-in-Class"),
wkhtml:P("Limited"), itext:Y("Yes"), aspose:P("Via Events"),
sync:P("Via Events"), apryse:Y("Yes"), select:NU("Templates"),
spire:NU("Manual"), pdfsharp:NU("Manual Only"), quest:Y("First-Class Slots"),
itext7j:Y("Yes")},
{name:"Add Page Numbers",
iron:B("Dynamic","Merge Fields"),
wkhtml:P("Limited"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:NU("Manual"), pdfsharp:NU("Manual Only"), quest:Y("Yes"),
itext7j:Y("Yes")},
]
},
{
label:"Make Full PDF Customization Easy",
rows:[
{name:"Orientation",
iron:Y("Portrait & Landscape"),
wkhtml:Y("Yes"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Custom Paper Size",
iron:Y("Yes"),
wkhtml:Y("Yes"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Set PDF Metadata",
iron:B("Yes","Author, Title, Keywords, Date"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
]
},
{
label:"Enhance PDF Standard, Accessibility & Compliance",
rows:[
{name:"PDF 1.2 to PDF 1.7",
iron:Y("Yes","Full Version Range"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"PDF/UA",
iron:B("Yes","Auto-Tag via API"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:N(),
spire:P("Partial"), pdfsharp:Y("Yes"), quest:P("Limited"),
itext7j:Y("Yes")},
{name:"PDF/A",
iron:Y("PDF/A-3B","A-1 through A-4"),
wkhtml:N(), itext:Y("Full PDF/A"), aspose:Y("Validate & Create"),
sync:P("Native SDK Req."), apryse:Y("PDFACompliance"), select:N(),
spire:Y("Yes"), pdfsharp:P("Limited"), quest:Y("PDF/A-2× & 3×"),
itext7j:Y("Full PDF/A")},
]
},
{
label:"Platform & Developer Experience",
rows:[
{name:"Cross-Platform",
iron:B("Win · Linux · macOS","All 3 — Native"),
wkhtml:P("Depends","On Binaries"), itext:NU(".NET Std 2.0"), aspose:P("Linux","Extra Setup"),
sync:P("Blink +",".NET Server"), apryse:NU("Native SDK"), select:W("Windows","Only"),
spire:P("Limited","Linux Docs"), pdfsharp:P("Windows","Focused"), quest:Y("Win / Linux / macOS"),
itext7j:NU("JVM","Any OS")},
{name:"Cloud & Docker Deploy",
iron:B("Azure · AWS · Docker","Best-in-Class"),
wkhtml:W("Complex","Legacy"), itext:P("Multi-Pkg"), aspose:P("Partial","Containers"),
sync:P("Blink Extras","Needed"), apryse:P("Native Deps"), select:W("Windows","Only"),
spire:P("Limited Info"), pdfsharp:Y("Simple","Lightweight"), quest:Y("Docker / K8s","Local"),
itext7j:Y("Docker","JVM")},
]
},
{
label:"Support & Documentation",
rows:[
{name:"Documentation",
iron:B("Extensive","Copy-Paste Ready"),
wkhtml:P("Partial","CLI Docs"), itext:Y("Extensive","KB"), aspose:Y("Broad","GitHub"),
sync:Y("Help Center"), apryse:Y("Cross-Language","Catalog"), select:P("Getting Started","Guides"),
spire:P("Program Guide"), pdfsharp:P("Community Guides"), quest:Y("Structured","Companion App"),
itext7j:Y("Extensive","KB")},
{name:"Developer Support",
iron:B("24/7 Engineers","Best-in-Class"),
wkhtml:P("Community","Only"), itext:Y("Sub.","Included"), aspose:P("Forum + Paid"),
sync:Y("24/5","Direct-Trac"), apryse:Y("Commercial"), select:P("Email"),
spire:P("Forum + Email"), pdfsharp:P("Community","Only"), quest:P("Community","+ GitHub"),
itext7j:Y("Sub.","Included")},
]
},
{
label:"Licensing & Pricing",
rows:[
{name:"License Model",
iron:Y("Perpetual"),
wkhtml:Y("Open Source","LGPLv3"), itext:W("AGPL","/ Sub."), aspose:Y("Perpetual"),
sync:W("Annual","Subscription"), apryse:W("Custom","Consumption"), select:Y("Perpetual"),
spire:W("Annual","Subscription"), pdfsharp:Y("Free","MIT"), quest:Y("MIT","/ Paid Tiers"),
itext7j:W("AGPL","/ Sub.")},
{name:"Starting Price",
iron:B("$999+","Perpetual · 1 Dev"),
wkhtml:Y("Free"), itext:W("~$45K/yr","Custom Quote"), aspose:W("$1,175+","Per Developer"),
sync:P("$995/yr","Free <$1M"), apryse:W("~$9K+/yr","Custom Quote"), select:Y("$499+","Perpetual"),
spire:W("$999/yr","Annual Sub."), pdfsharp:Y("Free"), quest:Y("Free","MIT < $1M"),
itext7j:W("~$45K/yr","Custom Quote")},
{name:"Free Trial",
iron:B("30 Days","Full Features · No Limits"),
wkhtml:Y("N/A","Always Free"), itext:P("30 Days","Watermarked"), aspose:P("Watermarked"),
sync:Y("Community","< $1M Rev."), apryse:Y("Unlimited","Trial"), select:P("5-Page","Limit"),
spire:P("10-Page","Limit"), pdfsharp:Y("N/A","Always Free"), quest:Y("N/A","MIT Free < $1M"),
itext7j:P("30 Days","Watermarked")},
{name:"Pricing Transparency",
iron:B("Published & Clear"),
wkhtml:Y("Free / Open"), itext:W("Custom","Quote Only"), aspose:P("On Request"),
sync:Y("Published"), apryse:W("Custom","Quote Only"), select:Y("Published"),
spire:P("Partial"), pdfsharp:Y("Free / Open"), quest:Y("Published"),
itext7j:W("Custom","Quote Only")},
]
},
];
// ── Score calc ─────────────────────────────────────────────────────────────────
const allKeys = ["iron",...COMPS.map(c=>c.k)];
const scores = {};
allKeys.forEach(k=>{
let full=0,part=0,total=0;
sections.forEach(sec=>sec.rows.forEach(row=>{
const v = k==="iron"?row.iron:row[k];
if(!v) return;
total++;
if(v.t==="yes"||v.t==="best") full++;
else if(v.t==="part"||v.t==="neu") part++;
}));
scores[k]={full,part,total,pct:total?Math.round((full+part*.5)/total*100):0};
});
// ── Chip HTML ─────────────────────────────────────────────────────────────────
function chip(v){
if(!v) return `<span style="color:#d1d5db;font-size:10px">—</span>`;
return `<div class="cell">
<span class="chip ${v.t}">${v.s}</span>
${v.sub?`<span class="chip-sub">${v.sub}</span>`:""}
${v.best?`<span class="chip-best">BEST</span>`:""}
</div>`;
}
// ── Build thead ───────────────────────────────────────────────────────────────
const thead = document.getElementById("thead");
const tr0 = document.createElement("tr");
// Feature col
const th0 = document.createElement("th");
th0.className="s0";
th0.style.cssText="text-align:left;padding-left:18px;";
th0.innerHTML=`<span style="font-family:'JetBrains Mono',monospace;font-size:8.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:#9ca3af">Feature</span>`;
tr0.appendChild(th0);
// IronPDF
const thI = document.createElement("th");
thI.className="s1";
const sc = scores.iron;
thI.innerHTML=`<div class="th-inner">
<span class="th-badge">★ Recommended</span>
<span class="th-name">IronPDF</span>
<div class="th-bar"><div class="th-bar-fill" style="width:${sc.pct}%;background:#2563eb"></div></div>
<span class="th-pct">${sc.pct}%</span>
</div>`;
tr0.appendChild(thI);
// Competitors
COMPS.forEach(c=>{
const th = document.createElement("th");
const s = scores[c.k];
th.innerHTML=`<div class="th-inner">
<span class="th-name-comp">${c.l}</span>
<div class="th-bar"><div class="th-bar-fill" style="width:${s.pct}%;background:#c7cdd6"></div></div>
<span class="th-pct-comp">${s.pct}%</span>
</div>`;
tr0.appendChild(th);
});
thead.appendChild(tr0);
// ── Build tbody ───────────────────────────────────────────────────────────────
const tbody = document.getElementById("tbody");
sections.forEach(sec=>{
// Section header
const secTr = document.createElement("tr");
secTr.className="sec-row";
const tdS0 = document.createElement("td");
tdS0.className="s0";
tdS0.innerHTML=`<span class="sec-label">${sec.label}</span>`;
secTr.appendChild(tdS0);
const tdSI = document.createElement("td");
tdSI.className="s1";
secTr.appendChild(tdSI);
COMPS.forEach(()=>{const td=document.createElement("td");secTr.appendChild(td);});
tbody.appendChild(secTr);
// Data rows
sec.rows.forEach(row=>{
const tr = document.createElement("tr");
tr.className="data-row";
const tdN = document.createElement("td");
tdN.className="s0";
tdN.innerHTML=`<span class="feat-label">${row.name}</span>`;
tr.appendChild(tdN);
const tdI = document.createElement("td");
tdI.className="s1";
tdI.innerHTML=chip(row.iron);
tr.appendChild(tdI);
COMPS.forEach(c=>{
const td=document.createElement("td");
td.innerHTML=chip(row[c.k]);
tr.appendChild(td);
});
tbody.appendChild(tr);
});
});
</script>
</div>
### 詳細比較
#### IronPDF 對比 wkhtmltopdf
- wkhtmltopdf 是免費的,但已於 2020 年停止維護,產生的 PDF 效果也顯得過時
- 需要使用特定平台的執行檔,增加了部署的複雜度
- 不支援 JavaScript,代表現代網頁應用程式無法正確呈現
- IronPDF 提供現代化的渲染效果,且無需任何外部相依性
#### IronPDF 對比 QuestPDF
- QuestPDF 需要完全透過 C# 程式碼建立 PDF,不支援 HTML
- 適合以程式化方式建立 PDF,但處理複雜版面時相當耗時
- 近期已從 MIT 授權改為商業授權
- IronPDF 讓您可以直接運用已經具備的 HTML/CSS 技能
#### IronPDF 對比 iText
- iText 採用 AGPL 授權,可能會「感染」您的程式碼庫
- 商業授權起價為 $1,999,且定價方式複雜
- HTML 轉 PDF 的功能有限,對 CSS 的支援也較差
- IronPDF 以更低的價格提供更出色的 HTML 渲染效果
#### IronPDF 對比 PDFSharp
- PDFSharp 非常適合進行低階 PDF 操作,但完全不支援 HTML
- 需要手動定位頁面上的每一個元素
- 免費且開放原始碼,但功能相當有限
- IronPDF 同時支援高階的 HTML 處理與低階的 PDF 操作
#### IronPDF 對比 Syncfusion/Aspose.PDF
- 兩者都是功能出色的企業級方案,但價格較高
- Syncfusion 起價為 $2,995,Aspose 起價為 $2,499
- 兩者皆無法達到與 IronPDF 相同的像素級精確 HTML 渲染效果
- IronPDF 在提供同等企業級功能的同時,性價比更高
### 遷移路徑
許多開發者從其他程式庫遷移至 IronPDF,原因如下:
#### 從 wkhtmltopdf 遷移
- 「我們已經厭倦了處理特定平台的二進位檔案和過時的渲染效果」
- 「IronPDF 為我們帶來了現代化的 CSS 支援,也解決了我們在 Docker 方面的困擾」
#### 從 iText/iText 7 遷移
- 「陡峭的學習曲線嚴重拖累了我們的生產力——IronPDF 讓我們可以改用 HTML」
- 「AGPL 授權對我們的商業產品來說是無法接受的」
#### 從 PDFSharp 遷移
- 「我們需要 HTML 轉 PDF 的功能,而 PDFSharp 根本做不到」
- 「手動定位每一個元素實在太耗時了」
#### 從 QuestPDF 遷移
- 「與使用 HTML/CSS 相比,用 C# 程式碼建立版面非常繁瑣」
- 「近期的授權變更讓我們重新考慮了自己的選擇」
## 結論
***在 C# 中建立 PDF*** 不必變得複雜。透過 IronPDF,您可以運用自己已經具備的 HTML 和 CSS 技能來**產生專業的 PDF 文件**。無論您要建立的是簡單的報告,還是包含圖表與表單的複雜文件,IronPDF 都能為您處理繁重的工作,讓您**專注於應用程式邏輯**。加入全球**1,400 萬名開發者**的行列,將 IronPDF 作為值得信賴的 **C# PDF 產生器**,可靠且高效地***產生 PDF***。
在本指南中,我們探討了多種***建立 PDF 文件***的方法——從 HTML 字串與 URL,到轉換 Word 文件、Markdown 等現有檔案。我們看到了 IronPDF 的**現代化 Chromium 渲染引擎**如何產生**像素級精確的結果**,讓效果真正呈現您的網頁設計,而非過時的印表機輸出樣式。以程式化方式**處理 PDF 文件**、加入安全功能並最佳化效能的能力,讓 IronPDF 成為您在 .NET 中完成各種***PDF 產生工作***的**完整解決方案**。
IronPDF 的與眾不同之處在於其**以開發者為優先的理念**。僅需三行程式碼,您就能***產生第一份 PDF***。直覺化的 API 代表您可以**減少學習**專有 PDF 語法的時間,將**更多時間投入功能開發**。再加上來自[真正的工程師](#live-chat-support)的**優質支援**、**透明的定價**,以及**持續的更新**(包括對 .NET 10 的預發行版本支援),IronPDF 讓您對自己的***C# PDF 建立***能力充滿信心,無論現在還是未來都能穩定運作。
立即開始***建立 PDF***——**[取得您的免費試用授權](trial-license)**,體驗在您的應用程式中進行***.NET PDF 產生***是多麼輕鬆。使用 IronPDF,您將在幾分鐘內(而非幾小時)***產生專業的 PDF***。
**準備好建立您的第一份 PDF 了嗎?** **[立即開始使用 IronPDF](trial-license)**——開發環境免費使用,幾分鐘內您就能***用 C# 建立 PDF***。
請注意Aspose、iText、wkhtmltopdf、QuestPDF、PDFSharp 和 Syncfusion 均為其各自所有者的註冊商標。本網站與 Aspose、iText、wkhtmltopdf、QuestPDF、PDFSharp 或 Syncfusion 並無任何關聯,亦未獲得其認可或贊助。所有產品名稱、標誌與品牌均為其各自所有者的財產。相關比較僅供參考,並依據撰寫當時可公開取得的資訊為準。
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>
");
### 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](/how-to/pdfa/) and [PDF/UA](/how-to/pdfua/) 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](/examples/form-data/), improved [PDF editing capabilities](/examples/editing-pdfs/), 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
<style>
.comparison-platform-pricing-table *,.comparison-platform-pricing-table *::before,.comparison-platform-pricing-table *::after{box-sizing:border-box;margin:0;padding:0;}
.comparison-platform-pricing-table{font-family:var(--ff-gotham);background:#f4f5f7;margin:24px 0;-webkit-font-smoothing:antialiased;}
.comparison-platform-pricing-table .card{
width:100%;max-width:1380px;
background:#fff;
border:1px solid #e2e5ea;
border-radius:10px;
overflow:hidden;
box-shadow:0 1px 3px rgba(0,0,0,.04),0 4px 16px rgba(0,0,0,.04);
}
.comparison-platform-pricing-table .scroll{overflow-x:auto;}
.comparison-platform-pricing-table ::-webkit-scrollbar{height:3px;}
.comparison-platform-pricing-table ::-webkit-scrollbar-track{background:#f0f0f0;}
.comparison-platform-pricing-table ::-webkit-scrollbar-thumb{background:#c7cdd6;border-radius:2px;}
.comparison-platform-pricing-table table{
border-collapse:collapse;
width:max-content;min-width:100%;
table-layout:fixed;
}
.comparison-platform-pricing-table col.c0{width:196px;}
.comparison-platform-pricing-table col.c1{width:140px;}
.comparison-platform-pricing-table col.cx{width:110px;}
.comparison-platform-pricing-table .s0{position:sticky;left:0;z-index:20;}
.comparison-platform-pricing-table .s1{position:sticky;left:196px;z-index:20;}
.comparison-platform-pricing-table thead th{
position:sticky;top:0;z-index:30;
padding:14px 12px 12px;
text-align:center;
border-bottom:1px solid #e2e5ea;
background:#fff;
vertical-align:bottom;
}
.comparison-platform-pricing-table thead th.s0{text-align:left;z-index:40;padding-left:18px;}
.comparison-platform-pricing-table thead th.s1{z-index:40;background:#f0f5ff;border-bottom:2px solid #2563eb;}
.comparison-platform-pricing-table .th-inner{display:flex;flex-direction:column;align-items:center;gap:5px;}
.comparison-platform-pricing-table .th-badge{
display:inline-block;
font-family:'JetBrains Mono',monospace;
font-size:7px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
background:#2563eb;color:#fff;
padding:2px 7px;border-radius:2px;
}
.comparison-platform-pricing-table .th-name{
font-size:12.5px;font-weight:700;
color:#1e2b3c;line-height:1.25;
}
.comparison-platform-pricing-table .th-name-comp{font-size:11px;font-weight:600;color:#374151;line-height:1.3;text-align:center;}
.comparison-platform-pricing-table .th-pct{
font-family:'JetBrains Mono',monospace;
font-size:11px;font-weight:600;
color:#2563eb;
}
.comparison-platform-pricing-table .th-pct-comp{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;color:#9ca3af;}
.comparison-platform-pricing-table .th-bar{width:48px;height:2px;background:#e5e7eb;border-radius:1px;overflow:hidden;margin:0 auto;}
.comparison-platform-pricing-table .th-bar-fill{height:100%;border-radius:1px;}
.comparison-platform-pricing-table .feat-label-row td.s0{background:#fff;}
.comparison-platform-pricing-table .feat-label{
font-size:12.5px;font-weight:600;
color:#1e2b3c;line-height:1.35;
padding:11px 18px;
}
.comparison-platform-pricing-table .sec-row td{
background:#f9fafb;
border-top:1px solid #e2e5ea;
border-bottom:1px solid #e8eaed;
padding:7px 18px;
}
.comparison-platform-pricing-table .sec-row td.s1{
background:#edf3ff;
border-left:2px solid #2563eb;
border-right:2px solid #2563eb;
}
.comparison-platform-pricing-table .sec-label{
font-family:'JetBrains Mono',monospace;
font-size:8.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
color:#9ca3af;
display:flex;align-items:center;gap:8px;
}
.comparison-platform-pricing-table .sec-label::after{content:'';flex:1;height:1px;background:#e5e7eb;}
.comparison-platform-pricing-table .data-row td{
border-bottom:1px solid #f0f1f3;
padding:10px 12px;
text-align:center;
vertical-align:middle;
background:#fff;
}
.comparison-platform-pricing-table .data-row:last-of-type td{border-bottom:none;}
.comparison-platform-pricing-table .data-row td.s0{background:#fff;text-align:left;}
.comparison-platform-pricing-table .data-row td.s1{
background:#f5f9ff;
border-left:2px solid #2563eb;
border-right:2px solid #2563eb;
}
.comparison-platform-pricing-table .data-row:hover td{background:#fafbfc!important;}
.comparison-platform-pricing-table .data-row:hover td.s1{background:#eef5ff!important;}
.comparison-platform-pricing-table .data-row:hover td.s0{background:#fafbfc!important;}
.comparison-platform-pricing-table .cell{
display:inline-flex;flex-direction:column;align-items:center;gap:2px;
max-width:100%;
}
.comparison-platform-pricing-table .chip{
font-family:'JetBrains Mono',monospace;
font-size:9.5px;font-weight:500;
padding:3px 9px;border-radius:100px;
border:1px solid transparent;
white-space:nowrap;line-height:1.45;
}
.comparison-platform-pricing-table .chip-sub{
font-family:'JetBrains Mono',monospace;
font-size:7.5px;color:#9ca3af;
text-align:center;line-height:1.4;max-width:96px;
}
.comparison-platform-pricing-table .chip-best{
font-family:'JetBrains Mono',monospace;
font-size:7px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
background:#dbeafe;color:#1d4ed8;border:1px solid #bfdbfe;
padding:1px 6px;border-radius:2px;
}
.comparison-platform-pricing-table .yes{background:#f0fdf4;color:#15803d;border-color:#bbf7d0;}
.comparison-platform-pricing-table .no{background:#fafafa;color:#9ca3af;border-color:#e5e7eb;}
.comparison-platform-pricing-table .part{background:#fffbeb;color:#b45309;border-color:#fde68a;}
.comparison-platform-pricing-table .best{background:#eff6ff;color:#1d4ed8;border-color:#bfdbfe;}
.comparison-platform-pricing-table .warn{background:#fff7ed;color:#c2410c;border-color:#fed7aa;}
.comparison-platform-pricing-table .neu{background:#f3f4f6;color:#374151;border-color:#e5e7eb;}
</style>
<div class='comparison-platform-pricing-table'>
<div class="card">
<div class="scroll">
<table id="t">
<colgroup>
<col class="c0"/>
<col class="c1"/>
<col class="cx"/><col class="cx"/><col class="cx"/>
<col class="cx"/><col class="cx"/><col class="cx"/>
<col class="cx"/><col class="cx"/><col class="cx"/>
<col class="cx"/>
</colgroup>
<thead id="thead"></thead>
<tbody id="tbody"></tbody>
</table>
</div>
</div>
<script>
// ── Competitors from ironpdf.com/features/create/ ─────────────────────────────
const COMPS = [
{k:"wkhtml", l:"wkhtmltopdf"},
{k:"itext", l:"iText 7"},
{k:"aspose", l:"Aspose.PDF"},
{k:"sync", l:"Syncfusion"},
{k:"apryse", l:"Apryse"},
{k:"select", l:"SelectPdf"},
{k:"spire", l:"Spire.PDF"},
{k:"pdfsharp",l:"PDFsharp"},
{k:"quest", l:"QuestPDF"},
{k:"itext7j", l:"iText 7 (Java)"},
];
// pill builders
const Y = (s,sub) => ({t:"yes", s,sub});
const N = (s) => ({t:"no", s:s||"No"});
const P = (s,sub) => ({t:"part", s,sub});
const B = (s,sub) => ({t:"best", s,sub,best:true});
const W = (s,sub) => ({t:"warn", s,sub});
const NU= (s,sub) => ({t:"neu", s,sub});
// ── Rows ─────────────────────────────────────────────────────────────────────
const sections = [
{
label:"Create PDF from Scratch",
rows:[
{name:"Create Blank PDF",
iron:B("Yes","Native API"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Add Texts & Images",
iron:B("Yes","HTML + Direct API"),
wkhtml:P("HTML Only"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Add Headers / Footers",
iron:B("HTML / Text / Image","Best-in-Class"),
wkhtml:P("Limited"), itext:Y("Yes"), aspose:P("Via Events"),
sync:P("Via Events"), apryse:Y("Yes"), select:NU("Templates"),
spire:NU("Manual"), pdfsharp:NU("Manual Only"), quest:Y("First-Class Slots"),
itext7j:Y("Yes")},
{name:"Add Page Numbers",
iron:B("Dynamic","Merge Fields"),
wkhtml:P("Limited"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:NU("Manual"), pdfsharp:NU("Manual Only"), quest:Y("Yes"),
itext7j:Y("Yes")},
]
},
{
label:"Make Full PDF Customization Easy",
rows:[
{name:"Orientation",
iron:Y("Portrait & Landscape"),
wkhtml:Y("Yes"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Custom Paper Size",
iron:Y("Yes"),
wkhtml:Y("Yes"), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"Set PDF Metadata",
iron:B("Yes","Author, Title, Keywords, Date"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
]
},
{
label:"Enhance PDF Standard, Accessibility & Compliance",
rows:[
{name:"PDF 1.2 to PDF 1.7",
iron:Y("Yes","Full Version Range"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:Y("Yes"),
spire:Y("Yes"), pdfsharp:Y("Yes"), quest:Y("Yes"),
itext7j:Y("Yes")},
{name:"PDF/UA",
iron:B("Yes","Auto-Tag via API"),
wkhtml:N(), itext:Y("Yes"), aspose:Y("Yes"),
sync:Y("Yes"), apryse:Y("Yes"), select:N(),
spire:P("Partial"), pdfsharp:Y("Yes"), quest:P("Limited"),
itext7j:Y("Yes")},
{name:"PDF/A",
iron:Y("PDF/A-3B","A-1 through A-4"),
wkhtml:N(), itext:Y("Full PDF/A"), aspose:Y("Validate & Create"),
sync:P("Native SDK Req."), apryse:Y("PDFACompliance"), select:N(),
spire:Y("Yes"), pdfsharp:P("Limited"), quest:Y("PDF/A-2× & 3×"),
itext7j:Y("Full PDF/A")},
]
},
{
label:"Platform & Developer Experience",
rows:[
{name:"Cross-Platform",
iron:B("Win · Linux · macOS","All 3 — Native"),
wkhtml:P("Depends","On Binaries"), itext:NU(".NET Std 2.0"), aspose:P("Linux","Extra Setup"),
sync:P("Blink +",".NET Server"), apryse:NU("Native SDK"), select:W("Windows","Only"),
spire:P("Limited","Linux Docs"), pdfsharp:P("Windows","Focused"), quest:Y("Win / Linux / macOS"),
itext7j:NU("JVM","Any OS")},
{name:"Cloud & Docker Deploy",
iron:B("Azure · AWS · Docker","Best-in-Class"),
wkhtml:W("Complex","Legacy"), itext:P("Multi-Pkg"), aspose:P("Partial","Containers"),
sync:P("Blink Extras","Needed"), apryse:P("Native Deps"), select:W("Windows","Only"),
spire:P("Limited Info"), pdfsharp:Y("Simple","Lightweight"), quest:Y("Docker / K8s","Local"),
itext7j:Y("Docker","JVM")},
]
},
{
label:"Support & Documentation",
rows:[
{name:"Documentation",
iron:B("Extensive","Copy-Paste Ready"),
wkhtml:P("Partial","CLI Docs"), itext:Y("Extensive","KB"), aspose:Y("Broad","GitHub"),
sync:Y("Help Center"), apryse:Y("Cross-Language","Catalog"), select:P("Getting Started","Guides"),
spire:P("Program Guide"), pdfsharp:P("Community Guides"), quest:Y("Structured","Companion App"),
itext7j:Y("Extensive","KB")},
{name:"Developer Support",
iron:B("24/7 Engineers","Best-in-Class"),
wkhtml:P("Community","Only"), itext:Y("Sub.","Included"), aspose:P("Forum + Paid"),
sync:Y("24/5","Direct-Trac"), apryse:Y("Commercial"), select:P("Email"),
spire:P("Forum + Email"), pdfsharp:P("Community","Only"), quest:P("Community","+ GitHub"),
itext7j:Y("Sub.","Included")},
]
},
{
label:"Licensing & Pricing",
rows:[
{name:"License Model",
iron:Y("Perpetual"),
wkhtml:Y("Open Source","LGPLv3"), itext:W("AGPL","/ Sub."), aspose:Y("Perpetual"),
sync:W("Annual","Subscription"), apryse:W("Custom","Consumption"), select:Y("Perpetual"),
spire:W("Annual","Subscription"), pdfsharp:Y("Free","MIT"), quest:Y("MIT","/ Paid Tiers"),
itext7j:W("AGPL","/ Sub.")},
{name:"Starting Price",
iron:B("$999+","Perpetual · 1 Dev"),
wkhtml:Y("Free"), itext:W("~$45K/yr","Custom Quote"), aspose:W("$1,175+","Per Developer"),
sync:P("$995/yr","Free <$1M"), apryse:W("~$9K+/yr","Custom Quote"), select:Y("$499+","Perpetual"),
spire:W("$999/yr","Annual Sub."), pdfsharp:Y("Free"), quest:Y("Free","MIT < $1M"),
itext7j:W("~$45K/yr","Custom Quote")},
{name:"Free Trial",
iron:B("30 Days","Full Features · No Limits"),
wkhtml:Y("N/A","Always Free"), itext:P("30 Days","Watermarked"), aspose:P("Watermarked"),
sync:Y("Community","< $1M Rev."), apryse:Y("Unlimited","Trial"), select:P("5-Page","Limit"),
spire:P("10-Page","Limit"), pdfsharp:Y("N/A","Always Free"), quest:Y("N/A","MIT Free < $1M"),
itext7j:P("30 Days","Watermarked")},
{name:"Pricing Transparency",
iron:B("Published & Clear"),
wkhtml:Y("Free / Open"), itext:W("Custom","Quote Only"), aspose:P("On Request"),
sync:Y("Published"), apryse:W("Custom","Quote Only"), select:Y("Published"),
spire:P("Partial"), pdfsharp:Y("Free / Open"), quest:Y("Published"),
itext7j:W("Custom","Quote Only")},
]
},
];
// ── Score calc ─────────────────────────────────────────────────────────────────
const allKeys = ["iron",...COMPS.map(c=>c.k)];
const scores = {};
allKeys.forEach(k=>{
let full=0,part=0,total=0;
sections.forEach(sec=>sec.rows.forEach(row=>{
const v = k==="iron"?row.iron:row[k];
if(!v) return;
total++;
if(v.t==="yes"||v.t==="best") full++;
else if(v.t==="part"||v.t==="neu") part++;
}));
scores[k]={full,part,total,pct:total?Math.round((full+part*.5)/total*100):0};
});
// ── Chip HTML ─────────────────────────────────────────────────────────────────
function chip(v){
if(!v) return `<span style="color:#d1d5db;font-size:10px">—</span>`;
return `<div class="cell">
<span class="chip ${v.t}">${v.s}</span>
${v.sub?`<span class="chip-sub">${v.sub}</span>`:""}
${v.best?`<span class="chip-best">BEST</span>`:""}
</div>`;
}
// ── Build thead ───────────────────────────────────────────────────────────────
const thead = document.getElementById("thead");
const tr0 = document.createElement("tr");
// Feature col
const th0 = document.createElement("th");
th0.className="s0";
th0.style.cssText="text-align:left;padding-left:18px;";
th0.innerHTML=`<span style="font-family:'JetBrains Mono',monospace;font-size:8.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:#9ca3af">Feature</span>`;
tr0.appendChild(th0);
// IronPDF
const thI = document.createElement("th");
thI.className="s1";
const sc = scores.iron;
thI.innerHTML=`<div class="th-inner">
<span class="th-badge">★ Recommended</span>
<span class="th-name">IronPDF</span>
<div class="th-bar"><div class="th-bar-fill" style="width:${sc.pct}%;background:#2563eb"></div></div>
<span class="th-pct">${sc.pct}%</span>
</div>`;
tr0.appendChild(thI);
// Competitors
COMPS.forEach(c=>{
const th = document.createElement("th");
const s = scores[c.k];
th.innerHTML=`<div class="th-inner">
<span class="th-name-comp">${c.l}</span>
<div class="th-bar"><div class="th-bar-fill" style="width:${s.pct}%;background:#c7cdd6"></div></div>
<span class="th-pct-comp">${s.pct}%</span>
</div>`;
tr0.appendChild(th);
});
thead.appendChild(tr0);
// ── Build tbody ───────────────────────────────────────────────────────────────
const tbody = document.getElementById("tbody");
sections.forEach(sec=>{
// Section header
const secTr = document.createElement("tr");
secTr.className="sec-row";
const tdS0 = document.createElement("td");
tdS0.className="s0";
tdS0.innerHTML=`<span class="sec-label">${sec.label}</span>`;
secTr.appendChild(tdS0);
const tdSI = document.createElement("td");
tdSI.className="s1";
secTr.appendChild(tdSI);
COMPS.forEach(()=>{const td=document.createElement("td");secTr.appendChild(td);});
tbody.appendChild(secTr);
// Data rows
sec.rows.forEach(row=>{
const tr = document.createElement("tr");
tr.className="data-row";
const tdN = document.createElement("td");
tdN.className="s0";
tdN.innerHTML=`<span class="feat-label">${row.name}</span>`;
tr.appendChild(tdN);
const tdI = document.createElement("td");
tdI.className="s1";
tdI.innerHTML=chip(row.iron);
tr.appendChild(tdI);
COMPS.forEach(c=>{
const td=document.createElement("td");
td.innerHTML=chip(row[c.k]);
tr.appendChild(td);
});
tbody.appendChild(tr);
});
});
</script>
</div>
### 詳細比較
#### IronPDF 對比 wkhtmltopdf
- wkhtmltopdf 是免費的,但已於 2020 年停止維護,產生的 PDF 效果也顯得過時
- 需要使用特定平台的執行檔,增加了部署的複雜度
- 不支援 JavaScript,代表現代網頁應用程式無法正確呈現
- IronPDF 提供現代化的渲染效果,且無需任何外部相依性
#### IronPDF 對比 QuestPDF
- QuestPDF 需要完全透過 C# 程式碼建立 PDF,不支援 HTML
- 適合以程式化方式建立 PDF,但處理複雜版面時相當耗時
- 近期已從 MIT 授權改為商業授權
- IronPDF 讓您可以直接運用已經具備的 HTML/CSS 技能
#### IronPDF 對比 iText
- iText 採用 AGPL 授權,可能會「感染」您的程式碼庫
- 商業授權起價為 $1,999,且定價方式複雜
- HTML 轉 PDF 的功能有限,對 CSS 的支援也較差
- IronPDF 以更低的價格提供更出色的 HTML 渲染效果
#### IronPDF 對比 PDFSharp
- PDFSharp 非常適合進行低階 PDF 操作,但完全不支援 HTML
- 需要手動定位頁面上的每一個元素
- 免費且開放原始碼,但功能相當有限
- IronPDF 同時支援高階的 HTML 處理與低階的 PDF 操作
#### IronPDF 對比 Syncfusion/Aspose.PDF
- 兩者都是功能出色的企業級方案,但價格較高
- Syncfusion 起價為 $2,995,Aspose 起價為 $2,499
- 兩者皆無法達到與 IronPDF 相同的像素級精確 HTML 渲染效果
- IronPDF 在提供同等企業級功能的同時,性價比更高
### 遷移路徑
許多開發者從其他程式庫遷移至 IronPDF,原因如下:
#### 從 wkhtmltopdf 遷移
- 「我們已經厭倦了處理特定平台的二進位檔案和過時的渲染效果」
- 「IronPDF 為我們帶來了現代化的 CSS 支援,也解決了我們在 Docker 方面的困擾」
#### 從 iText/iText 7 遷移
- 「陡峭的學習曲線嚴重拖累了我們的生產力——IronPDF 讓我們可以改用 HTML」
- 「AGPL 授權對我們的商業產品來說是無法接受的」
#### 從 PDFSharp 遷移
- 「我們需要 HTML 轉 PDF 的功能,而 PDFSharp 根本做不到」
- 「手動定位每一個元素實在太耗時了」
#### 從 QuestPDF 遷移
- 「與使用 HTML/CSS 相比,用 C# 程式碼建立版面非常繁瑣」
- 「近期的授權變更讓我們重新考慮了自己的選擇」
## 結論
***在 C# 中建立 PDF*** 不必變得複雜。透過 IronPDF,您可以運用自己已經具備的 HTML 和 CSS 技能來**產生專業的 PDF 文件**。無論您要建立的是簡單的報告,還是包含圖表與表單的複雜文件,IronPDF 都能為您處理繁重的工作,讓您**專注於應用程式邏輯**。加入全球**1,400 萬名開發者**的行列,將 IronPDF 作為值得信賴的 **C# PDF 產生器**,可靠且高效地***產生 PDF***。
在本指南中,我們探討了多種***建立 PDF 文件***的方法——從 HTML 字串與 URL,到轉換 Word 文件、Markdown 等現有檔案。我們看到了 IronPDF 的**現代化 Chromium 渲染引擎**如何產生**像素級精確的結果**,讓效果真正呈現您的網頁設計,而非過時的印表機輸出樣式。以程式化方式**處理 PDF 文件**、加入安全功能並最佳化效能的能力,讓 IronPDF 成為您在 .NET 中完成各種***PDF 產生工作***的**完整解決方案**。
IronPDF 的與眾不同之處在於其**以開發者為優先的理念**。僅需三行程式碼,您就能***產生第一份 PDF***。直覺化的 API 代表您可以**減少學習**專有 PDF 語法的時間,將**更多時間投入功能開發**。再加上來自[真正的工程師](#live-chat-support)的**優質支援**、**透明的定價**,以及**持續的更新**(包括對 .NET 10 的預發行版本支援),IronPDF 讓您對自己的***C# PDF 建立***能力充滿信心,無論現在還是未來都能穩定運作。
立即開始***建立 PDF***——**[取得您的免費試用授權](trial-license)**,體驗在您的應用程式中進行***.NET PDF 產生***是多麼輕鬆。使用 IronPDF,您將在幾分鐘內(而非幾小時)***產生專業的 PDF***。
**準備好建立您的第一份 PDF 了嗎?** **[立即開始使用 IronPDF](trial-license)**——開發環境免費使用,幾分鐘內您就能***用 C# 建立 PDF***。
請注意Aspose、iText、wkhtmltopdf、QuestPDF、PDFSharp 和 Syncfusion 均為其各自所有者的註冊商標。本網站與 Aspose、iText、wkhtmltopdf、QuestPDF、PDFSharp 或 Syncfusion 並無任何關聯,亦未獲得其認可或贊助。所有產品名稱、標誌與品牌均為其各自所有者的財產。相關比較僅供參考,並依據撰寫當時可公開取得的資訊為準。
Imports 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:
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("
# Hello World
<table>
<tr style='background: lightgray;'>
<td>Simple</td>
<td>Intuitive</td>
</tr>
</table>
")
常見問題
如何在C#中從HTML內容建立PDF?
您可以使用IronPDF的RenderHtmlAsPdf方法在C#中從HTML內容建立PDF。這使您能夠輕鬆將HTML字串或URL直接轉換為PDF文件。
使用商業PDF程式庫比使用免費的有什麼優勢?
像IronPDF這樣的商業PDF程式庫提供強大的功能,如完整支持JavaScript、CSS3和響應式布局。它們提供可靠的性能、定期的更新、全面的支持,並且針對建立高質量的PDF進行了優化。
IronPDF可以用於生成ASP.NET MVC應用程式中的PDF嗎?
是的,IronPDF可以用於ASP.NET MVC應用程式中,將Razor視圖或HTML模板轉換為PDF,使您能夠無縫整合PDF生成到您的網路應用程式中。
如何使用C#將圖片和CSS整合到我的PDF文件中?
使用IronPDF,您可以輕鬆將圖片和CSS整合到您的PDF文件中。這可以通過在轉換為PDF之前在HTML內容中包括圖片標籤和CSS樣式來實現。
是否可以在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的相容性:我可以將IronPDF與.NET 10一起使用嗎,是否有任何特殊考慮?
是的,IronPDF完全相容.NET 10。它開箱即用支持.NET 10,包括針對Windows、Linux、容器化環境和網路框架的項目。不需要特殊配置,只需安裝最新的IronPDF NuGet包,它就能無縫工作於.NET 10。

