跳至頁尾內容
移民指南

如何從fo.net遷移到IronPDF

從 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(可擴展樣式表語言格式化物件)是 W3C 於 2001 年制定的規範,自 2006 年以來沒有更新,因此被普遍認為是過時的。

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

3.不支援 HTML/CSS: fo.net 無法渲染 HTML 或 CSS-需要手動將 HTML 轉換為 XSL-FO 標記。

4.已停止維護:原 CodePlex 程式碼庫已失效; GitHub 上的分店已停止維護。

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

6.現代功能有限:不支援 JavaScript、CSS3、flexbox/grid、現代網頁字體。

7.不支援 URL 渲染: fo.net 無法直接渲染網頁-需要手動進行 HTML 到 XSL-FO 的轉換。

fo.net 與 IronPDF 的比較

方面fo.net (FO.NET)IronPDF
輸入格式XSL-FO(過時的 XML)HTML/CSS(現代網路標準)
學習曲線陡峭(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 版本,包括 .NET 10 和 C# 14,這些版本將在 2025 年和 2026 年陸續推出。


開始之前

先決條件

  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 to IronPDF migration"
# Create a backup branch
git checkout -b pre-ironpdf-migration
git add .
git commit -m "Backup before fo.net to IronPDF migration"
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;
$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";
$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");
$vbLabelText   $csharpLabel

完整 API 參考

命名空間映射

fo.net 命名空間IronPDF當量筆記
FonetIronPdf主命名空間
Fonet.Render.PdfIronPdfPDF渲染
Fonet.Layout不適用佈局由 CSS 處理。
Fonet.Fo不適用格式化物件 → HTML
Fonet.ImageIronPdf內建影像處理功能

FonetDriver 到 ChromePdfRenderer

FonetDriver 方法IronPDF當量筆記
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 語句錯誤處理

渲染選項(PDF 配置)

fo.net(XSL-FO 屬性)IronPDF渲染選項筆記
page-heightPaperSizeSetCustomPaperSize()頁面尺寸
page-widthPaperSize標準或定制
margin-topMarginTop單位:毫米
margin-bottomMarginBottom單位:毫米
margin-leftMarginLeft單位:毫米
margin-rightMarginRight單位:毫米
reference-orientationPaperOrientation人像/風景

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>或者
頁面內容
<fo:flow><main>或者<div>主要內容區域
<fo:static-content>HtmlHeaderFooter頁首/頁尾
<fo:block><p><div><h1> -<h6>區塊內容
<fo:inline><span>內嵌內容
<fo:table><table>表格
<fo:table-row><tr>表格行
<fo:table-cell><td><th>表格單元格
<fo:list-block><ul><ol>清單
<fo:list-item><li>清單項
<fo:external-graphic><img>圖片
<fo:page-number>{page}佔位符頁碼
<fo:page-number-citation>{total-pages}總頁數
<fo:basic-link><a href>超連結

XSL-FO 屬性到 CSS

XSL-FO 屬性CSS 等效項例子
font-familyfont-family相同的語法
font-sizefont-size相同的語法
font-weightfont-weightboldnormal700
text-aligntext-alignleftcenterrightjustify
colorcolor十六進位、RGB、名稱
background-colorbackground-color相同的語法
space-beforemargin-top元素之前
space-aftermargin-bottom元素之後
start-indentmargin-left左縮進
keep-togetherpage-break-inside: avoid防止斷裂
break-before="page"page-break-before: always強制分頁

程式碼範例

範例 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));
    }
}
$vbLabelText   $csharpLabel

(IronPDF 與 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");
    }
}
$vbLabelText   $csharpLabel

IronPDF 方法將 25 行以上的 XSL-FO 標記簡化為 4 行簡潔的 C# 程式碼。 如需更多 HTML 轉 PDF 選項,請參閱IronPDF HTML 轉 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));
    }
}
$vbLabelText   $csharpLabel

(IronPDF 與 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");
    }
}
$vbLabelText   $csharpLabel

IronPDF 提供程式化渲染選項,而不是將配置嵌入 XML 標記中。

範例 3:PDF 的 URL

之前(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();
    }
}
$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

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

(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
};
$vbLabelText   $csharpLabel

IronPDF 將複雜的 XSL-FO 區域定義替換為簡單的HTML 頭部和底部

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

(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;
}
$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;
}
$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
$vbLabelText   $csharpLabel

故障排除

問題一:頁面尺寸差異

問題: 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);
$vbLabelText   $csharpLabel

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

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

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

標題:<h1>透過<h6> 段落:<p>

  • 通用容器:<div>
  • 行內文字:<span>

問題三:字體不匹配

問題:字體與 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
};
$vbLabelText   $csharpLabel

遷移清單

遷移前

  • 對所有 XSL-FO 範本檔案( .fo.xslfo )進行編目
  • 文件頁面尺寸和邊距
  • 注意頁首/頁尾配置( fo:static-content
  • 確定表格結構和样式
  • 將項目備份到版本控制系統
  • 取得 IronPDF 許可證密鑰

軟體包遷移

  • 刪除FonetFO.NET套件: dotnet remove package Fonet 安裝IronPdf套件: dotnet add package IronPdf
  • 將命名空間匯入從Fonet更新為IronPdf
  • 啟動時設定 IronPDF 許可證密鑰

程式碼遷移

  • FonetDriver.Make()替換為new ChromePdfRenderer()
  • driver.Render()替換為renderer.RenderHtmlAsPdf()
  • 將流中的檔案輸出更新為pdf.SaveAs()
  • 將錯誤事件處理程序替換為 try/catch
  • fo:static-content轉換為HtmlHeaderFooter
  • 代替<fo:page-number/>帶有{page}佔位符

測試

  • 將輸出外觀與原始 fo.net PDF 進行比較
  • 檢查頁面尺寸和邊距。
  • 檢查頁首和頁尾
  • 驗證頁碼
  • 測試表格渲染
  • 驗證映像載入情況

移民後

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

參考](https://ironpdf.com/object-reference/api/)。

柯蒂斯·週
技術撰稿人

Curtis Chau擁有卡爾頓大學電腦科學學士學位,專長於前端開發,精通Node.js、TypeScript、JavaScript和React。他熱衷於打造直覺美觀的使用者介面,喜歡使用現代框架,並擅長撰寫結構清晰、視覺效果出色的使用者手冊。

除了開發工作之外,柯蒂斯對物聯網 (IoT) 也抱有濃厚的興趣,致力於探索硬體和軟體整合的創新方法。閒暇時,他喜歡玩遊戲和製作 Discord 機器人,將他對科技的熱愛與創造力結合。