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:減少 60% 的程式碼 | |
| 學習曲線 | 一般需時 1-2 天 | 一般需時 3-5 天 | IronPDF:快速採用 | |
| 平台支援 | 跨平台 | 原生支援,無需額外設定 | 需要特定平台的設定 | IronPDF:更簡單的部署 |
| .NET 版本 | .NET 10、9、8、7、6、5、Core 3.1 以上、Framework 4.6.2 以上 | .NET 8、7、6、5、Standard 2.0+、Framework 4.0+ | 兩者:現代框架支援 | |
| 操作系統 | Windows、Linux、macOS、Docker 本機 | Windows、Linux、macOS、Azure | IronPDF:Docker 最佳化 | |
| HTML至PDF | 渲染引擎 | 完整的 Chrome V8 引擎 | 自訂 HTML 渲染引擎 | IronPDF:98% 以上的瀏覽器逼真度 |
| 支援 CSS3/HTML5 | 完整支援 | 良好的支援 (90% 的覆蓋率) | IronPDF:現代網路標準 | |
| JavaScript 執行 | 完整的 JavaScript 支援與等待 | 良好的 JavaScript 支援 | IronPDF:動態內容就緒 | |
| 渲染速度 | 1.2-1.8s 典型值(複雜頁面) | 0.8-1.2s 典型 | EvoPdf:更快地處理簡單的 HTML | |
| Security & Encryption | 加密等級 | AES-256、自訂處理器 | AES-256 標準 | 兩者:行業標準 |
| 許可權選項 | 15+ 粒度權限 | 8 個標準權限 | IronPDF:更精細的控制 | |
| 數位簽名 | 整合、可視化的簽名 | 基本簽名支援 | IronPDF:更簡單的簽名 | |
| 內容處理 | 重製方法 | 真正的內容移除,單行 API | 無內建刪節 | IronPDF:合規就緒 |
| 添加水印 | 基於 HTML/CSS,完全造型 | 基於模板的水印 | IronPDF:豐富的水印 | |
| 蓋章 | 統一的 stamper 類別 | 與水印功能相同 | IronPDF:專用工具 | |
| 檔案轉換 | DOCX 到 PDF | 內建 DocxToPdfRenderer |
需要 Evo Word to PDF ($450)+) | IronPDF:無額外費用 |
| 開發人員經驗 | 代碼範例 | 100+ 個可立即執行的範例 | 50+ 個範例 | IronPDF:廣泛的資源 |
| 文件 | 教學、操作方法、影片、API 參考 | API 文件和範例 | IronPDF:多種學習途徑 | |
| 錯誤訊息 | 描述性、可操作性 | 標準錯誤報告 | IronPDF:更好的除錯 | |
| 效能指標 | 大型文件處理 | 1000 頁/分鐘水印 | 700 頁/分鐘水印 | IronPDF:速度快 30 |
| 線程支援 | 原生 async/await 最佳化 | 支援多執行緒 | IronPDF:更好的可擴展性 | |
| Licensing & Pricing | 入門級 | Lite: $999 (1 dev, 1 project) | 部署:450 美元(1 台伺服器、1 個應用程式) | EvoPdf:較低的初始成本 |
| Team License | Plus: $1,499 (3 位開發人員、3 個專案) | 公司:$1,200(不限開發人員) | EvoPdf:更適合大型團隊 | |
| 再發行 | +$1,999 免版稅 | 包含在公司授權內 | EvoPdf:內建再發行功能 | |
| 套件選項 | Iron Suite: $1,498 (9 products) | EVO PDF 工具包:1400 美元 | IronPDF:包含更多產品 | |
| <強>支援強 | 支援包括 | 是,24/5 工程支援 | 是,第一年標準支援 | IronPDF:直接工程存取 |
| 最適合 | 用例 | 現代網路應用程式、複雜的 PDF、合規性 | 簡單的 HTML 至 PDF,基本轉換 | 依據上下文 |
瞭解 IronPDF 和 EvoPdf:核心優勢和理念。
是什麼讓 IronPDF 在 .NET PDF Library 市場中脫穎而出?
IronPDF是以開發人員生產力為核心設計的全面 PDF 解決方案。 IronPDF 建立在簡單而不失功能的基礎上,可讓 .NET 開發人員使用直觀的 API 來建立、編輯和處理 PDF 文件,這些 API 反映了熟悉的 Web 開發模式。 該函式庫的突出特色是其基於 Chrome 的渲染引擎,可確保像素完美的 HTML 至 PDF 轉換,同時支援最新的網頁標準,包括 CSS3、JavaScript 框架和網頁字體。
該函式庫在需要高保真文件渲染、複雜 PDF 操作和企業級安全功能的場合中表現優異。 其廣泛的功能集不僅包括基本的 PDF 生成,還包括數位簽名、表格填寫、透過IronOCR 進行 OCR 整合以及無縫文件格式轉換等進階功能。 IronPDF 的跨平台相容性超越了簡單的框架支援,可在 Windows、Linux、macOS、Docker containers 以及 Azure 和 AWS 等雲端平台上提供原生效能。
EvoPdf 如何以不同的方式生成 PDF?
EvoPdf 採用較傳統的 PDF 操作方式,主要著重於 HTML 至 PDF 的轉換,並強調客製化和控制。 這個函式庫提供開發人員對轉換過程的細部控制,允許對呈現參數、頁面佈局和轉換設定進行微調。 EvoPdf 的架構是圍繞提供可靠、一致的標準網頁轉換為 PDF 的結果而建立的。
EvoPdf 的特別之處在於它輕巧的佔用空間和對簡單 HTML 文件更快的渲染速度。 對於沒有複雜 JavaScript 或 CSS3 功能的簡單 HTML 頁面,EvoPdf 通常可在 0.8-1.2 秒內完成轉換,適合大批量處理簡單文件。 該函式庫也對 ASP.NET 環境中的伺服器端渲染提供良好支援,並針對 Web 應用程式情境進行最佳化。
<!-- 建議:在此添加可視化圖表,顯示 IronPDF 基於 Chrome 的引擎與 EvoPdf 自訂渲染方式之間的架構差異 -->
不同程式庫的跨平台能力如何比較?
IronPDF 的現代跨平台架構
IronPDF 提供無縫的跨平台相容性,超越簡單的框架支援。 該函式庫可在下列語言間原生運作:.NET、Java、Python 或 Node.js
-
.NET版本支援:
- .NET 10、9、8、7、6、5 和 Core 3.1+
- .NET 標準 2.0+
- .NET Framework 4.6.2+
- 完全支援 C#、VB.NET 和 F#
-
作業系統相容性:
- Windows(x86、x64、ARM)
- Linux (Ubuntu、Debian、CentOS、Alpine)
- macOS (Intel 和 Apple Silicon)
- 具有預先設定影像的 Docker 容器
- 雲端平台整合:
- Azure 應用程式服務、功能和虛擬機器
- AWS Lambda 和 EC2
- Google 雲端平台
- Kubernetes 部署
IronPDF 的與眾不同之處在於其零組態部署模式。 與許多需要額外依賴或執行時安裝的 PDF 函式庫不同,IronPDF 在 NuGet 套件中包含所有必要的元件。 這種自成一格的方法可大幅降低部署的複雜性,並消除常見的"在我的機器上也能運作"問題。
EvoPdf 的平台要求和限制
EvoPdf 支援類似的 .NET 版本,但在跨平台的情況下需要更仔細的設定:
-
.NET Framework 支援:
- .NET 8、7、6 和 5
- .NET 標準 2.0+
- .NET Framework 4.8.1、4.7.2、4.6.1 和 4.0+
- 平台考慮因素:
- 主要優化 Windows 環境
- Linux 支援需要額外的設定
- 透過 .NET Core 支援 macOS
- 雲端部署需要特定平台的調整
對於跨平台部署,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 媒體查詢以優化列印效果 -支援高解析度:產生 300 DPI 的可列印 PDF 文件 -自動佈局:智慧地將內容適應頁面邊界
EvoPdf HTML to 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 的安全實作提供了企業級的功能:
- 15+ 個細粒度權限:精確控制使用者可以執行的操作 -可視化數位簽章:包含簽名影像和時間戳 -元資料保護:保護文件屬性和稽核追蹤 -多層安全防護:結合加密、簽名和浮水印
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 Redaction 示例
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 的編輯功能包括:
-真正的內容移除:永久移除文本,而不僅僅是覆蓋它。 -模式識別:支援對社保號碼、信用卡號碼、電子郵件地址進行正規表示式識別 -可視化編輯樣式:可自訂審計追蹤的外觀
- OCR整合:對掃描文件中的文字進行文字識別 選擇性編輯:針對特定頁面或區域
EvoPdf 不包含內建刪節功能,對於需要符合隱私權規定的應用程式而言,這可能是一大限制。
<!-- 建議:添加一個可視化示例,顯示編輯前/後的結果 -->
表單處理:建立互動式 PDFs
兩個函式庫都支援 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速度提升30-40%(0.8秒對比1.2秒) -複雜的 JavaScript: IronPDF 更可靠,EvoPDF 可能會失敗 -大量處理: IronPDF 更佳的平行化能力 記憶體使用: EvoPDF 的基線較低,IronPDF 的垃圾回收機制較好。 -大型文件: IronPDF 處理 1000 頁以上的文件速度提升 30%。
不同團隊規模的定價模式如何比較?
IronPDF 授權結構
IronPDF 提供多種定價選擇,包括 Lite、Plus 和 Professional License,並可選擇免版稅再發行。 Team License 的授權模式可根據您的團隊和專案需求調整(定價截至 2025 年):
*精簡版許可證:$999
- 1 名開發人員
- 1 位置
- 1 個專案
- 電子郵件支援
- 最適合個別開發人員、小型專案
- Plus 許可證:$1,499
- 3 名開發人員
- 3 個地點
- 3 個專案
- 電子郵件、聊天和電話支援
- 最適合小型團隊、多個專案
*專業許可證:$2,999
- 10 位開發人員
- 10 個地點
- 10 個專案
- 優先支援與螢幕分享
- 最適合中大型團隊
- 其他選項:
- 免版稅再分發:+$2,999
- 5 年支援與更新:1,999美元(或999美元/年)
- Iron Suite :$1,498,適用於所有 9 款 Iron Software 產品
EvoPdf 授權選項
EVO PDF Toolkit 部署版售價 650 美元,公司版售價 1400 美元,而獨立的 HTML 至 PDF 轉換器部署版售價 450 美元,公司版售價 1200 美元:
-
部署授權:
- EVO HTML 至 PDF:$450
- EVO PDF 工具包:650 美元
- 單一伺服器、單一應用程式
- 不可再散布
- 第一年標準支援
- 公司授權:
- EVO HTML 至 PDF:$1,200
- EVO PDF 工具包:1400 美元
- 不限開發人員
- 無限制部署
- 完整的再發行權利
- 第一年優先支援
總擁有成本分析
讓我們檢視真實世界的情境,瞭解真正的成本影響:
情況 1:有 2 位開發人員的初創公司
- IronPDF Lite:$999(需 2 張許可證 = $1,498)
- EvoPdf 公司:1,200 美元(涵蓋無限名開發人員) -優勝者: EvoPdf,初始成本最低
情況 2:成長中的團隊(5 位開發人員,多個專案)
- IronPDF Plus:$1,499(最多支援 3 位開發人員,需專業版)
- IronPDF 專業版:$2,999
- EvoPdf 公司: $1,200 -優勝者: EvoPdf,團隊擴展能力方面
情境 3:需要多種 PDF 工具的企業
- IronPDF Professional + IronOCR + IronBarcode:~$9,000
- Iron Suite:$1,498(全部 9 款產品)
- EvoPdf 工具包 + 附加工具:每個工具 1,400 美元以上 -優勝者: Iron Suite,滿足全面需求
情境 4:具有再發行功能的 SaaS 產品
IronPDF 專業版 + 發行許可:4,998 美元
- 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 作為使用者介面,並且需要產生與 Web 介面相符的報告或文檔,IronPDF 的無縫渲染功能可以顯著節省開發時間。而 EvoPdf 可能需要您專門為 PDF 產生建立單獨的、簡化的範本版本。
有關 CSS 架構相容性的全面資訊,請參閱 Bootstrap & Flexbox CSS 指南。
哪些文件和支援選項能更好地為開發人員服務?
IronPDF 的開發人員資源
IronPDF 提供全面的說明文件、24/5 工程師支援、視訊教學、社群論壇以及定期更新。 支援生態系統包括
-
文件品質:
- 綜合 API Reference
- 逐步教學。
- 100+ 程式碼範例。
- YouTube上的視訊教學。
- 其他程式庫的遷移指南
-
支援管道:
- 24/5 工程支援(直接與開發人員接洽)
- 回應時間:一般為 24-48 小時
- Plus License 的即時交談
- Professional License 的電話支援
- 複雜問題的螢幕分享
- 社群論壇和 Stack Overflow 的存在
- 學習資源:
- 入門指南
- 架構文件
- 效能最佳化指南
- 安全最佳實務
- 雲端部署指南
EvoPdf的支援架構
EvoPdf 透過以下方式提供文件與支援:
-
文件:
- API 參考文件
- 常見情況的程式碼範例
- 網站的即時示範部分
- 基本故障排除指南
- 支援選項:
- 電子郵件和電話支援(含第一年)
- 標準與優先支援層級
- 提供社群協助的支援論壇
- 第一年後需續約
與眾不同的關鍵在於 IronPDF 在教育內容和直接工程支援上的投資,可大幅降低學習曲線和故障排除時間。
<!-- 建議:添加截圖,顯示 IronPDF 文檔佈局與 EvoPdf 文檔的對比 -->
每個函式庫的最佳使用案例為何?
何時選擇 IronPDF?
IronPDF 擅長處理下列需求:
1.現代 Web 應用程式整合
- 生成動態報告的 SaaS 平台
- 電子商務網站使用圖表建立發票
- 輸出為 PDF 的商業智慧儀表板
- 使用 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.注重預算的團隊
- 單一 License 可供無限開發人員使用
- 基本功能的入門成本較低
- 不需要進階 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;
}
}
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
}
}
End Sub
Public Async Function GenerateInvoice(ByVal order As Order) As Task(Of Byte())
' Build invoice HTML with order details
, order.InvoiceNumbstring.Format(r, order.Date, GenerateBarcode(order.InvoiceNumber), String.Join(TangibleTempVerbatimDoubleQuote, order.Items.Select(Function(item) $TangibleTempVerbatimCloseTag"ignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignore<tr><td>{item.Name}</td><td>{item.Quantity}</td><td>${item.Price:F2}</td><td>${item.Total:F2}</td></tr>")), TangibleStringInterpolationMarker) var html = $"TangibleTempVerbatimOpenTagTangibleTempVerbatimStringLiteralLineJoin <html>TangibleTempVerbatimStringLiteralLineJoin <head>TangibleTempVerbatimStringLiteralLineJoin <style>TangibleTempVerbatimStringLiteralLineJoin @page {{ size: A4; margin: 0; }}TangibleTempVerbatimStringLiteralLineJoin body {{ font-family: Arial, sans-serif; }}TangibleTempVerbatimStringLiteralLineJoin .invoice-header {{ background: #f0f0f0; padding: 20px; }}TangibleTempVerbatimStringLiteralLineJoin .barcode {{ text-align: center; margin: 20px 0; }}TangibleTempVerbatimStringLiteralLineJoin table {{ width: 100%; border-collapse: collapse; }}TangibleTempVerbatimStringLiteralLineJoin th, td {{ padding: 10px; border-bottom: 1px solid #ddd; }}TangibleTempVerbatimStringLiteralLineJoin </style>TangibleTempVerbatimStringLiteralLineJoin </head>TangibleTempVerbatimStringLiteralLineJoin <body>TangibleTempVerbatimStringLiteralLineJoin <div class='invoice-header'>TangibleTempVerbatimStringLiteralLineJoin <h1>Invoice #{0}</h1>TangibleTempVerbatimStringLiteralLineJoin <p>Date: {1:yyyy-MM-dd}</p>TangibleTempVerbatimStringLiteralLineJoin </div>TangibleTempVerbatimStringLiteralLineJoinTangibleTempVerbatimStringLiteralLineJoin <div class='barcode'>TangibleTempVerbatimStringLiteralLineJoin <img src='data:image/png;base64,{2}' />TangibleTempVerbatimStringLiteralLineJoin </div>TangibleTempVerbatimStringLiteralLineJoinTangibleTempVerbatimStringLiteralLineJoin <table>TangibleTempVerbatimStringLiteralLineJoin <tr>TangibleTempVerbatimStringLiteralLineJoin <th>Item</th>TangibleTempVerbatimStringLiteralLineJoin <th>Quantity</th>TangibleTempVerbatimStringLiteralLineJoin <th>Price</th>TangibleTempVerbatimStringLiteralLineJoin <th>Total</th>TangibleTempVerbatimStringLiteralLineJoin </tr>TangibleTempVerbatimStringLiteralLineJoin {3}ignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignoreignore<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
- 適用於大型團隊的無限制開發人員 License
- 更快速地處理簡單的 HTML 內容
- 以 Windows 為中心的部署環境
最終的決定取決於您的特定需求、預算限制以及長期的擴充性需求。 對於需要強大 PDF 功能的大多數現代應用程式而言,IronPDF 的全面功能集和優異的渲染引擎證明了投資的合理性。 然而,EvoPdf 對於以成本為主要考量的簡單使用個案而言,仍是一個可行的選擇。
Consider starting with the 30-day free trial of IronPDF to evaluate its capabilities in your specific use case. 試用版包含所有功能,沒有任何限制,讓您可以根據環境中的實際效能做出明智的決定。
請記住,PDF 函式庫的真正成本不只是授權價格,還包括開發時間、維護開銷,以及應用程式成長時對附加功能的潛在需求。 選擇不僅能滿足您目前需求,還能隨著未來需求擴充的函式庫。
常見問題解答
如何使用.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通過提供本地async/await優化和更佳的內存管理,擅長批處理PDF處理,適合高效處理大型文檔。
哪個庫為開發者提供更好的支持和文檔?
IronPDF提供廣泛的支持和文檔,包括24/5的工程支持、全面的API文檔、100多個代碼示例和視頻教程,顯著縮短開發時間。
我可以使用.NET庫將DOCX文件轉換為PDF嗎?
可以,IronPDF通過其DocxToPdfRenderer類包含內置的DOCX到PDF轉換,允許您在保留格式的情況下轉換Word文檔。
使用IronPDF對於現代Web應用程序有什麼優勢?
IronPDF由於其基於Chrome的渲染引擎、全面的PDF操作功能和跨平台兼容性,適合現代Web應用程序,適用於動態內容生成和複雜文檔處理。
IronPDF如何處理PDF遮罩以滿足合規要求?
IronPDF提供全面的遮罩能力,包括基於正則表達式的內容移除和基於OCR的遮罩,確保符合GDPR和HIPAA等隱私法規。
IronPDF為什麼適合SaaS和電子商務平台?
IronPDF非常適合SaaS和電子商務平台,因為其能生成動態發票,支持數字簽名,並與現代Web技術無縫集成。

