迁移指南 如何从 fo.net 迁移到 IronPDF for .NET 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(现代网络标准) 学习曲线 Steep (XSL-FO 专业技能) 温柔(HTML/CSS 知识) 维护 无人维护 每月积极维护 平台支持 仅限 Windows 真正的跨平台(.NET 6/7/8/9/10+) CSS 支持 无 完整的 CSS3(Flexbox、网格) 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。 开始之前 前提条件 .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 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; $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 += 处理程序 围绕渲染的 Try/catch 错误处理 渲染选项(PDF 配置) fo.net(XSL-FO 属性) IronPdf 渲染选项 备注 页面高度 PaperSize</code>或<code>SetCustomPaperSize() 页面尺寸 页面宽度 纸张大小 标准或定制 边框-顶部 页边距 单位:毫米 边距-底部 边距下限 单位:毫米 margin-left 边距左移 单位:毫米 右边距 MarginRight 单位:毫米 参考-导向 文件方向 肖像/风景 XSL-FO 到 HTML 转换指南 将 XSL-FO 元素转换为 HTML/CSS. 这次 fo.net 迁移的基本转变是将 XSL-FO 元素转换为 HTML 对应元素: XSL-FO 元素 HTML/CSS 同等内容 备注 <fo:root> <html> 根元素 <fo:布局主集> CSS @page 规则 页面设置 <fo:simple-page-master> CSS @page 页面定义 <fo:page-sequence> <body> 或 <div> 页面内容 <fo:流程> <main> 或 <div> 主要内容 <fo:静态内容> HtmlHeaderFooter 页眉/页脚 <fo:块> <p>, <div>, <h1>-<h6> 区块内容 <fo:inline> <span> 内联内容 <fo:表格> <table> 表格 <fo:table-row> <tr> 表格行数 <fo:table-cell> <td></code>, <code><th> 表格单元格 <fo:list-block> <ul></code>, <code><ol> 清单 <fo:list-item> <li> 列表项目 <fo:外部图形> <img> 图片 <fo:页码> {page} 占位符 页码 <fo:页码-引文> {总页数} 总页数 <fo:basic-link> <a href> 超链接 将 XSL-FO 属性转换为 CSS. XSL-FO 属性 等效 CSS 范例 字体 字体 相同语法 字体大小 字体大小 相同语法 字体大小 字体大小 粗体</code>, <code>正常</code>, <code>700 文本对齐 文本对齐 左</code>, <code>居中</code>, <code>右</code>, <code>justify 颜色 颜色 十六进制、RGB、名称 背景颜色 背景颜色 相同语法 space-before 边框-顶部 元素前 后空 边距-底部 要素之后 start-indent margin-left 左缩进 保持一致 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)); } } $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: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(); } } $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 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 }; $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 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; } $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 故障排除 问题 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); $vbLabelText $csharpLabel 问题 2:fo:block 到 HTML 映射 问题:不确定是什么<fo:block>应该成为。 解决方案:使用合适的语义化 HTML: 标题:<h1></code>至<code><h6> 段落:<p> 通用容器:<div> 内联文本:<span> 问题 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 }; $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 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。 相关文章 已发布2026年2月1日 如何用 C# 从 ZetPDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 ZetPDF 到 IronPDF 的迁移。从基于坐标的库转换到现代的 HTML 到 PDF 解决方案。包括 HTML 转换、合并 PDF 和移除 PDFSharp 依赖性的代码示例。 阅读更多 已发布2026年2月1日 如何用 C# 从 Scryber.Core 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 Scryber.Core 迁移到 IronPDF 的方法。从自定义 XML/HTML 解析转换到现代 Chromium 渲染器。包括 HTML 转换、URL 呈现和替换专有绑定的代码示例。 阅读更多 已发布2026年2月1日 如何用 C# 从 XFINIUM.PDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 XFINIUM.PDF 到 IronPDF 的迁移。从基于坐标的手动定位切换到声明式 HTML/CSS 渲染。包括替换图形基元和自动布局的代码示例。 阅读更多 从 Foxit PDF SDK 迁移到 IronPdf:(.NET指南)如何从 ABCpdf for .NET 迁移到...
已发布2026年2月1日 如何用 C# 从 ZetPDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 ZetPDF 到 IronPDF 的迁移。从基于坐标的库转换到现代的 HTML 到 PDF 解决方案。包括 HTML 转换、合并 PDF 和移除 PDFSharp 依赖性的代码示例。 阅读更多
已发布2026年2月1日 如何用 C# 从 Scryber.Core 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 Scryber.Core 迁移到 IronPDF 的方法。从自定义 XML/HTML 解析转换到现代 Chromium 渲染器。包括 HTML 转换、URL 呈现和替换专有绑定的代码示例。 阅读更多
已发布2026年2月1日 如何用 C# 从 XFINIUM.PDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 XFINIUM.PDF 到 IronPDF 的迁移。从基于坐标的手动定位切换到声明式 HTML/CSS 渲染。包括替换图形基元和自动布局的代码示例。 阅读更多