IRONSOFTWAREHOME
视频

如何在PDF中绘制线条和矩形

Curtis Chau
Curtis Chau
Updated: 2026年5月18日

Adobe PDF Library SDK (APDFL) 由 Datalogics 根据 Adobe 的许可进行分发,并与 Acrobat 引擎共享核心源代码。虽然功能强大,但其销售主导的定价模式、本机运行时占用、没有内置 HTML 转 PDF 渲染器,以及低级 API 设计导致许多 .NET 团队寻找替代方案。 本指南提供了从Adobe PDF 库 SDK到IronPDF的分步迁移路径——这是一个现代的 .NET PDF 库,支持 .NET Framework 4.6.2 到 .NET 9。

为什么要考虑放弃 Adobe PDF Library SDK?

虽然 APDFL 提供了基于 Acrobat 的 PDF 引擎,但一些因素使开发团队探索 HTML 到 PDF、文档操作和报表生成的替代方案。

销售主导,自定义定价

Datalogics 不会发布 APDFL 的价格列表。 根据 Datalogics 的定价页面,内部使用计划从约 $5,999/年起,OEM、ISV 和 SaaS 部署协商每平台费用外加版税或收入分成。总成本通常超出中小团队的能力,几乎总是需要进行销售对话。

复杂的本地 SDK 集成

APDFL 包裹一个与 Acrobat 分享渊源的本机 C/C++ 引擎。 .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 意味着手动构建页面、字体和内容流,或者与单独的 HTML 渲染引擎配对使用 APDFL。

低级 API 设计

using APDFL 创建 PDF 涉及以编程方式构建页面、内容流、文本运行和字体。 像渲染 HTML 字符串这样简单的任务变成了多步骤操作,涉及坐标计算、字体嵌入和手动内容元素管理。

库生命周期管理开销

每个入口点都需要用Library.Initialize() / Library.Terminate()调用)封装代码,并谨慎处理在内部创建的每个PDF对象。遗漏的清理会导致资源泄漏。

对于许多项目来说,过于繁重

对于主要需要 HTML 到 PDF 转换、基本文档操作或报告生成的应用程序,完整的基于 Acrobat 的引擎通常超过了工作负荷的要求。

##Adobe PDF 库 SDK与 IronPDF:主要区别

了解这些库之间的基本架构差异有助于规划有效的迁移策略。

方面Adobe PDF 库 SDKIronPDF
定价销售主导; 内部使用从 ~$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+ 或 .NET Core 3.1 / .NET 5-9
  • Visual Studio 2019+ 或 JetBrains Rider
  • 访问 NuGet 包管理器 -IronPDF许可证密钥(可在ironpdf.com免费试用)

审核 Adobe PDF 库 SDK 使用情况

在您的解决方案目录中运行这些命令,以识别所有Adobe PDF 库 SDK引用:

grep -r "using Datalogics" --include="*.cs" .
grep -r "Adobe.PDF.Library" --include="*.csproj" .
grep -r "Library.Initialize\|Library.Terminate" --include="*.cs" .
SHELL

值得期待的重大变化

翻译类别Adobe PDF 库 SDKIronPDF迁移行动
初始化Library.Initialize() / Terminate()自动翻译删除生命周期代码
文件创建new Document() 与页面构建ChromePdfRenderer使用 HTML 渲染
坐标系PostScript 点,左下方原点基于 CSS 的布局使用 HTML/CSS
字体处理手动Font创建和嵌入自动翻译删除字体代码
内存管理手动处理 COM 对象标准 IDisposable使用using语句
页面构建CreatePage(), AddContent()从 HTML 自动生成大幅简化

逐步迁移过程

步骤 1:更新 NuGet 软件包

移除Adobe PDF 库 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
SHELL

步骤 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;

步骤 3:更新命名空间引用

在解决方案中执行全局查找和替换:

查找替换为
using Datalogics.PDFL;using IronPdf;

APDFL公开一个根命名空间,Datalogics.PDFLusing指令。

步骤 4:删除库生命周期代码

最重要的简化之一是删除初始化和终止模式:

//Adobe PDF 库 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);

