MIGRATION GUIDES How to Migrate from fo.net to IronPDF Curtis Chau 發表日期:2026年1月11日 下載 IronPDF NuGet 下載 DLL 下載 Windows 安裝程式 開始免費試用 法學碩士副本 法學碩士副本 將頁面複製為 Markdown 格式,用於 LLMs 在 ChatGPT 中打開 請向 ChatGPT 諮詢此頁面 在雙子座打開 請向 Gemini 詢問此頁面 在 Grok 中打開 向 Grok 詢問此頁面 打開困惑 向 Perplexity 詢問有關此頁面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 複製連結 電子郵件文章 從 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:block 、 fo:table 、 fo: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 年陸續推出。 開始之前 先決條件 .NET 環境: IronPDF 支援 .NET Framework 4.6.2+、.NET Core 3.1+ 和 .NET 5/6/7/8/9+。 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當量 筆記 Fonet IronPdf 主命名空間 Fonet.Render.Pdf IronPdf PDF渲染 Fonet.Layout 不適用 佈局由 CSS 處理。 Fonet.Fo 不適用 格式化物件 → HTML Fonet.Image IronPdf 內建影像處理功能 FonetDriver 到 ChromePdfRenderer FonetDriver 方法 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 語句 錯誤處理 渲染選項(PDF 配置) fo.net(XSL-FO 屬性) IronPDF渲染選項 筆記 page-height PaperSize或SetCustomPaperSize() 頁面尺寸 page-width PaperSize 標準或定制 margin-top MarginTop 單位:毫米 margin-bottom MarginBottom 單位:毫米 margin-left MarginLeft 單位:毫米 margin-right MarginRight 單位:毫米 reference-orientation PaperOrientation 人像/風景 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-family font-family 相同的語法 font-size font-size 相同的語法 font-weight font-weight bold , normal , 700 text-align text-align left 、 center 、 right 、 justify color color 十六進位、RGB、名稱 background-color background-color 相同的語法 space-before margin-top 元素之前 space-after margin-bottom 元素之後 start-indent margin-left 左縮進 keep-together page-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 許可證密鑰 軟體包遷移 刪除Fonet或FO.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 立即與工程團隊聊天 技術撰稿人 Curtis Chau 擁有電腦科學學士學位(卡爾頓大學),專長於前端開發,精通 Node.js、TypeScript、JavaScript 和 React。Curtis 對製作直覺且美觀的使用者介面充滿熱情,他喜歡使用現代化的架構,並製作結構良好且視覺上吸引人的手冊。除了開發之外,Curtis 對物聯網 (IoT) 也有濃厚的興趣,他喜歡探索整合硬體與軟體的創新方式。在空閒時間,他喜歡玩遊戲和建立 Discord bots,將他對技術的熱愛與創意結合。 相關文章 發表日期 2026年2月1日 How to Migrate from ZetPDF to IronPDF in C# Master the migration from ZetPDF to IronPDF with this complete C# guide. Switch from a coordinate-based library to a modern HTML-to-PDF solution. Includes code examples for HTML conversion, merging PDFs, and removing PDFSharp dependencies. 閱讀更多 發表日期 2026年2月1日 How to Migrate from Scryber.Core to IronPDF in C# Master the migration from Scryber.Core to IronPDF with this complete C# guide. Switch from custom XML/HTML parsing to a modern Chromium renderer. Includes code examples for HTML conversion, URL rendering, and replacing proprietary bindings. 閱讀更多 發表日期 2026年2月1日 How to Migrate from XFINIUM.PDF to IronPDF in C# Master the migration from XFINIUM.PDF to IronPDF with this complete C# guide. Switch from manual coordinate-based positioning to declarative HTML/CSS rendering. Includes code examples for replacing graphics primitives and automatic layout. 閱讀更多 Migrate from Foxit PDF SDK to IronPDF: (.NET Guide)How to Migrate from ABCpdf for .NET...
發表日期 2026年2月1日 How to Migrate from ZetPDF to IronPDF in C# Master the migration from ZetPDF to IronPDF with this complete C# guide. Switch from a coordinate-based library to a modern HTML-to-PDF solution. Includes code examples for HTML conversion, merging PDFs, and removing PDFSharp dependencies. 閱讀更多
發表日期 2026年2月1日 How to Migrate from Scryber.Core to IronPDF in C# Master the migration from Scryber.Core to IronPDF with this complete C# guide. Switch from custom XML/HTML parsing to a modern Chromium renderer. Includes code examples for HTML conversion, URL rendering, and replacing proprietary bindings. 閱讀更多
發表日期 2026年2月1日 How to Migrate from XFINIUM.PDF to IronPDF in C# Master the migration from XFINIUM.PDF to IronPDF with this complete C# guide. Switch from manual coordinate-based positioning to declarative HTML/CSS rendering. Includes code examples for replacing graphics primitives and automatic layout. 閱讀更多