比較

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.NETIronPDF
輸入格式XSL-FO(過時的XML)HTML/CSS(現代網路標準)
學習曲線陡峭(XSL-FO專業知識)緩和(HTML/CSS 知識)
維護已廢棄每月積極維護
平台支持僅限Windows真正的跨平台
CSS支援None完全支持CSS3 (Flexbox, Grid)
JavaScriptNone完整的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 Module
$vbLabelText   $csharpLabel

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 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
$vbLabelText   $csharpLabel

對比清晰。 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 Class
$vbLabelText   $csharpLabel

IronPDF:

// 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 Class
$vbLabelText   $csharpLabel

FO.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 Class
$vbLabelText   $csharpLabel

IronPDF:

// 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 Class
$vbLabelText   $csharpLabel

FO.NET中的程式碼評論明確指出:"FoNet設置是在XSL-FO標記中配置的。"頁面尺寸、邊距和格式都作為屬性嵌入在fo:simple-page-master的XML結構內。 這意味著配置與內容糾結在一起,使用冗長的XML格式。

IronPDF將配置與內容分開,使用程式化的RenderingOptions屬性。 MarginRight等設置是在渲染物件上設置的,內容保持整潔的HTML。

API映射參考

對於評估FO.NET遷移或比較功能的開發者,這個映射展示了等效操作:

核心類映射

FO.NETIronPDF
FonetDriver.Make()new ChromePdfRenderer()
driver.Render(inputStream, outputStream)renderer.RenderHtmlAsPdf(html)
driver.Render(inputFile, outputStream)renderer.RenderHtmlFileAsPdf(path)
driver.BaseDirectoryRenderingOptions.BaseUrl
driver.OnError += handler在渲染時使用try/catch

XSL-FO到RenderingOptions映射

XSL-FO屬性IronPDFRenderingOptions
page-widthPaperSize
margin-topMarginTop
margin-bottomMarginBottom
margin-leftMarginLeft
margin-rightMarginRight
reference-orientationPaperOrientation

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.NETIronPDF
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的優勢

  • HTML/CSS標準:使用超過98%的開發者已知的網頁技術
  • 現代渲染:Chromium引擎,全面支援CSS3和JavaScript
  • 活躍開發:每月釋出新功能和安全補丁
  • 跨平台:對Windows、Linux和macOS的真正支持
  • 直接URL渲染:原生RenderUrlAsPdf()功能
  • 專業功能: 標頭、頁尾、水印、安全性—全內建
  • 全面的資源: 豐富的教程文件

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,並探索全面的文件以評估特定需求的適用性。

請注意FONET是其相關所有者的註冊商標。 本網站不隸屬於、未受FONET認可或贊助。 所有產品名稱、標誌和品牌均為其各自所有者的財產。 比較僅供資訊參考,並反映了撰寫時公開的資訊。)}