完整的 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.NumPagespdf.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.PrintDocAllowUserPrinting

文本提取

Adobe 方法IronPDF 方法
new WordFinder(doc, config)pdf.ExtractAllText()
wordFinder.GetWordList()pdf.Pages[i].Text
复杂的单词/字符迭代单一方法调用

代码迁移示例

HTML 到 PDF 转换

APDFL 没有内置 HTML 渲染器。 最接近的一对一替代是手动构建页面和内容以模仿 HTML 文档将产生的布局,或将 APDFL 与一个独立的 HTML 到 PDF 引擎配对。

Adobe PDF 库 SDK 实现:

//Adobe PDF 库 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");
        }
    }
}
C#

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");
    }
}

IronPDF 消除了库生命周期包装器、转换参数对象和显式处置。 ChromePdfRenderer 使用基于Chromium的引擎来支持像素完美的CSS和JavaScript。 有关高级场景,请参阅 HTML 转 PDF 文档

合并多个 PDF 文件

PDF 合并清楚地展示了 API 复杂性的差异。

Adobe PDF 库 SDK 实现:

//Adobe PDF 库 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");
        }
    }
}
C#

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");
    }
}

Adobe 的方法要求使用插入参数逐页迭代。 IronPDF提供一个接受多个文档的单一Merge方法。

添加水印

水印说明了IronPDF如何利用 HTML/CSS 实现灵活的样式设计。

Adobe PDF 库 SDK 实现:

//Adobe PDF 库 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");
        }
    }
}
C#

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");
    }
}

IronPDF 基于 HTML 的水印通过 CSS 样式提供完整的设计控制,无需单独的参数对象。

密码保护和加密

Adobe PDF 库 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();
    }
}

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);
}

IronPDF 使用强类型属性代替位操作权限标志和加密处理程序对象。

文本提取

Adobe PDF 库 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;
}

IronPDF 实现:

using IronPdf;

public string ExtractText(string pdfPath)
{
    using var pdf = PdfDocument.FromFile(pdfPath);
    return pdf.ExtractAllText();
}

Adobe 的逐字迭代通过IronPDF变成了单一的方法调用。

页眉和页脚

Adobe PDF 库 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();
    }
}

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);
}

IronPDF自动处理页面迭代,并支持像{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);
}

有关完整的 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();
        }
    }
}

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>();

同步支持

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");
}

性能优化

内存使用对比

情景Adobe PDF 库 SDKIronPDF
简单 PDF~100 MB~50 MB
复杂文档~200 MB~80 MB
批量(100 份 PDF)高(本地内存)~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");
}

在 Web 应用程序中使用 Async:

public async Task<IActionResult> GenerateReport()
{
    var renderer = new ChromePdfRenderer();
    using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return File(pdf.BinaryData, "application/pdf");
}

常见迁移问题的故障排除

问题:基于坐标的定位不起作用

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 使用 PostScript 点。IronPDF使用枚举或自定义维度:

// 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>";

问题:SaveFlags 不可用

Adobe 使用保存标志组合。IronPDF采用直接保存的方式:

// 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 库 DLL 文件
  • 为您的开发团队记录新的模式

其他资源


从 APDFL 迁移到IronPDF可以简化典型的 .NET PDF 生成代码库,特别是对于主要需要 HTML 到 PDF 或文档操作而不是完整的 Acrobat 衍生功能的团队而言。 从低级页面构建转换为HTML/CSS渲染消除了大部分坐标计算、字体管理和Library生命周期处理代码,而且IronPDF的每位开发者透明许可通常比APDFL的销售主导、OEM/SaaS-版税模式更易于预算。

请注意: Adobe、Acrobat 和 Adobe PDF Library 是 Adobe Inc. 的注册商标。APDFL 由 Datalogics, Inc. 根据 Adobe 的许可分发。 本网站与 Adobe Inc. 或 Datalogics, Inc. 无关联、认可或赞助。所有产品名称、标志和品牌均为其各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。
Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

...
阅读更多

相关文章

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
预约您的免费现场演示
Booking Badge

深受全球数百万工程师信赖

Iron Software 的客户徽标
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户