Adobe PDF Library SDK與IronPDF:技術比較指南
當.NET開發人員查看PDF生成解決方案時,FO.NET作為一個專門的工具,能將XSL-FO文件轉換為PDF,脫穎而出。 然而,由於其依賴過時的XSL-FO語言,缺乏HTML/CSS支持,且維護已中止,許多團隊考慮其他選擇。IronPDF提供了一個現代解決方案,使用開發人員大多數已熟悉的HTML/CSS網頁標準,擁有Chromium渲染引擎和定期的每月更新。
此比較將檢視這兩個程式庫在相關技術方面的表現,以協助專業開發者和架構師做出符合其.NET PDF需求的明智決策。
了解 FO.NET
FO.NET(也稱為FoNet)是一個開源程式庫,設計用於使用C#將XSL格式物件(XSL-FO)文件轉換為PDF。 該程式庫在 Apache 2.0 授權下運行,並直接將XSL-FO語言映射到PDF格式。
FO.NET使用Render()方法處理XSL-FO輸入流以生成PDF輸出流。 配置發生在XSL-FO標記本身中,使用fo:layout-master-set等元素和用於邊距、頁面尺寸和字體的格式屬性。
一個重要的限制是FO.NET需要XSL-FO知識——這是一種根據2001年W3C規範的基於XML的語言,且自2006年以來未有更新。該程式庫不支持HTML或CSS,無法直接渲染網頁。 在當今的技術領域中,XSL-FO大致被認為是過時的,知道它的開發人員不到1%,而有超過98%的開發人員了解HTML/CSS。
原始的CodePlex庫已經廢止,而GitHub分支不再被積極維護。 FO.NET在System.Drawing上的內部依賴阻止了其在Linux/macOS上的運行,限制其僅能部署於Windows。
了解IronPDF
IronPDF是一個.NET的PDF程式庫,使用HTML/CSS進行文件樣式和佈局設計,使用在開發中常見的網頁標準。 該程式庫使用Chromium渲染引擎,提供完整的CSS3支持,包括Flexbox和Grid佈局,另外還支持JavaScript執行。
IronPDF使用RenderingOptions提供頁面尺寸、邊距、頁眉、頁腳及其他PDF設置的程式化配置。 該程式庫支持URL直接渲染、HTML字串渲染和HTML文件渲染,生成PdfDocument物件,可以保存、合併、安全處理或進一步操作。
IronPDF積極維護,每月釋出更新,且支持真正的跨平台部署(Windows、Linux、macOS),並提供詳盡的文件和教程。
架構與技術比較
這些.NET PDF程式庫之間的根本區別在於其輸入格式和技術基礎。
| 方面 | FO.NET | IronPDF |
|---|---|---|
| 輸入格式 | XSL-FO(過時的XML) | HTML/CSS(現代網路標準) |
| 學習曲線 | 陡峭(XSL-FO專業知識) | 緩和(HTML/CSS 知識) |
| 維護 | 已廢棄 | 每月積極維護 |
| 平台支持 | 僅限Windows | 真正的跨平台 |
| CSS支援 | None | 完全支持CSS3 (Flexbox, Grid) |
| JavaScript | None | 完整的JavaScript支持 |
| URL 渲染 | 不支持 | 內建支持 |
| 現代特徵 | 有限 | 頁眉、頁腳、水印、安全性 |
| 文件 | 過時 | 全面教程 |
FO.NET在XSL-FO預期會成為文件格式標準的時候設計。 這並未發生——HTML/CSS成為了通用的文件格式。 大多數XSL-FO的資源來自2005-2010年,使得找到當前的資料或社群支持愈發困難。
程式碼比較:常見的 PDF 操作
HTML 到 PDF 轉換
最基本的操作展示了XSL-FO和HTML方法之間的模式差異。
FO.NET:
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;
class Program
{
static void Main()
{
// FoNet requires XSL-FO format, not HTML
// First convert HTML to XSL-FO (manual process)
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='page'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='page'>
<fo:flow flow-name='xsl-region-body'>
<fo:block>Hello World</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("output.pdf", FileMode.Create));
}
}// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;
class Program
{
static void Main()
{
// FoNet requires XSL-FO format, not HTML
// First convert HTML to XSL-FO (manual process)
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='page'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='page'>
<fo:flow flow-name='xsl-region-body'>
<fo:block>Hello World</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("output.pdf", FileMode.Create));
}
}Imports Fonet
Imports Fonet.Render.Pdf
Imports System.IO
Imports System.Xml
Module Program
Sub Main()
' FoNet requires XSL-FO format, not HTML
' First convert HTML to XSL-FO (manual process)
Dim xslFo As String = "<?xml version='1.0' encoding='utf-8'?>" & _
"<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>" & _
"<fo:layout-master-set>" & _
"<fo:simple-page-master master-name='page'>" & _
"<fo:region-body/>" & _
"</fo:simple-page-master>" & _
"</fo:layout-master-set>" & _
"<fo:page-sequence master-reference='page'>" & _
"<fo:flow flow-name='xsl-region-body'>" & _
"<fo:block>Hello World</fo:block>" & _
"</fo:flow>" & _
"</fo:page-sequence>" & _
"</fo:root>"
Dim driver As FonetDriver = FonetDriver.Make()
driver.Render(New StringReader(xslFo),
New FileStream("output.pdf", FileMode.Create))
End Sub
End ModuleIronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = "<h1>Hello World</h1><p>This is HTML content.</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 HTML content.</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 HTML content.</p>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Sub
End Class對比清晰。 FO.NET需要冗長的XSL-FO標記,帶有XML命名空間聲明、fo:block元素——所有這些都在產生簡單的"Hello World"文字之前。 程式碼評論明確說明:"FoNet需要XSL-FO格式,而非HTML。"
IronPDF建立一個渲染器,傳入標準HTML,渲染為PDF並保存——使用開發人員已知的語法,只需四行簡單程式碼。
想了解進階HTML渲染選項,請參閱HTML到PDF轉換指南。
URL到PDF轉換
將網頁轉換為PDF揭示了一個重要的能力差距。
FO.NET:
// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;
class Program
{
static void Main()
{
// FoNet does not support URL rendering directly
// Must manually download, convert HTML to XSL-FO, then render
string url = "https://example.com";
string html = new WebClient().DownloadString(url);
// Manual conversion from HTML to XSL-FO required (complex)
string xslFo = ConvertHtmlToXslFo(html); // Not built-in
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("webpage.pdf", FileMode.Create));
}
static string ConvertHtmlToXslFo(string html)
{
// Custom implementation required
throw new System.NotImplementedException();
}
}// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;
class Program
{
static void Main()
{
// FoNet does not support URL rendering directly
// Must manually download, convert HTML to XSL-FO, then render
string url = "https://example.com";
string html = new WebClient().DownloadString(url);
// Manual conversion from HTML to XSL-FO required (complex)
string xslFo = ConvertHtmlToXslFo(html); // Not built-in
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("webpage.pdf", FileMode.Create));
}
static string ConvertHtmlToXslFo(string html)
{
// Custom implementation required
throw new System.NotImplementedException();
}
}Imports Fonet
Imports System.IO
Imports System.Net
Class Program
Shared Sub Main()
' FoNet does not support URL rendering directly
' Must manually download, convert HTML to XSL-FO, then render
Dim url As String = "https://example.com"
Dim html As String = New WebClient().DownloadString(url)
' Manual conversion from HTML to XSL-FO required (complex)
Dim xslFo As String = ConvertHtmlToXslFo(html) ' Not built-in
Dim driver As FonetDriver = FonetDriver.Make()
driver.Render(New StringReader(xslFo),
New FileStream("webpage.pdf", FileMode.Create))
End Sub
Shared Function ConvertHtmlToXslFo(html As String) As String
' Custom implementation required
Throw New System.NotImplementedException()
End Function
End ClassIronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End ClassFO.NET明確不支持URL渲染。 程式碼評論指出:"FoNet 不直接支持 URL 渲染"和"需要手動從 HTML 轉換到 XSL-FO(複雜)。"NotImplementedException,因為這種轉換不是內建的,需要自定義實現。
IronPDF提供本地化的RenderUrlAsPdf()功能,處理URL獲取、JavaScript執行和渲染,在一個方法調用中完成——三行程式碼對比一個複雜的,未實現的工作流程。
了解更多關於URL渲染的資訊,請參閱URL到PDF文件。
具有自定義設置的PDF
配置頁面尺寸和邊距展示了配置方法的區別。
FO.NET:
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
class Program
{
static void Main()
{
// FoNet settings are configured in XSL-FO markup
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='A4'
page-height='297mm' page-width='210mm'
margin-top='20mm' margin-bottom='20mm'
margin-left='25mm' margin-right='25mm'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='A4'>
<fo:flow flow-name='xsl-region-body'>
<fo:block font-size='14pt'>Custom PDF</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("custom.pdf", FileMode.Create));
}
}// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
class Program
{
static void Main()
{
// FoNet settings are configured in XSL-FO markup
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='A4'
page-height='297mm' page-width='210mm'
margin-top='20mm' margin-bottom='20mm'
margin-left='25mm' margin-right='25mm'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='A4'>
<fo:flow flow-name='xsl-region-body'>
<fo:block font-size='14pt'>Custom PDF</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("custom.pdf", FileMode.Create));
}
}Imports Fonet
Imports Fonet.Render.Pdf
Imports System.IO
Class Program
Shared Sub Main()
' FoNet settings are configured in XSL-FO markup
Dim xslFo As String = "<?xml version='1.0' encoding='utf-8'?>" & _
"<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>" & _
"<fo:layout-master-set>" & _
"<fo:simple-page-master master-name='A4' " & _
"page-height='297mm' page-width='210mm' " & _
"margin-top='20mm' margin-bottom='20mm' " & _
"margin-left='25mm' margin-right='25mm'>" & _
"<fo:region-body/>" & _
"</fo:simple-page-master>" & _
"</fo:layout-master-set>" & _
"<fo:page-sequence master-reference='A4'>" & _
"<fo:flow flow-name='xsl-region-body'>" & _
"<fo:block font-size='14pt'>Custom PDF</fo:block>" & _
"</fo:flow>" & _
"</fo:page-sequence>" & _
"</fo:root>"
Dim driver As FonetDriver = FonetDriver.Make()
driver.Render(New StringReader(xslFo),
New FileStream("custom.pdf", FileMode.Create))
End Sub
End ClassIronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 25;
renderer.RenderingOptions.MarginRight = 25;
string html = "<h1 style='font-size:14pt'>Custom PDF</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 25;
renderer.RenderingOptions.MarginRight = 25;
string html = "<h1 style='font-size:14pt'>Custom PDF</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom.pdf");
}
}Imports IronPdf
Imports IronPdf.Engines.Chrome
Class Program
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.MarginLeft = 25
renderer.RenderingOptions.MarginRight = 25
Dim html As String = "<h1 style='font-size:14pt'>Custom PDF</h1>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("custom.pdf")
End Sub
End ClassFO.NET中的程式碼評論明確指出:"FoNet設置是在XSL-FO標記中配置的。"頁面尺寸、邊距和格式都作為屬性嵌入在fo:simple-page-master的XML結構內。 這意味著配置與內容糾結在一起,使用冗長的XML格式。
IronPDF將配置與內容分開,使用程式化的RenderingOptions屬性。 MarginRight等設置是在渲染物件上設置的,內容保持整潔的HTML。
API映射參考
對於評估FO.NET遷移或比較功能的開發者,這個映射展示了等效操作:
核心類映射
| FO.NET | IronPDF |
|---|---|
FonetDriver.Make() | new ChromePdfRenderer() |
driver.Render(inputStream, outputStream) | renderer.RenderHtmlAsPdf(html) |
driver.Render(inputFile, outputStream) | renderer.RenderHtmlFileAsPdf(path) |
driver.BaseDirectory | RenderingOptions.BaseUrl |
driver.OnError += handler | 在渲染時使用try/catch |
XSL-FO到RenderingOptions映射
| XSL-FO屬性 | IronPDFRenderingOptions |
|---|---|
page-width | PaperSize |
margin-top | MarginTop |
margin-bottom | MarginBottom |
margin-left | MarginLeft |
margin-right | MarginRight |
reference-orientation | PaperOrientation |
XSL-FO元素到HTML映射
| XSL-FO元件 | HTML等效 |
|---|---|
<fo:root> | <html> |
<fo:layout-master-set> | CSS @page 規則 |
<fo:simple-page-master> | CSS @page |
<fo:page-sequence> | <body> 或 <div> |
<fo:flow> | <main> 或 <div> |
<fo:static-content> | HtmlHeaderFooter |
<fo:block> | <p>, <div>, <h1>-<h6> |
<fo:table> | <table> |
<fo:list-block> | <ul>, <ol> |
<fo:external-graphic> | <img> |
<fo:page-number/> | {page} 佔位符 |
功能比較總結
| 功能 | FO.NET | IronPDF |
|---|---|---|
| HTML到PDF | 否(需要手動XSL-FO轉換) | 是 |
| URL到PDF | 否(不支持) | 是 |
| XSL-FO到PDF | 是 | 不適用 |
| CSS3支持 | 無 | 是(Flexbox,Grid) |
| JavaScript | 無 | 是 |
| 頁眉/頁腳 | XSL-FO靜態內容 | 基於HTML |
| 頁碼 | fo:page-number | {page} 佔位符 |
| 跨平台 | 否(僅限Windows) | 是 |
| 積極維護 | 否(已廢棄) | 是(每月) |
當團隊考慮從FO.NET轉向IronPDF
開發團隊評估從FO.NET轉向IronPDF的幾個原因:
過時的技術:XSL-FO是2001年的W3C規範,2006年以來未有更新,通常被視為過時。 大部分資源和文件來自2005-2010年,讓找到當前資訊或雇用具備XSL-FO專業知識的開發者愈發困難。
陡峭的學習曲線:XSL-FO需要學習複雜的基於XML的標記,且具備專門的格式物件(fo:page-sequence等)。 少於1%的開發者了解XSL-FO,比起超過98%了解HTML/CSS的開發者。
沒有HTML/CSS支持:FO.NET無法渲染HTML或CSS——需要從HTML手動轉換到XSL-FO標記,這不在程式庫中內建。 擁有網頁內容或HTML模板的團隊必須實現自定義的轉換邏輯。
維護已廢棄:原始的CodePlex庫已經廢止,GitHub分支不再被積極維護。 安全補丁、錯誤修復和新功能不再開發。
平台限制:FO.NET在System.Drawing上的內部依賴阻止了其在Linux/macOS上的運行,限制部署於僅限Windows的環境。 現代應用程式越來越需要跨平台部署。
缺少現代功能:無JavaScript支持,無CSS3特性(Flexbox,Grid),無現代網頁字體,無直接URL渲染功能。
優勢和考量
FO.NET的優勢
- 直接XSL-FO轉換:專為XSL-FO到PDF轉換而優化
- 開源:Apache 2.0 授權—自由使用、修改和分發
- 精確控制:XSL-FO提供了對文件佈局詳盡的控制
FO.NET的考量
- 過時的技術:XSL-FO規範自2006年以來未有更新
- 需要XSL-FO知識:不到1%的開發者具備專業知識
- 無HTML支持:無法渲染HTML或CSS內容
- 已廢棄:無活躍維護或安全更新
- 僅限Windows:System.Drawing依賴阻止跨平台使用
- 無URL渲染:無法直接轉換網頁
- 有限的文件:資源已過時
IronPDF的優勢
IronPDF考量
- 商業許可證:生產使用需要許可
- 不同的范式:XSL-FO模板需要轉換為HTML
結論
FO.NET 和IronPDF代表了.NET 中PDF生成的基本不同方法。 FO.NET服務於XSL-FO到PDF轉換的利基用例,但其依賴於過時的技術、廢棄的維護、僅限Windows的限制和缺乏HTML支持,為新項目帶來瓶頸。
IronPDF提供了一個使用HTML/CSS網頁標準的現代方法,與當前的開發者技能和技術相符。 其直接渲染HTML、URLs的能力,及使用具備Chromium引擎的完整CSS3,使其適用於當代PDF生成要求。
在組織規劃.NET 10、C# 14,及通過2026年的應用開發時,技術基礎很重要。 維持遺留的XSL-FO系統的團隊可能會繼續使用FO.NET,但現代PDF生成的前途明顯指向如IronPDF這樣利用現有網頁開發專長的HTML基於解決方案。
從 免費試用 開始評估 IronPDF,並探索全面的文件以評估特定需求的適用性。
