如何在HTML到PDF转换中管理字体
EO.Pdf 在架构上提出了一些挑战,促使开发团队对替代方案进行评估。 了解这些问题对于规划迁移策略至关重要。
EO.Pdf 的问题
-
绑定的 Chromium 占用: EO.Pdf(当前 NuGet 版本 26.1.34,2026年3月)发送其自己的基于 Chromium 的渲染器,这增加了相对于非 Chromium 库的安装占用,并增加了 Docker 镜像和 CI/CD 管道的重量。
-
遗留架构包袱: EO.Pdf 的 HTML 转 PDF 转换器最初是在嵌入式 Internet Explorer / Trident 引擎上构建的,然后项目转移到一个基于 Chromium 的渲染器。 过渡留下了一些 API 怪异以及版本之间的行为差异。
-
仅 Windows 的 .NET Core:尽管宣传为"跨平台",Essential Objects 自己的 .NET Core 文档表明 EO.Pdf 支持 .NET Core 3.1+ 和 .NET 5/6 的 Windows——Linux 和 macOS 并未得到官方支持。
-
静态全局选项: EO.Pdf 的主要 HTML 转 PDF 入口点是静态
HtmlToPdf类与共享HtmlToPdf.Options。 从多个线程改变这个全局状态是不安全的,并且在多租户 Web 应用程序中很尴尬。 - 付费商业许可证: EO.Pdf 作为单个、3-许可证捆绑、公司和公司 Plus 等级出售(无永久免费等级 — 只有 30 天水印试用)。 确切的价格出现在 订购页面上。
架构比较
| 方面 | EO.Pdf | IronPDF |
|---|---|---|
| 渲染器 | 捆绑的 Chromium(从 IE/Trident 转移) | 嵌入式 Chromium |
| 版权问题 | IE/Trident 迁移包袱 | 从开始就基于 Chromium 构建 |
| 平台支持 | 仅在 .NET Core 上运行 Windows | Windows、Linux、macOS、Docker、Azure |
| 配置 | 静态 HtmlToPdf.Options (非线程安全) |
基于实例的 ChromePdfRenderer (线程安全) |
| API 设计 | 混合(HtmlToPdf 静态 + ACM 对象模型) |
统一 ChromePdfRenderer + HTML/CSS |
| 许可模式 | 单个 / 3-许可证 / 公司 / 公司 Plus(30 天试用) | 每开发人员商业; 免费开发者试用 |
| 现代.NET | .NET Framework + .NET Core 3.1+(仅限 Windows) | .NET Framework, .NET 6/7/8/9 跨平台 |
| 支持同步 | 有限的 | 完整 RenderHtmlAsPdfAsync / RenderUrlAsPdfAsync |
主要迁移优势
- 跨平台 .NET Core/.NET 6+: 工作在 Linux, macOS, 和 Docker — 不仅限于 Windows
- 线程安全配置: 基于实例的渲染器选项,而非静态全局
- 现代 API: 一致的方法命名 —
RenderHtmlAsPdf,RenderUrlAsPdf,PdfDocument.Merge - 完整异步支持:
RenderHtmlAsPdfAsync和RenderUrlAsPdfAsync用于非阻塞管道 - 文档: 丰富的教程,入门指南,以及一个活动的对象参考
迁移前准备
前提条件
确保您的环境符合这些要求:
- .NET Framework 4.6.2+ 或 .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ 或带有 C# 扩展的 VS Code
- 访问 NuGet 包管理器 -IronPDF许可证密钥(可在ironpdf.com免费试用)
审核 EO.Pdf 的使用情况
在解决方案目录中运行这些命令以识别所有 EO.Pdf 引用:
# Find all EO.Pdf references
grep -r "EO.Pdf\|HtmlToPdf\|AcmRender\|PdfDocument" --include="*.cs" .
# Check NuGet packages
dotnet list package | grep -i "EO.Pdf"
# Find all EO.Pdf references
grep -r "EO.Pdf\|HtmlToPdf\|AcmRender\|PdfDocument" --include="*.cs" .
# Check NuGet packages
dotnet list package | grep -i "EO.Pdf"
需要查找的常见 EO.Pdf 命名空间:
EO.Pdf- 核心 HTML 到 PDFEO.Pdf.Acm- 高级内容模型 (ACM)EO.Pdf.Contents- 低级内容操作EO.Pdf.Drawing- 图形操作
了解核心模式变更
EO.Pdf 和IronPDF在架构上的最大区别在于配置范围。 EO.Pdf 使用静态方法,其全局选项会影响所有转换--这种模式会导致网络应用程序中的线程安全问题。IronPDF使用基于实例的渲染器和本地选项,确保每次转换都是独立的。
逐步迁移过程
步骤 1:更新 NuGet 软件包
删除 EO.Pdf,安装 IronPDF:
# Remove EO.Pdf
dotnet remove package EO.Pdf
# Install IronPDF
dotnet add package IronPdf
# Remove EO.Pdf
dotnet remove package EO.Pdf
# Install IronPDF
dotnet add package IronPdf
步骤 2:更新命名空间引用
用IronPDF替换 EO.Pdf 命名空间:
// Remove these
using EO.Pdf;
using EO.Pdf.Acm;
// Add this
using IronPdf;
// Remove these
using EO.Pdf;
using EO.Pdf.Acm;
// Add this
using IronPdf;
Imports IronPdf
步骤 3:配置许可证
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
完整的 API 迁移参考
核心类映射
| EO.Pdf 类 | IronPDF 同等产品 |
|---|---|
HtmlToPdf |
ChromePdfRenderer |
PdfDocument |
PdfDocument |
HtmlToPdfOptions |
ChromePdfRenderOptions |
AcmRender |
不需要 |
AcmText |
HTML <span>, <p> |
AcmBlock |
HTML <div> |
方法映射
| EO.Pdf 方法 | IronPDF 方法 |
|---|---|
HtmlToPdf.ConvertHtml(html, path) |
renderer.RenderHtmlAsPdf(html) 然后 SaveAs(path) |
HtmlToPdf.ConvertUrl(url, path) |
renderer.RenderUrlAsPdf(url) 然后 SaveAs(path) |
PdfDocument.Save(path) |
pdf.SaveAs(path) |
new PdfDocument(path) |
PdfDocument.FromFile(path) |
PdfDocument.Merge(doc1, doc2) (静态) |
PdfDocument.Merge(doc1, doc2) (静态) |
选项映射
| EO.Pdf 选项 | IronPDF 渲染选项 |
|---|---|
Options.PageSize = PdfPageSizes.A4 |
PaperSize = PdfPaperSize.A4 |
Options.OutputArea (RectangleF) |
MarginTop, MarginBottom, 等。 |
代码迁移示例
HTML 到 PDF 转换
HTML 到 PDF 的基本转换展示了从静态方法到基于实例的渲染的转变。
EO.Pdf 实现:
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
string html = "<html><body><h1>Hello World</h1><p>This is a PDF generated from HTML.</p></body></html>";
HtmlToPdf.ConvertHtml(html, "output.pdf");
Console.WriteLine("PDF created successfully!");
}
}
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
string html = "<html><body><h1>Hello World</h1><p>This is a PDF generated from HTML.</p></body></html>";
HtmlToPdf.ConvertHtml(html, "output.pdf");
Console.WriteLine("PDF created successfully!");
}
}
Imports EO.Pdf
Imports System
Class Program
Shared Sub Main()
Dim html As String = "<html><body><h1>Hello World</h1><p>This is a PDF generated from HTML.</p></body></html>"
HtmlToPdf.ConvertHtml(html, "output.pdf")
Console.WriteLine("PDF created successfully!")
End Sub
End Class
IronPDF 实现:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string html = "<html><body><h1>Hello World</h1><p>This is a PDF generated from HTML.</p></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully!");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string html = "<html><body><h1>Hello World</h1><p>This is a PDF generated from HTML.</p></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully!");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim html As String = "<html><body><h1>Hello World</h1><p>This is a PDF generated from HTML.</p></body></html>"
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully!")
End Sub
End Class
IronPDF 的两步模式(渲染,然后保存)提供对 PdfDocument 对象的访问,以便在保存之前进行额外操作。 有关更多选项,请参阅 HTML 转 PDF 文档。
URL到PDF转换
EO.Pdf 实现:
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
string url = "https://www.example.com";
HtmlToPdf.ConvertUrl(url, "webpage.pdf");
Console.WriteLine("PDF from URL created successfully!");
}
}
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
string url = "https://www.example.com";
HtmlToPdf.ConvertUrl(url, "webpage.pdf");
Console.WriteLine("PDF from URL created successfully!");
}
}
Imports EO.Pdf
Imports System
Module Program
Sub Main()
Dim url As String = "https://www.example.com"
HtmlToPdf.ConvertUrl(url, "webpage.pdf")
Console.WriteLine("PDF from URL created successfully!")
End Sub
End Module
IronPDF 实现:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string url = "https://www.example.com";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL created successfully!");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string url = "https://www.example.com";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL created successfully!");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim url As String = "https://www.example.com"
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf(url)
pdf.SaveAs("webpage.pdf")
Console.WriteLine("PDF from URL created successfully!")
End Sub
End Class
IronPDF 的 RenderUrlAsPdf 提供完整的 JavaScript 执行和现代 CSS 支持。 有关更多选项,请参阅 URL to PDF 文档。
带有自定义设置的 HTML 文件
这个示例展示了配置模式的关键区别——EO.Pdf 的 OutputArea 使用英寸,而IronPDF的单独边距属性使用毫米。
EO.Pdf 实现:
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
HtmlToPdfOptions options = new HtmlToPdfOptions();
options.PageSize = PdfPageSizes.A4;
options.OutputArea = new RectangleF(0.5f, 0.5f, 7.5f, 10.5f);
HtmlToPdf.ConvertUrl("file:///C:/input.html", "output.pdf", options);
Console.WriteLine("PDF with custom settings created.");
}
}
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
HtmlToPdfOptions options = new HtmlToPdfOptions();
options.PageSize = PdfPageSizes.A4;
options.OutputArea = new RectangleF(0.5f, 0.5f, 7.5f, 10.5f);
HtmlToPdf.ConvertUrl("file:///C:/input.html", "output.pdf", options);
Console.WriteLine("PDF with custom settings created.");
}
}
Imports EO.Pdf
Imports System
Class Program
Shared Sub Main()
Dim options As New HtmlToPdfOptions()
options.PageSize = PdfPageSizes.A4
options.OutputArea = New RectangleF(0.5F, 0.5F, 7.5F, 10.5F)
HtmlToPdf.ConvertUrl("file:///C:/input.html", "output.pdf", options)
Console.WriteLine("PDF with custom settings created.")
End Sub
End Class
IronPDF 实现:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlFileAsPdf("C:/input.html");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF with custom settings created.");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlFileAsPdf("C:/input.html");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF with custom settings created.");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System
Class Program
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
Dim pdf = renderer.RenderHtmlFileAsPdf("C:/input.html")
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF with custom settings created.")
End Sub
End Class
请注意单位转换:EO.Pdf 在 OutputArea 中使用英寸,而IronPDF使用毫米。 转换使用:inches × 25.4 = mm。 有关更多选项,请参阅渲染选项文档。
合并多个 PDF 文件
两个库都提供了一个静态 PdfDocument.Merge 用于合并文档——EO.Pdf 无实例 Append 方法,因此任何使用 doc.Append(other) 的代码都是无效的,需要迁移到 Merge。
EO.Pdf 实现:
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
PdfDocument doc1 = new PdfDocument("file1.pdf");
PdfDocument doc2 = new PdfDocument("file2.pdf");
// EO.Pdf has no Append; merge is a static method that returns a new PdfDocument.
PdfDocument mergedDoc = PdfDocument.Merge(doc1, doc2);
mergedDoc.Save("merged.pdf");
Console.WriteLine("PDFs merged successfully!");
}
}
// NuGet: Install-Package EO.Pdf
using EO.Pdf;
using System;
class Program
{
static void Main()
{
PdfDocument doc1 = new PdfDocument("file1.pdf");
PdfDocument doc2 = new PdfDocument("file2.pdf");
// EO.Pdf has no Append; merge is a static method that returns a new PdfDocument.
PdfDocument mergedDoc = PdfDocument.Merge(doc1, doc2);
mergedDoc.Save("merged.pdf");
Console.WriteLine("PDFs merged successfully!");
}
}
Imports EO.Pdf
Imports System
Module Program
Sub Main()
Dim doc1 As New PdfDocument("file1.pdf")
Dim doc2 As New PdfDocument("file2.pdf")
' EO.Pdf has no Append; merge is a static method that returns a new PdfDocument.
Dim mergedDoc As PdfDocument = PdfDocument.Merge(doc1, doc2)
mergedDoc.Save("merged.pdf")
Console.WriteLine("PDFs merged successfully!")
End Sub
End Module
IronPDF 实现:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("file1.pdf");
var pdf2 = PdfDocument.FromFile("file2.pdf");
var merged = PdfDocument.Merge(new List<PdfDocument> { pdf1, pdf2 });
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully!");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("file1.pdf");
var pdf2 = PdfDocument.FromFile("file2.pdf");
var merged = PdfDocument.Merge(new List<PdfDocument> { pdf1, pdf2 });
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully!");
}
}
Imports IronPdf
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim pdf1 = PdfDocument.FromFile("file1.pdf")
Dim pdf2 = PdfDocument.FromFile("file2.pdf")
Dim merged = PdfDocument.Merge(New List(Of PdfDocument) From {pdf1, pdf2})
merged.SaveAs("merged.pdf")
Console.WriteLine("PDFs merged successfully!")
End Sub
End Module
IronPDF 的静态 Merge 接受文档的参数列表或一个 List<PdfDocument>。 请注意从构造函数(PdfDocument.FromFile(path))的变化。 更多选项请参阅PDF 合并文档。
关键迁移说明
边际单位转换
EO.Pdf 在 OutputArea 中使用英寸。IronPDF使用毫米。 转换使用:inches × 25.4 = mm
// EO.Pdf - 0.5 inch margins
options.OutputArea = new RectangleF(0.5f, 0.5f, 7.5f, 10.5f);
//IronPDF- equivalent in millimeters (0.5" = 12.7mm)
renderer.RenderingOptions.MarginTop = 12.7;
renderer.RenderingOptions.MarginBottom = 12.7;
renderer.RenderingOptions.MarginLeft = 12.7;
renderer.RenderingOptions.MarginRight = 12.7;
// EO.Pdf - 0.5 inch margins
options.OutputArea = new RectangleF(0.5f, 0.5f, 7.5f, 10.5f);
//IronPDF- equivalent in millimeters (0.5" = 12.7mm)
renderer.RenderingOptions.MarginTop = 12.7;
renderer.RenderingOptions.MarginBottom = 12.7;
renderer.RenderingOptions.MarginLeft = 12.7;
renderer.RenderingOptions.MarginRight = 12.7;
' EO.Pdf - 0.5 inch margins
options.OutputArea = New RectangleF(0.5F, 0.5F, 7.5F, 10.5F)
' IronPDF- equivalent in millimeters (0.5" = 12.7mm)
renderer.RenderingOptions.MarginTop = 12.7
renderer.RenderingOptions.MarginBottom = 12.7
renderer.RenderingOptions.MarginLeft = 12.7
renderer.RenderingOptions.MarginRight = 12.7
从静态配置到基于实例的配置
将所有 HtmlToPdf.Options.X 替换为 renderer.RenderingOptions.X:
// EO.Pdf - static options (NOT thread-safe!)
HtmlToPdf.Options.PageSize = PdfPageSizes.A4;
//IronPDF- instance options (thread-safe)
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// EO.Pdf - static options (NOT thread-safe!)
HtmlToPdf.Options.PageSize = PdfPageSizes.A4;
//IronPDF- instance options (thread-safe)
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
' EO.Pdf - static options (NOT thread-safe!)
HtmlToPdf.Options.PageSize = PdfPageSizes.A4
' IronPDF- instance options (thread-safe)
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
ACM 到 HTML 的迁移
如果使用 EO.Pdf 的高级内容模型(AcmRender, AcmText, AcmBlock),请迁移到标准 HTML/CSS:
// EO.Pdf ACM approach
var acmContent = new AcmContent();
acmContent.Add(new AcmText("Sample Text"));
//IronPDFHTML approach
var html = "<div>Sample Text</div>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// EO.Pdf ACM approach
var acmContent = new AcmContent();
acmContent.Add(new AcmText("Sample Text"));
//IronPDFHTML approach
var html = "<div>Sample Text</div>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
' EO.Pdf ACM approach
Dim acmContent As New AcmContent()
acmContent.Add(New AcmText("Sample Text"))
' IronPDFHTML approach
Dim html As String = "<div>Sample Text</div>"
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
两步保存模式
EO.Pdf 直接保存于 ConvertHtml() 中。IronPDF返回一个 PdfDocument 对象,然后调用 SaveAs():
// EO.Pdf - one step
HtmlToPdf.ConvertHtml(html, "output.pdf");
//IronPDF- two steps (enables manipulation before save)
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// EO.Pdf - one step
HtmlToPdf.ConvertHtml(html, "output.pdf");
//IronPDF- two steps (enables manipulation before save)
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
' EO.Pdf - one step
HtmlToPdf.ConvertHtml(html, "output.pdf")
' IronPDF- two steps (enables manipulation before save)
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
构造函数到静态工厂
将 new PdfDocument(path) 替换为 PdfDocument.FromFile(path):
// EO.Pdf
var doc = new PdfDocument("file.pdf");
// IronPDF
var doc = PdfDocument.FromFile("file.pdf");
// EO.Pdf
var doc = new PdfDocument("file.pdf");
// IronPDF
var doc = PdfDocument.FromFile("file.pdf");
' EO.Pdf
Dim doc = New PdfDocument("file.pdf")
' IronPDF
Dim doc = PdfDocument.FromFile("file.pdf")
迁移后核对表
完成代码迁移后,请验证以下内容:
- 生成PDF文件的可视化比较
- 验证页眉/页脚是否正确显示。
- 测试安全/加密设置
- 验证合并操作
- 性能基准测试
- 跨平台测试(Windows、Linux、macOS)
- 删除 EO.Pdf 许可证文件
- 更新文档
其他资源
从 EO.Pdf 迁移到IronPDF解决了遗留的 IE/Trident 时代包袱和 EO.Pdf 的静态全局选项的线程安全问题。 迁移到基于实例的配置确保您的 PDF 生成代码在并发负载下可靠运行,而IronPDF的跨平台支持将部署扩展到 Windows 之外的 Linux、macOS 和 Docker。

