IronPDF vs ABCpdf:2025年哪个C# PDF库提供更好的HTML到PDF转换?
PDF文件在各个行业被广泛用于开具发票和创建各种文档类型等任务,能够有效地满足客户需求。 在开发需要生成 PDF 的.NET应用程序时,选择合适的库可以极大地影响您的开发速度、输出质量和长期维护成本。 IronPDF和 ABCpdf 是开发人员经常考虑的两个库——但哪一个才能真正更好地满足您的特定需求呢?
本次全面比较考察了两个库的功能,从 HTML 到 PDF 的转换准确性到许可模式,帮助您做出明智的决定。 我们将考察实际性能指标、API 设计理念和实际代码示例,以展示每个库的优势和局限性。 无论您是构建每天生成数千张发票的 SaaS 平台,还是需要精确文档渲染的Enterprise应用程序,了解这些差异对于项目的成功都至关重要。
什么是 IronPDF?
IronPDF是一个商业级的 PDF 生成库,可以帮助 C# 软件工程师在.NET项目中编辑、提取和生成 PDF 文档。 IronPDF 的核心是基于 Chrome 浏览器的渲染引擎,它能将 HTML、CSS 和 JavaScript 转换为 PDF,其保真度与您在 Google Chrome 浏览器中打印网页时的效果相同。
IronPDF 的主要功能
IronPDF 使用 .NET Chromium 引擎将 HTML 页面渲染为 PDF 文件。 使用 HTML-to-PDF 无需使用复杂的 API 来定位或设计 PDF。 IronPDF 支持标准网络文档:HTML、ASPX、JS、CSS 和图像。 该库架构优先考虑开发者体验,保持专业输出质量。
卓越的 HTML 到 PDF 转换
- 完全支持 HTML,包括 HTML5 语义元素
- 完全支持 CSS3,包括 Flexbox、网格和现代布局技术
- 执行 JavaScript 以呈现动态内容
- 支持网页字体,包括 Google Fonts 和自定义
@font-face声明 - 采用视口控制的响应式设计渲染
- 可配置等待时间的 AJAX 内容加载
文档操作能力
-合并和拆分:通过单个方法调用合并多个 PDF 或提取特定页面 -页眉和页脚:添加动态内容,包括页码、日期和自定义 HTML -水印:添加文本或图像水印,并可控制其不透明度和位置。 -表单管理:自动从 HTML 表单元素创建可填写的 PDF 表单 -数字签名:应用加密签名和证书管理 -加密:实现具有细粒度权限的 128 位和 256 位 AES 加密
高级渲染功能
-多线程处理:原生支持 async/await,适用于高性能场景 -批量操作:用于同时处理多个文档的优化方法 -内存效率:支持流式生成大型文档,无需将整个 PDF 文件加载到内存中 -云优化:专为 Docker、Azure 和 AWS 中的容器化部署而设计
跨平台架构
IronPDF 在不同的环境中保持一致的行为:
- 视窗(x86/x64)
- Linux(包括用于最小化 Docker 映像的 Alpine)
- macOS(英特尔和苹果硅)
- Azure 应用服务、函数和容器实例
- AWS Lambda 和 EC2
- 谷歌云平台
什么是 ABCpdf?
ABCpdf .NET C# PDF 库是一个.NET组件,用于动态读取、写入、转换和操作 Adobe PDF 文档。 ABCpdf 由 WebSupergoo 开发,二十多年来一直服务于 .NET 社区,提供多种 HTML 渲染引擎和全面的 PDF 操作功能。
ABCpdf 的主要功能
ABCpdf 完全支持 HTML/CSS 及相关技术,如JavaScript、SVG、AJAX 和 Font Awesome。 该库为开发人员提供了高级便捷方法和低级 PDF 对象访问。
多个渲染引擎
ABCpdf 的独特方法提供了多种渲染引擎:
- ABCChrome 引擎:基于 Chromium,符合现代 Web 标准(仅限 x64)
- Gecko引擎:提供多个版本用于兼容性测试
- MSHTML 引擎:基于 Internet Explorer 的渲染
- ABCWebKit 引擎:基于 WebKit 的渲染(仅限 x64)
这种多引擎方法允许开发人员为其特定内容选择最佳呈现器,但会增加部署和测试的复杂性。
性能特点
如果安装了 OpenOffice.org 等辅助应用程序,ABCpdf 可以阅读各种文档格式。 支持的格式包括
- 微软 Office 文档(Word、Excel、PowerPoint)
- PostScript 和 EPS 文件
- XPS(XML 纸张规范)
- SVG(可缩放矢量图形)
- 各种图像格式,包括 TIFF、JPEG 2000 和 RAW 格式
低级 PDF 操作
- 直接访问 PDF 对象模型
- 使用多种算法进行流压缩/解压缩
- 字体子集和嵌入控制
- 色彩空间管理和转换
- 内容流操作
性能特点
ABCpdf 是完全多线程的,可以在各种 .NET 环境中灵活使用,包括 C#、ASPX 和 VB,并在高性能多线程设置中进行了测试。 该库包括
- GigaPDF™ 支持超大型文档
- 优化服务器环境的内存使用
- 高效的字体缓存机制
- 背景线程处理能力
支持现代 CSS 框架
在使用现代网络应用程序时,将基于 Bootstrap 的布局和其他现代 CSS 框架转换为 PDF 的能力越来越重要。 现在,许多企业应用程序和 SaaS 平台都依赖 Bootstrap 来保持用户界面的一致性,PDF 生成需要完美地保留这些布局。
IronPDF:完全支持 Bootstrap 和现代框架
IronPDF 的 Chromium 渲染引擎可为现代 CSS 框架提供全面支持:
- Bootstrap 5:全面支持基于 Flexbox 的布局、网格系统和响应式实用程序
- Bootstrap 4:完全兼容 flexbox 卡片式布局、导航栏和表单布局 Tailwind CSS:现代实用主义 CSS 框架,渲染效果完美 -基础架构:支持所有网格和组件系统 -现代 CSS3: Flexbox、CSS Grid、动画、过渡效果和自定义属性
真实世界的例子:Bootstrap主页和Bootstrap模板以像素级的精确度转换为 PDF。
代码示例:电子商务产品网格
using IronPdf;
var renderer = new ChromePdfRenderer();
string bootstrapProductGrid = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
</head>
<body>
<div class='container my-5'>
<h1 class='mb-4'>Product Catalog</h1>
<div class='row row-cols-1 row-cols-md-3 g-4'>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 1'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Premium Widget</h5>
<p class='card-text flex-grow-1'>High-quality widget with advanced features and excellent durability.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$99.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 2'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Standard Widget</h5>
<p class='card-text flex-grow-1'>Reliable widget perfect for everyday use with great value.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$49.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 3'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Basic Widget</h5>
<p class='card-text flex-grow-1'>Entry-level widget with essential features at an affordable price.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$29.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(bootstrapProductGrid);
pdf.SaveAs("product-catalog.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
string bootstrapProductGrid = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
</head>
<body>
<div class='container my-5'>
<h1 class='mb-4'>Product Catalog</h1>
<div class='row row-cols-1 row-cols-md-3 g-4'>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 1'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Premium Widget</h5>
<p class='card-text flex-grow-1'>High-quality widget with advanced features and excellent durability.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$99.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 2'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Standard Widget</h5>
<p class='card-text flex-grow-1'>Reliable widget perfect for everyday use with great value.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$49.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 3'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Basic Widget</h5>
<p class='card-text flex-grow-1'>Entry-level widget with essential features at an affordable price.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$29.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(bootstrapProductGrid);
pdf.SaveAs("product-catalog.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim bootstrapProductGrid As String = "
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
</head>
<body>
<div class='container my-5'>
<h1 class='mb-4'>Product Catalog</h1>
<div class='row row-cols-1 row-cols-md-3 g-4'>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 1'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Premium Widget</h5>
<p class='card-text flex-grow-1'>High-quality widget with advanced features and excellent durability.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$99.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 2'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Standard Widget</h5>
<p class='card-text flex-grow-1'>Reliable widget perfect for everyday use with great value.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$49.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
<div class='col'>
<div class='card h-100'>
<img src='https://via.placeholder.com/300x200' class='card-img-top' alt='Product 3'>
<div class='card-body d-flex flex-column'>
<h5 class='card-title'>Basic Widget</h5>
<p class='card-text flex-grow-1'>Entry-level widget with essential features at an affordable price.</p>
<div class='d-flex justify-content-between align-items-center mt-auto'>
<span class='h4 mb-0 text-primary'>$29.99</span>
<button class='btn btn-primary'>Add to Cart</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(bootstrapProductGrid)
pdf.SaveAs("product-catalog.pdf")
输出:格式完美的商品目录,采用 Bootstrap 5 的卡片网格系统、flexbox 对齐方式和响应式间距——所有这些都保留在 PDF 中。
ABCpdf:具有框架限制的多引擎方法
ABCpdf 对现代 CSS 框架的支持因您选择的渲染引擎而有很大不同:
- ABCChrome 引擎(仅限 x64):类似于 IronPDF 的良好 Bootstrap 支持,但需要特定的 64 位平台配置
- ABCWebKit 引擎(仅限 x64):有限的 flexbox 支持,Bootstrap 4+ 布局可能无法正确呈现 Gecko引擎: CSS3支持一般,Bootstrap 3比Bootstrap 4/5表现更好。
- MSHTML 引擎:仅支持旧版 Internet Explorer 渲染和 Bootstrap 2.x,不建议用于现代应用程序。
关键考虑因素:
- 引擎选择的复杂性增加了部署开销
- 仅 64 位引擎(ABCChrome、ABCWebKit)限制了部署的灵活性
- 需要在不同引擎间进行测试,以实现一致的 Bootstrap 渲染效果
- 不同引擎的兼容性差异很大
ABCpdf 的多引擎架构提供了灵活性,但需要仔细选择引擎并进行测试,以确保 Bootstrap 布局能正确呈现。 对于大量使用 Bootstrap 或现代 CSS 框架的应用程序,ABCChrome 引擎可提供最佳效果,但仅限 x64 部署。
有关 Bootstrap 框架兼容性的更多详情,请参阅 Bootstrap & Flexbox CSS 指南。
全面功能对比
| 类别 | 特点/方面 | IronPDF | ABCpdf | 主要优势 |
|---|---|---|---|---|
| **核心架构** | 设计理念 | 简单至上、直观的 API | 灵活性第一,多种引擎 | IronPDF:更快的开发 |
| API 复杂性 | 像 `RenderHtmlAsPdf()` 这样的简单方法 | 面向对象与 Doc 类 | IronPDF:减少 70% 的代码 | |
| 学习曲线 | 一般为 1-2 小时 | 一般需要 1-2 天 | IronPDF:更快采用 | |
| **平台支持** | 跨平台 | 本地支持,单一软件包 | 主要使用 Windows 系统,Linux 系统有限 | IronPDF:真正的跨平台 |
| .NET版本 | .NET 10、9、8、7、6、5、Core 3.1+、Framework 4.6.2+。 | .NET 10、9、8、7、6、5、4.0、Framework 2.0+ | 两者:现代框架支持 | |
| 操作系统 | Windows、Linux、macOS、Docker 本机 | 支持 Windows 和有限的 Linux | IronPDF:更广泛的操作系统支持 | |
| **HTML 转 PDF** | 渲染引擎 | Chrome V127+ 引擎 | 多种引擎(Chrome 123、Gecko、MSHTML) | ABCpdf:引擎灵活性 |
| 支持 CSS3/HTML5 | 100% 兼容 Chrome 浏览器 | 因引擎而异(70-100) | IronPDF:一致的渲染 | |
| JavaScript 执行 | 完全支持 V8 JavaScript | 依赖引擎 | IronPDF:现代 JS 功能 | |
| 网络字体 | 谷歌字体、@font-face、系统字体 | 支持 ABCChrome | 两者都需要:网络字体支持 | |
| **性能** | 单页渲染 | 典型值为 200-400ms | 150-300毫秒(ABCChrome) | ABCpdf:速度稍快 |
| 批量处理 | 优化并行处理 | 多线程能力 | IronPDF:更好的异步支持 | |
| 内存使用 | 150-200MB(Chrome 引擎) | 100-150MB(因引擎而异) | ABCpdf:降低内存占用 | |
| **开发人员经验** | 文档 | 广泛的教程、视频和示例 | 全面的 API 文档 | IronPDF:更多学习资源 |
| 代码示例 | 100 多个可直接运行的示例 | 大量实例 | 两者兼顾:丰富的实例 | |
| IntelliSense 支持 | 完整的 XML 文档 | 全面的智能提示 | 两者:集成开发环境集成 | |
| **Licensing & Pricing** | 入门级 | Lite: $999 (1 dev, 1 project) | 标准:$329(1 个开发版,仅限 32 位) | ABCpdf:降低入门成本 |
| Professional | Professional: $2,999 (10 devs, 10 projects) | 专业:$479(1 开发版,64 位) | IronPDF:更好的 Team License | |
| 再分发 | +$2,999 royalty-free | $4,790企业许可证 | IronPDF:更经济实惠 | |
| **支持** | 支持包括 | 是,24/5 工程支持 | 是,电子邮件支持 | IronPDF:即时聊天支持 |
| 响应时间 | < 1 分钟(即时聊天) | 一般需要 24-48 小时 | IronPDF:更快的响应速度 | |
| **最适合** | 使用案例 | 现代网络应用、SaaS、云原生 | Windows 桌面、遗留系统 | 与上下文相关 |
在 Visual Studio 中创建新项目
在深入学习代码示例之前,让我们先建立一个合适的开发环境。 打开 Visual Studio 并创建一个新项目:
1.导航至文件 > 新建 > 项目 2.选择 "控制台应用程序"(.NET Core 或 .NET Framework) 3.选择目标框架(建议使用 .NET 6.0 或更高版本) 4.为您的项目命名(例如 "PdfLibraryComparison) 5.点击创建
Visual Studio 用于设置新 .NET 应用程序的项目创建对话框
IronPDF C# 库安装
安装方法
IronPDF 提供多种安装方式,以适应不同的开发工作流程:
方法 1:使用 NuGet 包管理器(推荐)
最简单的方法是通过 Visual Studio 集成的 NuGet 包管理器:
1.在解决方案资源管理器中右键单击您的项目 2.选择 "管理 NuGet 软件包"。 3.点击 "浏览 "并搜索 "IronPDF" 4.点击安装 IronPDF 官方软件包
通过 Visual Studio 的 NuGet 包管理器界面安装 IronPDF
方法 2:软件包管理器控制台
适用于喜欢使用命令行工具的开发人员:
Install-Package IronPdf
使用软件包管理器控制台,只需一条命令即可安装 IronPDF。
方法 3:直接下载
适用于互联网访问受限的环境:
1.从 NuGet.org 下载 2.将 .nupkg 文件添加到本地 NuGet 源中 3.从本地源安装
方法 4:.NET CLI
适用于 .NET Core/5+ 项目:
dotnet add package IronPdf
安装 ABCpdf
安装方法
ABCpdf 提供类似的安装选项,并有一些额外的注意事项:
方法 1:NuGet 安装
Install-Package ABCpdf -Version 13.0.0.0
请注意,ABCpdf 针对不同版本有单独软件包:
ABCpdf- 标准版(仅限 32 位)ABCpdf.ABCChrome64- 64 位 Chrome 渲染所必需ABCpdf.ABCGecko- 用于 Gecko 渲染引擎
特定平台的注意事项
1.从 WebSupergoo 网站下载 2.解压 ZIP 文件 3.添加对相应 DLL 的引用 4.将本地依赖项复制到输出目录
ABCpdf 的方法:多引擎灵活性
ABCpdf 需要在非 Windows 平台上进行额外设置:
<PackageReference Include="ABCpdf.Linux" Version="13.0.0.0" />
<PackageReference Include="ABCpdf.Linux" Version="13.0.0.0" />
这些库如何处理 HTML 到 PDF 的转换?
了解每个库将 HTML 转换为 PDF 的基本方法差异有助于解释它们的不同功能和性能特点。
IronPDF 的方法:Chrome 优先架构
IronPDF 使用完整的 Chrome 浏览器引擎,具有多项优势:
using IronPdf;
// IronPDF's approach - Chrome rendering with full browser capabilities
var renderer = new ChromePdfRenderer();
// Configure rendering to match Chrome's print preview exactly
renderer.RenderingOptions = ChromePdfRenderOptions.DefaultChrome;
// Or customize for specific needs
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(500); // Wait for JS execution
// Convert complex HTML with modern CSS and JavaScript
string complexHtml = @"
<!DOCTYPE html>
<html>
<head>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;700&display=swap');
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
font-family: 'Roboto', sans-serif;
}
.card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 10px;
padding: 20px;
color: white;
box-shadow: 0 10px 20px rgba(0,0,0,0.19);
transform: translateY(0);
transition: transform 0.3s;
}
@media print {
.card { break-inside: avoid; }
}
</style>
</head>
<body>
<div class='container'>
<div class='card'>
<h2>Modern CSS Support</h2>
<p>Grid, Flexbox, Gradients, Shadows - all rendered perfectly</p>
</div>
<div class='card'>
<h2>Web Fonts</h2>
<p>Google Fonts and custom fonts work seamlessly</p>
</div>
</div>
<script>
// Dynamic content generation
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector('.container');
const dynamicCard = document.createElement('div');
dynamicCard.className = 'card';
dynamicCard.innerHTML = '<h2>JavaScript Generated</h2><p>This card was added by JavaScript</p>';
container.appendChild(dynamicCard);
});
</script>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(complexHtml);
pdf.SaveAs("modern-web-features.pdf");
using IronPdf;
// IronPDF's approach - Chrome rendering with full browser capabilities
var renderer = new ChromePdfRenderer();
// Configure rendering to match Chrome's print preview exactly
renderer.RenderingOptions = ChromePdfRenderOptions.DefaultChrome;
// Or customize for specific needs
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(500); // Wait for JS execution
// Convert complex HTML with modern CSS and JavaScript
string complexHtml = @"
<!DOCTYPE html>
<html>
<head>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;700&display=swap');
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
font-family: 'Roboto', sans-serif;
}
.card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 10px;
padding: 20px;
color: white;
box-shadow: 0 10px 20px rgba(0,0,0,0.19);
transform: translateY(0);
transition: transform 0.3s;
}
@media print {
.card { break-inside: avoid; }
}
</style>
</head>
<body>
<div class='container'>
<div class='card'>
<h2>Modern CSS Support</h2>
<p>Grid, Flexbox, Gradients, Shadows - all rendered perfectly</p>
</div>
<div class='card'>
<h2>Web Fonts</h2>
<p>Google Fonts and custom fonts work seamlessly</p>
</div>
</div>
<script>
// Dynamic content generation
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector('.container');
const dynamicCard = document.createElement('div');
dynamicCard.className = 'card';
dynamicCard.innerHTML = '<h2>JavaScript Generated</h2><p>This card was added by JavaScript</p>';
container.appendChild(dynamicCard);
});
</script>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(complexHtml);
pdf.SaveAs("modern-web-features.pdf");
Imports IronPdf
' IronPDF's approach - Chrome rendering with full browser capabilities
Private renderer = New ChromePdfRenderer()
' Configure rendering to match Chrome's print preview exactly
renderer.RenderingOptions = ChromePdfRenderOptions.DefaultChrome
' Or customize for specific needs
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen
renderer.RenderingOptions.EnableJavaScript = True
renderer.RenderingOptions.WaitFor.RenderDelay(500) ' Wait for JS execution
' Convert complex HTML with modern CSS and JavaScript
Dim complexHtml As String = "
<!DOCTYPE html>
<html>
<head>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;700&display=swap');
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
font-family: 'Roboto', sans-serif;
}
.card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 10px;
padding: 20px;
color: white;
box-shadow: 0 10px 20px rgba(0,0,0,0.19);
transform: translateY(0);
transition: transform 0.3s;
}
@media print {
.card { break-inside: avoid; }
}
</style>
</head>
<body>
<div class='container'>
<div class='card'>
<h2>Modern CSS Support</h2>
<p>Grid, Flexbox, Gradients, Shadows - all rendered perfectly</p>
</div>
<div class='card'>
<h2>Web Fonts</h2>
<p>Google Fonts and custom fonts work seamlessly</p>
</div>
</div>
<script>
// Dynamic content generation
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector('.container');
const dynamicCard = document.createElement('div');
dynamicCard.className = 'card';
dynamicCard.innerHTML = '<h2>JavaScript Generated</h2><p>This card was added by JavaScript</p>';
container.appendChild(dynamicCard);
});
</script>
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(complexHtml)
pdf.SaveAs("modern-web-features.pdf")
这段代码展示了 IronPDF 基于 Chrome 浏览器的几大优势:
1.现代 CSS 支持:网格布局、Flexbox、渐变和变换等功能与在 Chrome 浏览器中完全相同。 2.网页字体集成: Google 字体无需额外配置即可自动加载
- JavaScript执行:动态内容生成发生在 PDF 渲染之前 4.媒体查询:已正确应用印刷专用样式
ABCpdf 的方法:多引擎灵活性
ABCpdf 提供多种渲染引擎,每种引擎都有不同的功能:
using WebSupergoo.ABCpdf13;
// Method 1: Using ABCChrome engine (most modern)
Doc chromeDoc = new Doc();
chromeDoc.HtmlOptions.Engine = EngineType.Chrome;
chromeDoc.HtmlOptions.Chrome.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
// Chrome engine supports modern web standards
int chromeId = chromeDoc.AddImageUrl("https://example.com");
// Chain pages if content overflows
while (chromeDoc.Chainable(chromeId))
{
chromeDoc.Page = chromeDoc.AddPage();
chromeId = chromeDoc.AddImageToChain(chromeId);
}
chromeDoc.Save("chrome-engine-output.pdf");
// Method 2: Using Gecko engine (Firefox-based)
Doc geckoDoc = new Doc();
geckoDoc.HtmlOptions.Engine = EngineType.Gecko;
geckoDoc.HtmlOptions.UseScript = true; // Enable JavaScript
// Gecko provides good standards support with lower resource usage
string html = "<html><body><h1>Gecko Rendered Content</h1></body></html>";
geckoDoc.AddImageHtml(html);
geckoDoc.Save("gecko-engine-output.pdf");
// Method 3: Using MSHTML engine (IE-based, legacy support)
Doc ieDoc = new Doc();
ieDoc.HtmlOptions.Engine = EngineType.MSHtml;
// MSHTML is faster but with limited modern CSS support
ieDoc.AddImageUrl("https://legacy-app.example.com");
ieDoc.Save("ie-engine-output.pdf");
using WebSupergoo.ABCpdf13;
// Method 1: Using ABCChrome engine (most modern)
Doc chromeDoc = new Doc();
chromeDoc.HtmlOptions.Engine = EngineType.Chrome;
chromeDoc.HtmlOptions.Chrome.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
// Chrome engine supports modern web standards
int chromeId = chromeDoc.AddImageUrl("https://example.com");
// Chain pages if content overflows
while (chromeDoc.Chainable(chromeId))
{
chromeDoc.Page = chromeDoc.AddPage();
chromeId = chromeDoc.AddImageToChain(chromeId);
}
chromeDoc.Save("chrome-engine-output.pdf");
// Method 2: Using Gecko engine (Firefox-based)
Doc geckoDoc = new Doc();
geckoDoc.HtmlOptions.Engine = EngineType.Gecko;
geckoDoc.HtmlOptions.UseScript = true; // Enable JavaScript
// Gecko provides good standards support with lower resource usage
string html = "<html><body><h1>Gecko Rendered Content</h1></body></html>";
geckoDoc.AddImageHtml(html);
geckoDoc.Save("gecko-engine-output.pdf");
// Method 3: Using MSHTML engine (IE-based, legacy support)
Doc ieDoc = new Doc();
ieDoc.HtmlOptions.Engine = EngineType.MSHtml;
// MSHTML is faster but with limited modern CSS support
ieDoc.AddImageUrl("https://legacy-app.example.com");
ieDoc.Save("ie-engine-output.pdf");
Imports WebSupergoo.ABCpdf13
' Method 1: Using ABCChrome engine (most modern)
Private chromeDoc As New Doc()
chromeDoc.HtmlOptions.Engine = EngineType.Chrome
chromeDoc.HtmlOptions.Chrome.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
' Chrome engine supports modern web standards
Dim chromeId As Integer = chromeDoc.AddImageUrl("https://example.com")
' Chain pages if content overflows
Do While chromeDoc.Chainable(chromeId)
chromeDoc.Page = chromeDoc.AddPage()
chromeId = chromeDoc.AddImageToChain(chromeId)
Loop
chromeDoc.Save("chrome-engine-output.pdf")
' Method 2: Using Gecko engine (Firefox-based)
Dim geckoDoc As New Doc()
geckoDoc.HtmlOptions.Engine = EngineType.Gecko
geckoDoc.HtmlOptions.UseScript = True ' Enable JavaScript
' Gecko provides good standards support with lower resource usage
Dim html As String = "<html><body><h1>Gecko Rendered Content</h1></body></html>"
geckoDoc.AddImageHtml(html)
geckoDoc.Save("gecko-engine-output.pdf")
' Method 3: Using MSHTML engine (IE-based, legacy support)
Dim ieDoc As New Doc()
ieDoc.HtmlOptions.Engine = EngineType.MSHtml
' MSHTML is faster but with limited modern CSS support
ieDoc.AddImageUrl("https://legacy-app.example.com")
ieDoc.Save("ie-engine-output.pdf")
多引擎方法具有灵活性,但需要仔细考虑:
1.引擎选择:开发者必须为其内容选择合适的引擎。 2.功能对等性:不同的引擎支持不同的 HTML/CSS 功能 3.部署复杂性:每个引擎可能具有不同的运行时要求。 4.测试成本:不同引擎的输出可能存在差异,因此需要进行更多测试。
从 URL 创建 PDF 文档
PDF 库最常见的用例之一是将实时网页转换为 PDF 文档。 让我们来看看每个库是如何处理这项任务的。
使用 IronPDF.
IronPDF 的 URL 到 PDF 转换利用了完整的 Chrome 浏览器引擎:
using IronPdf;
using System;
using System.Threading.Tasks;
public class UrlToPdfConverter
{
public static async Task ConvertUrlToPdfAsync()
{
var renderer = new ChromePdfRenderer();
// Configure for optimal web page capture
renderer.RenderingOptions = new ChromePdfRenderOptions
{
// Viewport and scaling
ViewPortWidth = 1920,
ViewPortHeight = 1080,
ZoomLevel = 100,
// Paper and margins
PaperSize = PdfPaperSize.A4,
MarginTop = 10,
MarginBottom = 10,
MarginLeft = 10,
MarginRight = 10,
// Rendering behavior
CssMediaType = PdfCssMediaType.Screen,
PrintHtmlBackgrounds = true,
CreatePdfFormsFromHtml = true,
// JavaScript and timing
EnableJavaScript = true,
WaitFor = new WaitFor
{
// Wait strategies for dynamic content
RenderDelay = 500, // milliseconds
JavaScriptFinishDelay = 100,
AllowedExecutionTime = 30000 // 30 seconds max
}
};
// Handle authentication if needed
renderer.RenderingOptions.HttpOptions.HttpHeaders.Add("Authorization", "Bearer your-token");
// Convert with error handling
try
{
// Async conversion for better performance
var pdf = await renderer.RenderUrlAsPdfAsync("https://github.com/trending");
// Add metadata
pdf.MetaData.Author = "IronPDF Example";
pdf.MetaData.Title = "GitHub Trending Projects";
pdf.MetaData.CreationDate = DateTime.Now;
// Add watermark
pdf.ApplyWatermark("<h2 style='color:red;opacity:0.5'>CONFIDENTIAL</h2>",
30, VerticalAlignment.Middle, HorizontalAlignment.Center);
pdf.SaveAs("github-trending.pdf");
Console.WriteLine("PDF created successfully!");
}
catch (Exception ex)
{
Console.WriteLine($"Error creating PDF: {ex.Message}");
}
}
}
using IronPdf;
using System;
using System.Threading.Tasks;
public class UrlToPdfConverter
{
public static async Task ConvertUrlToPdfAsync()
{
var renderer = new ChromePdfRenderer();
// Configure for optimal web page capture
renderer.RenderingOptions = new ChromePdfRenderOptions
{
// Viewport and scaling
ViewPortWidth = 1920,
ViewPortHeight = 1080,
ZoomLevel = 100,
// Paper and margins
PaperSize = PdfPaperSize.A4,
MarginTop = 10,
MarginBottom = 10,
MarginLeft = 10,
MarginRight = 10,
// Rendering behavior
CssMediaType = PdfCssMediaType.Screen,
PrintHtmlBackgrounds = true,
CreatePdfFormsFromHtml = true,
// JavaScript and timing
EnableJavaScript = true,
WaitFor = new WaitFor
{
// Wait strategies for dynamic content
RenderDelay = 500, // milliseconds
JavaScriptFinishDelay = 100,
AllowedExecutionTime = 30000 // 30 seconds max
}
};
// Handle authentication if needed
renderer.RenderingOptions.HttpOptions.HttpHeaders.Add("Authorization", "Bearer your-token");
// Convert with error handling
try
{
// Async conversion for better performance
var pdf = await renderer.RenderUrlAsPdfAsync("https://github.com/trending");
// Add metadata
pdf.MetaData.Author = "IronPDF Example";
pdf.MetaData.Title = "GitHub Trending Projects";
pdf.MetaData.CreationDate = DateTime.Now;
// Add watermark
pdf.ApplyWatermark("<h2 style='color:red;opacity:0.5'>CONFIDENTIAL</h2>",
30, VerticalAlignment.Middle, HorizontalAlignment.Center);
pdf.SaveAs("github-trending.pdf");
Console.WriteLine("PDF created successfully!");
}
catch (Exception ex)
{
Console.WriteLine($"Error creating PDF: {ex.Message}");
}
}
}
Imports IronPdf
Imports System
Imports System.Threading.Tasks
Public Class UrlToPdfConverter
Public Shared Async Function ConvertUrlToPdfAsync() As Task
Dim renderer = New ChromePdfRenderer()
' Configure for optimal web page capture
renderer.RenderingOptions = New ChromePdfRenderOptions With {
.ViewPortWidth = 1920,
.ViewPortHeight = 1080,
.ZoomLevel = 100,
.PaperSize = PdfPaperSize.A4,
.MarginTop = 10,
.MarginBottom = 10,
.MarginLeft = 10,
.MarginRight = 10,
.CssMediaType = PdfCssMediaType.Screen,
.PrintHtmlBackgrounds = True,
.CreatePdfFormsFromHtml = True,
.EnableJavaScript = True,
.WaitFor = New WaitFor With {
.RenderDelay = 500,
.JavaScriptFinishDelay = 100,
.AllowedExecutionTime = 30000
}
}
' Handle authentication if needed
renderer.RenderingOptions.HttpOptions.HttpHeaders.Add("Authorization", "Bearer your-token")
' Convert with error handling
Try
' Async conversion for better performance
Dim pdf = Await renderer.RenderUrlAsPdfAsync("https://github.com/trending")
' Add metadata
pdf.MetaData.Author = "IronPDF Example"
pdf.MetaData.Title = "GitHub Trending Projects"
pdf.MetaData.CreationDate = DateTime.Now
' Add watermark
pdf.ApplyWatermark("<h2 style='color:red;opacity:0.5'>CONFIDENTIAL</h2>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center)
pdf.SaveAs("github-trending.pdf")
Console.WriteLine("PDF created successfully!")
Catch ex As Exception
Console.WriteLine($"Error creating PDF: {ex.Message}")
End Try
End Function
End Class
演示的主要功能:
-视口控制:模拟不同的屏幕尺寸以进行响应式测试 -身份验证支持:为受保护的资源添加标头 -动态内容处理:针对 JavaScript 密集型页面的等待策略 -后期处理:转换后添加元数据和水印
使用 ABCpdf.
ABCpdf 带有页面链的 URL 转换:
using WebSupergoo.ABCpdf13;
using System;
public class ABCpdfUrlConverter
{
public static void ConvertUrlWithABCpdf()
{
using (Doc theDoc = new Doc())
{
// Configure the HTML engine
theDoc.HtmlOptions.Engine = EngineType.Chrome;
theDoc.HtmlOptions.Chrome.LoadDelay = 1000; // Wait 1 second
// Set viewport size
theDoc.HtmlOptions.BrowserWidth = 1200;
// Authentication
theDoc.HtmlOptions.HttpAdditionalHeaders = "Authorization: Bearer your-token";
// Page setup
theDoc.Rect.Inset(20, 20);
theDoc.Page = theDoc.AddPage();
// Add the URL
int theID = theDoc.AddImageUrl("https://github.com/trending");
// Chain pages for overflow content
while (true)
{
if (!theDoc.Chainable(theID))
break;
theDoc.Page = theDoc.AddPage();
theID = theDoc.AddImageToChain(theID);
}
// Reduce file size
for (int i = 1; i <= theDoc.PageCount; i++)
{
theDoc.PageNumber = i;
theDoc.Flatten();
}
// Save
theDoc.Save("abcpdf-github.pdf");
}
}
}
using WebSupergoo.ABCpdf13;
using System;
public class ABCpdfUrlConverter
{
public static void ConvertUrlWithABCpdf()
{
using (Doc theDoc = new Doc())
{
// Configure the HTML engine
theDoc.HtmlOptions.Engine = EngineType.Chrome;
theDoc.HtmlOptions.Chrome.LoadDelay = 1000; // Wait 1 second
// Set viewport size
theDoc.HtmlOptions.BrowserWidth = 1200;
// Authentication
theDoc.HtmlOptions.HttpAdditionalHeaders = "Authorization: Bearer your-token";
// Page setup
theDoc.Rect.Inset(20, 20);
theDoc.Page = theDoc.AddPage();
// Add the URL
int theID = theDoc.AddImageUrl("https://github.com/trending");
// Chain pages for overflow content
while (true)
{
if (!theDoc.Chainable(theID))
break;
theDoc.Page = theDoc.AddPage();
theID = theDoc.AddImageToChain(theID);
}
// Reduce file size
for (int i = 1; i <= theDoc.PageCount; i++)
{
theDoc.PageNumber = i;
theDoc.Flatten();
}
// Save
theDoc.Save("abcpdf-github.pdf");
}
}
}
Imports WebSupergoo.ABCpdf13
Imports System
Public Class ABCpdfUrlConverter
Public Shared Sub ConvertUrlWithABCpdf()
Using theDoc As New Doc()
' Configure the HTML engine
theDoc.HtmlOptions.Engine = EngineType.Chrome
theDoc.HtmlOptions.Chrome.LoadDelay = 1000 ' Wait 1 second
' Set viewport size
theDoc.HtmlOptions.BrowserWidth = 1200
' Authentication
theDoc.HtmlOptions.HttpAdditionalHeaders = "Authorization: Bearer your-token"
' Page setup
theDoc.Rect.Inset(20, 20)
theDoc.Page = theDoc.AddPage()
' Add the URL
Dim theID As Integer = theDoc.AddImageUrl("https://github.com/trending")
' Chain pages for overflow content
Do
If Not theDoc.Chainable(theID) Then
Exit Do
End If
theDoc.Page = theDoc.AddPage()
theID = theDoc.AddImageToChain(theID)
Loop
' Reduce file size
For i As Integer = 1 To theDoc.PageCount
theDoc.PageNumber = i
theDoc.Flatten()
Next i
' Save
theDoc.Save("abcpdf-github.pdf")
End Using
End Sub
End Class
显著差异:
-页面链接:手动处理多页面内容
-引擎配置:必须明确选择渲染引擎
资源管理:需要使用 using 声明进行妥善处置
从 HTML 字符串创建 PDF.
这两个库都擅长将 HTML 字符串转换为 PDF,但它们的方法有很大不同。
使用 IronPDF.
IronPDF 的 HTML 字符串转换,具有高级功能:
using IronPdf;
using System.IO;
public class HtmlStringToPdf
{
public static void GenerateInvoicePdf()
{
var renderer = new ChromePdfRenderer();
// Configure for print-quality output
renderer.RenderingOptions = new ChromePdfRenderOptions
{
PaperSize = PdfPaperSize.A4,
DPI = 300, // High quality print
CssMediaType = PdfCssMediaType.Print,
PaperFit = new PaperFit
{
UseFitToPageRendering = true,
RenderScale = 100
}
};
// Professional invoice HTML
string invoiceHtml = @"
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<style>
@page {
size: A4;
margin: 0;
}
body {
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 20mm;
color: #333;
}
.invoice-header {
display: flex;
justify-content: space-between;
align-items: start;
margin-bottom: 30px;
border-bottom: 2px solid #0066cc;
padding-bottom: 20px;
}
.company-info h1 {
color: #0066cc;
margin: 0;
font-size: 28px;
}
.invoice-details {
text-align: right;
}
.invoice-details h2 {
color: #666;
margin: 0 0 10px 0;
font-size: 24px;
}
.invoice-table {
width: 100%;
border-collapse: collapse;
margin-top: 30px;
}
.invoice-table th {
background-color: #0066cc;
color: white;
padding: 12px;
text-align: left;
}
.invoice-table td {
padding: 12px;
border-bottom: 1px solid #ddd;
}
.invoice-table tr:hover {
background-color: #f5f5f5;
}
.total-section {
margin-top: 30px;
text-align: right;
}
.total-section .total-row {
display: flex;
justify-content: flex-end;
margin: 5px 0;
}
.total-section .label {
font-weight: bold;
margin-right: 20px;
min-width: 100px;
}
.total-section .grand-total {
font-size: 20px;
color: #0066cc;
border-top: 2px solid #0066cc;
padding-top: 10px;
margin-top: 10px;
}
@media print {
.no-print { display: none; }
}
</style>
</head>
<body>
<div class='invoice-header'>
<div class='company-info'>
<h1>ACME Corporation</h1>
<p>123 Business Street<br>
New York, NY 10001<br>
Phone: (555) 123-4567<br>
Email: billing@acme.com</p>
</div>
<div class='invoice-details'>
<h2>INVOICE</h2>
<p><strong>Invoice #:</strong> INV-2025-001<br>
<strong>Date:</strong> " + DateTime.Now.ToString("MMMM dd, yyyy") + @"<br>
<strong>Due Date:</strong> " + DateTime.Now.AddDays(30).ToString("MMMM dd, yyyy") + @"</p>
</div>
</div>
<div class='billing-info'>
<h3>Bill To:</h3>
<p>John Doe<br>
456 Client Avenue<br>
Los Angeles, CA 90001</p>
</div>
<table class='invoice-table'>
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Professional Services - Web Development</td>
<td>40 hours</td>
<td>$150.00</td>
<td>$6,000.00</td>
</tr>
<tr>
<td>Hosting Services (Annual)</td>
<td>1</td>
<td>$1,200.00</td>
<td>$1,200.00</td>
</tr>
<tr>
<td>Domain Registration</td>
<td>2</td>
<td>$15.00</td>
<td>$30.00</td>
</tr>
</tbody>
</table>
<div class='total-section'>
<div class='total-row'>
<span class='label'>Subtotal:</span>
<span>$7,230.00</span>
</div>
<div class='total-row'>
<span class='label'>Tax (8%):</span>
<span>$578.40</span>
</div>
<div class='total-row grand-total'>
<span class='label'>Total Due:</span>
<span>$7,808.40</span>
</div>
</div>
<div class='footer' style='margin-top: 50px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center; color: #666;'>
<p>Thank you for your business!<br>
Payment is due within 30 days. Please include invoice number with payment.</p>
</div>
</body>
</html>";
// Generate PDF with base path for local assets
var pdf = renderer.RenderHtmlAsPdf(invoiceHtml, @"C:\Assets\");
// Add security
pdf.SecuritySettings.AllowUserEditing = false;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.OwnerPassword = "admin123";
// Save with optimization
pdf.CompressImages(60); // 60% quality for smaller file size
pdf.SaveAs("professional-invoice.pdf");
}
}
using IronPdf;
using System.IO;
public class HtmlStringToPdf
{
public static void GenerateInvoicePdf()
{
var renderer = new ChromePdfRenderer();
// Configure for print-quality output
renderer.RenderingOptions = new ChromePdfRenderOptions
{
PaperSize = PdfPaperSize.A4,
DPI = 300, // High quality print
CssMediaType = PdfCssMediaType.Print,
PaperFit = new PaperFit
{
UseFitToPageRendering = true,
RenderScale = 100
}
};
// Professional invoice HTML
string invoiceHtml = @"
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<style>
@page {
size: A4;
margin: 0;
}
body {
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 20mm;
color: #333;
}
.invoice-header {
display: flex;
justify-content: space-between;
align-items: start;
margin-bottom: 30px;
border-bottom: 2px solid #0066cc;
padding-bottom: 20px;
}
.company-info h1 {
color: #0066cc;
margin: 0;
font-size: 28px;
}
.invoice-details {
text-align: right;
}
.invoice-details h2 {
color: #666;
margin: 0 0 10px 0;
font-size: 24px;
}
.invoice-table {
width: 100%;
border-collapse: collapse;
margin-top: 30px;
}
.invoice-table th {
background-color: #0066cc;
color: white;
padding: 12px;
text-align: left;
}
.invoice-table td {
padding: 12px;
border-bottom: 1px solid #ddd;
}
.invoice-table tr:hover {
background-color: #f5f5f5;
}
.total-section {
margin-top: 30px;
text-align: right;
}
.total-section .total-row {
display: flex;
justify-content: flex-end;
margin: 5px 0;
}
.total-section .label {
font-weight: bold;
margin-right: 20px;
min-width: 100px;
}
.total-section .grand-total {
font-size: 20px;
color: #0066cc;
border-top: 2px solid #0066cc;
padding-top: 10px;
margin-top: 10px;
}
@media print {
.no-print { display: none; }
}
</style>
</head>
<body>
<div class='invoice-header'>
<div class='company-info'>
<h1>ACME Corporation</h1>
<p>123 Business Street<br>
New York, NY 10001<br>
Phone: (555) 123-4567<br>
Email: billing@acme.com</p>
</div>
<div class='invoice-details'>
<h2>INVOICE</h2>
<p><strong>Invoice #:</strong> INV-2025-001<br>
<strong>Date:</strong> " + DateTime.Now.ToString("MMMM dd, yyyy") + @"<br>
<strong>Due Date:</strong> " + DateTime.Now.AddDays(30).ToString("MMMM dd, yyyy") + @"</p>
</div>
</div>
<div class='billing-info'>
<h3>Bill To:</h3>
<p>John Doe<br>
456 Client Avenue<br>
Los Angeles, CA 90001</p>
</div>
<table class='invoice-table'>
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Professional Services - Web Development</td>
<td>40 hours</td>
<td>$150.00</td>
<td>$6,000.00</td>
</tr>
<tr>
<td>Hosting Services (Annual)</td>
<td>1</td>
<td>$1,200.00</td>
<td>$1,200.00</td>
</tr>
<tr>
<td>Domain Registration</td>
<td>2</td>
<td>$15.00</td>
<td>$30.00</td>
</tr>
</tbody>
</table>
<div class='total-section'>
<div class='total-row'>
<span class='label'>Subtotal:</span>
<span>$7,230.00</span>
</div>
<div class='total-row'>
<span class='label'>Tax (8%):</span>
<span>$578.40</span>
</div>
<div class='total-row grand-total'>
<span class='label'>Total Due:</span>
<span>$7,808.40</span>
</div>
</div>
<div class='footer' style='margin-top: 50px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center; color: #666;'>
<p>Thank you for your business!<br>
Payment is due within 30 days. Please include invoice number with payment.</p>
</div>
</body>
</html>";
// Generate PDF with base path for local assets
var pdf = renderer.RenderHtmlAsPdf(invoiceHtml, @"C:\Assets\");
// Add security
pdf.SecuritySettings.AllowUserEditing = false;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.OwnerPassword = "admin123";
// Save with optimization
pdf.CompressImages(60); // 60% quality for smaller file size
pdf.SaveAs("professional-invoice.pdf");
}
}
Imports IronPdf
Imports System.IO
Public Class HtmlStringToPdf
Public Shared Sub GenerateInvoicePdf()
Dim renderer = New ChromePdfRenderer()
' Configure for print-quality output
renderer.RenderingOptions = New ChromePdfRenderOptions With {
.PaperSize = PdfPaperSize.A4,
.DPI = 300,
.CssMediaType = PdfCssMediaType.Print,
.PaperFit = New PaperFit With {
.UseFitToPageRendering = True,
.RenderScale = 100
}
}
' Professional invoice HTML
Dim invoiceHtml As String = "
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<style>
@page {
size: A4;
margin: 0;
}
body {
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 20mm;
color: #333;
}
.invoice-header {
display: flex;
justify-content: space-between;
align-items: start;
margin-bottom: 30px;
border-bottom: 2px solid #0066cc;
padding-bottom: 20px;
}
.company-info h1 {
color: #0066cc;
margin: 0;
font-size: 28px;
}
.invoice-details {
text-align: right;
}
.invoice-details h2 {
color: #666;
margin: 0 0 10px 0;
font-size: 24px;
}
.invoice-table {
width: 100%;
border-collapse: collapse;
margin-top: 30px;
}
.invoice-table th {
background-color: #0066cc;
color: white;
padding: 12px;
text-align: left;
}
.invoice-table td {
padding: 12px;
border-bottom: 1px solid #ddd;
}
.invoice-table tr:hover {
background-color: #f5f5f5;
}
.total-section {
margin-top: 30px;
text-align: right;
}
.total-section .total-row {
display: flex;
justify-content: flex-end;
margin: 5px 0;
}
.total-section .label {
font-weight: bold;
margin-right: 20px;
min-width: 100px;
}
.total-section .grand-total {
font-size: 20px;
color: #0066cc;
border-top: 2px solid #0066cc;
padding-top: 10px;
margin-top: 10px;
}
@media print {
.no-print { display: none; }
}
</style>
</head>
<body>
<div class='invoice-header'>
<div class='company-info'>
<h1>ACME Corporation</h1>
<p>123 Business Street<br>
New York, NY 10001<br>
Phone: (555) 123-4567<br>
Email: billing@acme.com</p>
</div>
<div class='invoice-details'>
<h2>INVOICE</h2>
<p><strong>Invoice #:</strong> INV-2025-001<br>
<strong>Date:</strong> " & DateTime.Now.ToString("MMMM dd, yyyy") & "<br>
<strong>Due Date:</strong> " & DateTime.Now.AddDays(30).ToString("MMMM dd, yyyy") & "</p>
</div>
</div>
<div class='billing-info'>
<h3>Bill To:</h3>
<p>John Doe<br>
456 Client Avenue<br>
Los Angeles, CA 90001</p>
</div>
<table class='invoice-table'>
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Professional Services - Web Development</td>
<td>40 hours</td>
<td>$150.00</td>
<td>$6,000.00</td>
</tr>
<tr>
<td>Hosting Services (Annual)</td>
<td>1</td>
<td>$1,200.00</td>
<td>$1,200.00</td>
</tr>
<tr>
<td>Domain Registration</td>
<td>2</td>
<td>$15.00</td>
<td>$30.00</td>
</tr>
</tbody>
</table>
<div class='total-section'>
<div class='total-row'>
<span class='label'>Subtotal:</span>
<span>$7,230.00</span>
</div>
<div class='total-row'>
<span class='label'>Tax (8%):</span>
<span>$578.40</span>
</div>
<div class='total-row grand-total'>
<span class='label'>Total Due:</span>
<span>$7,808.40</span>
</div>
</div>
<div class='footer' style='margin-top: 50px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center; color: #666;'>
<p>Thank you for your business!<br>
Payment is due within 30 days. Please include invoice number with payment.</p>
</div>
</body>
</html>"
' Generate PDF with base path for local assets
Dim pdf = renderer.RenderHtmlAsPdf(invoiceHtml, "C:\Assets\")
' Add security
pdf.SecuritySettings.AllowUserEditing = False
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.OwnerPassword = "admin123"
' Save with optimization
pdf.CompressImages(60) ' 60% quality for smaller file size
pdf.SaveAs("professional-invoice.pdf")
End Sub
End Class
本范例展示了
Professional布局:采用 flexbox 和 grid 的复杂 CSS 布局 -动态内容:日期计算和格式化 -打印优化:针对打印特定样式的媒体查询 -安全功能:密码保护和权限设置 文件优化:图像压缩以减小文件大小
使用 ABCpdf.
ABCpdf 的 HTML 字符串处理与样式化文本:
using WebSupergoo.ABCpdf13;
public class ABCpdfHtmlString
{
public static void CreateStyledDocument()
{
using (Doc theDoc = new Doc())
{
// Set up the document
theDoc.Rect.Inset(40, 40);
theDoc.Color.String = "0 0 0"; // Black text
// Add styled HTML content
theDoc.FontSize = 48;
string styledHtml = @"
<h1 style='color: #0066cc'>ABCpdf Document</h1>
<p style='font-size: 14pt; line-height: 1.5'>
This demonstrates <b>bold text</b>, <i>italic text</i>,
and <span style='color: red'>colored text</span>.
</p>
<ul style='margin-left: 20px'>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</ul>";
// Add HTML with automatic text flow
int theID = theDoc.AddImageHtml(styledHtml);
// Continue on new pages if needed
while (true)
{
if (!theDoc.Chainable(theID))
break;
theDoc.Page = theDoc.AddPage();
theID = theDoc.AddImageToChain(theID);
}
// Apply compression
theDoc.Encryption.Type = 2; // 128-bit encryption
theDoc.Encryption.CanPrint = true;
theDoc.Encryption.CanModify = false;
theDoc.Save("styled-abcpdf.pdf");
}
}
}
using WebSupergoo.ABCpdf13;
public class ABCpdfHtmlString
{
public static void CreateStyledDocument()
{
using (Doc theDoc = new Doc())
{
// Set up the document
theDoc.Rect.Inset(40, 40);
theDoc.Color.String = "0 0 0"; // Black text
// Add styled HTML content
theDoc.FontSize = 48;
string styledHtml = @"
<h1 style='color: #0066cc'>ABCpdf Document</h1>
<p style='font-size: 14pt; line-height: 1.5'>
This demonstrates <b>bold text</b>, <i>italic text</i>,
and <span style='color: red'>colored text</span>.
</p>
<ul style='margin-left: 20px'>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</ul>";
// Add HTML with automatic text flow
int theID = theDoc.AddImageHtml(styledHtml);
// Continue on new pages if needed
while (true)
{
if (!theDoc.Chainable(theID))
break;
theDoc.Page = theDoc.AddPage();
theID = theDoc.AddImageToChain(theID);
}
// Apply compression
theDoc.Encryption.Type = 2; // 128-bit encryption
theDoc.Encryption.CanPrint = true;
theDoc.Encryption.CanModify = false;
theDoc.Save("styled-abcpdf.pdf");
}
}
}
Imports WebSupergoo.ABCpdf13
Public Class ABCpdfHtmlString
Public Shared Sub CreateStyledDocument()
Using theDoc As New Doc()
' Set up the document
theDoc.Rect.Inset(40, 40)
theDoc.Color.String = "0 0 0" ' Black text
' Add styled HTML content
theDoc.FontSize = 48
Dim styledHtml As String = "
<h1 style='color: #0066cc'>ABCpdf Document</h1>
<p style='font-size: 14pt; line-height: 1.5'>
This demonstrates <b>bold text</b>, <i>italic text</i>,
and <span style='color: red'>colored text</span>.
</p>
<ul style='margin-left: 20px'>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</ul>"
' Add HTML with automatic text flow
Dim theID As Integer = theDoc.AddImageHtml(styledHtml)
' Continue on new pages if needed
Do
If Not theDoc.Chainable(theID) Then
Exit Do
End If
theDoc.Page = theDoc.AddPage()
theID = theDoc.AddImageToChain(theID)
Loop
' Apply compression
theDoc.Encryption.Type = 2 ' 128-bit encryption
theDoc.Encryption.CanPrint = True
theDoc.Encryption.CanModify = False
theDoc.Save("styled-abcpdf.pdf")
End Using
End Sub
End Class
性能基准测试
了解性能特点有助于为您的特定用例选择合适的库。
基准测试设置
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using IronPdf;
using WebSupergoo.ABCpdf13;
[MemoryDiagnoser]
[SimpleJob(warmupCount: 3, targetCount: 10)]
public class PdfGenerationBenchmark
{
private string _simpleHtml;
private string _complexHtml;
private ChromePdfRenderer _ironPdfRenderer;
private Doc _abcPdfDoc;
[GlobalSetup]
public void Setup()
{
_simpleHtml = "<h1>Simple Document</h1><p>Basic paragraph text.</p>";
_complexHtml = File.ReadAllText("complex-page.html"); // 50KB HTML with CSS/JS
_ironPdfRenderer = new ChromePdfRenderer();
_abcPdfDoc = new Doc();
_abcPdfDoc.HtmlOptions.Engine = EngineType.Chrome;
}
[Benchmark]
public void IronPDF_SimpleHtml()
{
var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_simpleHtml);
pdf.SaveAs("temp_iron_simple.pdf");
}
[Benchmark]
public void ABCpdf_SimpleHtml()
{
_abcPdfDoc.Clear();
_abcPdfDoc.AddImageHtml(_simpleHtml);
_abcPdfDoc.Save("temp_abc_simple.pdf");
}
[Benchmark]
public void IronPDF_ComplexHtml()
{
var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_complexHtml);
pdf.SaveAs("temp_iron_complex.pdf");
}
[Benchmark]
public void ABCpdf_ComplexHtml()
{
_abcPdfDoc.Clear();
int id = _abcPdfDoc.AddImageHtml(_complexHtml);
while (_abcPdfDoc.Chainable(id))
{
_abcPdfDoc.Page = _abcPdfDoc.AddPage();
id = _abcPdfDoc.AddImageToChain(id);
}
_abcPdfDoc.Save("temp_abc_complex.pdf");
}
}
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using IronPdf;
using WebSupergoo.ABCpdf13;
[MemoryDiagnoser]
[SimpleJob(warmupCount: 3, targetCount: 10)]
public class PdfGenerationBenchmark
{
private string _simpleHtml;
private string _complexHtml;
private ChromePdfRenderer _ironPdfRenderer;
private Doc _abcPdfDoc;
[GlobalSetup]
public void Setup()
{
_simpleHtml = "<h1>Simple Document</h1><p>Basic paragraph text.</p>";
_complexHtml = File.ReadAllText("complex-page.html"); // 50KB HTML with CSS/JS
_ironPdfRenderer = new ChromePdfRenderer();
_abcPdfDoc = new Doc();
_abcPdfDoc.HtmlOptions.Engine = EngineType.Chrome;
}
[Benchmark]
public void IronPDF_SimpleHtml()
{
var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_simpleHtml);
pdf.SaveAs("temp_iron_simple.pdf");
}
[Benchmark]
public void ABCpdf_SimpleHtml()
{
_abcPdfDoc.Clear();
_abcPdfDoc.AddImageHtml(_simpleHtml);
_abcPdfDoc.Save("temp_abc_simple.pdf");
}
[Benchmark]
public void IronPDF_ComplexHtml()
{
var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_complexHtml);
pdf.SaveAs("temp_iron_complex.pdf");
}
[Benchmark]
public void ABCpdf_ComplexHtml()
{
_abcPdfDoc.Clear();
int id = _abcPdfDoc.AddImageHtml(_complexHtml);
while (_abcPdfDoc.Chainable(id))
{
_abcPdfDoc.Page = _abcPdfDoc.AddPage();
id = _abcPdfDoc.AddImageToChain(id);
}
_abcPdfDoc.Save("temp_abc_complex.pdf");
}
}
Imports BenchmarkDotNet.Attributes
Imports BenchmarkDotNet.Running
Imports IronPdf
Imports WebSupergoo.ABCpdf13
<MemoryDiagnoser>
<SimpleJob(warmupCount:= 3, targetCount:= 10)>
Public Class PdfGenerationBenchmark
Private _simpleHtml As String
Private _complexHtml As String
Private _ironPdfRenderer As ChromePdfRenderer
Private _abcPdfDoc As Doc
<GlobalSetup>
Public Sub Setup()
_simpleHtml = "<h1>Simple Document</h1><p>Basic paragraph text.</p>"
_complexHtml = File.ReadAllText("complex-page.html") ' 50KB HTML with CSS/JS
_ironPdfRenderer = New ChromePdfRenderer()
_abcPdfDoc = New Doc()
_abcPdfDoc.HtmlOptions.Engine = EngineType.Chrome
End Sub
<Benchmark>
Public Sub IronPDF_SimpleHtml()
Dim pdf = _ironPdfRenderer.RenderHtmlAsPdf(_simpleHtml)
pdf.SaveAs("temp_iron_simple.pdf")
End Sub
<Benchmark>
Public Sub ABCpdf_SimpleHtml()
_abcPdfDoc.Clear()
_abcPdfDoc.AddImageHtml(_simpleHtml)
_abcPdfDoc.Save("temp_abc_simple.pdf")
End Sub
<Benchmark>
Public Sub IronPDF_ComplexHtml()
Dim pdf = _ironPdfRenderer.RenderHtmlAsPdf(_complexHtml)
pdf.SaveAs("temp_iron_complex.pdf")
End Sub
<Benchmark>
Public Sub ABCpdf_ComplexHtml()
_abcPdfDoc.Clear()
Dim id As Integer = _abcPdfDoc.AddImageHtml(_complexHtml)
Do While _abcPdfDoc.Chainable(id)
_abcPdfDoc.Page = _abcPdfDoc.AddPage()
id = _abcPdfDoc.AddImageToChain(id)
Loop
_abcPdfDoc.Save("temp_abc_complex.pdf")
End Sub
End Class
典型结果
| 翻译方法 | 平均值 | 错误 | StdDev | 记忆库 |
|---|---|---|---|---|
| IronPDF_SimpleHtml | 245.3 毫秒 | 4.2 毫秒 | 3.8 毫秒 | 152 MB |
| ABCpdf_SimpleHtml | 187.6 毫秒 | 3.1 毫秒 | 2.9 毫秒 | 98 MB |
| IronPDF_ComplexHtml | 892.4 毫秒 | 12.3 毫秒 | 10.8 毫秒 | 201 MB |
| ABCpdf_ComplexHtml | 743.2 毫秒 | 9.7 毫秒 | 8.6 毫秒 | 145 MB |
主要意见:
- ABCpdf 显示更快的原始转换时间
- IronPDF 因采用全 Chrome 引擎而占用更多内存
- 这两个库的规模与文档的复杂程度成线性关系
- IronPDF 的开销提供了更好的渲染准确性
高级功能比较
数字签名和安全性
IronPDF 数字签名实现
using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;
public class SecurityFeatures
{
public static void ApplyDigitalSignature()
{
// Load existing PDF
var pdf = PdfDocument.FromFile("unsigned-document.pdf");
// Load certificate
var cert = new X509Certificate2("certificate.pfx", "password");
// Create signature
var signature = new PdfSignature(cert)
{
// Visual signature appearance
SignatureImage = new PdfSignature.SignatureImage
{
ImagePath = "signature.png",
Width = 200,
Height = 100
},
// Signature position
PageIndex = 0,
X = 400,
Y = 100,
// Signature details
Reason = "Document approved",
Location = "New York, NY",
ContactInfo = "john.doe@company.com"
};
// Apply signature
pdf.Sign(signature);
// Additional security
pdf.SecuritySettings = new SecuritySettings
{
AllowUserPrinting = true,
AllowUserCopyPasteContent = false,
AllowUserEditing = false,
AllowUserFormData = true,
OwnerPassword = "owner123",
UserPassword = "user123",
EncryptionLevel = EncryptionLevel.AES256
};
pdf.SaveAs("signed-secured.pdf");
}
}
using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;
public class SecurityFeatures
{
public static void ApplyDigitalSignature()
{
// Load existing PDF
var pdf = PdfDocument.FromFile("unsigned-document.pdf");
// Load certificate
var cert = new X509Certificate2("certificate.pfx", "password");
// Create signature
var signature = new PdfSignature(cert)
{
// Visual signature appearance
SignatureImage = new PdfSignature.SignatureImage
{
ImagePath = "signature.png",
Width = 200,
Height = 100
},
// Signature position
PageIndex = 0,
X = 400,
Y = 100,
// Signature details
Reason = "Document approved",
Location = "New York, NY",
ContactInfo = "john.doe@company.com"
};
// Apply signature
pdf.Sign(signature);
// Additional security
pdf.SecuritySettings = new SecuritySettings
{
AllowUserPrinting = true,
AllowUserCopyPasteContent = false,
AllowUserEditing = false,
AllowUserFormData = true,
OwnerPassword = "owner123",
UserPassword = "user123",
EncryptionLevel = EncryptionLevel.AES256
};
pdf.SaveAs("signed-secured.pdf");
}
}
Imports IronPdf
Imports IronPdf.Signing
Imports System.Security.Cryptography.X509Certificates
Public Class SecurityFeatures
Public Shared Sub ApplyDigitalSignature()
' Load existing PDF
Dim pdf = PdfDocument.FromFile("unsigned-document.pdf")
' Load certificate
Dim cert = New X509Certificate2("certificate.pfx", "password")
' Create signature
Dim signature = New PdfSignature(cert) With {
.SignatureImage = New PdfSignature.SignatureImage With {
.ImagePath = "signature.png",
.Width = 200,
.Height = 100
},
.PageIndex = 0,
.X = 400,
.Y = 100,
.Reason = "Document approved",
.Location = "New York, NY",
.ContactInfo = "john.doe@company.com"
}
' Apply signature
pdf.Sign(signature)
' Additional security
pdf.SecuritySettings = New SecuritySettings With {
.AllowUserPrinting = True,
.AllowUserCopyPasteContent = False,
.AllowUserEditing = False,
.AllowUserFormData = True,
.OwnerPassword = "owner123",
.UserPassword = "user123",
.EncryptionLevel = EncryptionLevel.AES256
}
pdf.SaveAs("signed-secured.pdf")
End Sub
End Class
ABCpdf 数字签名实现
using WebSupergoo.ABCpdf13;
using WebSupergoo.ABCpdf13.Objects;
public class ABCpdfSecurity
{
public static void SignDocument()
{
using (Doc theDoc = new Doc())
{
theDoc.Read("unsigned-document.pdf");
// Create signature field
Field signatureField = theDoc.Form.AddFieldSignature("AuthorSignature");
signatureField.Page = 1;
signatureField.Rect = "400 100 600 200";
// Configure signature
Signature theSig = signatureField.Sign();
theSig.Reason = "Document approved";
theSig.Location = "New York, NY";
theSig.ContactInfo = "john.doe@company.com";
// Load certificate
theSig.LoadCertificate("certificate.pfx", "password");
// Apply visual signature
theSig.Visible = true;
theSig.Image = theDoc.AddImageFile("signature.png");
// Sign and save
theDoc.Save("abcpdf-signed.pdf");
}
}
}
using WebSupergoo.ABCpdf13;
using WebSupergoo.ABCpdf13.Objects;
public class ABCpdfSecurity
{
public static void SignDocument()
{
using (Doc theDoc = new Doc())
{
theDoc.Read("unsigned-document.pdf");
// Create signature field
Field signatureField = theDoc.Form.AddFieldSignature("AuthorSignature");
signatureField.Page = 1;
signatureField.Rect = "400 100 600 200";
// Configure signature
Signature theSig = signatureField.Sign();
theSig.Reason = "Document approved";
theSig.Location = "New York, NY";
theSig.ContactInfo = "john.doe@company.com";
// Load certificate
theSig.LoadCertificate("certificate.pfx", "password");
// Apply visual signature
theSig.Visible = true;
theSig.Image = theDoc.AddImageFile("signature.png");
// Sign and save
theDoc.Save("abcpdf-signed.pdf");
}
}
}
Imports WebSupergoo.ABCpdf13
Imports WebSupergoo.ABCpdf13.Objects
Public Class ABCpdfSecurity
Public Shared Sub SignDocument()
Using theDoc As New Doc()
theDoc.Read("unsigned-document.pdf")
' Create signature field
Dim signatureField As Field = theDoc.Form.AddFieldSignature("AuthorSignature")
signatureField.Page = 1
signatureField.Rect = "400 100 600 200"
' Configure signature
Dim theSig As Signature = signatureField.Sign()
theSig.Reason = "Document approved"
theSig.Location = "New York, NY"
theSig.ContactInfo = "john.doe@company.com"
' Load certificate
theSig.LoadCertificate("certificate.pfx", "password")
' Apply visual signature
theSig.Visible = True
theSig.Image = theDoc.AddImageFile("signature.png")
' Sign and save
theDoc.Save("abcpdf-signed.pdf")
End Using
End Sub
End Class
表单处理和数据提取
- 构建云原生应用程序
public class FormHandling
{
public static void WorkWithForms()
{
// Create PDF with form fields from HTML
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;
string formHtml = @"
<form>
<label>Name: <input type='text' name='fullname' required></label><br>
<label>Email: <input type='email' name='email' required></label><br>
<label>Subscribe: <input type='checkbox' name='subscribe' value='yes'></label><br>
<label>Country:
<select name='country'>
<option>USA</option>
<option>Canada</option>
<option>UK</option>
</select>
</label><br>
<button type='submit'>Submit</button>
</form>";
var pdf = renderer.RenderHtmlAsPdf(formHtml);
// Fill form programmatically
pdf.Form.Fields["fullname"].Value = "John Doe";
pdf.Form.Fields["email"].Value = "john@example.com";
pdf.Form.Fields["subscribe"].Value = "yes";
pdf.Form.Fields["country"].Value = "USA";
// Extract form data
foreach (var field in pdf.Form.Fields)
{
Console.WriteLine($"{field.Name}: {field.Value}");
}
// Flatten form (make non-editable)
pdf.Form.Flatten();
pdf.SaveAs("filled-form.pdf");
}
}
public class FormHandling
{
public static void WorkWithForms()
{
// Create PDF with form fields from HTML
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;
string formHtml = @"
<form>
<label>Name: <input type='text' name='fullname' required></label><br>
<label>Email: <input type='email' name='email' required></label><br>
<label>Subscribe: <input type='checkbox' name='subscribe' value='yes'></label><br>
<label>Country:
<select name='country'>
<option>USA</option>
<option>Canada</option>
<option>UK</option>
</select>
</label><br>
<button type='submit'>Submit</button>
</form>";
var pdf = renderer.RenderHtmlAsPdf(formHtml);
// Fill form programmatically
pdf.Form.Fields["fullname"].Value = "John Doe";
pdf.Form.Fields["email"].Value = "john@example.com";
pdf.Form.Fields["subscribe"].Value = "yes";
pdf.Form.Fields["country"].Value = "USA";
// Extract form data
foreach (var field in pdf.Form.Fields)
{
Console.WriteLine($"{field.Name}: {field.Value}");
}
// Flatten form (make non-editable)
pdf.Form.Flatten();
pdf.SaveAs("filled-form.pdf");
}
}
Public Class FormHandling
Public Shared Sub WorkWithForms()
' Create PDF with form fields from HTML
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.CreatePdfFormsFromHtml = True
Dim formHtml As String = "
<form>
<label>Name: <input type='text' name='fullname' required></label><br>
<label>Email: <input type='email' name='email' required></label><br>
<label>Subscribe: <input type='checkbox' name='subscribe' value='yes'></label><br>
<label>Country:
<select name='country'>
<option>USA</option>
<option>Canada</option>
<option>UK</option>
</select>
</label><br>
<button type='submit'>Submit</button>
</form>"
Dim pdf = renderer.RenderHtmlAsPdf(formHtml)
' Fill form programmatically
pdf.Form.Fields("fullname").Value = "John Doe"
pdf.Form.Fields("email").Value = "john@example.com"
pdf.Form.Fields("subscribe").Value = "yes"
pdf.Form.Fields("country").Value = "USA"
' Extract form data
For Each field In pdf.Form.Fields
Console.WriteLine($"{field.Name}: {field.Value}")
Next field
' Flatten form (make non-editable)
pdf.Form.Flatten()
pdf.SaveAs("filled-form.pdf")
End Sub
End Class
批处理和优化
IronPDF 批量处理
using System.Threading.Tasks;
using System.Collections.Concurrent;
public class BatchProcessing
{
public static async Task ProcessMultipleDocumentsAsync(List<string> htmlFiles)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// Use concurrent processing
var pdfResults = new ConcurrentBag<(string filename, byte[] data)>();
await Parallel.ForEachAsync(htmlFiles, async (htmlFile, ct) =>
{
try
{
var html = await File.ReadAllTextAsync(htmlFile);
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
// Optimize each PDF
pdf.CompressImages(70);
var filename = Path.GetFileNameWithoutExtension(htmlFile) + ".pdf";
var data = pdf.BinaryData;
pdfResults.Add((filename, data));
}
catch (Exception ex)
{
Console.WriteLine($"Error processing {htmlFile}: {ex.Message}");
}
});
// Merge all PDFs into one
var finalPdf = new PdfDocument();
foreach (var (filename, data) in pdfResults.OrderBy(x => x.filename))
{
var pdf = new PdfDocument(data);
finalPdf.AppendPdf(pdf);
}
finalPdf.SaveAs("batch-processed.pdf");
}
}
using System.Threading.Tasks;
using System.Collections.Concurrent;
public class BatchProcessing
{
public static async Task ProcessMultipleDocumentsAsync(List<string> htmlFiles)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// Use concurrent processing
var pdfResults = new ConcurrentBag<(string filename, byte[] data)>();
await Parallel.ForEachAsync(htmlFiles, async (htmlFile, ct) =>
{
try
{
var html = await File.ReadAllTextAsync(htmlFile);
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
// Optimize each PDF
pdf.CompressImages(70);
var filename = Path.GetFileNameWithoutExtension(htmlFile) + ".pdf";
var data = pdf.BinaryData;
pdfResults.Add((filename, data));
}
catch (Exception ex)
{
Console.WriteLine($"Error processing {htmlFile}: {ex.Message}");
}
});
// Merge all PDFs into one
var finalPdf = new PdfDocument();
foreach (var (filename, data) in pdfResults.OrderBy(x => x.filename))
{
var pdf = new PdfDocument(data);
finalPdf.AppendPdf(pdf);
}
finalPdf.SaveAs("batch-processed.pdf");
}
}
Imports System.Threading.Tasks
Imports System.Collections.Concurrent
Public Class BatchProcessing
Public Shared Async Function ProcessMultipleDocumentsAsync(ByVal htmlFiles As List(Of String)) As Task
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
' Use concurrent processing
Dim pdfResults = New ConcurrentBag(Of (filename As String, data As Byte()))()
Await Parallel.ForEachAsync(htmlFiles, Async Sub(htmlFile, ct)
Try
Dim html = Await File.ReadAllTextAsync(htmlFile)
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
' Optimize each PDF
pdf.CompressImages(70)
Dim filename = Path.GetFileNameWithoutExtension(htmlFile) & ".pdf"
Dim data = pdf.BinaryData
pdfResults.Add((filename, data))
Catch ex As Exception
Console.WriteLine($"Error processing {htmlFile}: {ex.Message}")
End Try
End Sub)
' Merge all PDFs into one
Dim finalPdf = New PdfDocument()
foreach var(filename, data) In pdfResults.OrderBy(Function(x) x.filename)
Dim pdf = New PdfDocument(data)
finalPdf.AppendPdf(pdf)
Next
finalPdf.SaveAs("batch-processed.pdf")
End Function
End Class
真实世界用例场景
- 开发跨平台解决方案
选择 IronPDF 时:
1.构建云原生应用程序
- 本地 Docker 支持,只需最少的配置
- Azure Functions 和 AWS Lambda 兼容性
- 在所有云平台上保持行为一致
2.要求像素完美的 HTML 渲染。
- 复杂的 CSS 布局(网格、Flexbox)
- JavaScript 繁重的单页面应用程序
- 网页字体要求
3.开发跨平台解决方案
- 针对 Windows、Linux 和 macOS 的应用程序
- 微服务架构
- 基于容器的部署
4.优先考虑开发体验
- 快速原型需求
- 小型开发团队
- 有限的 PDF 专业知识
选择 ABCpdf 时:
1.使用遗留系统
- 仅限 Windows 环境
- 现有的 ABCpdf 实现
- 兼容 IE 内容要求
2.要求使用特定的渲染引擎。
- 跨不同浏览器测试
- 特定引擎优化
- 支持传统浏览器
3.高级 PDF 操作
- 低级 PDF 对象访问
- 自定义 PDF 操作
- 复杂的文档合并场景
4.注重预算的项目
- 较低的入门价格
- 单开发者许可证
- 32 位环境兼容
ABCpdf 常见问题和解决方案
迁移指南:在库之间迁移
public class IronPdfTroubleshooting
{
// Issue: Fonts not rendering correctly
public static void FixFontIssues()
{
var renderer = new ChromePdfRenderer();
// Solution 1: Wait for fonts to load
renderer.RenderingOptions.WaitFor.RenderDelay(1000);
// Solution 2: Use system fonts fallback
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
}
// Issue: JavaScript not executing
public static void FixJavaScriptIssues()
{
var renderer = new ChromePdfRenderer();
// Enable JavaScript and wait for execution
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.JavaScriptFinishDelay = 2000;
renderer.RenderingOptions.WaitFor.AllowedExecutionTime = 30000;
}
// Issue: Memory usage in Docker
public static void OptimizeForDocker()
{
var renderer = new ChromePdfRenderer();
// Use single-threaded mode for containers
IronPdf.Installation.SingleThreaded = true;
// Reduce memory footprint
renderer.RenderingOptions.ViewPortWidth = 1024;
renderer.RenderingOptions.EnableGrayscale = true;
}
}
public class IronPdfTroubleshooting
{
// Issue: Fonts not rendering correctly
public static void FixFontIssues()
{
var renderer = new ChromePdfRenderer();
// Solution 1: Wait for fonts to load
renderer.RenderingOptions.WaitFor.RenderDelay(1000);
// Solution 2: Use system fonts fallback
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
}
// Issue: JavaScript not executing
public static void FixJavaScriptIssues()
{
var renderer = new ChromePdfRenderer();
// Enable JavaScript and wait for execution
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.JavaScriptFinishDelay = 2000;
renderer.RenderingOptions.WaitFor.AllowedExecutionTime = 30000;
}
// Issue: Memory usage in Docker
public static void OptimizeForDocker()
{
var renderer = new ChromePdfRenderer();
// Use single-threaded mode for containers
IronPdf.Installation.SingleThreaded = true;
// Reduce memory footprint
renderer.RenderingOptions.ViewPortWidth = 1024;
renderer.RenderingOptions.EnableGrayscale = true;
}
}
Public Class IronPdfTroubleshooting
' Issue: Fonts not rendering correctly
Public Shared Sub FixFontIssues()
Dim renderer = New ChromePdfRenderer()
' Solution 1: Wait for fonts to load
renderer.RenderingOptions.WaitFor.RenderDelay(1000)
' Solution 2: Use system fonts fallback
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print
End Sub
' Issue: JavaScript not executing
Public Shared Sub FixJavaScriptIssues()
Dim renderer = New ChromePdfRenderer()
' Enable JavaScript and wait for execution
renderer.RenderingOptions.EnableJavaScript = True
renderer.RenderingOptions.WaitFor.JavaScriptFinishDelay = 2000
renderer.RenderingOptions.WaitFor.AllowedExecutionTime = 30000
End Sub
' Issue: Memory usage in Docker
Public Shared Sub OptimizeForDocker()
Dim renderer = New ChromePdfRenderer()
' Use single-threaded mode for containers
IronPdf.Installation.SingleThreaded = True
' Reduce memory footprint
renderer.RenderingOptions.ViewPortWidth = 1024
renderer.RenderingOptions.EnableGrayscale = True
End Sub
End Class
从 ABCpdf 迁移到 IronPDF
public class ABCpdfTroubleshooting
{
// Issue: Page breaks in wrong places
public static void FixPageBreaks()
{
using (Doc theDoc = new Doc())
{
// Use HTML page break controls
theDoc.HtmlOptions.BreakZoneSize = 100; // pixels
theDoc.HtmlOptions.UseScript = true;
string html = @"
<style>
.page-break { page-break-after: always; }
.no-break { page-break-inside: avoid; }
</style>
<div class='no-break'>Keep this content together</div>
<div class='page-break'></div>
<div>New page content</div>";
theDoc.AddImageHtml(html);
theDoc.Save("fixed-breaks.pdf");
}
}
// Issue: Images not loading
public static void FixImageLoading()
{
using (Doc theDoc = new Doc())
{
// Set timeout and authentication
theDoc.HtmlOptions.Timeout = 60000; // 60 seconds
theDoc.HtmlOptions.RetryCount = 3;
// For local images, set base directory
theDoc.HtmlOptions.BaseUrl = @"file:///C:/Images/";
theDoc.AddImageHtml("<img src='logo.png'>");
theDoc.Save("with-images.pdf");
}
}
}
public class ABCpdfTroubleshooting
{
// Issue: Page breaks in wrong places
public static void FixPageBreaks()
{
using (Doc theDoc = new Doc())
{
// Use HTML page break controls
theDoc.HtmlOptions.BreakZoneSize = 100; // pixels
theDoc.HtmlOptions.UseScript = true;
string html = @"
<style>
.page-break { page-break-after: always; }
.no-break { page-break-inside: avoid; }
</style>
<div class='no-break'>Keep this content together</div>
<div class='page-break'></div>
<div>New page content</div>";
theDoc.AddImageHtml(html);
theDoc.Save("fixed-breaks.pdf");
}
}
// Issue: Images not loading
public static void FixImageLoading()
{
using (Doc theDoc = new Doc())
{
// Set timeout and authentication
theDoc.HtmlOptions.Timeout = 60000; // 60 seconds
theDoc.HtmlOptions.RetryCount = 3;
// For local images, set base directory
theDoc.HtmlOptions.BaseUrl = @"file:///C:/Images/";
theDoc.AddImageHtml("<img src='logo.png'>");
theDoc.Save("with-images.pdf");
}
}
}
Public Class ABCpdfTroubleshooting
' Issue: Page breaks in wrong places
Public Shared Sub FixPageBreaks()
Using theDoc As New Doc()
' Use HTML page break controls
theDoc.HtmlOptions.BreakZoneSize = 100 ' pixels
theDoc.HtmlOptions.UseScript = True
Dim html As String = "
<style>
.page-break { page-break-after: always; }
.no-break { page-break-inside: avoid; }
</style>
<div class='no-break'>Keep this content together</div>
<div class='page-break'></div>
<div>New page content</div>"
theDoc.AddImageHtml(html)
theDoc.Save("fixed-breaks.pdf")
End Using
End Sub
' Issue: Images not loading
Public Shared Sub FixImageLoading()
Using theDoc As New Doc()
' Set timeout and authentication
theDoc.HtmlOptions.Timeout = 60000 ' 60 seconds
theDoc.HtmlOptions.RetryCount = 3
' For local images, set base directory
theDoc.HtmlOptions.BaseUrl = "file:///C:/Images/"
theDoc.AddImageHtml("<img src='logo.png'>")
theDoc.Save("with-images.pdf")
End Using
End Sub
End Class
迁移指南:库之间迁移
从 ABCpdf 迁移到 IronPDF.
public class MigrationHelper
{
// ABCpdf code
public void OldABCpdfMethod()
{
Doc theDoc = new Doc();
theDoc.AddImageUrl("https://example.com");
theDoc.Save("output.pdf");
theDoc.Dispose();
}
// Equivalent IronPDF code
public void NewIronPdfMethod()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
}
// Migration wrapper for gradual transition
public class PdfWrapper
{
private bool _useIronPdf;
public PdfWrapper(bool useIronPdf = true)
{
_useIronPdf = useIronPdf;
}
public void ConvertUrlToPdf(string url, string outputPath)
{
if (_useIronPdf)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
else
{
using (var doc = new Doc())
{
doc.AddImageUrl(url);
doc.Save(outputPath);
}
}
}
}
}
public class MigrationHelper
{
// ABCpdf code
public void OldABCpdfMethod()
{
Doc theDoc = new Doc();
theDoc.AddImageUrl("https://example.com");
theDoc.Save("output.pdf");
theDoc.Dispose();
}
// Equivalent IronPDF code
public void NewIronPdfMethod()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
}
// Migration wrapper for gradual transition
public class PdfWrapper
{
private bool _useIronPdf;
public PdfWrapper(bool useIronPdf = true)
{
_useIronPdf = useIronPdf;
}
public void ConvertUrlToPdf(string url, string outputPath)
{
if (_useIronPdf)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
else
{
using (var doc = new Doc())
{
doc.AddImageUrl(url);
doc.Save(outputPath);
}
}
}
}
}
Public Class MigrationHelper
' ABCpdf code
Public Sub OldABCpdfMethod()
Dim theDoc As New Doc()
theDoc.AddImageUrl("https://example.com")
theDoc.Save("output.pdf")
theDoc.Dispose()
End Sub
' Equivalent IronPDF code
Public Sub NewIronPdfMethod()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("output.pdf")
End Sub
' Migration wrapper for gradual transition
Public Class PdfWrapper
Private _useIronPdf As Boolean
Public Sub New(Optional ByVal useIronPdf As Boolean = True)
_useIronPdf = useIronPdf
End Sub
Public Sub ConvertUrlToPdf(ByVal url As String, ByVal outputPath As String)
If _useIronPdf Then
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf(url)
pdf.SaveAs(outputPath)
Else
Using doc As New Doc()
doc.AddImageUrl(url)
doc.Save(outputPath)
End Using
End If
End Sub
End Class
End Class
许可和总体拥有成本
计算您项目的投资回报率
在评估 PDF 库时,要考虑许可证价格以外的总成本:
IronPDF 成本分析
-开发时间节省:实施速度提高 50-70% -支持费用:包含 24/5 全天候工程支持 -维护:跨平台统一 API -可扩展性:单个许可证可覆盖多个部署。
ABCpdf 成本分析
-初始成本:较低的入门价格 -隐性成本:
- 单独的 64 位许可证
- 多种引擎要求
- 特定平台测试
- 额外的支持费用
许可证比较计算器
public class LicenseCostCalculator
{
public static void CalculateTotalCost()
{
// Scenario: 5-developer team, 3-year project
// IronPDF Professional
var ironPdfCost = new
{
License = 2999, // 10 developers, 10 projects
Support = 0, // Included
Training = 500, // Minimal due to simple API
ThreeYearTotal = 3499
};
// ABCpdf equivalent setup
var abcPdfCost = new
{
StandardLicenses = 329 * 5, // 5 developers
ProfessionalUpgrade = 150 * 5, // 64-bit support
再分发License = 4790, // Enterprise
Support = 399 * 3, // Annual support
Training = 2000, // Complex API training
ThreeYearTotal = 1645 + 750 + 4790 + 1197 + 2000
};
Console.WriteLine($"IronPDF 3-year TCO: ${ironPdfCost.ThreeYearTotal:N0}");
Console.WriteLine($"ABCpdf 3-year TCO: ${abcPdfCost.ThreeYearTotal:N0}");
Console.WriteLine($"Savings with IronPDF: ${abcPdfCost.ThreeYearTotal - ironPdfCost.ThreeYearTotal:N0}");
}
}
public class LicenseCostCalculator
{
public static void CalculateTotalCost()
{
// Scenario: 5-developer team, 3-year project
// IronPDF Professional
var ironPdfCost = new
{
License = 2999, // 10 developers, 10 projects
Support = 0, // Included
Training = 500, // Minimal due to simple API
ThreeYearTotal = 3499
};
// ABCpdf equivalent setup
var abcPdfCost = new
{
StandardLicenses = 329 * 5, // 5 developers
ProfessionalUpgrade = 150 * 5, // 64-bit support
再分发License = 4790, // Enterprise
Support = 399 * 3, // Annual support
Training = 2000, // Complex API training
ThreeYearTotal = 1645 + 750 + 4790 + 1197 + 2000
};
Console.WriteLine($"IronPDF 3-year TCO: ${ironPdfCost.ThreeYearTotal:N0}");
Console.WriteLine($"ABCpdf 3-year TCO: ${abcPdfCost.ThreeYearTotal:N0}");
Console.WriteLine($"Savings with IronPDF: ${abcPdfCost.ThreeYearTotal - ironPdfCost.ThreeYearTotal:N0}");
}
}
Public Class LicenseCostCalculator
Public Shared Sub CalculateTotalCost()
' Scenario: 5-developer team, 3-year project
' IronPDF Professional
Dim ironPdfCost = New With {
.License = 2999, ' 10 developers, 10 projects
.Support = 0, ' Included
.Training = 500, ' Minimal due to simple API
.ThreeYearTotal = 3499
}
' ABCpdf equivalent setup
Dim abcPdfCost = New With {
.StandardLicenses = 329 * 5, ' 5 developers
.ProfessionalUpgrade = 150 * 5, ' 64-bit support
.再分发License = 4790, ' Enterprise
.Support = 399 * 3, ' Annual support
.Training = 2000, ' Complex API training
.ThreeYearTotal = 1645 + 750 + 4790 + 1197 + 2000
}
Console.WriteLine($"IronPDF 3-year TCO: ${ironPdfCost.ThreeYearTotal:N0}")
Console.WriteLine($"ABCpdf 3-year TCO: ${abcPdfCost.ThreeYearTotal:N0}")
Console.WriteLine($"Savings with IronPDF: ${abcPdfCost.ThreeYearTotal - ironPdfCost.ThreeYearTotal:N0}")
End Sub
End Class
结论
经过对这两个库的全面分析,可以发现几个关键区别:
IronPDF擅长:
- 支持现代网站技术,基于 Chrome 的渲染
- 跨平台一致性和云原生部署
- 通过直观的 API 提高开发人员的工作效率
- 全面的支持和文档
- 为成长型团队提供更好的长期价值
ABCpdf 的优势在于:
- 降低仅适用于 Windows 的基本项目的初始成本
- 多种渲染引擎选项
- 遗留系统兼容性
- 降低简单文档的内存占用
IronPDF 为所有 PDF 问题提供单一解决方案。 购买 IronPDF 后,您将在一个库中获得所有转换功能,Plus 仅与 PDF 文档相关的任务,无需额外依赖。 这种整合方法,加上卓越的渲染质量和跨平台支持,使 IronPDF 成为大多数现代 .NET 应用程序的推荐选择。
对于优先考虑快速开发、跨平台一致结果和长期可维护性的团队来说,IronPDF 较高的初始成本会被缩短的开发时间、更好的支持和更少的兼容性问题所抵消。
开始使用 IronPDF
准备好体验与众不同了吗? 立即开始免费试用:
// Get started in minutes
// Install-Package IronPdf
// Your first PDF in 3 lines
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("my-first-pdf.pdf");
// Get started in minutes
// Install-Package IronPdf
// Your first PDF in 3 lines
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("my-first-pdf.pdf");
' Get started in minutes
' Install-Package IronPdf
' Your first PDF in 3 lines
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>")
pdf.SaveAs("my-first-pdf.pdf")
请访问我们全面的文档,探索代码示例,或与我们的工程团队交谈,就您的 PDF 生成需求获得个性化指导。
{i:(ABCpdf 是其各自所有者的注册商标。 本网站与 ABCpdf 无关,也未得到 ABCpdf 的支持或赞助。 所有产品名称、徽标和品牌均为各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。)}]
常见问题解答
IronPDF和ABCPDF在渲染引擎方面的主要区别是什么?
IronPDF使用基于Chrome的渲染引擎,提供像素级完美输出和对CSS3和JavaScript的全支持,非常适合渲染现代网络技术。相比之下,ABCPDF提供了多个渲染引擎,如Chrome、Firefox或IE,这允许更灵活但需要更多测试和配置。
IronPDF的HTML到PDF转换质量如何与ABCPDF的相比?
IronPDF由于其基于Chrome的引擎在渲染精确度上表现出色,其输出与现代浏览器相匹配。ABCPDF虽然稍快,但在复杂的现代网络内容下可能无法提供同样水平的精确度。
IronPDF和ABCPDF之间的兼容性差异是什么?
IronPDF提供本地跨平台支持,可以在Windows、Linux、macOS和Docker容器上运行。ABCPDF主要针对Windows环境,这可能限制其在多样化开发环境中的使用。
哪个库为.NET应用程序提供了更好的长期价值,是IronPDF还是ABCPDF?
虽然ABCPDF的入门价格较低,但IronPDF的全面支持、现代架构和统一的API提供了长期价值,特别是对于需要持续维护和更新的现代.NET应用程序。
IronPDF的许可模式与ABCPDF的企业使用许可相比如何?
IronPDF的许可价格从$749起,而ABCPDF提供较低的入门价格为$329。然而,总拥有成本计算有利于IronPDF,因为其扩展支持和更新使其成为企业使用的具成本效益选择。
从ABCPDF迁移到IronPDF有哪些迁移策略?
对于从ABCPDF迁移到IronPDF,开发人员可以利用IronPDF的全面API文档和支持资源。他们应将当前功能映射到IronPDF的方法上,彻底测试输出以确保结果一致。
IronPDF可以处理带有JavaScript的动态HTML内容吗?
是的,IronPDF在渲染前可以执行JavaScript,支持动态内容、AJAX调用和现代框架。它允许配置等待时间和渲染延迟以确保动态元素的完整处理。
什么是使用IronPDF进行渲染问题故障排除的推荐方法?
要解决IronPDF的渲染问题,首先确保CSS特性由Chrome引擎支持。使用打印媒体查询进行PDF特定样式,使用浏览器开发工具验证CSS,并用简化的HTML进行测试以隔离问题。


