跳過到頁腳內容
遷移指南

如何從 fo.net 轉移到 IronPDF for .NET

從 fo.net 移植到 IronPDF:完整的 C# 遷移指南。

從fo.net (FO.NET)轉移到IronPDF代表著您的 .NET PDF 生成工作流程的重大現代化。 本指南提供了一個明確、循序漸進的轉換路徑,可將您的程式碼基礎從過時的 XSL-FO 標記轉換為基於 HTML/CSS 的現代化 PDF 生成 - 充分利用您的開發團隊已有的技能。

為什麼要從 fo.net 轉移到 IronPDF?

fo.net 的挑戰

fo.net 是 XSL-FO 到 PDF 的渲染器,對於現代開發來說有很大的限制:

1.過時的技術:XSL-FO (Extensible Stylesheet Language Formatting Objects,可擴充樣式表語言格式化物件) 是 2001 年的 W3C 規格,自 2006 年以來就沒有更新,基本上已被視為過時的技術。

2.陡峭的學習曲線:XSL-FO 需要學習複雜的基於 XML 的標記與專門的格式化物件 (fo:blockfo:tablefo:page-sequence 等)。

3.No HTML/CSS Support:fo.net 無法呈現 HTML 或 CSS - 它需要手動將 HTML 轉換為 XSL-FO 標記。

4.Abandoned/Unmaintained: CodePlex 原始資源庫已停用; GitHub 分叉已不再積極維護。

5.僅限 Windows:fo.net 對 System.Drawing 有內部依賴,因此無法在 Linux/macOS 上運作。

6.有限的現代功能:無JavaScript支援、無 CSS3、無 flexbox/grid、無現代網路字型。

7.No URL Rendering:fo.net 無法直接渲染網頁 - 需要手動將 HTML 轉換為 XSL-FO。

fo.net vsIronPDF對比。

範疇fo.net (FO.NET)IronPDF
輸入格式XSL-FO (過時的 XML)HTML/CSS (現代網路標準)
學習曲線Steep (XSL-FO 專長)溫和 (HTML/CSS 知識)
維護每月積極維護
平台支援僅限 Windows真正的跨平台(.NET 6/7/8/9/10+)
CSS 支援完整的 CSS3 (Flexbox、Grid)
JavaScript完整的JavaScript支援
URL 渲染不支援內建
現代功能限額頁眉、頁腳、水印、安全性
文件過時的綜合教學

為什麼轉換是合理的

fo.net 設計時,XSL-FO 可望成為文件格式的標準。 這個期望從未實現。 HTML/CSS 成為通用的文件格式,超過 98% 的開發人員瞭解 HTML/CSS,而瞭解 XSL-FO 的開發人員則不到 1%。 大多數 XSL-FO 資源的日期為 2005-2010 年間,使得維護變得越來越困難。

IronPDF 可讓您使用已有的技術來製作專業的 PDF,並完全支援現代的 .NET 版本,包括 2025 年至 2026 年上市的 .NET 10 和 C# 14。


開始之前

先決條件

1..NET環境:IronPDF 支援 .NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+. 2.NuGet存取:確保您可以從 NuGet 安裝套件 3.許可金鑰:從ironpdf.com取得您的IronPDF授權金鑰,以供生產使用。

備份您的專案

# Create a backup branch
git checkout -b pre-ironpdf-migration
git add .
git commit -m "Backup before fo.net toIronPDFmigration"
# Create a backup branch
git checkout -b pre-ironpdf-migration
git add .
git commit -m "Backup before fo.net toIronPDFmigration"
SHELL

辨識所有 fo.net 使用方式

# Find all fo.net references
grep -r "FonetDriver\|Fonet\|\.fo\"\|xsl-region" --include="*.cs" --include="*.csproj" .

# Find all XSL-FO template files
find . -name "*.fo" -o -name "*.xslfo" -o -name "*xsl-fo*"
# Find all fo.net references
grep -r "FonetDriver\|Fonet\|\.fo\"\|xsl-region" --include="*.cs" --include="*.csproj" .

