如何在 C# 中將 Spire.PDF 遷移到 IronPDF
從 Spire.PDF 遷移到 IronPDF 會將您的 PDF 生成工作流程從使用將文字渲染為圖像的庫轉變為使用現代 Chromium 渲染引擎產生真正可選擇、可搜尋文字的流程。本指南提供了完整的逐步遷移路徑,解決了 Spire.PDF 的關鍵 HTML 渲染限制和字體嵌入問題。
為什麼要從 Spire.PDF 遷移到 IronPDF
了解 Spire.PDF
Spire.PDF 是一個功能強大的商業 PDF 庫,專為 .NET 開發人員設計,用於高效處理 PDF 文件。 Spire.PDF 憑藉其獨特的功能,尤其是在傳統應用程式中,在程式設計界贏得了聲譽,並且其整合功能與 E-iceblue 工具集中的其他組件無縫銜接。
然而,Spire.PDF 存在一些影響實際使用的根本性問題,尤其是在 HTML 到 PDF 的轉換和對現代 Web 標準的支援方面。
關鍵技術問題
| 問題 | 影響 | IronPDF解決方案 |
|---|---|---|
| 文字以圖像形式呈現 | PDF檔案無法搜尋、無法存取、無法複製文本 | 真實文字渲染 |
| Internet Explorer 依賴項 | 渲染效果過時,有安全風險 | 現代鉻發動機 |
| 字體嵌入失敗 | 文件在其他系統中顯示錯誤 | 可靠的字體處理 |
| 部署規模大 | 記憶體佔用高,啟動緩慢 | 高效率部署 |
| CSS 支援有限 | 現代佈局無法正確渲染。 | 完全支援 CSS3 |
核心問題:基於影像的PDF
Spire.PDF 的一個重大缺點是它傾向於將 HTML 文件中的文字渲染成圖像。 這會導致生成的 PDF 文件中的文本無法選擇或搜索,這對於需要搜索功能或文檔文本交互的應用程式來說可能是一個嚴重的限制。
當您使用 Spire.PDF 的LoadFromHTML()方法時,它通常會將文本渲染為點陣圖圖像而不是實際文本,從而導致以下問題:
- 無法選擇文字 文字無法搜尋。
- 文字無法複製 螢幕閱讀器無法讀取(違反無障礙規定) 檔案大小要大得多。 縮放會導致像素化
Spire.PDF 與 IronPDF 對比
| 特徵 | Spire.PDF | IronPDF |
|---|---|---|
| HTML 轉 PDF 渲染 | 文字以圖像形式呈現 | 真正的文字渲染(可選擇和可搜尋) |
| 渲染引擎 | Internet Explorer 依賴某些系統 | 基於 Chium,符合現代 Web 標準 |
| 字體處理 | 字體嵌入的已知問題 | 可靠且強大的字體處理 |
| CSS3 支持 | 有限的 | 滿的 |
| Flexbox/Grid | 不支援 | 全力支持 |
| JavaScript | 有限的 | 完整的 ES6+ |
| PDF 無障礙訪問 | 差(基於圖像) | 出色的 |
| API設計 | 複雜的 | 簡單直觀 |
| 部署範圍 | 大的 | 緩和 |
| 授權 | 免費增值/商業模式 | 商業的 |
對於計劃在 2025 年和 2026 年採用 .NET 10 和 C# 14 的團隊,IronPDF 透過將文字渲染為實際的可選擇文字而不是圖像,解決了 Spire.PDF 的 HTML 到 PDF 轉換的關鍵問題,從而確保 PDF 可搜尋和可存取。
開始之前
先決條件
- .NET 環境: .NET Framework 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet 存取權限:能夠安裝 NuGet 套件
- IronPDF 許可證:請從ironpdf.com取得您的許可證密鑰。
NuGet 套件變更
# Remove Spire.PDF
dotnet remove package Spire.PDF
dotnet remove package FreeSpire.PDF # If using free version
# Install IronPDF
dotnet add package IronPdf# Remove Spire.PDF
dotnet remove package Spire.PDF
dotnet remove package FreeSpire.PDF # If using free version
# Install IronPDF
dotnet add package IronPdf許可證配置
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";完整 API 參考
命名空間變更
// Before: Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using Spire.Pdf.HtmlConverter;
// After: IronPDF
using IronPdf;
using IronPdf.Editing;// Before: Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using Spire.Pdf.HtmlConverter;
// After: IronPDF
using IronPdf;
using IronPdf.Editing;核心 API 映射
| Spire.PDF | IronPDF | 筆記 |
|---|---|---|
new PdfDocument() | new ChromePdfRenderer() | 用於 HTML 渲染 |
pdf.LoadFromHTML() | renderer.RenderHtmlAsPdf() | HTML轉換 |
pdf.LoadFromFile() | PdfDocument.FromFile() | 載入現有PDF |
pdf.SaveToFile() | pdf.SaveAs() | 儲存到文件 |
pdf.Close() | 不需要 | 使用處置模式 |
pdf.Pages.Add() | renderer.RenderHtmlAsPdf() | 從 HTML 建立頁面 |
pdf.InsertPageRange() | PdfDocument.Merge() | 合併PDF |
page.Canvas.DrawString() | TextStamper + ApplyStamp() | 新增文字 |
PdfFont | HTML中的CSS樣式 | 字體配置 |
PdfBrush | HTML中的CSS樣式 | 色彩/填滿配置 |
程式碼遷移範例
範例 1:HTML 轉 PDF
之前(Spire.PDF):
// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfHtmlLayoutFormat htmlLayoutFormat = new PdfHtmlLayoutFormat();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
pdf.LoadFromHTML(htmlString, false, true, true);
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfHtmlLayoutFormat htmlLayoutFormat = new PdfHtmlLayoutFormat();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
pdf.LoadFromHTML(htmlString, false, true, true);
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlString);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlString);
pdf.SaveAs("output.pdf");
}
}這個例子展示了HTML渲染的根本差異。 Spire.PDF 使用LoadFromHTML()和PdfHtmlLayoutFormat對象,通常會將文字渲染為點陣圖影像。 結果是生成的 PDF 文件,用戶無法選擇、複製或搜尋文字。
IronPDF 使用ChromePdfRenderer和RenderHtmlAsPdf() ,產生完全可選、可搜尋和可存取的真正文字。 無需呼叫Close()函數-IronPDF 使用 dispose 模式進行自動清理。有關完整範例,請參閱HTML 轉 PDF 文件。
範例 2:合併多個 PDF 文件
之前(Spire.PDF):
// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using System;
class Program
{
static void Main()
{
PdfDocument pdf1 = new PdfDocument();
pdf1.LoadFromFile("document1.pdf");
PdfDocument pdf2 = new PdfDocument();
pdf2.LoadFromFile("document2.pdf");
pdf1.InsertPageRange(pdf2, 0, pdf2.Pages.Count - 1);
pdf1.SaveToFile("merged.pdf");
pdf1.Close();
pdf2.Close();
}
}// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using System;
class Program
{
static void Main()
{
PdfDocument pdf1 = new PdfDocument();
pdf1.LoadFromFile("document1.pdf");
PdfDocument pdf2 = new PdfDocument();
pdf2.LoadFromFile("document2.pdf");
pdf1.InsertPageRange(pdf2, 0, pdf2.Pages.Count - 1);
pdf1.SaveToFile("merged.pdf");
pdf1.Close();
pdf2.Close();
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
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;
using System;
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");
}
}Spire.PDF 需要手動使用new PdfDocument() + LoadFromFile()載入每個文檔,然後使用InsertPageRange()指定要插入的頁面,最後對每個文檔呼叫Close() 。
IronPDF 使用更簡單的PdfDocument.FromFile()模式和靜態PdfDocument.Merge()方法,接受多個文件。 無需呼叫Close()函數。 了解更多信息,請閱讀我們的教程。
範例 3:為 PDF 新增文本
之前(Spire.PDF):
// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfPageBase page = pdf.Pages.Add();
PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 20);
PdfBrush brush = new PdfSolidBrush(Color.Black);
page.Canvas.DrawString("Hello from Spire.PDF!", font, brush, new PointF(50, 50));
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfPageBase page = pdf.Pages.Add();
PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 20);
PdfBrush brush = new PdfSolidBrush(Color.Black);
page.Canvas.DrawString("Hello from Spire.PDF!", font, brush, new PointF(50, 50));
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}(IronPDF 之後):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body></body></html>");
var textStamper = new TextStamper()
{
Text = "Hello from IronPDF!",
FontSize = 20,
VerticalOffset = 50,
HorizontalOffset = 50
};
pdf.ApplyStamp(textStamper);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body></body></html>");
var textStamper = new TextStamper()
{
Text = "Hello from IronPDF!",
FontSize = 20,
VerticalOffset = 50,
HorizontalOffset = 50
};
pdf.ApplyStamp(textStamper);
pdf.SaveAs("output.pdf");
}
}Spire.PDF 使用基於畫布的繪圖模型,結合PdfFont 、 PdfBrush和page.Canvas.DrawString()利用PointF將文字定位到特定座標。
IronPDF 使用TextStamper對象,該物件具有Text 、 FontSize 、 VerticalOffset和HorizontalOffset等直覺屬性,然後使用ApplyStamp()應用它。 這種方法更具聲明性,也更容易維護。
文字圖像問題
為什麼這一點至關重要
Spire.PDF 使用基於影像的渲染方式將 HTML 轉換為 PDF 時,文件會失去一些重要功能:
1. 不支援文字搜尋:使用者無法使用 Ctrl+F 尋找文字。 文檔管理系統無法索引內容。
2. 無法選擇/複製文字:嘗試複製引文、參考文獻或資料的使用者無法選擇文字-它顯示的是圖像。
3. 無障礙存取違規:基於影像的 PDF 不符合 WCAG 2.1 標準、第 508 條(美國政府)標準、ADA 要求和螢幕閱讀器相容性要求。
4. 檔案大小較大:相同內容的比較顯示,Spire.PDF(基於圖像)產生的檔案比 IronPDF(基於文字)大 16 倍。
檢測:您的 PDF 是否基於圖像?
開啟 Spire.PDF 產生的文檔,並嘗試以下測試:
1.文字選擇:點選並拖曳選擇文字。 如果沒有反白顯示 → 基於圖像
- Ctrl+F 搜尋:搜尋頁面上的任何單字。 如果"找不到匹配項"→ 基於影像 3.複製/貼上:選擇文字並複製到記事本。 如果沒有任何內容可以貼上 → 基於圖像
Internet Explorer 問題
Spire.PDF 的渲染引擎
在某些環境下,Spire.PDF 依賴 Internet Explorer/Edge Legacy 進行 HTML 渲染。 IE瀏覽器已於2022年棄用,現代CSS無法正常運作,JavaScript支援有限,且在不同系統上的渲染效果不一致。
在 Spire 中失敗的現代 CSS.PDF
<!-- This HTML renders incorrectly in Spire.PDF -->
<div style="display: flex; justify-content: space-between; gap: 20px;">
<div style="flex: 1;">Column 1</div>
<div style="flex: 1;">Column 2</div>
</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<!-- CSS Variables don't work -->
<style>
:root { --primary-color: #007bff; }
h1 { color: var(--primary-color); }
</style><!-- This HTML renders incorrectly in Spire.PDF -->
<div style="display: flex; justify-content: space-between; gap: 20px;">
<div style="flex: 1;">Column 1</div>
<div style="flex: 1;">Column 2</div>
</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<!-- CSS Variables don't work -->
<style>
:root { --primary-color: #007bff; }
h1 { color: var(--primary-color); }
</style>IronPDF 使用現代 Chromium 渲染技術,因此所有這些 CSS 功能都能正常運作。
遷移後的新功能
遷移到 IronPDF 後,您將獲得 Spire.PDF 無法提供的功能:
可選擇、可搜尋的文本
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Important Contract</h1>");
pdf.SaveAs("contract.pdf");
// Result:
// ✅ Text is fully selectable
// ✅ Text is searchable with Ctrl+F
// ✅ Text can be copied to clipboard
// ✅ Screen readers work perfectly
// ✅ File size is compact
// ✅ Zooming is crystal clearvar renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Important Contract</h1>");
pdf.SaveAs("contract.pdf");
// Result:
// ✅ Text is fully selectable
// ✅ Text is searchable with Ctrl+F
// ✅ Text can be copied to clipboard
// ✅ Screen readers work perfectly
// ✅ File size is compact
// ✅ Zooming is crystal clear現代 CSS 支持
var renderer = new ChromePdfRenderer();
var html = @"
<style>
:root { --primary: #007bff; }
.container { display: flex; gap: 20px; }
.grid { display: grid; grid-template-columns: repeat(3, 1fr); }
</style>
<div class='container'>
<div style='flex: 1; color: var(--primary)'>Column 1</div>
<div style='flex: 1'>Column 2</div>
</div>
<div class='grid'>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
// All modern CSS features render correctly!var renderer = new ChromePdfRenderer();
var html = @"
<style>
:root { --primary: #007bff; }
.container { display: flex; gap: 20px; }
.grid { display: grid; grid-template-columns: repeat(3, 1fr); }
</style>
<div class='container'>
<div style='flex: 1; color: var(--primary)'>Column 1</div>
<div style='flex: 1'>Column 2</div>
</div>
<div class='grid'>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
// All modern CSS features render correctly!基於HTML的浮水印
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.ApplyWatermark(@"
<div style='
font-size: 48px;
color: rgba(255, 0, 0, 0.5);
transform: rotate(-45deg);
'>DRAFT</div>");var pdf = renderer.RenderHtmlAsPdf(html);
pdf.ApplyWatermark(@"
<div style='
font-size: 48px;
color: rgba(255, 0, 0, 0.5);
transform: rotate(-45deg);
'>DRAFT</div>");遷移清單
遷移前
- 清點程式碼庫中所有 Spire.PDF 的使用情況
- 測試現有PDF文件的文字選擇性(關鍵問題檢測)
- Document
LoadFromHTML()呼叫(這是需要優先修復的問題) - 從ironpdf.com取得 IronPDF 許可證金鑰
程式碼更新
- 移除
Spire.PDFNuGet 套件(如果使用的是免費版本,則同時移除FreeSpire.PDF) 安裝IronPdfNuGet 套件 - 更新命名空間導入(
using Spire.Pdf;→using IronPdf;) - 將
LoadFromHTML()替換為RenderHtmlAsPdf()(關鍵修復) - 將
new PdfDocument()+LoadFromFile()替換為PdfDocument.FromFile() - 將
InsertPageRange()替換為PdfDocument.Merge() - 將
Canvas.DrawString()替換為TextStamper+ApplyStamp() - 將
SaveToFile()替換為SaveAs() - 移除所有
Close()呼叫(IronPDF 中不需要) - 在應用程式啟動時新增許可證初始化
測試
- 驗證產生的 PDF 檔案中的文字是否可選(關鍵測試)
- 驗證 CSS 渲染改進(Flexbox/Grid 現在可以正常運作)
- 確認檔案大小較小
- 使用螢幕閱讀器測試輔助功能
- 效能比較






