如何從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: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"識別所有 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*"編寫 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步驟 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;步驟 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";步驟 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");完整 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));
}
}(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");
}
}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));
}
}(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");
}
}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();
}
}(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");
}
}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>(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
};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(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;
}性能考量
重用 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;
}單位換算助手
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 inchpublic 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故障排除
問題一:頁面尺寸差異
問題: 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);問題 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>問題 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
};遷移清單
遷移前
- 對所有 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 相關的程式碼和實用程式
- 更新文檔






