Saltar al pie de página
GUíAS DE MIGRACIóN

Cómo migrar de fo.net a IronPDF

Migrar de fo.net (FO.NET)aIronPDFes una actualización importante para su proceso de generación de PDF .NET. Esta guía ofrece una ruta sencilla, paso a paso, para realizar la transición de su código base desde el obsoleto marcado XSL-FO a la generación moderna de PDF basada en HTML/CSS, utilizando las habilidades que su equipo de desarrollo ya tiene.

Por qué migrar de fo.net a IronPDF

Los retos de fo.net

fo.net es un renderizador de XSL-FO a PDF con varias limitaciones para el desarrollo actual:

  1. Tecnología obsoleta: XSL-FO (Extensible Stylesheet Language Formatting Objects) es una especificación del W3C de 2001, sin actualizaciones desde 2006, y se considera en gran medida obsoleta.

  2. Curva de aprendizaje compleja: XSL-FO requiere aprender un marcado complejo basado en XML con objetos de formato especializados ( fo:block , fo:table , fo:page-sequence , etc.).

  3. No hay compatibilidad con HTML/CSS: fo.net no puede representar HTML ni CSS; requiere una conversión manual de HTML a marcado XSL-FO.

  4. Sin mantenimiento: el repositorio original de CodePlex está descontinuado; Las bifurcaciones de GitHub ya no se mantienen de forma activa.

  5. Solo para Windows: fo.net tiene dependencias internas en System.Drawing que le impiden funcionar en Linux/macOS.

  6. Funciones modernas limitadas: no hay compatibilidad con JavaScript, CSS3, flexbox/grid ni fuentes web modernas.

  7. Sin representación de URL: fo.net no puede representar páginas web directamente; requiere conversión manual de HTML a XSL-FO.

Comparación entre fo.net e IronPDF

Aspecto fo.net (FO.NET) IronPDF
Formato de entrada XSL-FO (XML obsoleto) HTML/CSS (estándares web modernos)
Curva de aprendizaje Steep (conocimientos de XSL-FO) Suave (conocimientos de HTML/CSS)
Mantenimiento Sin mantenimiento Mantenimiento activo mensual
Soporte de plataformas Sólo para Windows Verdadera multiplataforma (.NET 6/7/8/9/10+)
Soporte CSS Ninguno CSS3 completo (Flexbox, Grid)
JavaScript Ninguno Compatibilidad total con JavaScript
Representación de URL No soportado Incorporado en
Características modernas Limitado Encabezados, pies de página, marcas de agua, seguridad
Documentación Desactualizado Tutoriales completos

Por qué tiene sentido el cambio

fo.net se diseñó cuando se esperaba que XSL-FO se convirtiera en un estándar para el formato de documentos. Esa expectativa nunca se materializó. HTML/CSS se ha convertido en el formato de documento universal: más del 98% de los desarrolladores conocen HTML/CSS, frente a menos del 1% que conocen XSL-FO. La mayoría de los recursos XSL-FO datan de 2005-2010, lo que dificulta cada vez más su mantenimiento.

IronPDF le permite utilizar los conocimientos que ya posee para crear PDF profesionales, con compatibilidad total con las versiones modernas de .NET, incluidas .NET 10 y C# 14, a medida que estén disponibles hasta 2025 y 2026.


Antes de empezar

Prerrequisitos

  1. Entorno .NET:IronPDFes compatible con .NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+
  2. Acceso a NuGet: asegúrese de poder instalar paquetes desde NuGet
  3. Clave de licencia: Obtenga su clave de licencia deIronPDFpara uso en producción en ironpdf.com

Haga una copia de seguridad de su proyecto

# 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

Identificar todo el uso de 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

Documente sus plantillas XSL-FO

Antes de la migración, catalogue todos los archivos XSL-FO y anótelos:

  • Dimensiones y márgenes de la página
  • Fuentes utilizadas
  • Tablas y sus estructuras
  • Encabezados y pies de página (fo:static-content)
  • Patrones de numeración de páginas
  • Carga de fuentes

Inicio rápido de la migración

Paso 1: Actualizar paquetes 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

