如何用 C# 从 HiQPdf 迁移到 IronPDF
HiQPdf 是一种商用 HTML 转 PDF 库,存在一些影响生产应用的局限性:
1.限制性"免费"版本:免费版本限制为 3 页,并带有侵入性水印——对于需要完整生成文档的生产工作负载来说,基本上无法使用。
2.较旧的 WebKit 引擎:HiQPdf使用的是较旧的基于 WebKit 的渲染引擎,该引擎难以处理 React、Angular 和 Vue 等现代 JavaScript 框架。
- .NET Core 支持不明确:文档没有明确说明 .NET Core / .NET 5+ 支持情况,给现代应用程序开发带来了不确定性。
4.分散的包:针对不同平台的多个 NuGet 包(HiQPdf、HiQPdf.Free、HiQPdf.NetCore、HiQPdf.NetCore.x64、HiQPdf.Client)使依赖项管理变得复杂。
API 复杂:需要通过
Document、Header、Footer属性链进行冗长的配置,而不是流畅、直观的方法。- JavaScript 支持有限: WebKit 引擎在渲染现代 JavaScript 框架和复杂动态布局生成的内容方面存在挑战。
HiQPdf与IronPDF对比
| 方面 | HiQPdf | IronPDF |
|---|---|---|
| 渲染引擎 | 基于 WebKit(较旧) | 现代 Chromium |
| 免费级别 | 3 页限制 + 水印 | 30 天全面试用 |
| 现代 JS 支持 | 有限的 | 完整(React、Angular、Vue) |
| 支持 .NET Core/5+ | 需要多个软件包 | 单一的统一软件包 |
| 应用程序接口设计 | 复杂的属性链 | 简洁流畅的 API |
| CSS3 支持 | 部分翻译 | 全面支持 |
| 文档 | 支离破碎 | 综合性 |
| NuGet 软件包 | 多种变体 | 单个软件包 |
对于计划在 2025 年和 2026 年之前采用 .NET 10 和 C# 14 的团队,IronPDF 提供了一个面向未来的基础,对最新的 .NET 版本和现代 Chromium 渲染引擎提供了文档支持。
迁移复杂性评估
按功能估算的工作量
| 特征 | 迁移复杂性 | 备注 |
|---|---|---|
| HTML 至 PDF | 极低 | 直接方法替换 |
| URL 至 PDF | 极低 | 直接方法替换 |
| 合并 PDF | 低 | 不同的合并方法 |
| 页眉/页脚 | 语言 | 占位符语法更改 |
| 页面大小/页边距 | 低 | 单位相同(毫米) |
| 触发器模式/延迟 | 低 | 属性映射 |
范式转换
HiQPdf 迁移的根本转变在于从属性链配置转向流畅的渲染选项:
HiQPdf:converter.Document.Header.Height = 50;
converter.Document.Header.Add(new HtmlToPdfVariableElement(...));
IronPdf: renderer.RenderingOptions.TextHeader = new TextHeaderFooter() { ... };开始之前
前提条件
- .NET 版本:IronPDF支持 .NET Framework 4.6.2+ 和 .NET Core 3.1+ / .NET 5/6/7/8/9+ 2.许可证密钥:从ironpdf.com获取您的IronPDF许可证密钥。 3.移除 HiQPdf:计划移除所有HiQPdfNuGet 包变体。
识别所有HiQPdf使用情况
# FindHiQPdfnamespace usage
grep -r "using HiQPdf\|HtmlToPdf\|PdfDocument" --include="*.cs" .
# Find header/footer usage
grep -r "\.Header\.\|\.Footer\.\|HtmlToPdfVariableElement" --include="*.cs" .
# Find placeholder syntax
grep -r "CrtPage\|PageCount" --include="*.cs" .
# Find NuGet references
grep -r "HiQPdf" --include="*.csproj" .# FindHiQPdfnamespace usage
grep -r "using HiQPdf\|HtmlToPdf\|PdfDocument" --include="*.cs" .
# Find header/footer usage
grep -r "\.Header\.\|\.Footer\.\|HtmlToPdfVariableElement" --include="*.cs" .
# Find placeholder syntax
grep -r "CrtPage\|PageCount" --include="*.cs" .
# Find NuGet references
grep -r "HiQPdf" --include="*.csproj" .NuGet 软件包变更
# Remove allHiQPdfvariants
dotnet remove package HiQPdf
dotnet remove package HiQPdf.Free
dotnet remove package HiQPdf.NetCore
dotnet remove package HiQPdf.NetCore.x64
dotnet remove package HiQPdf.Client
# InstallIronPDF(single package for all platforms)
dotnet add package IronPdf# Remove allHiQPdfvariants
dotnet remove package HiQPdf
dotnet remove package HiQPdf.Free
dotnet remove package HiQPdf.NetCore
dotnet remove package HiQPdf.NetCore.x64
dotnet remove package HiQPdf.Client
# InstallIronPDF(single package for all platforms)
dotnet add package IronPdf快速启动迁移
步骤 1:更新许可配置
之前 (HiQPdf):
HtmlToPdf converter = new HtmlToPdf();
converter.SerialNumber = "HIQPDF-SERIAL-NUMBER";HtmlToPdf converter = new HtmlToPdf();
converter.SerialNumber = "HIQPDF-SERIAL-NUMBER";After (IronPDF):
// Set globally at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";// Set globally at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";步骤 2:更新名称空间导入
// Before (HiQPdf)
using HiQPdf;
// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;// Before (HiQPdf)
using HiQPdf;
// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;完整的 API 参考
主类映射
| HiQPdf 类 | IronPdf 类 | 备注 |
|---|---|---|
| <代码>HtmlToPdf</代码 | <代码>ChromePdfRenderer</代码 | 主转换器类 |
| <代码>PDF 文档</代码 | <代码>PDF 文档</代码 | 名称相同,命名空间不同 |
| <代码>HtmlToPdfVariableElement</代码 | <代码>TextHeaderFooter</代码> 或 <代码>HtmlHeaderFooter</代码 | 页眉/页脚内容 |
转换方法映射
| HiQPdf 方法 | IronPdf 方法 | 备注 |
|---|---|---|
| <代码>ConvertHtmlToMemory(html,baseUrl)</代码 | <代码>RenderHtmlAsPdf(html)</代码 | 返回 PdfDocument |
| <代码>ConvertUrlToMemory(url)</代码 | <代码>RenderUrlAsPdf(url)</代码 | 返回 PdfDocument |
| <代码>File.WriteAllBytes(path,字节)</代码 | <代码>pdf.SaveAs(路径)</代码 | 直接保存法 |
PDF 文档方法映射
| HiQPdf 方法 | IronPdf 方法 | 备注 |
|---|---|---|
| <代码>PdfDocument.FromFile(路径)</代码 | <代码>PdfDocument.FromFile(路径)</代码 | 相同的方法名称 |
| <代码>document1.AddDocument(document2)</代码 | <代码>PdfDocument.Merge(pdf1, pdf2)</ 代码 | 静态合并法 |
| <代码>document.WriteToFile(路径)</代码 | <代码>pdf.SaveAs(路径)</代码 | 不同的方法名称 |
页眉/页脚占位符映射
| HiQPdf 占位符 | IronPdf 占位符 | 说明 |
|---|---|---|
| <代码>{CrtPage}</代码 | {page} | 当前页码 |
| <代码>{页数}</代码 | <代码>{总页数}</代码 | 总页数 |
代码迁移示例
示例 1:HTML 到 PDF 的转换
之前 (HiQPdf):
// NuGet: Install-Package HiQPdf
using HiQPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
byte[] pdfBuffer = htmlToPdfConverter.ConvertUrlToMemory("https://example.com");
System.IO.File.WriteAllBytes("output.pdf", pdfBuffer);
// Convert HTML string
string html = "<h1>Hello World</h1><p>This is a PDF document.</p>";
byte[] pdfFromHtml = htmlToPdfConverter.ConvertHtmlToMemory(html, "");
System.IO.File.WriteAllBytes("fromhtml.pdf", pdfFromHtml);
}
}// NuGet: Install-Package HiQPdf
using HiQPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
byte[] pdfBuffer = htmlToPdfConverter.ConvertUrlToMemory("https://example.com");
System.IO.File.WriteAllBytes("output.pdf", pdfBuffer);
// Convert HTML string
string html = "<h1>Hello World</h1><p>This is a PDF document.</p>";
byte[] pdfFromHtml = htmlToPdfConverter.ConvertHtmlToMemory(html, "");
System.IO.File.WriteAllBytes("fromhtml.pdf", pdfFromHtml);
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
// Convert HTML string
string html = "<h1>Hello World</h1><p>This is a PDF document.</p>";
var pdfFromHtml = renderer.RenderHtmlAsPdf(html);
pdfFromHtml.SaveAs("fromhtml.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
// Convert HTML string
string html = "<h1>Hello World</h1><p>This is a PDF document.</p>";
var pdfFromHtml = renderer.RenderHtmlAsPdf(html);
pdfFromHtml.SaveAs("fromhtml.pdf");
}
}HiQPdf 方法需要创建一个<代码>HtmlToPdf</代码实例,调用 ConvertUrlToMemory() 或 ConvertHtmlToMemory() 获得一个字节数组,然后手动将字节写入文件。IronPDF 的<代码>ChromePdfRenderer</代码返回一个<代码>PDF 文档</代码对象,并直接提供 SaveAs() 方法,从而省去了手动写入文件的步骤。现代 Chromium 引擎还能更好地呈现复杂的 HTML/CSS/JavaScript 内容。 有关其他渲染选项,请参阅 HTML to PDF 文档。
示例 2:合并多个 PDF 文件
之前 (HiQPdf):
// NuGet: Install-Package HiQPdf
using HiQPdf;
using System;
class Program
{
static void Main()
{
// Create first PDF
HtmlToPdf converter1 = new HtmlToPdf();
byte[] pdf1 = converter1.ConvertHtmlToMemory("<h1>First Document</h1>", "");
System.IO.File.WriteAllBytes("doc1.pdf", pdf1);
// Create second PDF
HtmlToPdf converter2 = new HtmlToPdf();
byte[] pdf2 = converter2.ConvertHtmlToMemory("<h1>Second Document</h1>", "");
System.IO.File.WriteAllBytes("doc2.pdf", pdf2);
// Merge PDFs
PdfDocument document1 = PdfDocument.FromFile("doc1.pdf");
PdfDocument document2 = PdfDocument.FromFile("doc2.pdf");
document1.AddDocument(document2);
document1.WriteToFile("merged.pdf");
}
}// NuGet: Install-Package HiQPdf
using HiQPdf;
using System;
class Program
{
static void Main()
{
// Create first PDF
HtmlToPdf converter1 = new HtmlToPdf();
byte[] pdf1 = converter1.ConvertHtmlToMemory("<h1>First Document</h1>", "");
System.IO.File.WriteAllBytes("doc1.pdf", pdf1);
// Create second PDF
HtmlToPdf converter2 = new HtmlToPdf();
byte[] pdf2 = converter2.ConvertHtmlToMemory("<h1>Second Document</h1>", "");
System.IO.File.WriteAllBytes("doc2.pdf", pdf2);
// Merge PDFs
PdfDocument document1 = PdfDocument.FromFile("doc1.pdf");
PdfDocument document2 = PdfDocument.FromFile("doc2.pdf");
document1.AddDocument(document2);
document1.WriteToFile("merged.pdf");
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Create first PDF
var pdf1 = renderer.RenderHtmlAsPdf("<h1>First Document</h1>");
pdf1.SaveAs("doc1.pdf");
// Create second PDF
var pdf2 = renderer.RenderHtmlAsPdf("<h1>Second Document</h1>");
pdf2.SaveAs("doc2.pdf");
// Merge PDFs
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Create first PDF
var pdf1 = renderer.RenderHtmlAsPdf("<h1>First Document</h1>");
pdf1.SaveAs("doc1.pdf");
// Create second PDF
var pdf2 = renderer.RenderHtmlAsPdf("<h1>Second Document</h1>");
pdf2.SaveAs("doc2.pdf");
// Merge PDFs
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}HiQPdf 方法要求使用 PdfDocument.FromFile() 从文件加载文档,在第一个文档上调用 AddDocument() 添加第二个文档,然后使用 WriteToFile() 保存。IronPDF提供了一个更简洁的静态 PdfDocument.Merge() 方法,可直接接受多个<代码>PDF 文档</代码对象--无需中间文件操作。 了解有关 合并和拆分 PDF 的更多信息。
示例 3:带有页码的 PDF 页眉和页脚
之前 (HiQPdf):
// NuGet: Install-Package HiQPdf
using HiQPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// Add header
htmlToPdfConverter.Document.Header.Height = 50;
HtmlToPdfVariableElement headerHtml = new HtmlToPdfVariableElement("<div style='text-align:center'>Page Header</div>", "");
htmlToPdfConverter.Document.Header.Add(headerHtml);
// Add footer with page number
htmlToPdfConverter.Document.Footer.Height = 50;
HtmlToPdfVariableElement footerHtml = new HtmlToPdfVariableElement("<div style='text-align:center'>Page {CrtPage} of {PageCount}</div>", "");
htmlToPdfConverter.Document.Footer.Add(footerHtml);
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory("<h1>Document with Headers and Footers</h1>", "");
System.IO.File.WriteAllBytes("header-footer.pdf", pdfBuffer);
}
}// NuGet: Install-Package HiQPdf
using HiQPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// Add header
htmlToPdfConverter.Document.Header.Height = 50;
HtmlToPdfVariableElement headerHtml = new HtmlToPdfVariableElement("<div style='text-align:center'>Page Header</div>", "");
htmlToPdfConverter.Document.Header.Add(headerHtml);
// Add footer with page number
htmlToPdfConverter.Document.Footer.Height = 50;
HtmlToPdfVariableElement footerHtml = new HtmlToPdfVariableElement("<div style='text-align:center'>Page {CrtPage} of {PageCount}</div>", "");
htmlToPdfConverter.Document.Footer.Add(footerHtml);
byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory("<h1>Document with Headers and Footers</h1>", "");
System.IO.File.WriteAllBytes("header-footer.pdf", pdfBuffer);
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Configure header and footer
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Page Header",
FontSize = 12
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Document with Headers and Footers</h1>");
pdf.SaveAs("header-footer.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Configure header and footer
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Page Header",
FontSize = 12
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10
};
var pdf = renderer.RenderHtmlAsPdf("<h1>Document with Headers and Footers</h1>");
pdf.SaveAs("header-footer.pdf");
}
}HiQPdf 方法要求设置 Document.Header.Height, 创建<代码>HtmlToPdfVariableElement</代码对象,并在页眉/页脚部分调用 Add() 。 页码占位符使用<代码>{CrtPage}</代码和<代码>{页数}</代码语法。 IronPdf 通过 CenterText 属性和不同的占位符语法提供了更简洁的 TextHeaderFooter 配置:{page} 和 {total-pages}. 有关其他选项,包括基于 HTML 的页眉,请参见 页眉和页脚文档。
关键迁移说明
替换语法
对于有页码的文档来说,最重要的变化是占位符语法:
//HiQPdfplaceholders
"Page {CrtPage} of {PageCount}"
//IronPDFplaceholders
"Page {page} of {total-pages}"//HiQPdfplaceholders
"Page {CrtPage} of {PageCount}"
//IronPDFplaceholders
"Page {page} of {total-pages}"完整的占位符映射: -<代码>{CrtPage}</代码→ {page} -<代码>{页数}</代码→<代码>{总页数}</代码页码总数
合并方法差异
HiQPdf 将第一个文档修改到位:
// HiQPdf: Modifies document1
document1.AddDocument(document2);
document1.WriteToFile("merged.pdf");// HiQPdf: Modifies document1
document1.AddDocument(document2);
document1.WriteToFile("merged.pdf");IronPdf 返回一个新的合并文档:
// IronPDF: Returns new document
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");// IronPDF: Returns new document
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");无 3 页限制
HiQPdf 的免费版本输出上限为 3 页,并带有水印。IronPDF可生成完整的文档,在试用期内没有人为限制。
重用 ChromePdfRenderer。
与HiQPdf不同的是,您可能会为每次转换创建新的<代码>HtmlToPdf</代码实例,而IronPDF的<代码>ChromePdfRenderer</代码应重复使用:
// IronPDF: Create once, reuse
var renderer = new ChromePdfRenderer();
var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);// IronPDF: Create once, reuse
var renderer = new ChromePdfRenderer();
var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);故障排除
问题 1:HtmlToPdf 未找到
问题:IronPDF中不存在HtmlToPdf类。
解决方案:替换为ChromePdfRenderer :
// HiQPdf
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// IronPDF
var renderer = new ChromePdfRenderer();// HiQPdf
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
// IronPDF
var renderer = new ChromePdfRenderer();问题 2:未找到 ConvertHtmlToMemory
问题: ConvertHtmlToMemory()方法不存在。
解决方案:使用RenderHtmlAsPdf() :
// HiQPdf
byte[] pdfBytes = converter.ConvertHtmlToMemory(html, "");
// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);
byte[] pdfBytes = pdf.BinaryData;// HiQPdf
byte[] pdfBytes = converter.ConvertHtmlToMemory(html, "");
// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);
byte[] pdfBytes = pdf.BinaryData;问题 3:页码占位符不工作
问题: {CrtPage}和{PageCount}直接出现在输出结果中。
解决方案:更新IronPDF占位符语法:
//HiQPdfsyntax (won't work)
"Page {CrtPage} of {PageCount}"
//IronPDFsyntax
"Page {page} of {total-pages}"//HiQPdfsyntax (won't work)
"Page {CrtPage} of {PageCount}"
//IronPDFsyntax
"Page {page} of {total-pages}"问题 4:未找到 HtmlToPdfVariableElement
问题: HtmlToPdfVariableElement类不存在。
解决方案:使用TextHeaderFooter或HtmlHeaderFooter :
// HiQPdf
HtmlToPdfVariableElement headerHtml = new HtmlToPdfVariableElement("<div>Header</div>", "");
converter.Document.Header.Add(headerHtml);
// IronPDF
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Header",
FontSize = 12
};// HiQPdf
HtmlToPdfVariableElement headerHtml = new HtmlToPdfVariableElement("<div>Header</div>", "");
converter.Document.Header.Add(headerHtml);
// IronPDF
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
CenterText = "Header",
FontSize = 12
};迁移清单
迁移前
- 清点代码库中所有HiQPdfAPI 调用
- 记录当前页面尺寸、边距和设置
- 确定页眉/页脚配置和占位符
- 获取IronPDF许可证密钥
- 在开发环境中测试 IronPDF
代码迁移
- 删除所有HiQPdfNuGet 包(所有变体) 安装 IronPdf NuGet 包:
dotnet add package IronPdf - 更新命名空间导入
- 将
HtmlToPdf替换为ChromePdfRenderer - 将
ConvertHtmlToMemory()转换为RenderHtmlAsPdf() - 将
ConvertUrlToMemory()转换为RenderUrlAsPdf() - 更新页眉/页脚占位符(<代码>{CrtPage}</代码→
{page},<代码>{页数}</代码→<代码>{总页数}</代码) - 将
HtmlToPdfVariableElement替换为TextHeaderFooter - 更新合并操作(
AddDocument→PdfDocument.Merge) - 添加启动时许可证密钥初始化功能
测试
- 测试 HTML 到 PDF 的转换
- 测试 URL 到 PDF 的转换
- 验证页眉/页脚渲染效果
- 核对页码占位符
- 测试 PDF 合并
- 测试大量使用 JavaScript 的页面(现在 Chromium 已支持)
后迁移
- 从配置中移除HiQPdf序列号
- 更新文档
- 监控渲染差异