# Find all XSL-FO template files
find . -name "*.fo" -o -name "*.xslfo" -o -name "*xsl-fo*"
SHELL

記錄您的 XSL-FO 範本

在轉換之前,將所有 XSL-FO 檔案編目並備註:

  • 頁面尺寸與頁邊
  • 使用的字體
  • 表格及其結構
  • 頁首和頁尾 (fo:static-content)
  • 頁面編號模式
  • 圖片參考

快速啟動遷移

步驟 1:更新 NuGet 套件

# Remove fo.net package
dotnet remove package Fonet
dotnet remove package FO.NET

# Install IronPDF
dotnet add package IronPdf
# Remove fo.net package
dotnet remove package Fonet
dotnet remove package FO.NET

# Install IronPDF
dotnet add package IronPdf
SHELL

步驟 2:更新命名空間

// Before (fo.net)
using Fonet;
using Fonet.Render.Pdf;
using System.Xml;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;
// Before (fo.net)
using Fonet;
using Fonet.Render.Pdf;
using System.Xml;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

步驟 3:初始化 IronPDF

// Set license key at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Set license key at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

步驟 4:基本轉換模式

// Before (fo.net with XSL-FO)
FonetDriver driver = FonetDriver.Make();
using (FileStream output = new FileStream("output.pdf", FileMode.Create))
{
    driver.Render(new StringReader(xslFoContent), output);
}

// After (IronPDF with HTML)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
// Before (fo.net with XSL-FO)
FonetDriver driver = FonetDriver.Make();
using (FileStream output = new FileStream("output.pdf", FileMode.Create))
{
    driver.Render(new StringReader(xslFoContent), output);
}

// After (IronPDF with HTML)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

完整的 API 參考資料

命名空間對應

fo.net 命名空間IronPdf 同等級產品筆記
Fonet<編碼>IronPdf</編碼主要命名空間
<編碼>Fonet.Render.Pdf</編碼<編碼>IronPdf</編碼PDF 繪製
<編碼>Fonet.Layout</編碼不適用以 CSS 處理版面
<編碼>Fonet.Fo</編碼不適用格式化物件 → HTML
<編碼>Fonet.Image</編碼<編碼>IronPdf</編碼內建圖片處理

FonetDriver 至 ChromePdfRenderer。

FonetDriver 方法IronPdf 同等級產品筆記
<編碼>FonetDriver.Make()</編碼新的 ChromePdfRenderer()建立呈現器
driver.Render(inputStream,outputStream)renderer.RenderHtmlAsPdf(html)以流為基礎
driver.Render(inputFile,outputStream)renderer.RenderHtmlFileAsPdf(path)檔案型
<編碼>driver.BaseDirectory</編碼RenderingOptions.BaseUrl資源的基本路徑
driver.OnError += 處理器圍繞 render 的 Try/catch錯誤處理

RenderingOptions(PDF 配置)

fo.net (XSL-FO 屬性)IronPdf RenderingOptions筆記
<編碼>頁面高度</編碼PaperSizeSetCustomPaperSize()頁面尺寸
頁面寬度紙張大小標準或自訂
margin-topMarginTop以毫米為單位
margin-bottom邊界底線以毫米為單位
margin-left邊界左側以毫米為單位
<編碼>右邊距</編碼MarginRight以毫米為單位
參考導向紙張方向肖像/風景

XSL-FO 至 HTML 轉換指南

XSL-FO 元件轉換為 HTML/CSS

這次 fo.net 移植的基本轉換是將 XSL-FO 元素轉換為其 HTML 對應元素:

