如何使用C#向PDF添加页码
从GemBox.Pdf迁移到IronPDF将您的.NET PDF工作流从基于坐标的程序化文档构建转换为现代的HTML/CSS渲染。 本指南提供了一个全面的分步迁移路径,去除了2页免费模式限制并简化了专业.NET开发人员的文档创建。
为什么要从GemBox.Pdf迁移到IronPDF
GemBox.Pdf的挑战
GemBox.Pdf是一个功能强大的.NET PDF组件,但在现实世界开发中存在值得考量的限制:
-
2页免费模式限制:免费版本在加载或保存超过2页的PDF时,会抛出
FreeLimitReachedException,因此超过一页的收据或两页的发票需要付费许可证。 (Source: gemboxsoftware.com/pdf/free-version.) -
无HTML到PDF转换功能:GemBox.Pdf无法呈现HTML——
PdfDocument.Load只能打开现有的PDF文件。 要将HTML转换为PDF,您必须购买单独的GemBox.Document产品(不同的SKU,不同的许可证)。 -
基于坐标的布局:GemBox.Pdf是一个底层PDF内容流API。 要放置文本,您需计算PDF用户空间单位中的X/Y并调用
page.Content.DrawText(formattedText, new PdfPoint(x, y))。 没有流布局。 - Office到PDF需要其他SKU:Word→PDF需要GemBox.Document,Excel→PDF需要GemBox.Spreadsheet,每个SKU都需单独许可; GemBox.Bundle涵盖所有SKU但价格更高。
5.仅限程序化:任何设计变更都需要代码变更。 调整间距? 重新计算坐标。 改变字体大小?调整其下方的Y位置。
-
商业许可证定价:单个开发者许可证为$890(续订$534),小团队(10名开发人员)为$4,450,大团队(50名开发人员)为$13,350。(来源:gemboxsoftware.com/pdf/pricing。)
- 设计的学习曲线:开发人员必须用坐标来思考而不是文档流,使得诸如"添加段落"之类的简单任务变得意外复杂。
GemBox.Pdf与IronPDF比较
| 方面 | GemBox.Pdf | IronPDF |
|---|---|---|
| 免费版本限制 | 2页封顶(FreeLimitReachedException) | 仅水印,无页数上限 |
| HTML 转 PDF | 不支持(需要GemBox.Document) | 完整的 Chromium 引擎 |
| Word/Excel → PDF | 单独SKU(GemBox.Document / GemBox.Spreadsheet) | 通过HTML管道渲染 |
| 排版方法 | 基于坐标的手动翻译 | HTML/CSS 流程布局 |
| 现代 CSS | 不适用 | Flexbox、网格、CSS3 动画 |
| JavaScript 支持 | 不适用 | 全面执行 JavaScript |
| 设计变更 | 重新计算坐标 | 编辑 HTML/CSS |
| 学习曲线 | PDF 坐标系 | HTML/CSS(熟悉网络) |
IronPDF利用熟悉的Web技术生成现代.NET的PDF。
迁移复杂性评估
按功能估算的工作量
| 特征 | 迁移复杂性 |
|---|---|
| 加载/保存 PDF | 极低 |
| 合并 PDF | 极低 |
| 拆分 PDF | low |
| 文本提取 | 极低 |
| 添加文本 | 语言 |
| 表格 | low |
| 图片 | low |
| 水印 | low |
| 密码保护 | 语言 |
| 表格字段 | 语言 |
范式转换
此GemBox.Pdf迁移中最大的变化是从基于坐标的布局转向HTML/CSS布局:
GemBox.Pdf:"在(100,700)位置绘制文本"
IronPDF: "使用 CSS 样式渲染 HTML
对于熟悉网络技术的开发人员来说,这种模式的转变通常比较容易,但需要以不同的思维方式来看待 PDF。
开始之前
前提条件
- .NET版本:IronPDF支持.NET Framework 4.6.2+和.NET Core 2.0+ / .NET 5+ 2.许可证密钥:从ironpdf.com获取您的IronPDF许可证密钥。 3.备份:创建一个用于迁移工作的分支
- HTML/CSS知识:具备基本知识会有帮助,但并非必需。
识别所有GemBox.Pdf使用
# Find all GemBox.Pdf references
grep -r "GemBox\.Pdf\|PdfDocument\|PdfPage\|PdfFormattedText\|ComponentInfo\.SetLicense" --include="*.cs" .
# Find package references
grep -r "GemBox\.Pdf" --include="*.csproj" .
# Find all GemBox.Pdf references
grep -r "GemBox\.Pdf\|PdfDocument\|PdfPage\|PdfFormattedText\|ComponentInfo\.SetLicense" --include="*.cs" .
# Find package references
grep -r "GemBox\.Pdf" --include="*.csproj" .
NuGet 软件包变更
# Remove GemBox.Pdf
dotnet remove package GemBox.Pdf
# Install IronPDF
dotnet add package IronPdf
# Remove GemBox.Pdf
dotnet remove package GemBox.Pdf
# Install IronPDF
dotnet add package IronPdf
快速启动迁移
步骤 1:更新许可配置
之前(GemBox.Pdf):
// Must call before any GemBox.Pdf operations
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE");
// Must call before any GemBox.Pdf operations
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE");
' Must call before any GemBox.Pdf operations
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE")
After (IronPDF):
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }
Imports IronPdf
' Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
' Or in appsettings.json:
' { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }
步骤 2:更新名称空间导入
// Before (GemBox.Pdf)
using GemBox.Pdf;
using GemBox.Pdf.Content;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;
// Before (GemBox.Pdf)
using GemBox.Pdf;
using GemBox.Pdf.Content;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;
Imports IronPdf
Imports IronPdf.Editing
步骤 3:基本转换模式
之前(GemBox.Pdf):
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
// PdfFormattedText has no Text property; use Append/AppendLine.
var formattedText = new PdfFormattedText();
formattedText.FontSize = 24;
formattedText.Append("Hello World");
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
// PdfFormattedText has no Text property; use Append/AppendLine.
var formattedText = new PdfFormattedText();
formattedText.FontSize = 24;
formattedText.Append("Hello World");
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim page = document.Pages.Add()
' PdfFormattedText has no Text property; use Append/AppendLine.
Dim formattedText As New PdfFormattedText()
formattedText.FontSize = 24
formattedText.Append("Hello World")
page.Content.DrawText(formattedText, New PdfPoint(100, 700))
document.Save("output.pdf")
End Using
After (IronPDF):
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>");
pdf.SaveAs("output.pdf");
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>");
pdf.SaveAs("output.pdf");
Imports IronPdf
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>")
pdf.SaveAs("output.pdf")
关键差异:
- 无需进行坐标计算
- 用 HTML/CSS 代替编程布局
- 无2页免费模式上限
- 更简单、更易读的代码
完整的 API 参考
命名空间映射
| GemBox.Pdf | IronPDF |
|---|---|
GemBox.Pdf |
IronPdf |
GemBox.Pdf.Content |
IronPdf (内容是HTML) |
GemBox.Pdf.Security |
IronPdf (SecuritySettings) |
GemBox.Pdf.Forms |
IronPdf.Forms |
核心类映射
| GemBox.Pdf | IronPDF | 说明 |
|---|---|---|
PdfDocument |
PdfDocument |
主要 PDF 文档类别 |
PdfPage |
PdfDocument.Pages[i] |
页面表示 |
PdfContent |
不适用(使用 HTML) | 页面内容 |
PdfFormattedText |
不适用(使用 HTML) | 格式化文本 |
PdfPoint |
不适用(使用 CSS 定位) | 坐标定位 |
ComponentInfo.SetLicense() |
IronPdf.License.LicenseKey |
许可证管理 |
文档操作
| GemBox.Pdf | IronPDF |
|---|---|
new PdfDocument() |
new PdfDocument() |
PdfDocument.Load(path) |
PdfDocument.FromFile(path) |
PdfDocument.Load(stream) |
PdfDocument.FromStream(stream) |
document.Save(path) |
pdf.SaveAs(path) |
document.Save(stream) |
pdf.BinaryData (返回byte[]) |
页面操作
| GemBox.Pdf | IronPDF |
|---|---|
document.Pages.Add() |
通过 HTML 渲染创建 |
document.Pages.Count |
pdf.PageCount |
document.Pages[index] |
pdf.Pages[index] |
document.Pages.AddClone(pages) |
PdfDocument.Merge() |
文本和内容操作
| GemBox.Pdf | IronPDF |
|---|---|
new PdfFormattedText() |
HTML 字符串 |
formattedText.Append(text) |
包含在HTML中 |
formattedText.AppendLine(text) |
包含在HTML中 |
formattedText.FontSize = 12 |
CSS font-size: 12pt |
formattedText.Font = ... |
CSS font-family: ... |
page.Content.DrawText(text, point) |
renderer.RenderHtmlAsPdf(html) |
page.Content.GetText() |
pdf.ExtractTextFromPage(i) |
代码迁移示例
示例 1:HTML 到 PDF 的转换
之前(GemBox.Pdf)—不受GemBox.Pdf支持; 需要单独的GemBox.Document SKU:
// NuGet: Install-Package GemBox.Document
// NOTE: GemBox.Pdf does NOT support HTML-to-PDF. PdfDocument.Load only opens
// existing PDF files. To convert HTML to PDF you must use the separate
// GemBox.Document product (different SKU, different license).
using GemBox.Document;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// GemBox.Document loads HTML and saves as PDF.
var document = DocumentModel.Load("input.html");
document.Save("output.pdf");
}
}
// NuGet: Install-Package GemBox.Document
// NOTE: GemBox.Pdf does NOT support HTML-to-PDF. PdfDocument.Load only opens
// existing PDF files. To convert HTML to PDF you must use the separate
// GemBox.Document product (different SKU, different license).
using GemBox.Document;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// GemBox.Document loads HTML and saves as PDF.
var document = DocumentModel.Load("input.html");
document.Save("output.pdf");
}
}
Imports GemBox.Document
Module Program
Sub Main()
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' GemBox.Document loads HTML and saves as PDF.
Dim document = DocumentModel.Load("input.html")
document.Save("output.pdf")
End Sub
End Module
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>")
pdf.SaveAs("output.pdf")
End Sub
End Class
IronPDF的ChromePdfRenderer使用现代的Chromium引擎进行HTML/CSS/JavaScript渲染,因此一个NuGet包可以直接涵盖HTML到PDF的转换——无需单独的SKU。 请参阅 HTML to PDF 文档,了解更多渲染选项。
示例 2:合并 PDF 文件
之前(GemBox.Pdf):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using System.Linq;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var source1 = PdfDocument.Load("document1.pdf");
var source2 = PdfDocument.Load("document2.pdf");
document.Pages.AddClone(source1.Pages);
document.Pages.AddClone(source2.Pages);
document.Save("merged.pdf");
}
}
}
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using System.Linq;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var source1 = PdfDocument.Load("document1.pdf");
var source2 = PdfDocument.Load("document2.pdf");
document.Pages.AddClone(source1.Pages);
document.Pages.AddClone(source2.Pages);
document.Save("merged.pdf");
}
}
}
Imports GemBox.Pdf
Imports System.Linq
Module Program
Sub Main()
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim source1 = PdfDocument.Load("document1.pdf")
Dim source2 = PdfDocument.Load("document2.pdf")
document.Pages.AddClone(source1.Pages)
document.Pages.AddClone(source2.Pages)
document.Save("merged.pdf")
End Using
End Sub
End Module
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
End Sub
End Class
IronPDF的静态Merge方法简化了操作——无需创建空白文档和单独克隆页面。 了解有关 合并和拆分 PDF 的更多信息。
示例 3:在 PDF 中添加文本
之前(GemBox.Pdf):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
// PdfFormattedText has no Text property; use Append/AppendLine.
var formattedText = new PdfFormattedText();
formattedText.FontSize = 24;
formattedText.Append("Hello World");
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
}
}
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
// PdfFormattedText has no Text property; use Append/AppendLine.
var formattedText = new PdfFormattedText();
formattedText.FontSize = 24;
formattedText.Append("Hello World");
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
}
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
Module Program
Sub Main()
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim page = document.Pages.Add()
' PdfFormattedText has no Text property; use Append/AppendLine.
Dim formattedText As New PdfFormattedText()
formattedText.FontSize = 24
formattedText.Append("Hello World")
page.Content.DrawText(formattedText, New PdfPoint(100, 700))
document.Save("output.pdf")
End Using
End Sub
End Module
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>");
var stamper = new TextStamper()
{
Text = "Hello World",
FontSize = 24,
HorizontalOffset = 100,
VerticalOffset = 700
};
pdf.ApplyStamp(stamper);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>");
var stamper = new TextStamper()
{
Text = "Hello World",
FontSize = 24,
HorizontalOffset = 100,
VerticalOffset = 700
};
pdf.ApplyStamp(stamper);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports IronPdf.Editing
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>")
Dim stamper = New TextStamper() With {
.Text = "Hello World",
.FontSize = 24,
.HorizontalOffset = 100,
.VerticalOffset = 700
}
pdf.ApplyStamp(stamper)
pdf.SaveAs("output.pdf")
End Sub
End Class
为了向现有PDF添加文本,IronPDF提供TextStamper类,提供精确的定位控制。 对于新文档,只需将文本包含在 HTML 模板中即可。 有关其他选项,请参阅冲压文档。
示例 4:创建表格(最大的改进!)
之前(GemBox.Pdf)—基于坐标的布局,在免费模式下封顶为2页:
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
double y = 700;
double[] xPositions = { 50, 200, 300, 400 };
// Headers
var headers = new[] { "Product", "Price", "Qty", "Total" };
for (int i = 0; i < headers.Length; i++)
{
var text = new PdfFormattedText();
text.FontSize = 12;
text.Append(headers[i]);
page.Content.DrawText(text, new PdfPoint(xPositions[i], y));
}
y -= 20;
// Data rows — each row requires manual Y advancement,
// and free mode caps the saved file at 2 pages total.
document.Save("products.pdf");
}
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
double y = 700;
double[] xPositions = { 50, 200, 300, 400 };
// Headers
var headers = new[] { "Product", "Price", "Qty", "Total" };
for (int i = 0; i < headers.Length; i++)
{
var text = new PdfFormattedText();
text.FontSize = 12;
text.Append(headers[i]);
page.Content.DrawText(text, new PdfPoint(xPositions[i], y));
}
y -= 20;
// Data rows — each row requires manual Y advancement,
// and free mode caps the saved file at 2 pages total.
document.Save("products.pdf");
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim page = document.Pages.Add()
Dim y As Double = 700
Dim xPositions As Double() = {50, 200, 300, 400}
' Headers
Dim headers = New String() {"Product", "Price", "Qty", "Total"}
For i As Integer = 0 To headers.Length - 1
Dim text As New PdfFormattedText()
text.FontSize = 12
text.Append(headers(i))
page.Content.DrawText(text, New PdfPoint(xPositions(i), y))
Next
y -= 20
' Data rows — each row requires manual Y advancement,
' and free mode caps the saved file at 2 pages total.
document.Save("products.pdf")
End Using
之后(IronPDF)—无页数上限,正确的HTML表格:
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var html = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
</tbody>
</table>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("products.pdf");
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var html = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
</tbody>
</table>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("products.pdf");
Imports IronPdf
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim html As String = "
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
</tbody>
</table>
</body>
</html>"
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("products.pdf")
这是GemBox.Pdf迁移中最重要的改进。 在IronPDF中,可能将GemBox.Pdf文档推过2页上限的表格在不受该上限的影响下渲染,支持全CSS样式。
关键迁移说明
坐标到 CSS 定位
如果您需要像GemBox.Pdf的坐标系统那样的像素级精确定位,请使用CSS绝对定位:
<div style="position:absolute; left:50px; top:750px; font-size:24px;">
Text positioned at specific coordinates
</div>
<div style="position:absolute; left:50px; top:750px; font-size:24px;">
Text positioned at specific coordinates
</div>
页面索引
GemBox.Pdf和IronPDF都使用0为起始的页面,使得迁移相当简单:
// GemBox.Pdf
var page = document.Pages[0];
// IronPDF
var page = pdf.Pages[0];
// GemBox.Pdf
var page = document.Pages[0];
// IronPDF
var page = pdf.Pages[0];
' GemBox.Pdf
Dim page = document.Pages(0)
' IronPDF
Dim page = pdf.Pages(0)
安全设置
// GemBox.Pdf
var encryption = document.SaveOptions.SetPasswordEncryption();
encryption.DocumentOpenPassword = "userPassword";
encryption.PermissionsPassword = "ownerPassword";
// IronPDF
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
// GemBox.Pdf
var encryption = document.SaveOptions.SetPasswordEncryption();
encryption.DocumentOpenPassword = "userPassword";
encryption.PermissionsPassword = "ownerPassword";
// IronPDF
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
' GemBox.Pdf
Dim encryption = document.SaveOptions.SetPasswordEncryption()
encryption.DocumentOpenPassword = "userPassword"
encryption.PermissionsPassword = "ownerPassword"
' IronPDF
pdf.SecuritySettings.UserPassword = "userPassword"
pdf.SecuritySettings.OwnerPassword = "ownerPassword"
故障排除
问题 1:未找到 PdfFormattedText
问题: IronPDF中不存在PdfFormattedText。
解决方案:使用 HTML 和 CSS 样式:
// GemBox.Pdf
var text = new PdfFormattedText();
text.FontSize = 24;
text.Append("Hello");
// IronPDF
var html = "<p style='font-size:24px;'>Hello</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
// GemBox.Pdf
var text = new PdfFormattedText();
text.FontSize = 24;
text.Append("Hello");
// IronPDF
var html = "<p style='font-size:24px;'>Hello</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
Imports GemBox.Pdf
Imports IronPDF
Dim text As New PdfFormattedText()
text.FontSize = 24
text.Append("Hello")
Dim html As String = "<p style='font-size:24px;'>Hello</p>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
问题 2:未找到 DrawText 方法
问题: page.Content.DrawText()不可用。
解决方案:通过 HTML 渲染创建内容或使用图章:
// For new documents - render HTML
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>");
// For existing documents - use stampers
var stamper = new TextStamper() { Text = "Added Text" };
pdf.ApplyStamp(stamper);
// For new documents - render HTML
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>");
// For existing documents - use stampers
var stamper = new TextStamper() { Text = "Added Text" };
pdf.ApplyStamp(stamper);
Imports System
' For new documents - render HTML
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>")
' For existing documents - use stampers
Dim stamper As New TextStamper() With {.Text = "Added Text"}
pdf.ApplyStamp(stamper)
问题 3:文档加载差异
问题: PdfDocument.Load()未找到。
解决方案: 使用FromStream():
// GemBox.Pdf
var doc = PdfDocument.Load("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
// GemBox.Pdf
var doc = PdfDocument.Load("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
Imports GemBox.Pdf
Imports IronPdf
Dim doc = PdfDocument.Load("input.pdf")
Dim pdf = PdfDocument.FromFile("input.pdf")
问题 4:保存方法的差异
问题: document.Save()方法签名不同。
解决方案: 使用SaveAs():
// GemBox.Pdf
document.Save("output.pdf");
// IronPDF
pdf.SaveAs("output.pdf");
// GemBox.Pdf
document.Save("output.pdf");
// IronPDF
pdf.SaveAs("output.pdf");
迁移清单
迁移前
- 盘点代码库中所有GemBox.Pdf使用
- 识别需要转换为 HTML 的基于坐标的布局
- 评估2页免费模式上限对代码的影响
- 获取IronPDF许可证密钥
- 在版本控制系统中创建迁移分支
代码迁移
- 移除GemBox.Pdf NuGet包:
dotnet remove package GemBox.Pdf - 安装IronPDF NuGet包:
dotnet add package IronPdf - 更新命名空间导入
- 将
IronPdf.License.LicenseKey - 将
PdfDocument.FromFile() - 将
pdf.SaveAs() - 将基于坐标的文本替换为 HTML 内容
- 将
PdfFormattedText转换为带CSS样式的HTML - 更新合并操作以使用
PdfDocument.Merge()
测试
- 核实所有文档是否正确生成
- 验证文档外观是否符合预期
- 测试多页输出(先前在免费模式下限制为2页)
- 验证文本提取功能是否正常
- 测试合并和拆分操作
- 验证安全/加密功能
后迁移
- 删除GemBox.Pdf许可证密钥
- 更新文档
- 培训团队使用 HTML/CSS 方法制作 PDF 文件
- 享受无限页数而没有免费模式限制!

