如何在 Chrome 中除錯 HTML 以建立像素完美的 PDF
從iText遷移到IronPDF將您的.NET PDF工作流程從程式化的API轉移——在程式碼中構建Cell物件——到一種支持CSS3和JavaScript的HTML優先方法。 本指南提供了一個分步遷移路徑,消除了AGPL風險和對於額外pdfHTML附加組件的需求。
為什麼要從iText遷移到IronPDF
AGPL授權考慮
iText(由iText Group / Apryse Group NV擁有)具有以下授權特徵,商業團隊應在使用前權衡:
-
AGPL傳染性授權: 如果您在網頁應用程式中使用iText的開源授權版本,AGPL通常被解釋為要求您向任何通過網路與其交互的使用者公開發布您的應用程式源碼。 對於閉源的商業軟體,這通常意味著需要購買一個商業授權。
-
僅限訂閱的商業授權: iText的商業授權作為年度訂閱銷售,基於PDF處理量; 在公共定價頁面上未公告永久授權選項(自定義OEM條款僅通過報價)。
-
pdfHTML附加組件費用: HTML-to-PDF需要
itext包(目前版本9.6.0)分開銷售。 -
複雜的授權審核: 企業部署面臨授權複雜性和審核風險。
-
程式化的API優先: 核心iText通過編寫程式碼來組合
Cell物件來構建PDF; pdfHTML可讓您從HTML開始。 - 指定的CSS子集,無渲染時JS: pdfHTML支持一個指定的CSS子集,而在將HTML轉換為PDF時不執行JavaScript(PDF級別的JS表單操作是一個分開的支持特徵)。
iText與IronPDF比較
| 功能 | iText 9 / iTextSharp 5.x | IronPDF |
|---|---|---|
| 授權 | AGPL(傳染性)或商業年訂閱 | 商業,永久選擇 |
| HTML到PDF | 獨立的itext.pdfhtml附加組件(6.3.2) |
內建的Chromium渲染器 |
| CSS支持 | pdfHTML中的指定CSS子集 | 全面支持CSS3、Flexbox、Grid |
| 渲染時的JavaScript | pdfHTML在HTML→PDF過程中不運行JS | 渲染時的全面JS執行 |
| API範式 | 程式化的(段落、表格、單元格) | HTML優先和CSS |
| 學習曲線 | 陡峭(PDF座標系統) | 網頁開發者友好 |
| 開源風險 | 必須在AGPL下開源網頁應用程式 | 無傳染性要求 |
| 價格模式 | 年度訂閱(基於容量)或自定OEM | 永久或訂閱 |
對專注於現代.NET的團隊來說,IronPDF的HTML優先方法依賴於團隊已掌握的網頁開發技能。
遷移複雜性評估
功能的預估努力程度
| 功能 | 遷移複雜性 |
|---|---|
| HTML轉PDF | 非常低 |
| 合併PDF | 低 |
| 文字和圖片 | 低 |
| 表格 | 中 |
| 頁眉/頁腳 | 中 |
| 安全/加密 | 低 |
範式轉變
此iText遷移的根本改變是從程式化的PDF構建到HTML優先的渲染:
iText: PdfWriter → PdfDocument → Document → Add(Paragraph) → Add(Table)
IronPDF: ChromePdfRenderer → RenderHtmlAsPdf(htmlString) → SaveAs()
這種範式轉變是解放的:而不是學習iText的物件模型,您使用網頁開發者已經掌握的HTML和CSS技能。
開始之前
前提條件
- .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet存取: 有能力安裝NuGet套件
- IronPDF授權: 從ironpdf.com獲取您的授權金鑰
NuGet包變更
# Remove iText packages (current naming is 'itext'; 'itext7' is the deprecated alias)
dotnet remove package itext
dotnet remove package itext.pdfhtml
dotnet remove package itext7
dotnet remove package itext7.pdfhtml
dotnet remove package itextsharp
# Install IronPDF
dotnet add package IronPdf
# Remove iText packages (current naming is 'itext'; 'itext7' is the deprecated alias)
dotnet remove package itext
dotnet remove package itext.pdfhtml
dotnet remove package itext7
dotnet remove package itext7.pdfhtml
dotnet remove package itextsharp
# Install IronPDF
dotnet add package IronPdf
授權配置
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
識別iText使用情況
# Find all iText references
grep -r "using iText\|using iTextSharp" --include="*.cs" .
grep -r "PdfWriter\|PdfDocument\|Document\|Paragraph\|Table\|Cell" --include="*.cs" .
grep -r "HtmlConverter\|ConverterProperties" --include="*.cs" .
# Find all iText references
grep -r "using iText\|using iTextSharp" --include="*.cs" .
grep -r "PdfWriter\|PdfDocument\|Document\|Paragraph\|Table\|Cell" --include="*.cs" .
grep -r "HtmlConverter\|ConverterProperties" --include="*.cs" .
完整API參考
類別映射
| iText 7+ 類別 | iTextSharp 5.x 類別 | IronPDF等價 |
|---|---|---|
PdfWriter |
PdfWriter |
ChromePdfRenderer |
PdfDocument |
Document |
PdfDocument |
Document |
Document |
ChromePdfRenderer.RenderHtmlAsPdf() |
Paragraph |
Paragraph |
HTML <h1>等 |
Table |
PdfPTable |
HTML <table> |
Cell |
PdfPCell |
HTML <th> |
Image |
Image |
HTML <img> |
PdfReader |
PdfReader |
PdfDocument.FromFile() |
PdfMerger |
無 | PdfDocument.Merge() |
命名空間映射
| iText 命名空間 | IronPDF等價 |
|---|---|
iText.Kernel.Pdf |
IronPdf |
iText.Layout |
IronPdf |
iText.Layout.Element |
使用HTML元素 |
iText.Html2pdf |
IronPdf(內建) |
iText.IO.Image |
使用 HTML <img> |
iText.Kernel.Utils |
IronPdf |
程式碼遷移範例
範例1:HTML轉PDF轉換
在使用前(iText):
// NuGet: Install-Package itext7
using iText.Html2pdf;
using System.IO;
class Program
{
static void Main()
{
string html = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";
string outputPath = "output.pdf";
using (FileStream fs = new FileStream(outputPath, FileMode.Create))
{
HtmlConverter.ConvertToPdf(html, fs);
}
}
}
// NuGet: Install-Package itext7
using iText.Html2pdf;
using System.IO;
class Program
{
static void Main()
{
string html = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";
string outputPath = "output.pdf";
using (FileStream fs = new FileStream(outputPath, FileMode.Create))
{
HtmlConverter.ConvertToPdf(html, fs);
}
}
}
Imports iText.Html2pdf
Imports System.IO
Class Program
Shared Sub Main()
Dim html As String = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
Dim outputPath As String = "output.pdf"
Using fs As FileStream = New FileStream(outputPath, FileMode.Create)
HtmlConverter.ConvertToPdf(html, fs)
End Using
End Sub
End Class
之後(IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html As String = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Sub
End Class
iText方法需要單獨的itext 9.6.0一起單獨出售),建立using語句中以進行正確的處理。 HtmlConverter.ConvertToPdf()方法直接寫入流。
IronPDF的方法更為簡單:建立SaveAs()。 沒有單獨的包,沒有流管理,Chromium渲染引擎提供更好的CSS3和JavaScript支持。 查看HTML到PDF文件以獲取其他渲染選項。
範例二:合併多個PDF
在使用前(iText):
// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Kernel.Utils;
using System.IO;
class Program
{
static void Main()
{
string outputPath = "merged.pdf";
string[] inputFiles = { "document1.pdf", "document2.pdf", "document3.pdf" };
using (PdfWriter writer = new PdfWriter(outputPath))
using (PdfDocument pdfDoc = new PdfDocument(writer))
{
PdfMerger merger = new PdfMerger(pdfDoc);
foreach (string file in inputFiles)
{
using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
{
merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
}
}
}
}
}
// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Kernel.Utils;
using System.IO;
class Program
{
static void Main()
{
string outputPath = "merged.pdf";
string[] inputFiles = { "document1.pdf", "document2.pdf", "document3.pdf" };
using (PdfWriter writer = new PdfWriter(outputPath))
using (PdfDocument pdfDoc = new PdfDocument(writer))
{
PdfMerger merger = new PdfMerger(pdfDoc);
foreach (string file in inputFiles)
{
using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
{
merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
}
}
}
}
}
Imports iText.Kernel.Pdf
Imports iText.Kernel.Utils
Imports System.IO
Class Program
Shared Sub Main()
Dim outputPath As String = "merged.pdf"
Dim inputFiles As String() = {"document1.pdf", "document2.pdf", "document3.pdf"}
Using writer As New PdfWriter(outputPath)
Using pdfDoc As New PdfDocument(writer)
Dim merger As New PdfMerger(pdfDoc)
For Each file As String In inputFiles
Using sourcePdf As New PdfDocument(New PdfReader(file))
merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages())
End Using
Next
End Using
End Using
End Sub
End Class
之後(IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdfDocuments = new List<PdfDocument>
{
PdfDocument.FromFile("document1.pdf"),
PdfDocument.FromFile("document2.pdf"),
PdfDocument.FromFile("document3.pdf")
};
var merged = PdfDocument.Merge(pdfDocuments);
merged.SaveAs("merged.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdfDocuments = new List<PdfDocument>
{
PdfDocument.FromFile("document1.pdf"),
PdfDocument.FromFile("document2.pdf"),
PdfDocument.FromFile("document3.pdf")
};
var merged = PdfDocument.Merge(pdfDocuments);
merged.SaveAs("merged.pdf");
}
}
Imports IronPdf
Imports System.Collections.Generic
Class Program
Shared Sub Main()
Dim pdfDocuments As New List(Of PdfDocument) From {
PdfDocument.FromFile("document1.pdf"),
PdfDocument.FromFile("document2.pdf"),
PdfDocument.FromFile("document3.pdf")
}
Dim merged = PdfDocument.Merge(pdfDocuments)
merged.SaveAs("merged.pdf")
End Sub
End Class
iText合併操作需要大量樣板程式碼:為輸出建立PdfReader進行操作。 您還必須使用merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages())指定頁面範圍。
IronPDF將這樣縮減到三個步驟:使用PdfDocument.Merge()方法使用列表,然後保存。 整個合併操作變得可讀且易於維護。 了解更多合併和拆分PDF的資訊。
範例3:建立包含文字和圖片的PDF
在使用前(iText):
// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.IO.Image;
class Program
{
static void Main()
{
string outputPath = "document.pdf";
using (PdfWriter writer = new PdfWriter(outputPath))
using (PdfDocument pdf = new PdfDocument(writer))
using (Document document = new Document(pdf))
{
document.Add(new Paragraph("Sample PDF Document"));
document.Add(new Paragraph("This document contains text and an image."));
Image img = new Image(ImageDataFactory.Create("image.jpg"));
img.SetWidth(200);
document.Add(img);
}
}
}
// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.IO.Image;
class Program
{
static void Main()
{
string outputPath = "document.pdf";
using (PdfWriter writer = new PdfWriter(outputPath))
using (PdfDocument pdf = new PdfDocument(writer))
using (Document document = new Document(pdf))
{
document.Add(new Paragraph("Sample PDF Document"));
document.Add(new Paragraph("This document contains text and an image."));
Image img = new Image(ImageDataFactory.Create("image.jpg"));
img.SetWidth(200);
document.Add(img);
}
}
}
Imports iText.Kernel.Pdf
Imports iText.Layout
Imports iText.Layout.Element
Imports iText.IO.Image
Class Program
Shared Sub Main()
Dim outputPath As String = "document.pdf"
Using writer As New PdfWriter(outputPath),
pdf As New PdfDocument(writer),
document As New Document(pdf)
document.Add(New Paragraph("Sample PDF Document"))
document.Add(New Paragraph("This document contains text and an image."))
Dim img As New Image(ImageDataFactory.Create("image.jpg"))
img.SetWidth(200)
document.Add(img)
End Using
End Sub
End Class
之後(IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = @"
<h1>Sample PDF Document</h1>
<p>This document contains text and an image.</p>
<img src='image.jpg' width='200' />";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("document.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = @"
<h1>Sample PDF Document</h1>
<p>This document contains text and an image.</p>
<img src='image.jpg' width='200' />";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("document.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html As String = "
<h1>Sample PDF Document</h1>
<p>This document contains text and an image.</p>
<img src='image.jpg' width='200' />"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("document.pdf")
End Sub
End Class
這個範例最能說明這種範式上的轉變。 iText需要:
- 三重巢狀的
Document) - 為每個文字元素建立
new Paragraph() - 使用
ImageDataFactory.Create()載入圖片 - 建立
SetWidth() - 為每個元素呼叫
document.Add()
IronPDF使用標準的HTML:width屬性的圖片。 網頁開發人員可以立即利用他們現有的技能,設計人員可以使用他們已知的CSS來設計文件。
關鍵遷移注意事項
範式轉變:從程式化到HTML優先
此iText遷移中最顯著的變化是概念的。 iText程式化地生成PDF:
// iText approach
document.Add(new Paragraph("Title")
.SetTextAlignment(TextAlignment.CENTER)
.SetFontSize(24)
.SetBold());
var table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth();
table.AddHeaderCell(new Cell().Add(new Paragraph("ID")));
table.AddHeaderCell(new Cell().Add(new Paragraph("Name")));
// ... many more lines
// iText approach
document.Add(new Paragraph("Title")
.SetTextAlignment(TextAlignment.CENTER)
.SetFontSize(24)
.SetBold());
var table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth();
table.AddHeaderCell(new Cell().Add(new Paragraph("ID")));
table.AddHeaderCell(new Cell().Add(new Paragraph("Name")));
// ... many more lines
' iText approach
document.Add(New Paragraph("Title") _
.SetTextAlignment(TextAlignment.CENTER) _
.SetFontSize(24) _
.SetBold())
Dim table = New Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth()
table.AddHeaderCell(New Cell().Add(New Paragraph("ID")))
table.AddHeaderCell(New Cell().Add(New Paragraph("Name")))
' ... many more lines
IronPDF使用HTML和CSS:
//IronPDFapproach
string html = @"
<style>
h1 { text-align: center; font-size: 24px; font-weight: bold; }
table { width: 100%; border-collapse: collapse; }
th { background-color: #4CAF50; color: white; padding: 8px; }
</style>
<h1>Title</h1>
<table>
<tr><th>ID</th><th>Name</th></tr>
</table>";
var pdf = renderer.RenderHtmlAsPdf(html);
//IronPDFapproach
string html = @"
<style>
h1 { text-align: center; font-size: 24px; font-weight: bold; }
table { width: 100%; border-collapse: collapse; }
th { background-color: #4CAF50; color: white; padding: 8px; }
</style>
<h1>Title</h1>
<table>
<tr><th>ID</th><th>Name</th></tr>
</table>";
var pdf = renderer.RenderHtmlAsPdf(html);
'IronPDFapproach
Dim html As String = "
<style>
h1 { text-align: center; font-size: 24px; font-weight: bold; }
table { width: 100%; border-collapse: collapse; }
th { background-color: #4CAF50; color: white; padding: 8px; }
</style>
<h1>Title</h1>
<table>
<tr><th>ID</th><th>Name</th></tr>
</table>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
移除AGPL風險
根據iText的AGPL條款,使用iText的網頁應用程式通常被期望公開發布其源程式碼給任何通過網路與其交互的使用者; 商業授權是另一條路徑。 IronPDF的商業授權允許在專有軟體中部署,無傳染性授權要求。
不需要pdfHTML附加組件
iText需要獨立的itext包一起銷售。 IronPDF在基礎包中包含了基於Chromium的HTML渲染。
方法替換模式
| iText模式 | IronPDF替換 |
|---|---|
SetTextAlignment(TextAlignment.CENTER) |
CSS text-align: center |
SetFontSize(24) |
CSS font-size: 24px |
SetBold() |
CSS font-weight: bold |
new Table(3) |
HTML <table> |
AddHeaderCell(new Cell().Add(new Paragraph())) |
HTML <th> |
AddCell(new Cell().Add(new Paragraph())) |
HTML <td> |
故障排除
問題1:PdfWriter/Document模式
問題:程式碼使用了PdfWriter → PdfDocument → Document巢狀模式。
解決方案:用ChromePdfRenderer替換:
// Delete this iText pattern:
// using (var writer = new PdfWriter(outputPath))
// using (var pdfDoc = new PdfDocument(writer))
// using (var document = new Document(pdfDoc))
// Replace with:
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
// Delete this iText pattern:
// using (var writer = new PdfWriter(outputPath))
// using (var pdfDoc = new PdfDocument(writer))
// using (var document = new Document(pdfDoc))
// Replace with:
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(outputPath)
問題2:找不到HtmlConverter
問題:程式碼使用了itext.pdfhtml附加組件中。
解決方案:使用IronPDF的內建HTML渲染:
// iText (requires pdfHTML add-on)
HtmlConverter.ConvertToPdf(html, fileStream);
//IronPDF(built-in)
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
// iText (requires pdfHTML add-on)
HtmlConverter.ConvertToPdf(html, fileStream);
//IronPDF(built-in)
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
' iText (requires pdfHTML add-on)
HtmlConverter.ConvertToPdf(html, fileStream)
' IronPDF(built-in)
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(outputPath)
問題3:PdfMerger的複雜性
問題:iText的PdfMerger需要巢狀的讀取器和頁面範圍說明。
解決方案:使用IronPDF的靜態合併方法:
// iText merger pattern (delete this)
// using (PdfDocument pdfDoc = new PdfDocument(writer))
// {
// PdfMerger merger = new PdfMerger(pdfDoc);
// foreach (string file in inputFiles)
// {
// using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
// {
// merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
// }
// }
// }
//IronPDF(simple)
var merged = PdfDocument.Merge(pdfDocuments);
merged.SaveAs("merged.pdf");
// iText merger pattern (delete this)
// using (PdfDocument pdfDoc = new PdfDocument(writer))
// {
// PdfMerger merger = new PdfMerger(pdfDoc);
// foreach (string file in inputFiles)
// {
// using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
// {
// merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
// }
// }
// }
//IronPDF(simple)
var merged = PdfDocument.Merge(pdfDocuments);
merged.SaveAs("merged.pdf");
Imports System.Collections.Generic
' iText merger pattern (delete this)
' Using pdfDoc As New PdfDocument(writer)
' Dim merger As New PdfMerger(pdfDoc)
' For Each file As String In inputFiles
' Using sourcePdf As New PdfDocument(New PdfReader(file))
' merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages())
' End Using
' Next
' End Using
' IronPDF(simple)
Dim merged = PdfDocument.Merge(pdfDocuments)
merged.SaveAs("merged.pdf")
遷移檢查表
遷移前
- 清點程式碼庫中的所有iText API調用
- 確定程式化PDF構建模式(段落、表格、單元格)
- 記錄HtmlConverter的使用情況(pdfHTML附加組件)
- 評估AGPL合規風險
- 獲得IronPDF授權金鑰
程式碼遷移
- 移除iText NuGet套件:
itext.pdfhtml/iTextSharp) - 安裝IronPDF NuGet套件:
dotnet add package IronPdf - 更新命名空間匯入(
using iText.*→using IronPdf) - 用
Document模式 - 將
Cell轉換為HTML元素 - 使用
HtmlConverter.ConvertToPdf() - 更新合併作業為
PdfDocument.Merge() - 在啟動時新增授權金鑰初始化
測試
- 測試所有PDF生成流程
- 確認視覺輸出符合預期
- 使用複雜的HTML/CSS內容進行測試
- 基準測試性能
遷移後
- 移除iText授權文件和引用
- 更新文件
- 取消iText的訂閱(如適用)
- 將遺留的iText程式碼存檔