Paso 2: Actualizar los espacios de nombres

// 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

Paso 3: Inicializar 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

Paso 4: Patrón básico de conversión

// 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

Referencia completa de la API

Mapeo de espacios de nombres

espacio de nombres fo.net Equivalente de IronPDF Notas
Fonet <código>IronPDF` Espacio de nombres principal
<código>Fonet.Render.Pdf <código>IronPDF Traducción en PDF
<código>Fonet.Layout N/A Maquetación mediante CSS
Fonet.Fo N/A Objetos de formato → HTML
<código>Fonet.Image` <código>IronPDF Manejo de imágenes integrado

FonetDriver a ChromePdfRenderer

Método FonetDriver Equivalente de IronPDF Notas
<código>FonetDriver.Make() <código>new ChromePdfRenderer() Crear renderizador
<código>driver.Render(inputStream, outputStream) renderer.RenderHtmlAsPdf(html) Basado en flujos
<código>driver.Render(inputFile, outputStream)` <código>renderer.RenderHtmlFileAsPdf(ruta) Basado en archivos
driver.BaseDirectory <código>RenderingOptions.BaseUrl` Ruta base de los recursos
driver.OnError += handler Try/catch alrededor de render Tratamiento de errores

Opciones de renderizado (configuración de PDF)

fo.net (Atributos XSL-FO) Opciones de renderizado de IronPDF Notas
altura de página <código>TamañoDePapeloSetCustomPaperSize()` Dimensiones de la página
ancho de página <código>TamañoDePapel` Estándar o personalizado
margin-top <código>MarginTop` En milímetros
margin-bottom MargenInferior En milímetros
margen-izquierda MargenIzquierdo En milímetros
margen-derecha MargenDerecho En milímetros
orientación a referencias Orientación del documento Retrato/Paisaje

Guía de conversión de XSL-FO a HTML

Elementos XSL-FO a HTML/CSS

El cambio fundamental en esta migración a fo.net es la conversión de elementos XSL-FO a sus equivalentes HTML:

Elemento XSL-FO Equivalente HTML/CSS Notas
<código>` <código> Elemento raíz
<fo:layout-master-set> Regla CSS @page Configuración de la página
<código>| CSS@page` Definición de la página
<código>` <código> o <código>
Contenido de la página
<código> <main> o <div> Contenido principal
<código>` <código>HtmlHeaderFooter Encabezados/pies de página
<código> <p>, <div>, <h1>-<h6> Contenido del bloque
<código>` <código> Contenido en línea
<código> <código> Tablas
<código> <código>
Filas de la tabla
<código> <código>, <código> Celdas de tabla
<código> <ul>, <ol> Listas
<código>` <código>
  • Elementos de la lista
    <código><fo:gráfico externo> <código> related to Elementos XSL-FO a HTML/CSS Imágenes
    <código><fo:número de página> {page} marcador de posición Números de página
    <fo:page-number-citation> {total de páginas} Total de páginas
    <fo:basic-link> <código>` Hipervínculos

    Propiedades XSL-FO a CSS

    Propiedad XSL-FO Equivalente en CSS Ejemplo
    family family Misma sintaxis
    tamaño de fuente tamaño de fuente Misma sintaxis
    <código>font-weight| <código>font-weight</code>|negrita,normal,700`
    text-align text-align izquierda, centro, derecha, justificar
    color color Hex, RGB, nombres
    color de fondo color de fondo Misma sintaxis
    espacio-antes margin-top Antes del elemento
    <código>espacio-después|margin-bottom` Después del elemento
    start-indent margen-izquierda Sangría izquierda
    mantener juntos page-break-inside: evitar Evitar interrupciones
    break-before="page" page-break-before: always Forzar salto de página

    Ejemplos de código

    Ejemplo 1: HTML básico a PDF

    Antes (fo.net con XSL-FO):

    // 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

    Después (IronPDF con 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

    El métodoIronPDFreduce más de 25 líneas de marcado XSL-FO a sólo 4 líneas de código C# limpio. Para obtener más opciones de HTML a PDF, consulte la documentación de HTML a PDF de IronPDF.

    Ejemplo 2: PDF con ajustes personalizados

    Antes (fo.net con XSL-FO):

    // 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

    Después (IronPDF con 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 ofrece opciones programáticas de presentación en lugar de incrustar la configuración en el marcado XML.

    Ejemplo 3: URL a PDF

    Antes (fo.net - no compatible):

    // 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

    Después (IronPDF - soporte integrado):

    // 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

    La conversión de URL a PDF es una de las ventajas más significativas de esta migración a .net.IronPDFse encarga de ello de forma nativa con ejecución completa de JavaScript. Más información sobre Conversión de URL a PDF.

    Ejemplo 4: Encabezados y pies de página

    Antes (fo.net con XSL-FO):

    <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

    Después (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 sustituye las complejas definiciones de regiones XSL-FO por sencillos encabezados y pies de página HTML.

    Ejemplo 5: Seguridad de PDF

    Antes (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

    Después (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

    Consideraciones sobre el rendimiento

    Reutilizar ChromePdfRenderer

    Para un rendimiento óptimo durante la migración a fo.net, reutilice la instancia 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

    Ayudante de conversión de unidades

    fo.net XSL-FO utiliza varias unidades.IronPDFutiliza milímetros para los márgenes. Aquí tienes una clase de ayuda:

    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

    Solución de problemas

    Cuestión 1: Diferencias de tamaño de página

    Problema: el tamaño de la página PDF se ve diferente después de la migración de fo.net.

    Solución: Asigne correctamente las dimensiones de la página 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

    Edición 2: Mapeo de fo:block a HTML

    Problema: No estoy seguro de qué<fo:block> Debería convertirse.

    Solución: utilice HTML semántico apropiado:

    • Encabezados: <h1> a <h6>
    • Párrafos: <p>
    • Contenedores genéricos: <div>
    • Texto en línea: <span>

    Cuestión 3: Fuentes no coincidentes

    Problema: Las fuentes se ven diferentes a la salida de fo.net.

    Solución: utilice fuentes web o especifique fuentes del sistema en 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

    Cuestión 4: Los números de página no funcionan

    Problema:<fo:page-number/> no funciona

    Solución: utilice marcadores de posiciónIronPDFen encabezados y pies de página:

    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

    Lista de comprobación de la migración

    Pre-Migración

    • Catalogar todos los archivos de plantilla XSL-FO ( .fo , .xslfo )
    • Dimensiones de la página del documento y márgenes utilizados
    • Configuraciones de encabezado/pie de página de notas ( fo:static-content )
    • Identificar estructuras y estilos de tablas
    • Realizar una copia de seguridad del proyecto en el control de versiones
    • Obtener la clave de licencia de IronPDF

    Migración de paquetes

    • Eliminar el paquete Foneto FO.NET : dotnet remove package Fonet
    • Instalar el paquete <código>IronPDF:dotnet add package IronPdf`
    • Actualizar las importaciones de espacios de nombres de Foneta IronPdf
    • Establecer la clave de licencia deIronPDFal inicio

    Migración de código

    • Reemplace <código>FonetDriver.Make()connew ChromePdfRenderer()`
    • Reemplace driver.Render() con renderer.RenderHtmlAsPdf()
    • Actualizar la salida del archivo de streams a pdf.SaveAs()
    • Reemplazar los controladores de eventos de error con try/catch
    • Convertir fo:static-content a HtmlHeaderFooter
    • Reemplazar<fo:page-number/> con marcador de posición {page}

    Pruebas

    • Comparar la apariencia de salida con los PDF originales de fo.net
    • Verificar las dimensiones y márgenes de la página
    • Verificar encabezados y pies de página
    • Validar números de página
    • Representación de la tabla de pruebas
    • Verificar la carga de la imagen

    Posmigración

    • Eliminar archivos de plantilla .fo y .xslfo
    • Eliminar código y utilidades relacionadas con fo.net
    • Actualización de la documentación

    referencia](https://ironpdf.com/object-reference/api/).

    Curtis Chau
    Escritor Técnico

    Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

    Leer más