XSL-FO 元件HTML/CSS 對應筆記
<fo:root><html>根元素
<fo:layout-master-set>CSS @page 規則頁面設定
<fo:simple-page-master>CSS @page頁面定義
<fo:page-sequence><body><div>頁面內容
<編碼><fo:流程></編碼<main><div>主要內容領域
<fo:static-content><編碼>HtmlHeaderFooter</編碼標題/頁腳
<fo:block><p>, <div>, <h1>-<h6>區塊內容
<fo:inline><編碼></編碼內嵌內容
<fo:table><table>表格
<fo:table-row><tr>表格行數
<fo:table-cell><td><th>表格單元
<fo:list-block><ul><ol>清單
<fo:list-item>編碼<li>清單項目
<fo:外部圖形><編碼> related to XSL-FO 元件轉換為 HTML/CSS</編碼圖片
<fo:page-number>{page} 占位符頁數
<fo:page-number-citation>{總頁數}總頁數
<fo:basic-link><a href>超連結

XSL-FO 屬性轉換為 CSS

XSL-FO 特性CSS 對應範例
<編碼>字型</編碼<編碼>字型</編碼相同的語法
<編碼>字型大小</編碼<編碼>字型大小</編碼相同的語法
<編碼>字體重量</編碼<編碼>字體重量</編碼粗體, normal, 700
文字對齊文字對齊justify
顏色顏色十六進制、RGB、名稱
背景顏色背景顏色相同的語法
空格前margin-top元素之前
<編碼>後空</編碼margin-bottom元素之後
<編碼>start-indent</編碼margin-left左縮
keep-together<編碼>page-break-inside:避免</編碼防止中斷
break-before="page"page-break-before:永遠強制分頁

程式碼範例

範例 1:基本 HTML 到 PDF

之前(使用 XSL-FO 的 fo.net):

// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;

