如何在 PDF 上畫線和矩形
Adobe PDF Library SDK (APDFL) 由 Adobe 提供授權,並由 Datalogics 分發,與 Acrobat 引擎共享核心源程式碼。它功能強大,但其以銷售為主導的定價模式、本機運行時佔用、缺乏內建HTML到PDF的渲染器,以及低層次API設計導致許多.NET團隊尋求替代方案。 本指南提供從Adobe PDF Library SDK遷移到IronPDF的逐步遷移路徑——這是一個現代的.NET PDF 程式庫,支持從.NET Framework 4.6.2 到.NET 9。
為什麼考慮遠離 Adobe PDF Library SDK?
儘管 APDFL 提供 derives 自 Acrobat 的 PDF 引擎,但幾個因素導致開發團隊探索 HTML 到 PDF、文件操作和報表生成的替代方案。
銷售主導,量身定制定價
Datalogics 不發布 APDFL 的列表定價。 根據 Datalogics 的定價頁面,內部使用計劃約為每年 $5,999,OEM、ISV 和 SaaS 部署在平台費用上談判增加版稅或收入分成。總成本通常超出小型到中型團隊的承受能力,幾乎總是需要銷售對話。
複雜的原生 SDK 整合
APDFL 包裝一個原生 C/C++ 引擎,這與 Acrobat 共享起源。 .NET 綁定 (Datalogics.PDFL) 需要特定平台的運行時二進製文件——Adobe.PDF.Library.LM.NET NuGet 包裝船隻 x64 Windows、Linux 和 macOS ARM 負載——謹慎的記憶體管理,以及每個入口點上的明確 Library 生命週期。 這增加了開發的負擔並複雜化了 CI/CD 管道。
沒有內建的 HTML 渲染器
APDFL 的文件轉換列表涵蓋 PDF/A、PDF/X、ZUGFeRD、EPS、PS、XPS 和 Office 格式,但不包括 HTML。 僅使用 APDFL 的情況下從 HTML 字串生成 PDF 意味著手動構建頁面、字體和內容運行,或者將 APDFL 與單獨的 HTML 渲染引擎配對。
低層次 API 設計
using APDFL 生成 PDF 涉及程式化構建頁面、內容流、文字運行和字體。 像呈現 HTML 字串這樣的簡單任務也變成涉及座標計算、字體嵌入和手動內容元素管理的多步操作。
程式庫生命週期管理負擔
每個入口點都需要在using (var lib = new Library()) 中包裹程式碼(或者配對Library.Terminate() 調用)並小心處理每個在內建立的 PDF 物件的清理。漏掉的清理會產生資源泄漏。
對許多專案來說是過度設置
對於主要需要 HTML 到 PDF 轉換、基本文件操作或報表生成的應用程式,完整的 derives 自 Acrobat 的引擎通常超出工作負荷需求。
Adobe PDF Library SDK與 IronPDF:關鍵區別
理解這些程式庫之間的基本架構差異有助於規劃有效的遷移策略。
| 方面 | Adobe PDF Library SDK | IronPDF |
|---|---|---|
| 定價 | 銷售主導; 內部使用起始約為每年 $5,999,OEM/SaaS 版稅附加 | 透明化每開發者/每部署 |
| 安裝 | Adobe.PDF.Library.LM.NET 隨平台運送本機運行時 |
簡單的NuGet 套件 |
| 文件建立 | 低層次的頁面/內容構建 | HTML/CSS 渲染 |
| HTML 到 PDF | 未內建 | ChromePdfRenderer.RenderHtmlAsPdf |
| 初始化 | using (Library lib = new Library()) 必需 |
自動 |
| 坐標系統 | PostScript 點,左下為原點 | 基於 CSS 的佈局 |
| 字體處理 | 需要手動嵌入 | 自動 |
| 記憶體管理 | 逐一處理每個 PDF 物件 | 標準 IDisposable 模式 |
| 異步支援 | 不可用 | 完全的 async/await 支援 |
遷移前準備
前提條件
確保您的環境滿足這些要求,然後再開始遷移:
- .NET Framework 4.6.2+ or .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ or JetBrains Rider
- NuGet包管理器存取 -IronPDF許可證金鑰(免費試用可在 ironpdf.com 獲得)
審核Adobe PDF Library SDK的使用
在您的解決方案目錄中運行這些命令以識別所有Adobe PDF Library SDK的引用:
grep -r "using Datalogics" --include="*.cs" .
grep -r "Adobe.PDF.Library" --include="*.csproj" .
grep -r "Library.Initialize\|Library.Terminate" --include="*.cs" .
grep -r "using Datalogics" --include="*.cs" .
grep -r "Adobe.PDF.Library" --include="*.csproj" .
grep -r "Library.Initialize\|Library.Terminate" --include="*.cs" .
預期的中斷變更
| 類別 | Adobe PDF Library SDK | IronPDF | 遷移動作 |
|---|---|---|---|
| 初始化 | Library.Initialize() / Terminate() |
自動 | 移除生命週期程式碼 |
| 文件建立 | new Document() 與頁面構建 |
ChromePdfRenderer |
使用 HTML 渲染 |
| 座標系統 | PostScript 點,左下為原點 | 基於 CSS 的佈局 | 使用 HTML/CSS |
| 字體處理 | 手動Font建立和嵌入 |
自動 | 移除字體程式碼 |
| 記憶體管理 | 手動處理 COM 物件 | 標準 IDisposable | 使用using聲明 |
| 頁面構建 | CreatePage(), AddContent() |
從 HTML 自動 | 顯著簡化 |
逐步遷移過程
步驟1:更新NuGet包
移除Adobe PDF Library SDK套件並安裝 IronPDF:
# Remove Adobe PDF Library (.NET 6/7/8 projects)
dotnet remove package Adobe.PDF.Library.LM.NET
# .NET Framework projects use the LM.NETFramework variant
dotnet remove package Adobe.PDF.Library.LM.NETFramework
# Install IronPDF
dotnet add package IronPdf
# Remove Adobe PDF Library (.NET 6/7/8 projects)
dotnet remove package Adobe.PDF.Library.LM.NET
# .NET Framework projects use the LM.NETFramework variant
dotnet remove package Adobe.PDF.Library.LM.NETFramework
# Install IronPDF
dotnet add package IronPdf
步驟 2:配置許可證金鑰
用IronPDF的基於程式碼的授權金鑰替換 Adobe 的授權:
// Replace Adobe's Library.LicenseKey withIronPDFlicense
// Add at application startup, before anyIronPDFoperations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Verify license status
bool isLicensed = IronPdf.License.IsLicensed;
// Replace Adobe's Library.LicenseKey withIronPDFlicense
// Add at application startup, before anyIronPDFoperations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Verify license status
bool isLicensed = IronPdf.License.IsLicensed;
' Replace Adobe's Library.LicenseKey with IronPDF license
' Add at application startup, before any IronPDF operations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
' Verify license status
Dim isLicensed As Boolean = IronPdf.License.IsLicensed
步驟 3:更新命名空間參考
在您的解決方案中執行全域查找和替換:
| 查找 | 替換為 |
|---|---|
using Datalogics.PDFL; |
using IronPdf; |
APDFL 揭示一個根命名空間,Datalogics.PDFL。 Font 和 Color 全是該命名空間內的類,所以只需替換一個 using 指令即可。
步驟 4:移除程式庫生命週期程式碼
最重要的簡化之一是移除初始化和終止模式:
//Adobe PDF Library SDK- REMOVE THIS PATTERN
Library.Initialize();
try
{
// PDF operations
}
finally
{
Library.Terminate(); // Must always terminate
}
//IronPDF- Just use directly
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
//Adobe PDF Library SDK- REMOVE THIS PATTERN
Library.Initialize();
try
{
// PDF operations
}
finally
{
Library.Terminate(); // Must always terminate
}
//IronPDF- Just use directly
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
'Adobe PDF Library SDK- REMOVE THIS PATTERN
Library.Initialize()
Try
' PDF operations
Finally
Library.Terminate() ' Must always terminate
End Try
'IronPDF- Just use directly
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
完整 API 遷移參考
程式庫生命週期方法
| Adobe 方法 | IronPDF等價 |
|---|---|
Library.Initialize() |
不需要 |
Library.Terminate() |
不需要 |
Library.LicenseKey = "KEY" |
IronPdf.License.LicenseKey = "KEY" |
using (Library lib = new Library()) |
不需要 |
文件建立方法
| Adobe 方法 | IronPDF方法 |
|---|---|
new Document() |
new ChromePdfRenderer() |
new Document(path) |
PdfDocument.FromFile(path) |
doc.CreatePage(index, rect) |
從 HTML 自動 |
doc.Save(SaveFlags.Full, path) |
pdf.SaveAs(path) |
doc.NumPages |
pdf.PageCount |
doc.GetPage(index) |
pdf.Pages[index] |
doc.InsertPages(insertAfter, src, start, count, flags) |
PdfDocument.Merge(pdfs) |
內容建立(主要範式轉變)
Adobe PDF Library SDK 需要低層次的內容構建。IronPDF使用 HTML/CSS:
| Adobe 方法 | IronPDF方法 |
|---|---|
new Text() |
使用 HTML <h1> 等 |
text.AddRun(textRun) |
使用 HTML |
new TextRun(text, font, size, point) |
CSS 樣式 |
new Font(name, flags) |
CSS font-family |
new Image(path) |
HTML <img>標籤 |
content.AddElement(...) |
HTML 內容 |
page.UpdateContent() |
不需要 |
水印和安全方法
| Adobe 方法 | IronPDF方法 |
|---|---|
doc.Watermark(textParams, wmParams) |
pdf.ApplyWatermark(html) |
WatermarkParams.Opacity (0.0-1.0) |
opacity 參數 (0-100) 或 CSS opacity |
new EncryptionHandler(user, owner, perms) |
pdf.SecuritySettings |
PermissionFlags.PrintDoc |
AllowUserPrinting |
文字提取
| Adobe 方法 | IronPDF方法 |
|---|---|
new WordFinder(doc, config) |
pdf.ExtractAllText() |
wordFinder.GetWordList() |
pdf.Pages[i].Text |
| 複雜的字/字元遍歷 | 單一方法調用 |
程式碼遷移範例
HTML到PDF轉換
APDFL 沒有內建的 HTML 渲染器。 最接近的一對一功能是手動構建頁面和內容運行來模仿 HTML 文件會產生的佈局 - 或者將 APDFL 與單獨的 HTML 到 PDF 引擎配對。
Adobe PDF Library SDK 實現:
//Adobe PDF Library SDK(Datalogics APDFL)
// NuGet: Adobe.PDF.Library.LM.NET — namespace Datalogics.PDFL
using Datalogics.PDFL;
using System;
class AdobeHtmlToPdf
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document())
{
// US Letter in points (8.5 x 11 inches @ 72 DPI)
Rect pageRect = new Rect(0, 0, 612, 792);
using (Page page = doc.CreatePage(Document.BeforeFirstPage, pageRect))
{
Content content = page.Content;
Font font = new Font("Helvetica", FontCreateFlags.Embedded);
Text text = new Text();
text.AddRun(new TextRun("Hello World", font, 24, new Point(72, 720)));
content.AddElement(text);
page.UpdateContent();
}
doc.Save(SaveFlags.Full, "output.pdf");
}
}
}
//Adobe PDF Library SDK(Datalogics APDFL)
// NuGet: Adobe.PDF.Library.LM.NET — namespace Datalogics.PDFL
using Datalogics.PDFL;
using System;
class AdobeHtmlToPdf
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document())
{
// US Letter in points (8.5 x 11 inches @ 72 DPI)
Rect pageRect = new Rect(0, 0, 612, 792);
using (Page page = doc.CreatePage(Document.BeforeFirstPage, pageRect))
{
Content content = page.Content;
Font font = new Font("Helvetica", FontCreateFlags.Embedded);
Text text = new Text();
text.AddRun(new TextRun("Hello World", font, 24, new Point(72, 720)));
content.AddElement(text);
page.UpdateContent();
}
doc.Save(SaveFlags.Full, "output.pdf");
}
}
}
Imports Datalogics.PDFL
Imports System
Class AdobeHtmlToPdf
Shared Sub Main()
Using lib As New Library()
Using doc As New Document()
' US Letter in points (8.5 x 11 inches @ 72 DPI)
Dim pageRect As New Rect(0, 0, 612, 792)
Using page As Page = doc.CreatePage(Document.BeforeFirstPage, pageRect)
Dim content As Content = page.Content
Dim font As New Font("Helvetica", FontCreateFlags.Embedded)
Dim text As New Text()
text.AddRun(New TextRun("Hello World", font, 24, New Point(72, 720)))
content.AddElement(text)
page.UpdateContent()
End Using
doc.Save(SaveFlags.Full, "output.pdf")
End Using
End Using
End Sub
End Class
IronPDF實現:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfHtmlToPdf
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
// Convert HTML to PDF with simple API
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfHtmlToPdf
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
// Convert HTML to PDF with simple API
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports System
Class IronPdfHtmlToPdf
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
' Convert HTML to PDF with simple API
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
End Sub
End Class
IronPDF 消除了程式庫生命週期包裝、轉換參數物件和顯式處理。 ChromePdfRenderer 使用基於 Chromium 的引擎來獲得精確的 CSS 和 JavaScript 支持。 對於高級場景,請參見HTML 到 PDF 文件。
合併多個 PDF
PDF 合併明顯展示了 API 複雜性的差別。
Adobe PDF Library SDK 實現:
//Adobe PDF Library SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeMergePdfs
{
static void Main()
{
using (Library lib = new Library())
using (Document doc1 = new Document("document1.pdf"))
using (Document doc2 = new Document("document2.pdf"))
{
// InsertPages(insertAfter, sourceDoc, sourceStartPage, pageCount, flags)
doc1.InsertPages(
Document.LastPage,
doc2,
0,
Document.AllPages,
PageInsertFlags.Bookmarks | PageInsertFlags.Threads);
doc1.Save(SaveFlags.Full, "merged.pdf");
}
}
}
//Adobe PDF Library SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeMergePdfs
{
static void Main()
{
using (Library lib = new Library())
using (Document doc1 = new Document("document1.pdf"))
using (Document doc2 = new Document("document2.pdf"))
{
// InsertPages(insertAfter, sourceDoc, sourceStartPage, pageCount, flags)
doc1.InsertPages(
Document.LastPage,
doc2,
0,
Document.AllPages,
PageInsertFlags.Bookmarks | PageInsertFlags.Threads);
doc1.Save(SaveFlags.Full, "merged.pdf");
}
}
}
Imports Datalogics.PDFL
Imports System
Class AdobeMergePdfs
Shared Sub Main()
Using lib As New Library()
Using doc1 As New Document("document1.pdf")
Using doc2 As New Document("document2.pdf")
' InsertPages(insertAfter, sourceDoc, sourceStartPage, pageCount, flags)
doc1.InsertPages(Document.LastPage, doc2, 0, Document.AllPages, PageInsertFlags.Bookmarks Or PageInsertFlags.Threads)
doc1.Save(SaveFlags.Full, "merged.pdf")
End Using
End Using
End Using
End Sub
End Class
IronPDF實現:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfMergePdfs
{
static void Main()
{
// Load PDF documents
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
// Merge PDFs with simple method
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfMergePdfs
{
static void Main()
{
// Load PDF documents
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
// Merge PDFs with simple method
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
Imports IronPdf
Imports System
Class IronPdfMergePdfs
Shared Sub Main()
' Load PDF documents
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
' Merge PDFs with simple method
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
End Sub
End Class
Adobe 的方法需要逐頁迭代與插入參數。IronPDF提供了一個接受多個文件的 Merge 方法。
新增水印
打水印展示了IronPDF如何利用 HTML/CSS 提供樣式的靈活性。
Adobe PDF Library SDK 實現:
//Adobe PDF Library SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeAddWatermark
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document("input.pdf"))
{
WatermarkParams watermarkParams = new WatermarkParams();
watermarkParams.Opacity = 0.5; // 0.0 - 1.0
watermarkParams.Rotation = 45.0;
watermarkParams.Scale = -1; // auto-fit
WatermarkTextParams textParams = new WatermarkTextParams();
textParams.Text = "CONFIDENTIAL";
textParams.Color = new Color(0.8, 0.8, 0.8);
textParams.TextAlign = HorizontalAlignment.Center;
// Apply via Document.Watermark(textParams, wmParams)
doc.Watermark(textParams, watermarkParams);
doc.Save(SaveFlags.Full, "watermarked.pdf");
}
}
}
//Adobe PDF Library SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeAddWatermark
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document("input.pdf"))
{
WatermarkParams watermarkParams = new WatermarkParams();
watermarkParams.Opacity = 0.5; // 0.0 - 1.0
watermarkParams.Rotation = 45.0;
watermarkParams.Scale = -1; // auto-fit
WatermarkTextParams textParams = new WatermarkTextParams();
textParams.Text = "CONFIDENTIAL";
textParams.Color = new Color(0.8, 0.8, 0.8);
textParams.TextAlign = HorizontalAlignment.Center;
// Apply via Document.Watermark(textParams, wmParams)
doc.Watermark(textParams, watermarkParams);
doc.Save(SaveFlags.Full, "watermarked.pdf");
}
}
}
Imports Datalogics.PDFL
Imports System
Class AdobeAddWatermark
Shared Sub Main()
Using lib As New Library()
Using doc As New Document("input.pdf")
Dim watermarkParams As New WatermarkParams()
watermarkParams.Opacity = 0.5 ' 0.0 - 1.0
watermarkParams.Rotation = 45.0
watermarkParams.Scale = -1 ' auto-fit
Dim textParams As New WatermarkTextParams()
textParams.Text = "CONFIDENTIAL"
textParams.Color = New Color(0.8, 0.8, 0.8)
textParams.TextAlign = HorizontalAlignment.Center
' Apply via Document.Watermark(textParams, wmParams)
doc.Watermark(textParams, watermarkParams)
doc.Save(SaveFlags.Full, "watermarked.pdf")
End Using
End Using
End Sub
End Class
IronPDF實現:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class IronPdfAddWatermark
{
static void Main()
{
var pdf = PdfDocument.FromFile("input.pdf");
// Apply text watermark with simple API
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.5;'>CONFIDENTIAL</h1>",
rotation: 45,
verticalAlignment: VerticalAlignment.Middle,
horizontalAlignment: HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class IronPdfAddWatermark
{
static void Main()
{
var pdf = PdfDocument.FromFile("input.pdf");
// Apply text watermark with simple API
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.5;'>CONFIDENTIAL</h1>",
rotation: 45,
verticalAlignment: VerticalAlignment.Middle,
horizontalAlignment: HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");
}
}
Imports IronPdf
Imports IronPdf.Editing
Imports System
Class IronPdfAddWatermark
Shared Sub Main()
Dim pdf = PdfDocument.FromFile("input.pdf")
' Apply text watermark with simple API
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.5;'>CONFIDENTIAL</h1>",
rotation:=45,
verticalAlignment:=VerticalAlignment.Middle,
horizontalAlignment:=HorizontalAlignment.Center)
pdf.SaveAs("watermarked.pdf")
End Sub
End Class
IronPDF 的基於 HTML 的打水印通過 CSS 樣式提供了完整的設計控制,消除了單獨參數物件的需要。
密碼保護和加密
Adobe PDF Library SDK 實現:
using Datalogics.PDFL;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
PermissionFlags permissions =
PermissionFlags.PrintDoc |
PermissionFlags.PrintFidelity;
EncryptionHandler encHandler = new EncryptionHandler(
password, // User password
password, // Owner password
permissions,
EncryptionMethod.AES256);
doc.SetEncryptionHandler(encHandler);
doc.Save(SaveFlags.Full | SaveFlags.Encrypted, outputPath);
}
}
finally
{
Library.Terminate();
}
}
using Datalogics.PDFL;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
PermissionFlags permissions =
PermissionFlags.PrintDoc |
PermissionFlags.PrintFidelity;
EncryptionHandler encHandler = new EncryptionHandler(
password, // User password
password, // Owner password
permissions,
EncryptionMethod.AES256);
doc.SetEncryptionHandler(encHandler);
doc.Save(SaveFlags.Full | SaveFlags.Encrypted, outputPath);
}
}
finally
{
Library.Terminate();
}
}
Imports Datalogics.PDFL
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Library.Initialize()
Try
Using doc As New Document(inputPath)
Dim permissions As PermissionFlags = PermissionFlags.PrintDoc Or PermissionFlags.PrintFidelity
Dim encHandler As New EncryptionHandler(
password, ' User password
password, ' Owner password
permissions,
EncryptionMethod.AES256)
doc.SetEncryptionHandler(encHandler)
doc.Save(SaveFlags.Full Or SaveFlags.Encrypted, outputPath)
End Using
Finally
Library.Terminate()
End Try
End Sub
IronPDF實現:
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs(outputPath);
}
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Using pdf = PdfDocument.FromFile(inputPath)
pdf.SecuritySettings.UserPassword = password
pdf.SecuritySettings.OwnerPassword = password
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF 使用強型別屬性代替按位權限標誌和加密處理物件。
文字提取
Adobe PDF Library SDK 實現:
using Datalogics.PDFL;
public string ExtractText(string pdfPath)
{
string extractedText = "";
Library.Initialize();
try
{
using (Document doc = new Document(pdfPath))
{
WordFinderConfig config = new WordFinderConfig();
config.IgnoreCharGaps = true;
for (int i = 0; i < doc.NumPages; i++)
{
using (WordFinder wordFinder = new WordFinder(doc, i, config))
{
IList<Word> words = wordFinder.GetWordList();
foreach (Word word in words)
{
extractedText += word.Text + " ";
}
extractedText += "\n";
}
}
}
}
finally
{
Library.Terminate();
}
return extractedText;
}
using Datalogics.PDFL;
public string ExtractText(string pdfPath)
{
string extractedText = "";
Library.Initialize();
try
{
using (Document doc = new Document(pdfPath))
{
WordFinderConfig config = new WordFinderConfig();
config.IgnoreCharGaps = true;
for (int i = 0; i < doc.NumPages; i++)
{
using (WordFinder wordFinder = new WordFinder(doc, i, config))
{
IList<Word> words = wordFinder.GetWordList();
foreach (Word word in words)
{
extractedText += word.Text + " ";
}
extractedText += "\n";
}
}
}
}
finally
{
Library.Terminate();
}
return extractedText;
}
Imports Datalogics.PDFL
Public Function ExtractText(ByVal pdfPath As String) As String
Dim extractedText As String = ""
Library.Initialize()
Try
Using doc As New Document(pdfPath)
Dim config As New WordFinderConfig()
config.IgnoreCharGaps = True
For i As Integer = 0 To doc.NumPages - 1
Using wordFinder As New WordFinder(doc, i, config)
Dim words As IList(Of Word) = wordFinder.GetWordList()
For Each word As Word In words
extractedText &= word.Text & " "
Next
extractedText &= vbLf
End Using
Next
End Using
Finally
Library.Terminate()
End Try
Return extractedText
End Function
IronPDF實現:
using IronPdf;
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
using IronPdf;
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
Imports IronPdf
Public Function ExtractText(pdfPath As String) As String
Using pdf = PdfDocument.FromFile(pdfPath)
Return pdf.ExtractAllText()
End Using
End Function
Adobe 的逐字迭代變成了IronPDF的單一方法調用。
頭部和尾部
Adobe PDF Library SDK 實現:
using Datalogics.PDFL;
public void AddHeaderFooter(string inputPath, string outputPath)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
Font font = new Font("Helvetica", FontCreateFlags.None);
for (int i = 0; i < doc.NumPages; i++)
{
using (Page page = doc.GetPage(i))
{
Content content = page.Content;
// Add header
Text header = new Text();
header.AddRun(new TextRun("Document Header",
font, 10, new Point(72, page.MediaBox.Top - 36)));
content.AddElement(header);
// Add footer with page number
Text footer = new Text();
footer.AddRun(new TextRun($"Page {i + 1} of {doc.NumPages}",
font, 10, new Point(72, 36)));
content.AddElement(footer);
page.UpdateContent();
}
}
doc.Save(SaveFlags.Full, outputPath);
}
}
finally
{
Library.Terminate();
}
}
using Datalogics.PDFL;
public void AddHeaderFooter(string inputPath, string outputPath)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
Font font = new Font("Helvetica", FontCreateFlags.None);
for (int i = 0; i < doc.NumPages; i++)
{
using (Page page = doc.GetPage(i))
{
Content content = page.Content;
// Add header
Text header = new Text();
header.AddRun(new TextRun("Document Header",
font, 10, new Point(72, page.MediaBox.Top - 36)));
content.AddElement(header);
// Add footer with page number
Text footer = new Text();
footer.AddRun(new TextRun($"Page {i + 1} of {doc.NumPages}",
font, 10, new Point(72, 36)));
content.AddElement(footer);
page.UpdateContent();
}
}
doc.Save(SaveFlags.Full, outputPath);
}
}
finally
{
Library.Terminate();
}
}
Imports Datalogics.PDFL
Public Sub AddHeaderFooter(inputPath As String, outputPath As String)
Library.Initialize()
Try
Using doc As New Document(inputPath)
Dim font As New Font("Helvetica", FontCreateFlags.None)
For i As Integer = 0 To doc.NumPages - 1
Using page As Page = doc.GetPage(i)
Dim content As Content = page.Content
' Add header
Dim header As New Text()
header.AddRun(New TextRun("Document Header", font, 10, New Point(72, page.MediaBox.Top - 36)))
content.AddElement(header)
' Add footer with page number
Dim footer As New Text()
footer.AddRun(New TextRun($"Page {i + 1} of {doc.NumPages}", font, 10, New Point(72, 36)))
content.AddElement(footer)
page.UpdateContent()
End Using
Next
doc.Save(SaveFlags.Full, outputPath)
End Using
Finally
Library.Terminate()
End Try
End Sub
IronPDF實現:
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Document Header",
FontSize = 10,
FontFamily = "Helvetica"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10,
FontFamily = "Helvetica"
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Document Header",
FontSize = 10,
FontFamily = "Helvetica"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10,
FontFamily = "Helvetica"
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub CreatePdfWithHeaderFooter(html As String, outputPath As String)
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Document Header",
.FontSize = 10,
.FontFamily = "Helvetica"
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "Page {page} of {total-pages}",
.FontSize = 10,
.FontFamily = "Helvetica"
}
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF 自動處理頁面迭代,並支持像 {page} 和 {total-pages} 這樣的佔位符標記。 對於更高級的佈局,請參見頭部和尾部文件。
URL 到 PDF 轉換
Adobe PDF Library SDK 缺乏內建的 URL 渲染功能。IronPDF提供原生支持:
using IronPdf;
public void ConvertUrlToPdf(string url, string outputPath)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void ConvertUrlToPdf(string url, string outputPath)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub ConvertUrlToPdf(url As String, outputPath As String)
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderUrlAsPdf(url)
pdf.SaveAs(outputPath)
End Using
End Sub
有關完整的 URL 轉換選項,請參見URL 到 PDF 文件。
ASP.NET Core 整合
Adobe PDF Library SDK 的靜態初始化模式與依賴注入造成摩擦。IronPDF與現代 .NET 架構自然整合。
Adobe 模式(對於 DI 問題的根源):
public class AdobePdfService
{
public byte[] Generate(string content)
{
Library.Initialize();
try
{
//複雜的文件construction...
return bytes;
}
finally
{
Library.Terminate();
}
}
}
public class AdobePdfService
{
public byte[] Generate(string content)
{
Library.Initialize();
try
{
//複雜的文件construction...
return bytes;
}
finally
{
Library.Terminate();
}
}
}
Public Class AdobePdfService
Public Function Generate(content As String) As Byte()
Library.Initialize()
Try
'複雜的文件construction...
Return bytes
Finally
Library.Terminate()
End Try
End Function
End Class
IronPDF 模式(對 DI 友好):
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
}
// Register in Program.cs (.NET 6+):
builder.Services.AddSingleton<IPdfService, IronPdfService>();
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
}
// Register in Program.cs (.NET 6+):
builder.Services.AddSingleton<IPdfService, IronPdfService>();
Imports System.Threading.Tasks
Public Interface IPdfService
Function GeneratePdfAsync(html As String) As Task(Of Byte())
End Interface
Public Class IronPdfService
Implements IPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte()) Implements IPdfService.GeneratePdfAsync
Using pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
End Function
End Class
' Register in Program.vb (.NET 6+):
builder.Services.AddSingleton(Of IPdfService, IronPdfService)()
異步支持
Adobe PDF Library SDK 不支持異步操作。IronPDF提供了完全的 async/await 功能,對於可擴展的網頁應用程式至關重要:
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc
Public Class ReportController
Inherits Controller
Public Async Function GenerateReport() As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
End Using
End Function
End Class
性能優化
記憶體使用比較
| 場景 | Adobe PDF Library SDK | IronPDF |
|---|---|---|
| 簡單的 PDF | ~100 MB | ~50 MB |
| 複雜的文件 | ~200 MB | ~80 MB |
| 批次(100 PDFs) | 高(本機記憶體) | ~100 MB |
優化提示
重用渲染器例子:
// Good: Reuse renderer for batch operations
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
// Good: Reuse renderer for batch operations
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
' Good: Reuse renderer for batch operations
Dim renderer = New ChromePdfRenderer()
For Each html In htmlList
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs($"output_{i}.pdf")
End Using
Next
在 Web 應用中使用異步:
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc
Public Class ReportController
Inherits Controller
Public Async Function GenerateReport() As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
End Using
End Function
End Class
故障排除常見的遷移問題
問題:基於座標的位置不起作用
Adobe 使用 PostScript 點座標。IronPDF使用 CSS 定位:
// Adobe: Point-based
new TextRun("Hello", font, 12, new Point(100, 700));
// IronPDF: CSS-based
string html = "<p style='position:absolute; left:100px; top:92px;'>Hello</p>";
// Adobe: Point-based
new TextRun("Hello", font, 12, new Point(100, 700));
// IronPDF: CSS-based
string html = "<p style='position:absolute; left:100px; top:92px;'>Hello</p>";
' Adobe: Point-based
New TextRun("Hello", font, 12, New Point(100, 700))
' IronPDF: CSS-based
Dim html As String = "<p style='position:absolute; left:100px; top:92px;'>Hello</p>"
問題:頁面大小差異
Adobe 使用 PostScript 點。IronPDF使用 enum 或自定義尺寸:
// Adobe: Points
Rect(0, 0, 612, 792) // Letter
// IronPDF: Enum or custom
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom:
renderer.RenderingOptions.SetCustomPaperSizeInInches(8.5, 11);
// Adobe: Points
Rect(0, 0, 612, 792) // Letter
// IronPDF: Enum or custom
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom:
renderer.RenderingOptions.SetCustomPaperSizeInInches(8.5, 11);
' Adobe: Points
Rect(0, 0, 612, 792) ' Letter
' IronPDF: Enum or custom
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
' Or custom:
renderer.RenderingOptions.SetCustomPaperSizeInInches(8.5, 11)
問題:未找到字體
Adobe 需要手動嵌入字體。IronPDF自動處理字體:
// IronPDF: Use web fonts if needed
string html = @"
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', sans-serif; }
</style>";
// IronPDF: Use web fonts if needed
string html = @"
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', sans-serif; }
</style>";
' IronPDF: Use web fonts if needed
Dim html As String = "
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', sans-serif; }
</style>"
問題:SaveFlags 不可用
Adobe 使用保存標誌組合。IronPDF使用直接保存:
// Adobe
doc.Save(SaveFlags.Full | SaveFlags.Incremental, path);
//IronPDF- full save is default
pdf.SaveAs(path);
// Adobe
doc.Save(SaveFlags.Full | SaveFlags.Incremental, path);
//IronPDF- full save is default
pdf.SaveAs(path);
後遷移檢查清單
完成程式碼遷移後,請驗證以下內容:
- 運行所有現有的單元和整合測試
- 將 PDF 輸出與以前的版本進行視覺比較
- 在隔離環境中測試所有 PDF 工作流
- 確認授權適當運作 (
IronPdf.License.IsLicensed) - 性能與以前的實施做基準比較
- 移除 Adobe 授權配置
- 更新CI/CD管道依賴性
- 將所有 Adobe PDF Library DLL 從專案中移除
- 記錄新的模式以供開發團隊參考
其他資源
從 APDFL 遷移到IronPDF可以簡化典型的.NET PDF 生成程式碼庫,特別是對於主要需要 HTML 到 PDF 或文件操作的團隊,其它比完整的 derives 自 Acrobat 的功能面更不需要。 從低層次的頁面構造到 HTML/CSS 渲染的轉變大大減少了大部分的座標計算、字體管理和 Library 生命週期處理程式碼,而IronPDF的透明化每開發者授權通常比起 APDFL 的以銷售為導向、OEM/SaaS 版稅模式更容易根據預算規劃。

