IronPDF與EvoPdf:哪個.NET PDF庫在2025年提供更好的價值?
在構建需要PDF功能的現代.NET應用程式時,選擇正確的程式庫會顯著影響您的開發速度、應用程式性能和長期維護成本。 IronPDF和EvoPdf代表在.NET生態系統中兩種不同的PDF生成和操作方法,每種方法都有獨特的優勢,適合不同的開發場景。
這份全面的比較在渲染精確度、API設計、性能指標、平台相容性和擁有總成本等關鍵維度上檢視兩者的優劣。不論您是在構建高產量文件處理系統,實施合規性的數位簽名,還是僅僅將HTML報告轉換為PDF,瞭解這些差異將幫助您做出符合您的技術要求和預算限制的知情決策。
IronPDF和EvoPdf的快速比較
在深入詳細比較之前,這裡提供一個全面的概述,看看這些程式庫在對.NET開發人員最重要的關鍵類別中如何堆積起來:
| 類別 | 功能/方面 | IronPDF | EvoPdf | 關鍵優勢 |
|---|---|---|---|---|
| 核心架構 | 設計理念 | 簡潔優先,直觀的API | 功能豐富的、傳統的PDF方法 | IronPDF:更快的開發 |
| API複雜性 | 簡單的方法如RenderHtmlAsPdf() |
多類別方法,需要更多設定 | IronPDF:簡單的API介面 | |
| 學習曲線 | 需要的設置最少 | 涉及更多配置 | IronPDF:更快適應 | |
| 平台支持 | 跨平台 | 原生支援,無需額外配置 | 需要平台特定的設置 | IronPDF:更簡單的部署 |
| .NET版本 | .NET 10、9、8、7、6、5、Core 3.1+,Framework 4.6.2+ | .NET 10、9、8、7、6、Standard 2.0+,Framework 4.0+ | 兩者:現代框架支持 | |
| 操作系統 | Windows, Linux, macOS, Docker原生支持 | Windows、Linux、macOS、Azure | IronPDF:最佳化Docker | |
| HTML到PDF | 渲染引擎 | 完整的Chrome V8引擎 | 自定義HTML渲染引擎 | IronPDF:高瀏覽器保真度 |
| CSS3/HTML5支持 | 完整支援 | 對標準功能的支持良好 | IronPDF:現代網頁標準 | |
| JavaScript執行 | 等待時的全JavaScript支持 | 良好的JavaScript支持 | IronPDF:動態內容準備就緒 | |
| 渲染速度 | 優化處理包含JavaScript的複雜頁面 | 適用於簡單靜態HTML速度快 | 取決於文件的複雜性 | |
| Security & Encryption | 加密等級 | AES-256,自訂處理器 | AES-256標準 | 兩者:業界標準 |
| 許可選項 | 細粒度的權限控制 | 標準權限設置 | IronPDF:更細緻的控制 | |
| 數位簽名 | 整合的,可視簽名 | 基礎簽名支持 | IronPDF:更簡單的簽名 | |
| 內容操作 | 編輯方法 | 真正的內容移除,單行API | 無內建編輯功能 | IronPDF:合規就緒 |
| 加水印 | 基於HTML/CSS,完整樣式 | 基於模板的水印 | IronPDF:豐富的水印 | |
| 加印 | 統一的加印類別 | 與水印功能相同 | IronPDF:專用工具 | |
| 檔案轉換 | DOCX到PDF | 內建DocxToPdfRenderer |
需要Evo Word to PDF($450+) | IronPDF:無需額外成本 |
| 開發者體驗 | 程式碼範例 | 100多個即用範例 | 提供程式碼範例 | IronPDF:豐富的資源 |
| 文件 | 教程、使用方法、影片、API參考 | API文件和範例 | IronPDF:多重學習路徑 | |
| 錯誤資訊 | 描述性,具可操作性 | 標準錯誤報告 | IronPDF:更好的除錯 | |
| 性能指標 | 大型文件處理 | 高吞吐量批次處理 | 標準批次處理 | IronPDF:更好的擴展性 |
| 多執行緒支持 | 本機async/await優化 | 支持多執行緒 | IronPDF:更好的擴展性 | |
| Licensing & Pricing | 入門級 | Lite:$999(1位開發者,1個專案) | 部署:$450(1台伺服器,1個應用程式) | EvoPdf:初始成本較低 |
| 團隊授權 | Plus:$1,499(3位開發人員,3個專案) | 公司:$1,200(無限制開發人員) | EvoPdf:大團隊更好 | |
| 再分發 | +$1,999免版稅 | 包含在公司授權中 | EvoPdf:內建再分發 | |
| 套件選項 | Iron Suite:$2,998 (10 款產品) | EVO PDF Toolkit: $1,400 | IronPDF:包含更多產品 | |
| 支援 | 是否包含支援 | 是,24/5工程支援 | 是的,第一年提供標準支援 | IronPDF:直接工程師存取 |
| 最佳用途 | 用例 | 現代網頁應用、複雜PDF、合規 | 簡單HTML到PDF,基本轉換 | 依具體情況而定 |
理解IronPDF和EvoPdf:核心優勢與理念
什麼讓IronPDF在.NET PDF程式庫市場中脫穎而出?
IronPDF代表了一個以開發人員生產力為核心設計的全面PDF解決方案。 在不犧牲功能的情況下,以簡單性為基礎,IronPDF允許.NET開發人員使用類似於熟悉的網頁開發模式的直觀API建立、編輯和操作PDF文件。 該程式庫的突出特點是其基於Chrome的渲染引擎,可確保像素完美的HTML到PDF轉換,同時支持包括CSS3、JavaScript框架和網頁字體在內的最新網頁標準。
該程式庫在需要高保真文件渲染、複雜PDF操作和企業級安全功能的場景中表現出色。 其廣泛的功能集不僅包括基本PDF生成,還包括數位簽名、高級功能如表單填寫、通過IronOCR整合以及無縫的文件格式轉換等功能。 IronPDF的跨平台相容性不僅僅支持簡單的框架支持,它還提供在Windows、Linux、macOS、Docker容器和像Azure和AWS這樣的雲平台上的原生性能。
EvoPdf對PDF生成的不同處理方法是什麼?
EvoPdf採取更傳統的方法進行PDF操作,主要集中在HTML到PDF轉換,並強調自定義與控制。 這款程式庫為開發人員提供了轉換過程的細粒度掌控,允許對渲染參數、頁面佈局和轉換設置進行微調。 EvoPdf的架構是圍繞提供可靠、一致的標準網到PDF轉換場景的結果而構建的。
EvoPdf特別出色之處在其輕量級佔用和對簡單HTML文件的快速渲染速度。 對於沒有複雜JavaScript或CSS3功能的簡單HTML頁面,EvoPdf非常適合高流量批量處理簡單文件。 該程式庫還為ASP.NET環境中的伺服器端渲染提供了良好的支持,並對網路應用程式場景進行了優化。
兩個程式庫的跨平台功能比較如何?
IronPDF現代跨平台架構
IronPDF提供無縫的跨平台相容性,超越了簡單的框架支持。 該程式庫本地運行於:
-
.NET版本支持:
- .NET 10、9、8、7、6、5和Core 3.1+
- .NET Standard 2.0+
- .NET Framework 4.6.2+
- 完整支持C#、VB.NET和F#
-
操作系統相容性:
- Windows (x86, x64, ARM)
- Linux (Ubuntu, Debian, CentOS, Alpine)
- macOS (Intel and Apple Silicon)
- Docker容器帶有預先配置的映象
- 雲平台整合:
- Azure應用服務、函式和虛擬機
- AWS Lambda和EC2
- Google Cloud Platform
- Kubernetes部署
IronPDF的獨特之處是其零配置部署模型。 與很多需要額外依賴或運行時安裝的PDF程式庫不同,IronPDF將其必要組件打包在NuGet包內。 這種自我包含的方法顯著減少了部署的複雜性,並消除了常見的"僅在我的機器上運行"問題。
EvoPdf的平台需求與限制
EvoPdf支持相似範圍的.NET版本,但是在跨平台場景中需要更仔細的配置:
-
.NET框架支持:
- .NET 10、9、8、7和6
- .NET Standard 2.0+
- .NET Framework 4.0+
- 平台考量:
- 主要為Windows環境優化
- Linux支持需要額外配置
- macOS支持通過.NET Core
- 雲部署需平台特定的調整
對於跨平台部署,EvoPdf使用者經常需要處理平台特定的依賴和配置,尤其是在Windows和Linux環境間移動時。 這種額外的設置複雜性可能會影響開發時間表並增加維護成本。
哪個程式庫更好支持常見PDF功能?
HTML到PDF轉換:渲染質量及性能
這兩個程式庫最基本的功能是HTML到PDF的轉換,但它們的方法和結果有顯著差異。
IronPDF HTML到PDF範例
using IronPdf;
// Initialize the Chrome-based renderer with advanced options
var renderer = new ChromePdfRenderer
{
// Configure rendering options for optimal quality
RenderingOptions = new ChromePdfRenderOptions
{
// Set high-quality rendering at 300 DPI for print-ready PDFs
DPI = 300,
// Enable JavaScript execution with custom timeout
EnableJavaScript = true,
RenderDelay = 2000, // Wait 2 seconds for dynamic content
// Configure page layout
MarginTop = 20,
MarginBottom = 20,
MarginLeft = 15,
MarginRight = 15,
// Enable modern web features
CssMediaType = PdfCssMediaType.Print,
ViewPortWidth = 1920,
// Optimize for web fonts and images
CreatePdfFormsFromHtml = true,
FitToPaperMode = FitToPaperModes.Automatic
}
};
// Convert complex HTML with CSS3 and JavaScript
var htmlContent = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'>
<style>
body { font-family: 'Roboto', sans-serif; }
.chart-container { width: 100%; height: 400px; }
@media print {
.no-print { display: none; }
.page-break { page-break-after: always; }
}
</style>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
</head>
<body>
<h1>Dynamic Sales Report</h1>
<div class='chart-container'>
<canvas id='salesChart'></canvas>
</div>
<script>
// Dynamic chart generation
const ctx = document.getElementById('salesChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales 2025',
data: [65, 78, 90, 81, 96],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
}
});
</script>
</body>
</html>";
// Generate PDF with full JavaScript chart rendering
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
// Apply post-processing optimizations
pdf.CompressImages(90);
pdf.SaveAs("sales-report.pdf");
using IronPdf;
// Initialize the Chrome-based renderer with advanced options
var renderer = new ChromePdfRenderer
{
// Configure rendering options for optimal quality
RenderingOptions = new ChromePdfRenderOptions
{
// Set high-quality rendering at 300 DPI for print-ready PDFs
DPI = 300,
// Enable JavaScript execution with custom timeout
EnableJavaScript = true,
RenderDelay = 2000, // Wait 2 seconds for dynamic content
// Configure page layout
MarginTop = 20,
MarginBottom = 20,
MarginLeft = 15,
MarginRight = 15,
// Enable modern web features
CssMediaType = PdfCssMediaType.Print,
ViewPortWidth = 1920,
// Optimize for web fonts and images
CreatePdfFormsFromHtml = true,
FitToPaperMode = FitToPaperModes.Automatic
}
};
// Convert complex HTML with CSS3 and JavaScript
var htmlContent = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'>
<style>
body { font-family: 'Roboto', sans-serif; }
.chart-container { width: 100%; height: 400px; }
@media print {
.no-print { display: none; }
.page-break { page-break-after: always; }
}
</style>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
</head>
<body>
<h1>Dynamic Sales Report</h1>
<div class='chart-container'>
<canvas id='salesChart'></canvas>
</div>
<script>
// Dynamic chart generation
const ctx = document.getElementById('salesChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales 2025',
data: [65, 78, 90, 81, 96],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
}
});
</script>
</body>
</html>";
// Generate PDF with full JavaScript chart rendering
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
// Apply post-processing optimizations
pdf.CompressImages(90);
pdf.SaveAs("sales-report.pdf");
Imports IronPdf
' Initialize the Chrome-based renderer with advanced options
Private renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.DPI = 300,
.EnableJavaScript = True,
.RenderDelay = 2000,
.MarginTop = 20,
.MarginBottom = 20,
.MarginLeft = 15,
.MarginRight = 15,
.CssMediaType = PdfCssMediaType.Print,
.ViewPortWidth = 1920,
.CreatePdfFormsFromHtml = True,
.FitToPaperMode = FitToPaperModes.Automatic
}
}
' Convert complex HTML with CSS3 and JavaScript
Private htmlContent = "
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'>
<style>
body { font-family: 'Roboto', sans-serif; }
.chart-container { width: 100%; height: 400px; }
@media print {
.no-print { display: none; }
.page-break { page-break-after: always; }
}
</style>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
</head>
<body>
<h1>Dynamic Sales Report</h1>
<div class='chart-container'>
<canvas id='salesChart'></canvas>
</div>
<script>
// Dynamic chart generation
const ctx = document.getElementById('salesChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales 2025',
data: [65, 78, 90, 81, 96],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
}
});
</script>
</body>
</html>"
' Generate PDF with full JavaScript chart rendering
Private pdf = renderer.RenderHtmlAsPdf(htmlContent)
' Apply post-processing optimizations
pdf.CompressImages(90)
pdf.SaveAs("sales-report.pdf")
這個IronPDF範例展示了幾個高級功能:
- Chrome V8 JavaScript引擎:完整執行Chart.js以渲染動態可視化
- 網頁字體支持:自動下載並嵌入Google字體
- 響應式渲染:尊重CSS媒體查詢來優化列印
- 高DPI支持:生成300 DPI的可列印PDF
- 自動佈局:智能調整內容以適應頁面邊界
EvoPdf HTML到PDF範例
using EvoPdf;
// Create converter with configuration
HtmlToPdfConverter converter = new HtmlToPdfConverter();
// Set license key (required for production use)
converter.LicenseKey = "your-license-key";
// Configure conversion settings
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
converter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait;
converter.PdfDocumentOptions.TopMargin = 20;
converter.PdfDocumentOptions.BottomMargin = 20;
converter.PdfDocumentOptions.LeftMargin = 15;
converter.PdfDocumentOptions.RightMargin = 15;
// Enable JavaScript execution
converter.JavaScriptEnabled = true;
converter.ConversionDelay = 2; // seconds
// Set authentication if needed
converter.AuthenticationOptions.Username = "username";
converter.AuthenticationOptions.Password = "password";
// Convert HTML string
string htmlString = @"
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
</style>
</head>
<body>
<h1>Invoice</h1>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr>
<td>Product A</td>
<td>5</td>
<td>$50.00</td>
</tr>
</table>
</body>
</html>";
// Perform conversion
byte[] pdfBytes = converter.ConvertHtml(htmlString, "");
// Save to file
System.IO.File.WriteAllBytes("invoice.pdf", pdfBytes);
using EvoPdf;
// Create converter with configuration
HtmlToPdfConverter converter = new HtmlToPdfConverter();
// Set license key (required for production use)
converter.LicenseKey = "your-license-key";
// Configure conversion settings
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
converter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait;
converter.PdfDocumentOptions.TopMargin = 20;
converter.PdfDocumentOptions.BottomMargin = 20;
converter.PdfDocumentOptions.LeftMargin = 15;
converter.PdfDocumentOptions.RightMargin = 15;
// Enable JavaScript execution
converter.JavaScriptEnabled = true;
converter.ConversionDelay = 2; // seconds
// Set authentication if needed
converter.AuthenticationOptions.Username = "username";
converter.AuthenticationOptions.Password = "password";
// Convert HTML string
string htmlString = @"
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
</style>
</head>
<body>
<h1>Invoice</h1>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr>
<td>Product A</td>
<td>5</td>
<td>$50.00</td>
</tr>
</table>
</body>
</html>";
// Perform conversion
byte[] pdfBytes = converter.ConvertHtml(htmlString, "");
// Save to file
System.IO.File.WriteAllBytes("invoice.pdf", pdfBytes);
Imports EvoPdf
' Create converter with configuration
Private converter As New HtmlToPdfConverter()
' Set license key (required for production use)
converter.LicenseKey = "your-license-key"
' Configure conversion settings
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
converter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait
converter.PdfDocumentOptions.TopMargin = 20
converter.PdfDocumentOptions.BottomMargin = 20
converter.PdfDocumentOptions.LeftMargin = 15
converter.PdfDocumentOptions.RightMargin = 15
' Enable JavaScript execution
converter.JavaScriptEnabled = True
converter.ConversionDelay = 2 ' seconds
' Set authentication if needed
converter.AuthenticationOptions.Username = "username"
converter.AuthenticationOptions.Password = "password"
' Convert HTML string
Dim htmlString As String = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
</style>
</head>
<body>
<h1>Invoice</h1>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr>
<td>Product A</td>
<td>5</td>
<td>$50.00</td>
</tr>
</table>
</body>
</html>"
' Perform conversion
Dim pdfBytes() As Byte = converter.ConvertHtml(htmlString, "")
' Save to file
System.IO.File.WriteAllBytes("invoice.pdf", pdfBytes)
EvoPdf的方法專注於直接HTML轉換,並對基本樣式和佈局提供良好支持。 儘管它處理標準HTML和CSS良好,但在CSS Grid、Flexbox動畫或複雜的JavaScript框架等現代網路功能方面可能會有困難。
PDF安全性和加密:保護敏感文件
在處理敏感文件時安全性至關重要。 兩個程式庫都提供加密功能,但在複雜程度上有所不同。
IronPDF高級安全性實現
using IronPdf;
using IronPdf.Security;
// Load an existing PDF or create new one
var pdf = PdfDocument.FromFile("confidential-report.pdf");
// Configure comprehensive security settings
pdf.SecuritySettings = new SecuritySettings
{
// Set owner password (full permissions)
OwnerPassword = "admin-complex-password-2025",
// Set user password (restricted permissions)
UserPassword = "user-password-readonly",
// Configure granular permissions
AllowAccessibilityExtractContent = false,
AllowAnnotations = false,
AllowAssembleDocument = false,
AllowCopy = false,
AllowFillForms = true,
AllowFullQualityPrint = false,
AllowModifyDocument = false,
AllowPrint = true,
// Use strongest encryption available
EncryptionLevel = EncryptionLevel.AES256Bit
};
// Add metadata security
pdf.MetaData.Author = "Authorized Personnel Only";
pdf.MetaData.ModifiedDate = DateTime.UtcNow;
pdf.MetaData.Title = "Confidential: Internal Use Only";
// Apply digital signature for authenticity
var signature = new PdfSignature("certificate.pfx", "cert-password")
{
SigningReason = "Document Approval",
SigningLocation = "Corporate Headquarters",
SigningContact = "security@company.com",
// Visual signature appearance
IsVisible = true,
X = 100,
Y = 100,
Width = 200,
Height = 50,
PageIndex = 0,
// Custom appearance
SignatureImage = new PdfSignatureImage("signature.png"),
DateFormat = "yyyy-MM-dd HH:mm:ss"
};
pdf.Sign(signature);
// Add watermark for additional security
pdf.ApplyWatermark("<h2 style='color:red; opacity:0.5;'>CONFIDENTIAL</h2>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
pdf.SaveAs("secured-document.pdf");
using IronPdf;
using IronPdf.Security;
// Load an existing PDF or create new one
var pdf = PdfDocument.FromFile("confidential-report.pdf");
// Configure comprehensive security settings
pdf.SecuritySettings = new SecuritySettings
{
// Set owner password (full permissions)
OwnerPassword = "admin-complex-password-2025",
// Set user password (restricted permissions)
UserPassword = "user-password-readonly",
// Configure granular permissions
AllowAccessibilityExtractContent = false,
AllowAnnotations = false,
AllowAssembleDocument = false,
AllowCopy = false,
AllowFillForms = true,
AllowFullQualityPrint = false,
AllowModifyDocument = false,
AllowPrint = true,
// Use strongest encryption available
EncryptionLevel = EncryptionLevel.AES256Bit
};
// Add metadata security
pdf.MetaData.Author = "Authorized Personnel Only";
pdf.MetaData.ModifiedDate = DateTime.UtcNow;
pdf.MetaData.Title = "Confidential: Internal Use Only";
// Apply digital signature for authenticity
var signature = new PdfSignature("certificate.pfx", "cert-password")
{
SigningReason = "Document Approval",
SigningLocation = "Corporate Headquarters",
SigningContact = "security@company.com",
// Visual signature appearance
IsVisible = true,
X = 100,
Y = 100,
Width = 200,
Height = 50,
PageIndex = 0,
// Custom appearance
SignatureImage = new PdfSignatureImage("signature.png"),
DateFormat = "yyyy-MM-dd HH:mm:ss"
};
pdf.Sign(signature);
// Add watermark for additional security
pdf.ApplyWatermark("<h2 style='color:red; opacity:0.5;'>CONFIDENTIAL</h2>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
pdf.SaveAs("secured-document.pdf");
Imports IronPdf
Imports IronPdf.Security
' Load an existing PDF or create new one
Private pdf = PdfDocument.FromFile("confidential-report.pdf")
' Configure comprehensive security settings
pdf.SecuritySettings = New SecuritySettings With {
.OwnerPassword = "admin-complex-password-2025",
.UserPassword = "user-password-readonly",
.AllowAccessibilityExtractContent = False,
.AllowAnnotations = False,
.AllowAssembleDocument = False,
.AllowCopy = False,
.AllowFillForms = True,
.AllowFullQualityPrint = False,
.AllowModifyDocument = False,
.AllowPrint = True,
.EncryptionLevel = EncryptionLevel.AES256Bit
}
' Add metadata security
pdf.MetaData.Author = "Authorized Personnel Only"
pdf.MetaData.ModifiedDate = DateTime.UtcNow
pdf.MetaData.Title = "Confidential: Internal Use Only"
' Apply digital signature for authenticity
Dim signature = New PdfSignature("certificate.pfx", "cert-password") With {
.SigningReason = "Document Approval",
.SigningLocation = "Corporate Headquarters",
.SigningContact = "security@company.com",
.IsVisible = True,
.X = 100,
.Y = 100,
.Width = 200,
.Height = 50,
.PageIndex = 0,
.SignatureImage = New PdfSignatureImage("signature.png"),
.DateFormat = "yyyy-MM-dd HH:mm:ss"
}
pdf.Sign(signature)
' Add watermark for additional security
pdf.ApplyWatermark("<h2 style='color:red; opacity:0.5;'>CONFIDENTIAL</h2>", 45, VerticalAlignment.Middle, HorizontalAlignment.Center)
pdf.SaveAs("secured-document.pdf")
IronPDF的安全性實現提供企業級功能:
- 細粒度權限:精確調整使用者可以做什麼
- 可見數位簽名:包含簽名圖像和時間戳
- 元資料保護:安全的文件屬性和審計追溯
- 分層安全性:組合加密、簽名和水印
EvoPdf安全配置
using EvoPdf;
// Create security manager
PdfSecurityOptions securityOptions = new PdfSecurityOptions();
// Set basic security parameters
securityOptions.UserPassword = "user123";
securityOptions.OwnerPassword = "owner456";
securityOptions.KeySize = EncryptionKeySize.Key256Bit;
// Configure permissions
securityOptions.CanPrint = true;
securityOptions.CanCopyContent = false;
securityOptions.CanEditContent = false;
securityOptions.CanEditAnnotations = false;
securityOptions.CanFillFormFields = true;
securityOptions.CanAssembleDocument = false;
// Apply security to existing PDF
PdfSecurityManager securityManager = new PdfSecurityManager(securityOptions);
securityManager.SaveSecuredPdfToFile("input.pdf", "secured-output.pdf");
using EvoPdf;
// Create security manager
PdfSecurityOptions securityOptions = new PdfSecurityOptions();
// Set basic security parameters
securityOptions.UserPassword = "user123";
securityOptions.OwnerPassword = "owner456";
securityOptions.KeySize = EncryptionKeySize.Key256Bit;
// Configure permissions
securityOptions.CanPrint = true;
securityOptions.CanCopyContent = false;
securityOptions.CanEditContent = false;
securityOptions.CanEditAnnotations = false;
securityOptions.CanFillFormFields = true;
securityOptions.CanAssembleDocument = false;
// Apply security to existing PDF
PdfSecurityManager securityManager = new PdfSecurityManager(securityOptions);
securityManager.SaveSecuredPdfToFile("input.pdf", "secured-output.pdf");
Imports EvoPdf
' Create security manager
Private securityOptions As New PdfSecurityOptions()
' Set basic security parameters
securityOptions.UserPassword = "user123"
securityOptions.OwnerPassword = "owner456"
securityOptions.KeySize = EncryptionKeySize.Key256Bit
' Configure permissions
securityOptions.CanPrint = True
securityOptions.CanCopyContent = False
securityOptions.CanEditContent = False
securityOptions.CanEditAnnotations = False
securityOptions.CanFillFormFields = True
securityOptions.CanAssembleDocument = False
' Apply security to existing PDF
Dim securityManager As New PdfSecurityManager(securityOptions)
securityManager.SaveSecuredPdfToFile("input.pdf", "secured-output.pdf")
EvoPdf提供基本的安全功能,適合基本的文件保護,但缺乏IronPDF中可用的一些高級選項。
內容編輯:合規性和隱私保護
在當今注重隱私的環境中,能夠永久移除PDF中的敏感資訊對於遵守例如GDPR、HIPAA和CCPA等法規至關重要。
IronPDF編輯範例
using IronPdf;
// Load PDF containing sensitive information
PdfDocument pdf = PdfDocument.FromFile("customer-records.pdf");
// Redact using multiple strategies
// 1. Redact specific text patterns (SSN format)
pdf.RedactTextOnAllPages(@"\b\d{3}-\d{2}-\d{4}\b",
isRegex: true,
new RedactionOptions
{
RedactionColor = Color.Black,
RedactionStyle = RedactionStyle.Filled,
DrawRedactionBorder = true,
BorderColor = Color.Red
});
// 2. Redact specific phrases
pdf.RedactTextOnPages("Confidential",
new[] { 0, 1, 2 }, // Specific pages
caseSensitive: false);
// 3. Redact regions by coordinates
pdf.RedactRegion(new Rectangle(100, 200, 300, 50), 0);
// 4. Use advanced pattern matching for credit cards
string creditCardPattern = @"\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})\b";
pdf.RedactTextOnAllPages(creditCardPattern, isRegex: true);
// Apply OCR-based redaction for scanned documents
pdf.ApplyOcr(new TesseractLanguage[] { TesseractLanguage.English });
pdf.RedactTextOnAllPages("Salary:");
// Save with audit trail
pdf.MetaData.CustomProperties.Add("Redacted", DateTime.UtcNow.ToString());
pdf.MetaData.CustomProperties.Add("RedactedBy", Environment.UserName);
pdf.SaveAs("redacted-records.pdf");
using IronPdf;
// Load PDF containing sensitive information
PdfDocument pdf = PdfDocument.FromFile("customer-records.pdf");
// Redact using multiple strategies
// 1. Redact specific text patterns (SSN format)
pdf.RedactTextOnAllPages(@"\b\d{3}-\d{2}-\d{4}\b",
isRegex: true,
new RedactionOptions
{
RedactionColor = Color.Black,
RedactionStyle = RedactionStyle.Filled,
DrawRedactionBorder = true,
BorderColor = Color.Red
});
// 2. Redact specific phrases
pdf.RedactTextOnPages("Confidential",
new[] { 0, 1, 2 }, // Specific pages
caseSensitive: false);
// 3. Redact regions by coordinates
pdf.RedactRegion(new Rectangle(100, 200, 300, 50), 0);
// 4. Use advanced pattern matching for credit cards
string creditCardPattern = @"\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})\b";
pdf.RedactTextOnAllPages(creditCardPattern, isRegex: true);
// Apply OCR-based redaction for scanned documents
pdf.ApplyOcr(new TesseractLanguage[] { TesseractLanguage.English });
pdf.RedactTextOnAllPages("Salary:");
// Save with audit trail
pdf.MetaData.CustomProperties.Add("Redacted", DateTime.UtcNow.ToString());
pdf.MetaData.CustomProperties.Add("RedactedBy", Environment.UserName);
pdf.SaveAs("redacted-records.pdf");
Imports IronPdf
' Load PDF containing sensitive information
Private pdf As PdfDocument = PdfDocument.FromFile("customer-records.pdf")
' Redact using multiple strategies
' 1. Redact specific text patterns (SSN format)
pdf.RedactTextOnAllPages("\b\d{3}-\d{2}-\d{4}\b", isRegex:= True, New RedactionOptions With {
.RedactionColor = Color.Black,
.RedactionStyle = RedactionStyle.Filled,
.DrawRedactionBorder = True,
.BorderColor = Color.Red
})
' 2. Redact specific phrases
pdf.RedactTextOnPages("Confidential", { 0, 1, 2 }, caseSensitive:= False)
' 3. Redact regions by coordinates
pdf.RedactRegion(New Rectangle(100, 200, 300, 50), 0)
' 4. Use advanced pattern matching for credit cards
Dim creditCardPattern As String = "\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})\b"
pdf.RedactTextOnAllPages(creditCardPattern, isRegex:= True)
' Apply OCR-based redaction for scanned documents
pdf.ApplyOcr(New TesseractLanguage() { TesseractLanguage.English })
pdf.RedactTextOnAllPages("Salary:")
' Save with audit trail
pdf.MetaData.CustomProperties.Add("Redacted", DateTime.UtcNow.ToString())
pdf.MetaData.CustomProperties.Add("RedactedBy", Environment.UserName)
pdf.SaveAs("redacted-records.pdf")
IronPDF的編輯功能包括:
- 真正的內容移除:永久移除文字而不只是遮擋
- 模式識別:對SSN、信用卡、電子郵件的正則表示支援
- 可視的編輯樣式:自定義外觀以便審核
- OCR整合:在掃描文件中編輯文字
- 選擇性編輯:針對特定頁面或區域執行
IronPDF中包含原生的編輯功能,使其成為需要滿足如GDPR、HIPAA和CCPA等隱私法規合規應用程式的明智選擇。
表單處理:建立互動式PDF
兩個程式庫均支持PDF表單,但製作及操作方法不同。
IronPDF表單範例
using IronPdf;
using IronPdf.Forms;
// Create a new PDF with an HTML form
var html = @"
<html>
<body>
<h2>Employee Information Form</h2>
<form>
<label>Full Name:</label>
<input type='text' name='fullName' required />
<label>Email:</label>
<input type='email' name='email' required />
<label>Department:</label>
<select name='department'>
<option value=''>Select Department</option>
<option value='IT'>Information Technology</option>
<option value='HR'>Human Resources</option>
<option value='Sales'>Sales</option>
</select>
<label>Start Date:</label>
<input type='date' name='startDate' />
<label>
<input type='checkbox' name='agreement' />
I agree to the terms and conditions
</label>
<button type='submit'>Submit</button>
</form>
</body>
</html>";
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
CreatePdfFormsFromHtml = true // Enable form field creation
}
};
var pdf = renderer.RenderHtmlAsPdf(html);
// Programmatically fill form fields
pdf.Form.SetFieldValue("fullName", "John Doe");
pdf.Form.SetFieldValue("email", "john.doe@company.com");
pdf.Form.SetFieldValue("department", "IT");
pdf.Form.SetFieldValue("startDate", DateTime.Now.ToString("yyyy-MM-dd"));
pdf.Form.SetCheckBoxValue("agreement", true);
// Make specific fields read-only
pdf.Form.Fields["email"].ReadOnly = true;
// Add form field validation
foreach (var field in pdf.Form.Fields)
{
if (field.Name == "email")
{
field.Annotation.BorderColor = Color.Blue;
field.Annotation.BackgroundColor = Color.LightGray;
}
}
// Flatten form (convert to static content)
var flattenedPdf = pdf.Flatten();
flattenedPdf.SaveAs("completed-form.pdf");
// Or save as fillable form
pdf.SaveAs("fillable-form.pdf");
using IronPdf;
using IronPdf.Forms;
// Create a new PDF with an HTML form
var html = @"
<html>
<body>
<h2>Employee Information Form</h2>
<form>
<label>Full Name:</label>
<input type='text' name='fullName' required />
<label>Email:</label>
<input type='email' name='email' required />
<label>Department:</label>
<select name='department'>
<option value=''>Select Department</option>
<option value='IT'>Information Technology</option>
<option value='HR'>Human Resources</option>
<option value='Sales'>Sales</option>
</select>
<label>Start Date:</label>
<input type='date' name='startDate' />
<label>
<input type='checkbox' name='agreement' />
I agree to the terms and conditions
</label>
<button type='submit'>Submit</button>
</form>
</body>
</html>";
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
CreatePdfFormsFromHtml = true // Enable form field creation
}
};
var pdf = renderer.RenderHtmlAsPdf(html);
// Programmatically fill form fields
pdf.Form.SetFieldValue("fullName", "John Doe");
pdf.Form.SetFieldValue("email", "john.doe@company.com");
pdf.Form.SetFieldValue("department", "IT");
pdf.Form.SetFieldValue("startDate", DateTime.Now.ToString("yyyy-MM-dd"));
pdf.Form.SetCheckBoxValue("agreement", true);
// Make specific fields read-only
pdf.Form.Fields["email"].ReadOnly = true;
// Add form field validation
foreach (var field in pdf.Form.Fields)
{
if (field.Name == "email")
{
field.Annotation.BorderColor = Color.Blue;
field.Annotation.BackgroundColor = Color.LightGray;
}
}
// Flatten form (convert to static content)
var flattenedPdf = pdf.Flatten();
flattenedPdf.SaveAs("completed-form.pdf");
// Or save as fillable form
pdf.SaveAs("fillable-form.pdf");
Imports IronPdf
Imports IronPdf.Forms
' Create a new PDF with an HTML form
Private html = "
<html>
<body>
<h2>Employee Information Form</h2>
<form>
<label>Full Name:</label>
<input type='text' name='fullName' required />
<label>Email:</label>
<input type='email' name='email' required />
<label>Department:</label>
<select name='department'>
<option value=''>Select Department</option>
<option value='IT'>Information Technology</option>
<option value='HR'>Human Resources</option>
<option value='Sales'>Sales</option>
</select>
<label>Start Date:</label>
<input type='date' name='startDate' />
<label>
<input type='checkbox' name='agreement' />
I agree to the terms and conditions
</label>
<button type='submit'>Submit</button>
</form>
</body>
</html>"
Private renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {.CreatePdfFormsFromHtml = True}
}
Private pdf = renderer.RenderHtmlAsPdf(html)
' Programmatically fill form fields
pdf.Form.SetFieldValue("fullName", "John Doe")
pdf.Form.SetFieldValue("email", "john.doe@company.com")
pdf.Form.SetFieldValue("department", "IT")
pdf.Form.SetFieldValue("startDate", DateTime.Now.ToString("yyyy-MM-dd"))
pdf.Form.SetCheckBoxValue("agreement", True)
' Make specific fields read-only
pdf.Form.Fields("email").ReadOnly = True
' Add form field validation
For Each field In pdf.Form.Fields
If field.Name = "email" Then
field.Annotation.BorderColor = Color.Blue
field.Annotation.BackgroundColor = Color.LightGray
End If
Next field
' Flatten form (convert to static content)
Dim flattenedPdf = pdf.Flatten()
flattenedPdf.SaveAs("completed-form.pdf")
' Or save as fillable form
pdf.SaveAs("fillable-form.pdf")
IronPDF的表單處理功能包括:
- 自動表單生成:將HTML表單轉換為PDF表單
- 程式化操作:通過API填寫、讀取及修改表單欄位
- 欄位型別:文字、複選框、單選、下拉、簽名欄
- 驗證:設置欄位屬性和限制
- 表單平面化:將填好的表單轉換為靜態PDF
性能基準:現實情景
性能特徵根據文件複雜性和使用情景而顯著不同:
批量處理性能測試
// Performance comparison for batch processing
public class PerformanceBenchmark
{
public static async Task RunBenchmark()
{
var htmlTemplates = GenerateInvoiceTemplates(1000);
var stopwatch = new Stopwatch();
// IronPDF batch processing with optimization
Console.WriteLine("IronPDF Batch Processing:");
stopwatch.Start();
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
RenderDelay = 0, // No delay for static content
EnableJavaScript = false, // Disable JS for speed
DPI = 150 // Lower DPI for faster rendering
}
};
// Parallel processing
var tasks = htmlTemplates.Select(async (html, index) =>
{
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
await pdf.SaveAsAsync($"ironpdf-invoice-{index}.pdf");
});
await Task.WhenAll(tasks);
stopwatch.Stop();
Console.WriteLine($"Time: {stopwatch.ElapsedMilliseconds}ms");
Console.WriteLine($"Average: {stopwatch.ElapsedMilliseconds / 1000.0}ms per PDF");
// Memory usage
var process = Process.GetCurrentProcess();
Console.WriteLine($"Memory: {process.WorkingSet64 / 1024 / 1024}MB");
}
}
// Performance comparison for batch processing
public class PerformanceBenchmark
{
public static async Task RunBenchmark()
{
var htmlTemplates = GenerateInvoiceTemplates(1000);
var stopwatch = new Stopwatch();
// IronPDF batch processing with optimization
Console.WriteLine("IronPDF Batch Processing:");
stopwatch.Start();
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
RenderDelay = 0, // No delay for static content
EnableJavaScript = false, // Disable JS for speed
DPI = 150 // Lower DPI for faster rendering
}
};
// Parallel processing
var tasks = htmlTemplates.Select(async (html, index) =>
{
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
await pdf.SaveAsAsync($"ironpdf-invoice-{index}.pdf");
});
await Task.WhenAll(tasks);
stopwatch.Stop();
Console.WriteLine($"Time: {stopwatch.ElapsedMilliseconds}ms");
Console.WriteLine($"Average: {stopwatch.ElapsedMilliseconds / 1000.0}ms per PDF");
// Memory usage
var process = Process.GetCurrentProcess();
Console.WriteLine($"Memory: {process.WorkingSet64 / 1024 / 1024}MB");
}
}
' Performance comparison for batch processing
Public Class PerformanceBenchmark
Public Shared Async Function RunBenchmark() As Task
Dim htmlTemplates = GenerateInvoiceTemplates(1000)
Dim stopwatch As New Stopwatch()
' IronPDF batch processing with optimization
Console.WriteLine("IronPDF Batch Processing:")
stopwatch.Start()
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.RenderDelay = 0,
.EnableJavaScript = False,
.DPI = 150
}
}
' Parallel processing
Dim tasks = htmlTemplates.Select(Async Function(html, index)
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Await pdf.SaveAsAsync($"ironpdf-invoice-{index}.pdf")
End Function)
Await Task.WhenAll(tasks)
stopwatch.Stop()
Console.WriteLine($"Time: {stopwatch.ElapsedMilliseconds}ms")
Console.WriteLine($"Average: {stopwatch.ElapsedMilliseconds / 1000.0}ms per PDF")
' Memory usage
Dim process As System.Diagnostics.Process = System.Diagnostics.Process.GetCurrentProcess()
Console.WriteLine($"Memory: {process.WorkingSet64 \ 1024 \ 1024}MB")
End Function
End Class
根據場景的性能考慮因素:
- 簡單HTML: EvoPdf 因為其輕量的渲染引擎對於輕量的靜態文件更快
- 複雜JavaScript: IronPDF 提供更可靠的結果; EvoPdf可能會在動態內容中產生不一致的輸出
- 批量處理: IronPDF 提供更好的原生異步/等待並行化支援
- 記憶體使用: EvoPdf有較低的記憶體基線; IronPDF為高吞吐量工作負載優化
- 大型文件: IronPDF以優化的批量處理處理高頁數的文件
不同團隊規模的定價模式比較?
IronPDF授權結構
IronPDF提供不同的定價選項,包括Lite、Plus和Professional授權,其中還有免版稅再分發的選擇。 授權模型旨在隨您的團隊和專案需求而擴展(定價截至2026年4月):
-
Lite License: $999
- 1名開發人員
- 1個地點
- 1個專案
- 電子郵件支援
- 理想物件:個人開發者,小專案
-
Plus License: $1,499
- 3名開發人員
- 3個地點
- 3個專案
- 電子郵件、聊天和電話支持
- 理想物件:小團隊,多個專案
- Professional License: $2,399
- 10名開發人員
- 10個地點
- 10個專案
-
優先支援,帶有螢幕共享
- 理想物件:中到大型團隊
- 其他選項:
- 免版稅再分發:+$2,399
- 5年支援和更新:$1,999(或$999/年)
- Iron Suite:$2,998包括所有10個Iron Software產品
EvoPdf Licensing Options
EVO PDF工具包和獨立的HTML到PDF轉換器各提供兩種授權級別——部署和公司(定價截至2026年4月; 請在evopdf.com/buy.aspx驗證當前定價):
-
部署授權:
- EVO HTML到PDF:$450
- EVO PDF工具包:$650
- 單伺服器,單應用程式
- 不包括再分發
- 第一年標準支援
- 公司授權:
- EVO HTML到PDF:$1,200
- EVO PDF工具箱:$1,400
- 無限制開發人員
- 無限部署
- 完全再分發權限
- 第一年優先支援
擁有總成本分析
讓我們檢視真實世界的場景以了解實際的成本影響:
場景1:擁有2名開發人員的初創公司
- IronPDF Lite:$999(單一開發人員; 需要兩個授權證書以便2人團隊)
- EvoPdf公司:$1,200(涵蓋無限制的開發人員)
- 贏家:EvoPdf在初始團隊成本方面
場景2:成長中的團隊(5名開發人員,多個專案)
- IronPDF Plus:$1,499(涵蓋多達3名開發人員,需要專業版覆蓋5名開發人員)
- IronPDF Professional:$2,399
- EvoPdf公司:$1,200
- 贏家:EvoPdf可滿足團隊擴展需求
場景3:需要多個PDF工具的企業
- IronPDF Professional + IronOCR + IronBarcode:多個單獨的授權
- Iron Suite:$2,998(全部10個產品)
- EvoPdf工具包 + 其他工具:$1,400+ 每個工具
- 贏家: Iron Suite針對綜合需求
場景4:具有再分發的SaaS產品
- IronPDF Professional + 再分發:$2,399 + $2,399
- EvoPdf公司:$1,200(包括再分發)
- 贏家: EvoPdf適合再分發場景
現代CSS框架如何影響您的選擇?
PDF程式庫選擇中經常被低估的一個因素是對現代CSS框架支持。 隨著Bootstrap、Tailwind CSS和Foundation在網頁開發中的主導地位,您的程式庫處理這些框架的能力直接影響開發效率和輸出質量。
IronPDF:全面的框架支持
IronPDF的完整Chrome V8引擎提供對所有現代CSS框架的原生支持,且不妥協:
- Bootstrap 5: 完整的flexbox和CSS Grid支持以進行複雜佈局
- Tailwind CSS:所有實用程式類均可準確渲染
- 現代CSS3: 轉化、動畫、自定義屬性全部支持
- 生產驗證: 成功渲染Bootstrap首頁和Bootstrap模板
程式碼範例:Bootstrap時間軸組件
using IronPdf;
var renderer = new ChromePdfRenderer();
string bootstrapTimeline = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<style>
.timeline { position: relative; padding: 20px 0; }
.timeline::before {
content: '';
position: absolute;
left: 50%;
width: 2px;
height: 100%;
background: #dee2e6;
}
.timeline-item { position: relative; margin: 20px 0; }
</style>
</head>
<body>
<div class='container py-5'>
<h2 class='text-center mb-5'>Project Timeline</h2>
<div class='timeline'>
<div class='timeline-item'>
<div class='row'>
<div class='col-md-6'>
<div class='card shadow-sm'>
<div class='card-body'>
<h5 class='card-title'>Phase 1: Planning</h5>
<p class='text-muted'>Q1 2025</p>
<p class='card-text'>Initial project scope and requirements gathering completed.</p>
<span class='badge bg-success'>Completed</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(bootstrapTimeline);
pdf.SaveAs("project-timeline.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
string bootstrapTimeline = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<style>
.timeline { position: relative; padding: 20px 0; }
.timeline::before {
content: '';
position: absolute;
left: 50%;
width: 2px;
height: 100%;
background: #dee2e6;
}
.timeline-item { position: relative; margin: 20px 0; }
</style>
</head>
<body>
<div class='container py-5'>
<h2 class='text-center mb-5'>Project Timeline</h2>
<div class='timeline'>
<div class='timeline-item'>
<div class='row'>
<div class='col-md-6'>
<div class='card shadow-sm'>
<div class='card-body'>
<h5 class='card-title'>Phase 1: Planning</h5>
<p class='text-muted'>Q1 2025</p>
<p class='card-text'>Initial project scope and requirements gathering completed.</p>
<span class='badge bg-success'>Completed</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(bootstrapTimeline);
pdf.SaveAs("project-timeline.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim bootstrapTimeline As String = "
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<style>
.timeline { position: relative; padding: 20px 0; }
.timeline::before {
content: '';
position: absolute;
left: 50%;
width: 2px;
height: 100%;
background: #dee2e6;
}
.timeline-item { position: relative; margin: 20px 0; }
</style>
</head>
<body>
<div class='container py-5'>
<h2 class='text-center mb-5'>Project Timeline</h2>
<div class='timeline'>
<div class='timeline-item'>
<div class='row'>
<div class='col-md-6'>
<div class='card shadow-sm'>
<div class='card-body'>
<h5 class='card-title'>Phase 1: Planning</h5>
<p class='text-muted'>Q1 2025</p>
<p class='card-text'>Initial project scope and requirements gathering completed.</p>
<span class='badge bg-success'>Completed</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(bootstrapTimeline)
pdf.SaveAs("project-timeline.pdf")
EvoPdf:良好的CSS支持,有所限制
EvoPdf的自訂HTML渲染引擎提供可靠的CSS支持,但在某些現代框架上存在限制:
- Bootstrap 3: 與舊Bootstrap版適配良好
- Bootstrap 4+: Flexbox佈局可能需要調整
- CSS3支持: 良好的覆蓋率(約90%),但未完成
- 可用解決方案: 複雜佈局通常需要手動CSS調整
實際考量:
根據開發者經驗:
- 基本Bootstrap組件(按鈕、警示、表格)通常渲染正確
- 高級組件(導航條、模態框、複雜網格)可能需要定製化
- CSS網格佈局需要測試並可能需要後備方案
- 自定義Bootstrap主題有時會有意外的渲染問題
開發影響: 如果您的應用大量使用Bootstrap進行UI,並且需要生成與您的網頁介面匹配的報告或文件,IronPDF的無縫渲染可以節省大量開發時間。EvoPdf可能需要專門為PDF生成建立相比之下更簡化的模版。
關於CSS框架相容性的全面資訊,請參見Bootstrap & Flexbox CSS指南。
哪種文件和支援選項更好地服務於開發人員?
IronPDF的開發者資源
IronPDF提供全面的文件,24/5工程師支援,影片教程,社區論壇和定期更新。 支持生態系統包括:
-
文件質量:
- 全面的API參考
- 逐步教程
- 100+ code examples
- YouTube上的影片教程
- 來自其他程式庫的遷移指南
-
支援渠道:
- 24/5技術支援(可直達開發者)
- 回應時間:一般為24-48小時
- Plus+授權的即時聊天
- Professional授權的電話支持
- 複雜問題的螢幕共享
- 社區論壇和Stack Overflow存在
- 學習資源:
- 開始指南
- 架構文件
- 性能優化指南
- 安全性最佳實踐
- 雲部署指南
EvoPdf的支援結構
EvoPdf通過以下方式提供文件和支援:
-
文件:
- API參考文件
- 常見情景的程式碼範例
- 網站上的實時示範部分
- 基本故障排除指南
- 支援選項:
- 電子郵件和電話支援(包括第一年)
- 標準與優先支援等級
- 社區幫助的支持論壇
- 第一年後需要續保
關鍵的區別在於IronPDF對教育內容和直接工程師支援的投資,這能顯著地減少學習曲線和故障排除時間。
兩個程式庫的最佳使用案例是什麼?
何時選擇IronPDF
IronPDF在需要以下功能的場景中表現出色:
1. 現代網頁應用整合
- 生成動態報告的SaaS平台
- 使用圖表建立發票的電子商務網站
- 將商業智能儀表板匯出為PDFs
- 使用React、Angular或Vue.js的應用
2. 合規和安全要求
- 需要HIPAA合規的健康系統
- 需要審計追蹤的金融服務
- 編輯法律文件管理
- 具有安全性要求的政府申請
3. 複雜文件處理
- 多格式文件轉換(DOCX, HTML, 圖像)
- 用於掃描文件的OCR整合
- 並行執行的批量處理
- 具有數位簽名的文件
4. 跨平台部署
- Docker容器化的應用
- 基於Linux的雲端部署
- 微服務架構
- 無伺服器功能(AWS Lambda, Azure Functions)
真實世界範例:健康報告生成
public class HealthcareReportGenerator
{
private readonly ChromePdfRenderer _renderer;
public HealthcareReportGenerator()
{
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
DPI = 300, // High quality for medical imaging
EnableJavaScript = true,
RenderDelay = 3000, // Allow charts to fully render
CreatePdfFormsFromHtml = true
}
};
}
public async Task<byte[]> GeneratePatientReport(PatientData patient)
{
// Generate HTML with patient data and charts
var html = await GenerateReportHtml(patient);
// Convert to PDF
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Apply security and compliance
pdf.SecuritySettings = new SecuritySettings
{
AllowPrint = true,
AllowCopy = false,
EncryptionLevel = EncryptionLevel.AES256Bit,
UserPassword = patient.AccessCode
};
// Redact SSN except last 4 digits
pdf.RedactTextOnAllPages(@"\b\d{3}-\d{2}-(\d{4})\b",
replacement: "XXX-XX-$1",
isRegex: true);
// Add audit metadata
pdf.MetaData.Author = "Healthcare System";
pdf.MetaData.Title = $"Patient Report - {patient.PatientId}";
pdf.MetaData.CreationDate = DateTime.UtcNow;
pdf.MetaData.CustomProperties.Add("HIPAA_Compliant", "true");
// Add digital signature
var signature = new PdfSignature("hospital-cert.pfx", "password")
{
SigningReason = "Medical Record Authenticity",
SigningLocation = "Hospital Name"
};
pdf.Sign(signature);
return pdf.BinaryData;
}
}
public class HealthcareReportGenerator
{
private readonly ChromePdfRenderer _renderer;
public HealthcareReportGenerator()
{
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
DPI = 300, // High quality for medical imaging
EnableJavaScript = true,
RenderDelay = 3000, // Allow charts to fully render
CreatePdfFormsFromHtml = true
}
};
}
public async Task<byte[]> GeneratePatientReport(PatientData patient)
{
// Generate HTML with patient data and charts
var html = await GenerateReportHtml(patient);
// Convert to PDF
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Apply security and compliance
pdf.SecuritySettings = new SecuritySettings
{
AllowPrint = true,
AllowCopy = false,
EncryptionLevel = EncryptionLevel.AES256Bit,
UserPassword = patient.AccessCode
};
// Redact SSN except last 4 digits
pdf.RedactTextOnAllPages(@"\b\d{3}-\d{2}-(\d{4})\b",
replacement: "XXX-XX-$1",
isRegex: true);
// Add audit metadata
pdf.MetaData.Author = "Healthcare System";
pdf.MetaData.Title = $"Patient Report - {patient.PatientId}";
pdf.MetaData.CreationDate = DateTime.UtcNow;
pdf.MetaData.CustomProperties.Add("HIPAA_Compliant", "true");
// Add digital signature
var signature = new PdfSignature("hospital-cert.pfx", "password")
{
SigningReason = "Medical Record Authenticity",
SigningLocation = "Hospital Name"
};
pdf.Sign(signature);
return pdf.BinaryData;
}
}
Public Class HealthcareReportGenerator
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.DPI = 300,
.EnableJavaScript = True,
.RenderDelay = 3000,
.CreatePdfFormsFromHtml = True
}
}
End Sub
Public Async Function GeneratePatientReport(ByVal patient As PatientData) As Task(Of Byte())
' Generate HTML with patient data and charts
Dim html = Await GenerateReportHtml(patient)
' Convert to PDF
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
' Apply security and compliance
pdf.SecuritySettings = New SecuritySettings With {
.AllowPrint = True,
.AllowCopy = False,
.EncryptionLevel = EncryptionLevel.AES256Bit,
.UserPassword = patient.AccessCode
}
' Redact SSN except last 4 digits
pdf.RedactTextOnAllPages("\b\d{3}-\d{2}-(\d{4})\b", replacement:= "XXX-XX-$1", isRegex:= True)
' Add audit metadata
pdf.MetaData.Author = "Healthcare System"
pdf.MetaData.Title = $"Patient Report - {patient.PatientId}"
pdf.MetaData.CreationDate = DateTime.UtcNow
pdf.MetaData.CustomProperties.Add("HIPAA_Compliant", "true")
' Add digital signature
Dim signature = New PdfSignature("hospital-cert.pfx", "password") With {
.SigningReason = "Medical Record Authenticity",
.SigningLocation = "Hospital Name"
}
pdf.Sign(signature)
Return pdf.BinaryData
End Function
End Class
何時選擇EvoPdf
EvoPdf適合以下情況:
1. 簡單的HTML到PDF轉換
- 不含複雜JavaScript的基本報告
- 靜態HTML模板
- 簡單的發票和收據
- 使用一致模板的大量文件生成
2. 預算意識強的團隊
- 單一授權下無限制開發人員
- 基本功能的低進入成本
- 不需要高級PDF操作的專案
3. 特定伺服器環境
- 以Windows為中心的部署
- 簡單的PDF要求應用
- 與舊系統整合
4. 高批量簡單轉換
- 電子郵件至PDF文件存檔
- 靜態報表生成
- 文件系統
- 準備列印的文件建立
真實世界範例:發票生成系統
public class InvoiceGenerator
{
private readonly HtmlToPdfConverter _converter;
public InvoiceGenerator()
{
_converter = new HtmlToPdfConverter
{
LicenseKey = "your-license-key",
JavaScriptEnabled = false, // Not needed for static invoices
ConversionDelay = 0
};
// Configure for A4 invoices
_converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
_converter.PdfDocumentOptions.TopMargin = 30;
_converter.PdfDocumentOptions.BottomMargin = 30;
}
public byte[] GenerateInvoice(InvoiceData data)
{
// Load HTML template
var template = File.ReadAllText("invoice-template.html");
// Simple string replacement for data
var html = template
.Replace("{{InvoiceNumber}}", data.InvoiceNumber)
.Replace("{{Date}}", data.Date.ToString("yyyy-MM-dd"))
.Replace("{{CustomerName}}", data.CustomerName)
.Replace("{{Total}}", data.Total.ToString("C"));
// Convert to PDF
return _converter.ConvertHtml(html, "");
}
}
public class InvoiceGenerator
{
private readonly HtmlToPdfConverter _converter;
public InvoiceGenerator()
{
_converter = new HtmlToPdfConverter
{
LicenseKey = "your-license-key",
JavaScriptEnabled = false, // Not needed for static invoices
ConversionDelay = 0
};
// Configure for A4 invoices
_converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
_converter.PdfDocumentOptions.TopMargin = 30;
_converter.PdfDocumentOptions.BottomMargin = 30;
}
public byte[] GenerateInvoice(InvoiceData data)
{
// Load HTML template
var template = File.ReadAllText("invoice-template.html");
// Simple string replacement for data
var html = template
.Replace("{{InvoiceNumber}}", data.InvoiceNumber)
.Replace("{{Date}}", data.Date.ToString("yyyy-MM-dd"))
.Replace("{{CustomerName}}", data.CustomerName)
.Replace("{{Total}}", data.Total.ToString("C"));
// Convert to PDF
return _converter.ConvertHtml(html, "");
}
}
Public Class InvoiceGenerator
Private ReadOnly _converter As HtmlToPdfConverter
Public Sub New()
_converter = New HtmlToPdfConverter With {
.LicenseKey = "your-license-key",
.JavaScriptEnabled = False,
.ConversionDelay = 0
}
' Configure for A4 invoices
_converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
_converter.PdfDocumentOptions.TopMargin = 30
_converter.PdfDocumentOptions.BottomMargin = 30
End Sub
Public Function GenerateInvoice(ByVal data As InvoiceData) As Byte()
' Load HTML template
Dim template = File.ReadAllText("invoice-template.html")
' Simple string replacement for data
Dim html = template.Replace("{{InvoiceNumber}}", data.InvoiceNumber).Replace("{{Date}}", data.Date.ToString("yyyy-MM-dd")).Replace("{{CustomerName}}", data.CustomerName).Replace("{{Total}}", data.Total.ToString("C"))
' Convert to PDF
Return _converter.ConvertHtml(html, "")
End Function
End Class
進階實施方案和最佳實踐
在生產中優化性能
兩個程式庫受益於適當的配置和使用模式:
IronPDF性能優化
public class OptimizedPdfService
{
private readonly ChromePdfRenderer _renderer;
private readonly SemaphoreSlim _semaphore;
public OptimizedPdfService(int maxConcurrency = 4)
{
_semaphore = new SemaphoreSlim(maxConcurrency);
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
// Optimize for performance
EnableJavaScript = false, // Only if not needed
RenderDelay = 0,
DPI = 150, // Balance quality vs speed
CssMediaType = PdfCssMediaType.Screen,
Timeout = 30,
// Memory optimization
OptimizeForLowMemory = true
}
};
// Enable connection pooling
Installation.ChromeGpuMode = ChromeGpuModes.Disabled;
Installation.LinuxAndDockerDependenciesAutoConfig = false;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
await _semaphore.WaitAsync();
try
{
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Optimize file size
pdf.CompressImages(85);
pdf.RemoveUnusedResources();
return pdf.BinaryData;
}
finally
{
_semaphore.Release();
}
}
}
public class OptimizedPdfService
{
private readonly ChromePdfRenderer _renderer;
private readonly SemaphoreSlim _semaphore;
public OptimizedPdfService(int maxConcurrency = 4)
{
_semaphore = new SemaphoreSlim(maxConcurrency);
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
// Optimize for performance
EnableJavaScript = false, // Only if not needed
RenderDelay = 0,
DPI = 150, // Balance quality vs speed
CssMediaType = PdfCssMediaType.Screen,
Timeout = 30,
// Memory optimization
OptimizeForLowMemory = true
}
};
// Enable connection pooling
Installation.ChromeGpuMode = ChromeGpuModes.Disabled;
Installation.LinuxAndDockerDependenciesAutoConfig = false;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
await _semaphore.WaitAsync();
try
{
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Optimize file size
pdf.CompressImages(85);
pdf.RemoveUnusedResources();
return pdf.BinaryData;
}
finally
{
_semaphore.Release();
}
}
}
Public Class OptimizedPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Private ReadOnly _semaphore As SemaphoreSlim
Public Sub New(Optional ByVal maxConcurrency As Integer = 4)
_semaphore = New SemaphoreSlim(maxConcurrency)
_renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = False,
.RenderDelay = 0,
.DPI = 150,
.CssMediaType = PdfCssMediaType.Screen,
.Timeout = 30,
.OptimizeForLowMemory = True
}
}
' Enable connection pooling
Installation.ChromeGpuMode = ChromeGpuModes.Disabled
Installation.LinuxAndDockerDependenciesAutoConfig = False
End Sub
Public Async Function GeneratePdfAsync(ByVal html As String) As Task(Of Byte())
Await _semaphore.WaitAsync()
Try
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
' Optimize file size
pdf.CompressImages(85)
pdf.RemoveUnusedResources()
Return pdf.BinaryData
Finally
_semaphore.Release()
End Try
End Function
End Class
EvoPdf性能模式
public class EvoPdfOptimizedService
{
private readonly ObjectPool<HtmlToPdfConverter> _converterPool;
public EvoPdfOptimizedService()
{
// Create object pool for converter reuse
_converterPool = new DefaultObjectPool<HtmlToPdfConverter>(
new ConverterPoolPolicy(),
Environment.ProcessorCount * 2);
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
var converter = _converterPool.Get();
try
{
// Configure for speed
converter.ConversionDelay = 0;
converter.JavaScriptEnabled = false;
// Use async pattern
return await Task.Run(() => converter.ConvertHtml(html, ""));
}
finally
{
_converterPool.Return(converter);
}
}
private class ConverterPoolPolicy : IPooledObjectPolicy<HtmlToPdfConverter>
{
public HtmlToPdfConverter Create()
{
return new HtmlToPdfConverter
{
LicenseKey = "your-license-key"
};
}
public bool Return(HtmlToPdfConverter obj)
{
// Reset to default state
obj.ConversionDelay = 2;
return true;
}
}
}
public class EvoPdfOptimizedService
{
private readonly ObjectPool<HtmlToPdfConverter> _converterPool;
public EvoPdfOptimizedService()
{
// Create object pool for converter reuse
_converterPool = new DefaultObjectPool<HtmlToPdfConverter>(
new ConverterPoolPolicy(),
Environment.ProcessorCount * 2);
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
var converter = _converterPool.Get();
try
{
// Configure for speed
converter.ConversionDelay = 0;
converter.JavaScriptEnabled = false;
// Use async pattern
return await Task.Run(() => converter.ConvertHtml(html, ""));
}
finally
{
_converterPool.Return(converter);
}
}
private class ConverterPoolPolicy : IPooledObjectPolicy<HtmlToPdfConverter>
{
public HtmlToPdfConverter Create()
{
return new HtmlToPdfConverter
{
LicenseKey = "your-license-key"
};
}
public bool Return(HtmlToPdfConverter obj)
{
// Reset to default state
obj.ConversionDelay = 2;
return true;
}
}
}
Public Class EvoPdfOptimizedService
Private ReadOnly _converterPool As ObjectPool(Of HtmlToPdfConverter)
Public Sub New()
' Create object pool for converter reuse
_converterPool = New DefaultObjectPool(Of HtmlToPdfConverter)(New ConverterPoolPolicy(), Environment.ProcessorCount * 2)
End Sub
Public Async Function GeneratePdfAsync(ByVal html As String) As Task(Of Byte())
Dim converter = _converterPool.Get()
Try
' Configure for speed
converter.ConversionDelay = 0
converter.JavaScriptEnabled = False
' Use async pattern
Return Await Task.Run(Function() converter.ConvertHtml(html, ""))
Finally
_converterPool.Return(converter)
End Try
End Function
Private Class ConverterPoolPolicy
Implements IPooledObjectPolicy(Of HtmlToPdfConverter)
Public Function Create() As HtmlToPdfConverter
Return New HtmlToPdfConverter With {.LicenseKey = "your-license-key"}
End Function
Public Function [Return](ByVal obj As HtmlToPdfConverter) As Boolean
' Reset to default state
obj.ConversionDelay = 2
Return True
End Function
End Class
End Class
錯誤處理和除錯
對於生產應用而言,強而有力的錯誤處理至關重要:
IronPDF錯誤處理
public class RobustPdfGenerator
{
private readonly ILogger<RobustPdfGenerator> _logger;
private readonly ChromePdfRenderer _renderer;
public async Task<Result<byte[]>> TryGeneratePdfAsync(string html)
{
try
{
// Enable detailed logging
IronPdf.Logging.Logger.EnableDebugging = true;
IronPdf.Logging.Logger.LogFilePath = "ironpdf.log";
IronPdf.Logging.Logger.LoggingLevel = LoggingLevels.All;
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Validate output
if (pdf.PageCount == 0)
{
return Result<byte[]>.Failure("Generated PDF has no pages");
}
return Result<byte[]>.Success(pdf.BinaryData);
}
catch (IronPdf.Exceptions.IronPdfRenderException ex)
{
_logger.LogError(ex, "Rendering failed: {Message}", ex.Message);
// Attempt fallback with simpler settings
return await FallbackRender(html);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error in PDF generation");
return Result<byte[]>.Failure($"PDF generation failed: {ex.Message}");
}
}
private async Task<Result<byte[]>> FallbackRender(string html)
{
var fallbackRenderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = false,
DPI = 96,
Timeout = 60
}
};
try
{
var pdf = await fallbackRenderer.RenderHtmlAsPdfAsync(html);
return Result<byte[]>.Success(pdf.BinaryData);
}
catch (Exception ex)
{
return Result<byte[]>.Failure($"Fallback render failed: {ex.Message}");
}
}
}
public class RobustPdfGenerator
{
private readonly ILogger<RobustPdfGenerator> _logger;
private readonly ChromePdfRenderer _renderer;
public async Task<Result<byte[]>> TryGeneratePdfAsync(string html)
{
try
{
// Enable detailed logging
IronPdf.Logging.Logger.EnableDebugging = true;
IronPdf.Logging.Logger.LogFilePath = "ironpdf.log";
IronPdf.Logging.Logger.LoggingLevel = LoggingLevels.All;
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Validate output
if (pdf.PageCount == 0)
{
return Result<byte[]>.Failure("Generated PDF has no pages");
}
return Result<byte[]>.Success(pdf.BinaryData);
}
catch (IronPdf.Exceptions.IronPdfRenderException ex)
{
_logger.LogError(ex, "Rendering failed: {Message}", ex.Message);
// Attempt fallback with simpler settings
return await FallbackRender(html);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error in PDF generation");
return Result<byte[]>.Failure($"PDF generation failed: {ex.Message}");
}
}
private async Task<Result<byte[]>> FallbackRender(string html)
{
var fallbackRenderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = false,
DPI = 96,
Timeout = 60
}
};
try
{
var pdf = await fallbackRenderer.RenderHtmlAsPdfAsync(html);
return Result<byte[]>.Success(pdf.BinaryData);
}
catch (Exception ex)
{
return Result<byte[]>.Failure($"Fallback render failed: {ex.Message}");
}
}
}
Public Class RobustPdfGenerator
Private ReadOnly _logger As ILogger(Of RobustPdfGenerator)
Private ReadOnly _renderer As ChromePdfRenderer
Public Async Function TryGeneratePdfAsync(ByVal html As String) As Task(Of Result(Of Byte()))
Try
' Enable detailed logging
IronPdf.Logging.Logger.EnableDebugging = True
IronPdf.Logging.Logger.LogFilePath = "ironpdf.log"
IronPdf.Logging.Logger.LoggingLevel = LoggingLevels.All
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
' Validate output
If pdf.PageCount = 0 Then
Return Result(Of Byte()).Failure("Generated PDF has no pages")
End If
Return Result(Of Byte()).Success(pdf.BinaryData)
Catch ex As IronPdf.Exceptions.IronPdfRenderException
_logger.LogError(ex, "Rendering failed: {Message}", ex.Message)
' Attempt fallback with simpler settings
Return Await FallbackRender(html)
Catch ex As Exception
_logger.LogError(ex, "Unexpected error in PDF generation")
Return Result(Of Byte()).Failure($"PDF generation failed: {ex.Message}")
End Try
End Function
Private Async Function FallbackRender(ByVal html As String) As Task(Of Result(Of Byte()))
Dim fallbackRenderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = False,
.DPI = 96,
.Timeout = 60
}
}
Try
Dim pdf = Await fallbackRenderer.RenderHtmlAsPdfAsync(html)
Return Result(Of Byte()).Success(pdf.BinaryData)
Catch ex As Exception
Return Result(Of Byte()).Failure($"Fallback render failed: {ex.Message}")
End Try
End Function
End Class
行業特定的實施範例
金融服務:監管合規
金融機構要求特定功能以滿足合規要求:
public class FinancialStatementGenerator
{
public async Task<byte[]> GenerateQuarterlyReport(FinancialData data)
{
var renderer = new ChromePdfRenderer();
// Generate report with charts and tables
var html = await BuildFinancialReportHtml(data);
var pdf = renderer.RenderHtmlAsPdf(html);
// Add compliance watermark
pdf.ApplyWatermark(@"
<div style='text-align: center; color: rgba(0,0,0,0.1); font-size: 120px;
transform: rotate(-45deg); font-family: Arial;'>
DRAFT
</div>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Embed audit information
pdf.MetaData.Author = "Financial Reporting System";
pdf.MetaData.Keywords = "Quarterly Report, SOX Compliant";
pdf.MetaData.CustomProperties.Add("ReportPeriod", data.Quarter);
pdf.MetaData.CustomProperties.Add("GeneratedBy", Environment.UserName);
pdf.MetaData.CustomProperties.Add("Timestamp", DateTime.UtcNow.ToString("O"));
// Apply tamper-evident signature
var cert = new X509Certificate2("financial-cert.pfx", "password");
var signature = new PdfSignature(cert)
{
SigningReason = "Financial Report Certification",
SigningLocation = "Corporate Finance Department",
IsVisible = true,
SignatureImage = new PdfSignatureImage("cfo-signature.png")
};
pdf.Sign(signature);
// Lock document from editing
pdf.SecuritySettings = new SecuritySettings
{
AllowModifyDocument = false,
AllowCopy = true,
AllowPrint = true,
EncryptionLevel = EncryptionLevel.AES256Bit
};
return pdf.BinaryData;
}
}
public class FinancialStatementGenerator
{
public async Task<byte[]> GenerateQuarterlyReport(FinancialData data)
{
var renderer = new ChromePdfRenderer();
// Generate report with charts and tables
var html = await BuildFinancialReportHtml(data);
var pdf = renderer.RenderHtmlAsPdf(html);
// Add compliance watermark
pdf.ApplyWatermark(@"
<div style='text-align: center; color: rgba(0,0,0,0.1); font-size: 120px;
transform: rotate(-45deg); font-family: Arial;'>
DRAFT
</div>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Embed audit information
pdf.MetaData.Author = "Financial Reporting System";
pdf.MetaData.Keywords = "Quarterly Report, SOX Compliant";
pdf.MetaData.CustomProperties.Add("ReportPeriod", data.Quarter);
pdf.MetaData.CustomProperties.Add("GeneratedBy", Environment.UserName);
pdf.MetaData.CustomProperties.Add("Timestamp", DateTime.UtcNow.ToString("O"));
// Apply tamper-evident signature
var cert = new X509Certificate2("financial-cert.pfx", "password");
var signature = new PdfSignature(cert)
{
SigningReason = "Financial Report Certification",
SigningLocation = "Corporate Finance Department",
IsVisible = true,
SignatureImage = new PdfSignatureImage("cfo-signature.png")
};
pdf.Sign(signature);
// Lock document from editing
pdf.SecuritySettings = new SecuritySettings
{
AllowModifyDocument = false,
AllowCopy = true,
AllowPrint = true,
EncryptionLevel = EncryptionLevel.AES256Bit
};
return pdf.BinaryData;
}
}
Public Class FinancialStatementGenerator
Public Async Function GenerateQuarterlyReport(ByVal data As FinancialData) As Task(Of Byte())
Dim renderer = New ChromePdfRenderer()
' Generate report with charts and tables
Dim html = Await BuildFinancialReportHtml(data)
Dim pdf = renderer.RenderHtmlAsPdf(html)
' Add compliance watermark
pdf.ApplyWatermark("
<div style='text-align: center; color: rgba(0,0,0,0.1); font-size: 120px;
transform: rotate(-45deg); font-family: Arial;'>
DRAFT
</div>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center)
' Embed audit information
pdf.MetaData.Author = "Financial Reporting System"
pdf.MetaData.Keywords = "Quarterly Report, SOX Compliant"
pdf.MetaData.CustomProperties.Add("ReportPeriod", data.Quarter)
pdf.MetaData.CustomProperties.Add("GeneratedBy", Environment.UserName)
pdf.MetaData.CustomProperties.Add("Timestamp", DateTime.UtcNow.ToString("O"))
' Apply tamper-evident signature
Dim cert = New X509Certificate2("financial-cert.pfx", "password")
Dim signature = New PdfSignature(cert) With {
.SigningReason = "Financial Report Certification",
.SigningLocation = "Corporate Finance Department",
.IsVisible = True,
.SignatureImage = New PdfSignatureImage("cfo-signature.png")
}
pdf.Sign(signature)
' Lock document from editing
pdf.SecuritySettings = New SecuritySettings With {
.AllowModifyDocument = False,
.AllowCopy = True,
.AllowPrint = True,
.EncryptionLevel = EncryptionLevel.AES256Bit
}
Return pdf.BinaryData
End Function
End Class
電子商務:動態發票生成
電子商務平台需要快速、可靠的發票生成:
public class EcommerceInvoiceService
{
private readonly ChromePdfRenderer _renderer;
public EcommerceInvoiceService()
{
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
MarginTop = 10,
MarginBottom = 10,
PaperSize = PdfPaperSize.A4,
DPI = 200 // High quality for barcodes
}
};
}
public async Task<byte[]> GenerateInvoice(Order order)
{
// Build invoice HTML with order details
var html = $@"
<html>
<head>
<style>
@page {{size: A4; margin: 0;}}
body {{font-family: Arial, sans-serif;}}
.invoice-header {{background: #f0f0f0; padding: 20px;}}
.barcode {{text-align: center; margin: 20px 0;}}
table {{width: 100%; border-collapse: collapse;}}
th, td {{padding: 10px; border-bottom: 1px solid #ddd;}}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{order.InvoiceNumber}</h1>
<p>Date: {order.Date:yyyy-MM-dd}</p>
</div>
<div class='barcode'>
<img src='data:image/png;base64,{GenerateBarcode(order.InvoiceNumber)}' />
</div>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
{string.Join("", order.Items.Select(item => $@"
<tr>
<td>{item.Name}</td>
<td>{item.Quantity}</td>
<td>${item.Price:F2}</td>
<td>${item.Total:F2}</td>
</tr>"))}
<tr>
<td colspan='3'><strong>Total</strong></td>
<td><strong>${order.Total:F2}</strong></td>
</tr>
</table>
<div class='footer'>
<p>Thank you for your business!</p>
<p>Return policy and terms at: www.example.com/terms</p>
</div>
</body>
</html>";
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Add QR code for mobile payment verification
var qrStamper = new ImageStamper($"https://api.qrserver.com/v1/create-qr-code/?data={order.PaymentId}")
{
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Bottom,
Width = 100,
Height = 100
};
pdf.ApplyStamp(qrStamper);
return pdf.BinaryData;
}
}
public class EcommerceInvoiceService
{
private readonly ChromePdfRenderer _renderer;
public EcommerceInvoiceService()
{
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
MarginTop = 10,
MarginBottom = 10,
PaperSize = PdfPaperSize.A4,
DPI = 200 // High quality for barcodes
}
};
}
public async Task<byte[]> GenerateInvoice(Order order)
{
// Build invoice HTML with order details
var html = $@"
<html>
<head>
<style>
@page {{size: A4; margin: 0;}}
body {{font-family: Arial, sans-serif;}}
.invoice-header {{background: #f0f0f0; padding: 20px;}}
.barcode {{text-align: center; margin: 20px 0;}}
table {{width: 100%; border-collapse: collapse;}}
th, td {{padding: 10px; border-bottom: 1px solid #ddd;}}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{order.InvoiceNumber}</h1>
<p>Date: {order.Date:yyyy-MM-dd}</p>
</div>
<div class='barcode'>
<img src='data:image/png;base64,{GenerateBarcode(order.InvoiceNumber)}' />
</div>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
{string.Join("", order.Items.Select(item => $@"
<tr>
<td>{item.Name}</td>
<td>{item.Quantity}</td>
<td>${item.Price:F2}</td>
<td>${item.Total:F2}</td>
</tr>"))}
<tr>
<td colspan='3'><strong>Total</strong></td>
<td><strong>${order.Total:F2}</strong></td>
</tr>
</table>
<div class='footer'>
<p>Thank you for your business!</p>
<p>Return policy and terms at: www.example.com/terms</p>
</div>
</body>
</html>";
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
// Add QR code for mobile payment verification
var qrStamper = new ImageStamper($"https://api.qrserver.com/v1/create-qr-code/?data={order.PaymentId}")
{
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Bottom,
Width = 100,
Height = 100
};
pdf.ApplyStamp(qrStamper);
return pdf.BinaryData;
}
}
Imports System.Threading.Tasks
Public Class EcommerceInvoiceService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.MarginTop = 10,
.MarginBottom = 10,
.PaperSize = PdfPaperSize.A4,
.DPI = 200 ' High quality for barcodes
}
}
End Sub
Public Async Function GenerateInvoice(order As Order) As Task(Of Byte())
' Build invoice HTML with order details
Dim html As String = $"
<html>
<head>
<style>
@page {{size: A4; margin: 0;}}
body {{font-family: Arial, sans-serif;}}
.invoice-header {{background: #f0f0f0; padding: 20px;}}
.barcode {{text-align: center; margin: 20px 0;}}
table {{width: 100%; border-collapse: collapse;}}
th, td {{padding: 10px; border-bottom: 1px solid #ddd;}}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{order.InvoiceNumber}</h1>
<p>Date: {order.Date:yyyy-MM-dd}</p>
</div>
<div class='barcode'>
<img src='data:image/png;base64,{GenerateBarcode(order.InvoiceNumber)}' />
</div>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
{String.Join("", order.Items.Select(Function(item) $"
<tr>
<td>{item.Name}</td>
<td>{item.Quantity}</td>
<td>${item.Price:F2}</td>
<td>${item.Total:F2}</td>
</tr>"))}
<tr>
<td colspan='3'><strong>Total</strong></td>
<td><strong>${order.Total:F2}</strong></td>
</tr>
</table>
<div class='footer'>
<p>Thank you for your business!</p>
<p>Return policy and terms at: www.example.com/terms</p>
</div>
</body>
</html>"
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
' Add QR code for mobile payment verification
Dim qrStamper = New ImageStamper($"https://api.qrserver.com/v1/create-qr-code/?data={order.PaymentId}") With {
.HorizontalAlignment = HorizontalAlignment.Right,
.VerticalAlignment = VerticalAlignment.Bottom,
.Width = 100,
.Height = 100
}
pdf.ApplyStamp(qrStamper)
Return pdf.BinaryData
End Function
End Class
遷移策略:在程式庫間轉換
如果您正在考慮在程式庫間切換,這是一種遷移方法:
從EvoPdf遷移到IronPDF
// EvoPdf pattern
HtmlToPdfConverter evoPdfConverter = new HtmlToPdfConverter();
evoPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
byte[] pdfBytes = evoPdfConverter.ConvertUrl(url);
// Equivalent IronPDF pattern
var ironPdfRenderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
PaperSize = PdfPaperSize.A4
}
};
var pdf = ironPdfRenderer.RenderUrlAsPdf(url);
byte[] pdfBytes = pdf.BinaryData;
// Migration wrapper for gradual transition
public interface IPdfConverter
{
byte[] ConvertHtmlToPdf(string html);
byte[] ConvertUrlToPdf(string url);
}
public class IronPdfAdapter : IPdfConverter
{
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] ConvertHtmlToPdf(string html)
{
return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
public byte[] ConvertUrlToPdf(string url)
{
return _renderer.RenderUrlAsPdf(url).BinaryData;
}
}
public class EvoPdfAdapter : IPdfConverter
{
private readonly HtmlToPdfConverter _converter = new HtmlToPdfConverter();
public byte[] ConvertHtmlToPdf(string html)
{
return _converter.ConvertHtml(html, "");
}
public byte[] ConvertUrlToPdf(string url)
{
return _converter.ConvertUrl(url);
}
}
// EvoPdf pattern
HtmlToPdfConverter evoPdfConverter = new HtmlToPdfConverter();
evoPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
byte[] pdfBytes = evoPdfConverter.ConvertUrl(url);
// Equivalent IronPDF pattern
var ironPdfRenderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
PaperSize = PdfPaperSize.A4
}
};
var pdf = ironPdfRenderer.RenderUrlAsPdf(url);
byte[] pdfBytes = pdf.BinaryData;
// Migration wrapper for gradual transition
public interface IPdfConverter
{
byte[] ConvertHtmlToPdf(string html);
byte[] ConvertUrlToPdf(string url);
}
public class IronPdfAdapter : IPdfConverter
{
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] ConvertHtmlToPdf(string html)
{
return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
public byte[] ConvertUrlToPdf(string url)
{
return _renderer.RenderUrlAsPdf(url).BinaryData;
}
}
public class EvoPdfAdapter : IPdfConverter
{
private readonly HtmlToPdfConverter _converter = new HtmlToPdfConverter();
public byte[] ConvertHtmlToPdf(string html)
{
return _converter.ConvertHtml(html, "");
}
public byte[] ConvertUrlToPdf(string url)
{
return _converter.ConvertUrl(url);
}
}
' EvoPdf pattern
Dim evoPdfConverter As New HtmlToPdfConverter()
evoPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
Dim pdfBytes() As Byte = evoPdfConverter.ConvertUrl(url)
' Equivalent IronPDF pattern
Dim ironPdfRenderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {.PaperSize = PdfPaperSize.A4}
}
Dim pdf = ironPdfRenderer.RenderUrlAsPdf(url)
Dim pdfBytes() As Byte = pdf.BinaryData
' Migration wrapper for gradual transition
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'public interface IPdfConverter
'{
' byte[] ConvertHtmlToPdf(string html);
' byte[] ConvertUrlToPdf(string url);
'}
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'public class IronPdfAdapter : IPdfConverter
'{
' private readonly ChromePdfRenderer _renderer = New ChromePdfRenderer();
'
' public byte[] ConvertHtmlToPdf(string html)
' {
' Return _renderer.RenderHtmlAsPdf(html).BinaryData;
' }
'
' public byte[] ConvertUrlToPdf(string url)
' {
' Return _renderer.RenderUrlAsPdf(url).BinaryData;
' }
'}
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'public class EvoPdfAdapter : IPdfConverter
'{
' private readonly HtmlToPdfConverter _converter = New HtmlToPdfConverter();
'
' public byte[] ConvertHtmlToPdf(string html)
' {
' Return _converter.ConvertHtml(html, "");
' }
'
' public byte[] ConvertUrlToPdf(string url)
' {
' Return _converter.ConvertUrl(url);
' }
'}
結論:為您的專案選擇正確的方案
無論IronPDF還是EvoPdf在.NET PDF程式庫生態系統中都具有重要作用,但它們面向不同的使用案例和開發理念。
在您需要以下情況時選擇IronPDF:
- 現代網頁標準支持(CSS3, JavaScript 框架)
- 超越生成的全面PDF操作
- 企業安全功能和合規工具
- 跨平台部署靈活性
- 詳盡的文件和直接工程支援
- 與其他文件處理工具的整合
在您需要以下情況時選擇EvoPdf:
- 低成本的簡單HTML到PDF轉換
- 用於簡單文件的基本PDF生成
- 適合大型團隊的無限開發人員授權
- 更快地處理簡單HTML內容
- 以Windows為中心的部署環境
最終的決定取決於您的具體要求、預算限制和長期擴展需求。 對於大多數需要強大 PDF 功能的現代應用,IronPDF 的綜合功能集和基於Chrome的渲染引擎使其成為一項強勁的投資。 然而,對於成本是主要考慮因素的簡單用例,EvoPdf仍然是一個可行的選擇。
考慮從30天免費試用 IronPDF 開始,評估其在您的具體用例中的能力。 試用版提供IronPDF功能存取,允許您根據實際性能在環境中做出明智的決策。
請記住,PDF程式庫的實際花費超出了授權價格 - 計算開發時間、維護成本和隨著應用成長可能需要的其他功能。 選擇不僅能滿足您當前需求的程式庫,還能隨著您的未來需求擴展。
[[i:(EvoPdf是其各自所有者的註冊商標。 本網站與EvoPdf無關、未經其認可或贊助。 所有產品名稱、徽標和品牌均為其各自所有者的財產。 比較僅供資訊參考,並反映了撰寫時的公開可用資訊。)]]
常見問題
如何使用 .NET 程式庫在 C# 中將 HTML 轉換為 PDF?
您可以使用IronPDF的RenderHtmlAsPdf方法將HTML字串轉換成PDF。也可以使用RenderHtmlFileAsPdf將HTML文件轉換為PDF。
處理複雜的 JavaScript 和 CSS 的最佳 .NET PDF 程式庫是什麼?
IronPDF 是處理複雜 JavaScript 和 CSS 的最佳選擇,因為它使用完整的 Chrome V8 渲染引擎,提供超過 98% 的瀏覽器保真度,並支持如 React 和 Angular 等現代框架。
哪個 .NET PDF 程式庫提供更好的跨平台支持?
IronPDF 提供卓越的跨平台支持,具有原生相容於 Windows、Linux、macOS 和 Docker 容器的特性,允許零配置部署。
IronPDF 在安全性和合規性上的主要功能有哪些?
IronPDF 提供全面的安全功能,包括 AES-256 加密、超過 15 種細緻的權限設置、視覺電子簽名和使用 RedactTextOnAllPages() 方法進行真正的內容遮掩。
如何高效地在 .NET 中進行批次 PDF 處理?
IronPDF 在批次 PDF 處理方面表現出色,提供原生的 async/await 優化及更好的記憶體管理,使其適合高效地處理大型文件。
哪個程式庫為開發人員提供更好的支持和文件?
IronPDF 提供廣泛的支持和文件,包括 24/5 的工程支持、全面的 API 文件、超過 100 個程式碼範例和影片教學,顯著縮短開發時間。
我可以使用 .NET 程式庫將 DOCX 文件轉換為 PDF 嗎?
可以,IronPDF 包含內建的 DOCX 到 PDF 轉換功能,通過其 DocxToPdfRenderer 類允許您在保持格式的同時轉換 Word 文件。
using IronPDF 在現代網路應用程式中的優點是什麼?
IronPDF 是現代網路應用程式的理想選擇,因為它的基於 Chrome 的渲染引擎、全面的 PDF 操作功能和跨平台相容性,使其適合於動態內容生成和複雜文件處理。
IronPDF 如何處理合規性要求的 PDF 遮掩?
IronPDF 提供全面的遮掩功能,包括基於正則表達式的內容移除和基於 OCR 的遮掩,確保符合 GDPR、HIPAA 等隱私法規。
IronPDF 為何是 SaaS 和電子商務平台的好選擇?
IronPDF 適合於 SaaS 和電子商務平台,因為它可以生成動態發票、支持數位簽名,並提供與現代網頁技術的無縫整合。



