比較

FO.NET vs IronPDF for .NET:技術比較指南

當.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使用 FonetDriver 作為其主要類,其中 Make() 工廠方法創建驅動程式實例,而 Render() 方法處理 XSL-FO 輸入流以產生 PDF 輸出流。 配置是在 XSL-FO 標記本身中進行的,使用諸如 fo:layout-master-set 之類的元素,以及用於邊距、頁面大小和字體的格式屬性。

一個顯著的限制是,FO .NET需要 XSL-FO 知識——XSL-FO 是一種基於 XML 的語言,是 W3C 於 2001 年制定的規範,自 2006 年以來未進行更新。該庫不支援 HTML 或 CSS,也不能直接渲染網頁。 在當今的技術領域,XSL-FO 已被普遍認為過時,只有不到 1% 的開發人員精通它,而超過 98% 的開發人員了解 HTML/CSS。

原 CodePlex 程式碼庫已失效, GitHub的分支程式碼也已停止維護。 FO .NET對 System.Drawing 有內部依賴關係,這導致它無法在 Linux/macOS 上運行,因此只能在 Windows 上部署。

了解IronPDF

IronPDF是一個.NET PDF 函式庫,它使用 HTML/CSS 進行文件樣式和佈局,採用開發中常用的 Web 標準。 該庫使用 Chromium 渲染引擎,提供完整的 CSS3 支持,包括 Flexbox 和 Grid 佈局,以及JavaScript執行。

IronPDF使用 ChromePdfRenderer 作為其主要渲染類,而 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 支援沒有任何完整的 CSS3(Flexbox、Grid)
JavaScript沒有任何完全支援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));
    }
}
$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");
    }
}
$vbLabelText   $csharpLabel

對比很明顯。 FO .NET需要詳細的 XSL-FO 標記,其中包含 XML 命名空間聲明、fo:page-sequence、@@--CODE-926—@92---CO 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();
    }
}
$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");
    }
}
$vbLabelText   $csharpLabel

FO .NET明確不支援 URL 渲染。 程式碼註解指出:"FoNet 不支援直接 URL 渲染"和"需要手動將 HTML 轉換為 XSL-FO(較為複雜)"。 ConvertHtmlToXslFo() 方法拋出 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));
    }
}
$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");
    }
}
$vbLabelText   $csharpLabel

FO .NET中的程式碼註解明確指出:"FoNet 設定是在 XSL-FO 標記中配置​​的。"頁面大小、邊距和格式作為屬性嵌入到 XML 結構中 fo:simple-page-master。 這意味著配置資訊與內容以冗長的 XML 格式交織在一起。

IronPDF使用程式化的 RenderingOptions 屬性將配置與內容分開。 諸如 MarginLeftMarginRight 之類的設定被設定在渲染物件上,而內容則保持為乾淨的 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 到渲染選項的映射

XSL-FO 屬性IronPDF渲染選項
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 規則
<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 轉換)
PDF檔案的URL❌(不支援)
XSL-FO 轉 PDF不適用
CSS3 支持✅(Flexbox、Grid)
JavaScript
頁首/頁尾XSL-FO 靜態內容基於HTML
頁碼fo:page-number{page}佔位符
跨平台❌(僅限 Windows 系統)
主動維護❌(已廢棄)✅(每月)

當團隊考慮從 FO .NET遷移到IronPDF時

開發團隊基於以下幾個原因評估從 FO .NET過渡到IronPDF :

過時的技術: XSL-FO 是 W3C 於 2001 年制定的規範,自 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% 的開發人員已經了解的 Web 技術 -現代渲染:採用 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、URL 並使用 Chromium 引擎實現完整的 CSS3,使其能夠滿足現代 PDF 生成需求。

隨著各組織規劃.NET 10、C# 14 以及到 2026 年的應用程式開發,技術基礎至關重要。 維護傳統 XSL-FO 系統的團隊可以繼續使用 FO .NET,但現代 PDF 產生的未來發展方向顯然是採用基於 HTML 的解決方案,例如IronPDF ,利用現有的 Web 開發專業知識。

立即開始免費試用IronPDF ,並瀏覽其全面的文檔,以評估其是否符合您的特定需求。