class Program
{
    static void Main()
    {
        // fo.net 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()
    {
        // fo.net 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));
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

After (IronPDF with HTML):

// 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");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPdf 方法將 25 行以上的 XSL-FO 標記減少至僅 4 行乾淨的 C# 程式碼。 如需更多 HTML to PDF 選項,請參閱 IronPDF HTML to PDF 文件

範例 2:自訂設定的 PDF

之前(使用 XSL-FO 的 fo.net):

// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;

class Program
{
    static void Main()
    {
        // fo.net 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()
    {
        // fo.net 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));
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

After (IronPDF with HTML):

// 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");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPdf 提供程式化的 渲染選項,而非在 XML 標記中嵌入設定。

範例 3:URL 至 PDF

之前 (fo.net - 不支援):

// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;

class Program
{
    static void Main()
    {
        // fo.net 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 - extremely complex
        throw new System.NotImplementedException();
    }
}
// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;

class Program
{
    static void Main()
    {
        // fo.net 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 - extremely complex
        throw new System.NotImplementedException();
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

After (IronPDF - 內建支援):(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");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

URL 到 PDF 的渲染是此次 fo.net 移植中最顯著的優勢之一。IronPDF透過完整的JavaScript執行原生處理。 進一步瞭解 URL 至 PDF 轉換

範例 4:頁首和頁尾

之前(使用 XSL-FO 的 fo.net):

<fo:static-content flow-name="xsl-region-before">
    <fo:block text-align="center" font-size="10pt">
        Company Name - Confidential
    </fo:block>
</fo:static-content>

<fo:static-content flow-name="xsl-region-after">
    <fo:block text-align="right" font-size="10pt">
        Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/>
    </fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-before">
    <fo:block text-align="center" font-size="10pt">
        Company Name - Confidential
    </fo:block>
</fo:static-content>

<fo:static-content flow-name="xsl-region-after">
    <fo:block text-align="right" font-size="10pt">
        Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/>
    </fo:block>
</fo:static-content>
XML

After (IronPDF):

renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:center; font-size:10pt;'>Company Name - Confidential</div>",
    DrawDividerLine = true
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:right; font-size:10pt;'>Page {page} of {total-pages}</div>",
    DrawDividerLine = true
};
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:center; font-size:10pt;'>Company Name - Confidential</div>",
    DrawDividerLine = true
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:right; font-size:10pt;'>Page {page} of {total-pages}</div>",
    DrawDividerLine = true
};
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPdf 以簡單的 HTML 標頭和頁尾取代複雜的 XSL-FO 區域定義。

範例 5:PDF 安全性

之前 (fo.net):

// fo.net has very limited PDF security options
// Must use post-processing with another library
// fo.net has very limited PDF security options
// Must use post-processing with another library
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

After (IronPDF):

using IronPdf;

public byte[] GenerateSecurePdf(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = renderer.RenderHtmlAsPdf(html);

    // Set metadata
    pdf.MetaData.Title = "Confidential Report";
    pdf.MetaData.Author = "Company Name";

    // Password protection
    pdf.SecuritySettings.OwnerPassword = "owner123";
    pdf.SecuritySettings.UserPassword = "user456";

    // Restrict permissions
    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
    pdf.SecuritySettings.AllowUserEdits = IronPdf.Security.PdfEditSecurity.NoEdit;

    return pdf.BinaryData;
}
using IronPdf;

public byte[] GenerateSecurePdf(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = renderer.RenderHtmlAsPdf(html);

    // Set metadata
    pdf.MetaData.Title = "Confidential Report";
    pdf.MetaData.Author = "Company Name";

    // Password protection
    pdf.SecuritySettings.OwnerPassword = "owner123";
    pdf.SecuritySettings.UserPassword = "user456";

    // Restrict permissions
    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
    pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
    pdf.SecuritySettings.AllowUserEdits = IronPdf.Security.PdfEditSecurity.NoEdit;

    return pdf.BinaryData;
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

效能考量

重複使用 ChromePdfRenderer

為了在您的 fo.net 移植過程中獲得最佳效能,請重複使用 ChromePdfRenderer 實例:

// GOOD - Reuse the renderer
public class PdfService
{
    private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

    public byte[] Generate(string html) => _renderer.RenderHtmlAsPdf(html).BinaryData;
}

// BAD - Creating new instance each time
public byte[] GenerateBad(string html)
{
    var renderer = new ChromePdfRenderer();  // Wasteful
    return renderer.RenderHtmlAsPdf(html).BinaryData;
}
// GOOD - Reuse the renderer
public class PdfService
{
    private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

    public byte[] Generate(string html) => _renderer.RenderHtmlAsPdf(html).BinaryData;
}

// BAD - Creating new instance each time
public byte[] GenerateBad(string html)
{
    var renderer = new ChromePdfRenderer();  // Wasteful
    return renderer.RenderHtmlAsPdf(html).BinaryData;
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

單元轉換輔助工具

fo.net XSL-FO 使用多種單位。 IronPdf 使用毫米作為頁邊。 這裡有一個輔助類:

public static class UnitConverter
{
    public static double InchesToMm(double inches) => inches * 25.4;
    public static double PointsToMm(double points) => points * 0.352778;
    public static double PicasToMm(double picas) => picas * 4.233;
    public static double CmToMm(double cm) => cm * 10;
}

// Usage
renderer.RenderingOptions.MarginTop = UnitConverter.InchesToMm(1);  // 1 inch
public static class UnitConverter
{
    public static double InchesToMm(double inches) => inches * 25.4;
    public static double PointsToMm(double points) => points * 0.352778;
    public static double PicasToMm(double picas) => picas * 4.233;
    public static double CmToMm(double cm) => cm * 10;
}

// Usage
renderer.RenderingOptions.MarginTop = UnitConverter.InchesToMm(1);  // 1 inch
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

疑難排解

問題 1:頁面大小的差異

問題:轉移 fo.net 之後,PDF 頁面大小看起來不同。

解決方案:正確映射 XSL-FO 頁面尺寸:

// XSL-FO: page-height='11in' page-width='8.5in' (Letter)
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;

// XSL-FO: page-height='297mm' page-width='210mm' (A4)
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

// Custom size (in mm)
renderer.RenderingOptions.SetCustomPaperSize(210, 297);
// XSL-FO: page-height='11in' page-width='8.5in' (Letter)
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;

// XSL-FO: page-height='297mm' page-width='210mm' (A4)
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

// Custom size (in mm)
renderer.RenderingOptions.SetCustomPaperSize(210, 297);
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

問題 2:fo:block 到 HTML 的映射

問題:不確定<fo:block>應該變成什麼。

解決方案:使用適當的語意 HTML:

  • 標題:<h1><h6>
  • 段落:<p>
  • 通用容器:<div>
  • 內嵌文字:<編碼></編碼

問題 3:字型不匹配

問題:字型外觀與 fo.net 輸出不同。

解決方案:使用網頁字型或在 CSS 中指定系統字型:

<style>
    @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
    body { font-family: 'Roboto', Arial, sans-serif; }
</style>
<style>
    @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
    body { font-family: 'Roboto', Arial, sans-serif; }
</style>
HTML

問題 4:頁碼無法正常運作

問題<fo:page-number/> 無法運作。

解決方案:在頁首/頁尾使用IronPDF占位符:

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:center;'>Page {page} of {total-pages}</div>",
    MaxHeight = 15  // mm
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
    HtmlFragment = "<div style='text-align:center;'>Page {page} of {total-pages}</div>",
    MaxHeight = 15  // mm
};
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

遷移清單

預遷移

  • [ ] 將所有 XSL-FO 模板檔案 (.fo, .xslfo) 編入目錄
  • [ ] 使用的文件頁面尺寸和頁邊空白
  • [ ] 注意標頭/標腳配置 (fo:static-content)
  • [ ] 識別表格結構和樣式
  • [ ] 將專案備份至版本控制
  • [ ] 獲得 IronPdf 授權金鑰

套件遷移

  • [ ] 移除FonetFO.NET 套件:dotnet 移除套件 Fonet
  • [ ] 安裝<編碼>IronPdf</編碼套件:dotnet add package IronPdf
  • [ ] 更新命名空間匯入,從FonetIronPdf
  • [ ] 在啟動時設定 IronPdf 授權金鑰

程式碼遷移

  • [ ] 將<編碼>FonetDriver.Make()</編碼替換為新的 ChromePdfRenderer()
  • [將 driver.Render() 替換為 renderer.RenderHtmlAsPdf()
  • [ ] 將檔案輸出從串流更新為 pdf.SaveAs()
  • [ ] 使用 try/catch 取代錯誤事件處理器
  • [ ] 將 fo:static-content 轉換為 HtmlHeaderFooter
  • [ ] 將 <fo:page-number/> 替換為 {page} 占位符

測試

  • [ ] 將輸出外觀與原始的 fo.net PDF 比較
  • [ ] 確認頁面尺寸和頁邊空白
  • [ ] 檢查頁首和頁尾
  • [ ] 驗證頁碼
  • [ ] 測試表格渲染
  • [ ] 驗證圖片載入

後遷移

  • [ ] 刪除 .fo.xslfo 模板檔案
  • [ ] 移除與 fo.net 相關的程式碼和公用程式
  • [ ] 更新文件

結論

從 fo.net 轉換到 IronPDF,可以用 98% 以上的開發人員已經具備的 HTML/CSS 技能取代過時的 XSL-FO 標記,從而使您的 .NET PDF 生成工作流程現代化。 遷移消除了對廢棄函式庫的依賴,增加了跨平台支援,並提供對現代功能的存取,例如JavaScript渲染、CSS3 造型和全面的 PDF 安全性。

IronPDF 的積極維護可確保與目前及未來的 .NET 版本相容,包括 .NET 10 及更高版本。 如需其他指引,請參閱完整的 IronPDF 文件API 參考

準備好開始您的 fo.net 遷移了嗎? 下載 IronPDF 並立即開始將您的第一個 XSL-FO 模板轉換為 HTML。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。