Cómo migrar de NReco PDF Generator a IronPDF en C#
Por qué migrar de Generador de PDF de NRecoa IronPDF
Cuestiones críticas de seguridad con NReco PDF Generator
NReco PDF Generator envuelve el obsoleto binario wkhtmltopdf, heredando todas sus vulnerabilidades de seguridad. No se trata de una preocupación teórica: hay más de 20 CVE documentadas sin parches disponibles desde que wkhtmltopdf se abandonó en 2020:
- CVE-2020-21365: Falsificación de solicitud del lado del servidor (SSRF)
- CVE-2022-35583: Lectura de archivos locales mediante inyección HTML
- CVE-2022-35580: Potencial de ejecución remota de código
Estas vulnerabilidades no pueden parchearse porque el proyecto wkhtmltopdf subyacente ya no se mantiene.
Limitaciones adicionales del generador de PDF de NReco
-
Versión gratuita con marca de agua: el uso en producción requiere una licencia paga con precios opacos que requieren contactar al departamento de ventas.
-
Motor de renderizado obsoleto: WebKit Qt (circa 2012) ofrece compatibilidad web moderna limitada:
- Sin CSS Grid ni Flexbox
- Sin JavaScriptmoderno (ES6+)
- Escasa compatibilidad con fuentes web
- Sin variables CSS ni propiedades personalizadas
-
Dependencia binaria externa: requiere la gestión de binarios wkhtmltopdf por plataforma (
wkhtmltopdf.exe,wkhtmltox.dll). -
Sin desarrollo activo: el contenedor recibe mantenimiento sin actualizaciones del motor subyacentes.
- Compatibilidad asincrónica limitada: la API sincrónica bloquea subprocesos en aplicaciones web.
Comparación entre Generador de PDF de NRecoe IronPDF
| Aspecto | Generador de PDF de NReco | IronPDF |
|---|---|---|
| Motor de renderizado | WebKit Qt (2012) | Chromium (actual) |
| Seguridad | más de 20 CVE, sin parches | Actualizaciones de seguridad activas |
| Soporte CSS | CSS2.1, CSS3 limitado | CSS3 completo, Grid, Flexbox |
| JavaScript | ES5 básico | ES6+ completo, async/await |
| Dependencias | Binario externo wkhtmltopdf | Autocontenido |
| Soporte de Async | Sólo sincrónico | Async/await completo |
| Fuentes web | Limitado | Fuentes Google completas, @font-face |
| Licencias | Precios opacos, póngase en contacto con ventas | Precios transparentes |
| Prueba gratuita | Marca de agua | Funcionalidad completa |
Para los equipos que planifican la adopción de .NET 10 y C# 14 hasta 2025 y 2026,IronPDFproporciona una base preparada para el futuro con desarrollo activo y capacidades de renderización modernas.
Antes de empezar
Prerrequisitos
- Entorno .NET : .NET Framework 4.6.2+ o .NET Core 3.1+ / .NET 5/6/7/8/9+
- Acceso a NuGet : Capacidad para instalar paquetes NuGet
- Licencia deIronPDF: Obtenga su clave de licencia en IronPDF
Cambios en el paquete NuGet
# Remove NReco.PdfGenerator
dotnet remove package NReco.PdfGenerator
# Install IronPDF
dotnet add package IronPdf
# Remove NReco.PdfGenerator
dotnet remove package NReco.PdfGenerator
# Install IronPDF
dotnet add package IronPdf
Elimine también los binarios wkhtmltopdf de su despliegue:
- Eliminar
wkhtmltopdf.exe,wkhtmltox.dlldel proyecto - Eliminar cualquier script de instalación de wkhtmltopdf
- Eliminar carpetas binarias específicas de la plataforma
Configuración de licencias
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Identificar el uso del generador de PDF de NReco
# Find all NReco.PdfGenerator references
grep -r "NReco.PdfGenerator\|HtmlToPdfConverter\|GeneratePdf" --include="*.cs" .
# Find all NReco.PdfGenerator references
grep -r "NReco.PdfGenerator\|HtmlToPdfConverter\|GeneratePdf" --include="*.cs" .
Referencia completa de la API
Asignaciones de clases principales
| Generador de PDF de NReco | IronPDF |
|---|---|
HtmlToPdfConverter |
ChromePdfRenderer |
PageMargins |
Propiedades de los márgenes individuales |
PageOrientation |
PdfPaperOrientation |
PageSize |
PdfPaperSize |
Métodos de renderizado
| Generador de PDF de NReco | IronPDF |
|---|---|
GeneratePdf(html) |
RenderHtmlAsPdf(html) |
GeneratePdfFromFile(url, output) |
RenderUrlAsPdf(url) |
GeneratePdfFromFile(htmlPath, output) |
RenderHtmlFileAsPdf(path) |
| (async no compatible)_ | RenderHtmlAsPdfAsync(html) |
| (async no compatible)_ | RenderUrlAsPdfAsync(url) |
Configuración de páginas
| Generador de PDF de NReco | IronPDF |
|---|---|
PageWidth = 210 |
RenderingOptions.PaperSize = PdfPaperSize.A4 |
PageHeight = 297 |
RenderingOptions.SetCustomPaperSizeinMilimeters(w, h) |
Orientation = PageOrientation.Landscape |
RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape |
Size = PageSize.A4 |
RenderingOptions.PaperSize = PdfPaperSize.A4 |
Mapeo de márgenes
| Generador de PDF de NReco | IronPDF |
|---|---|
Margins.Top = 10 |
RenderingOptions.MarginTop = 10 |
Margins.Bottom = 10 |
RenderingOptions.MarginBottom = 10 |
Margins.Left = 10 |
RenderingOptions.MarginLeft = 10 |
Margins.Right = 10 |
RenderingOptions.MarginRight = 10 |
nuevos PageMargins { ... } |
Propiedades individuales |
Mapas de marcador de posición de encabezado/pie
| Generador de PDF de NReco (wkhtmltopdf) | IronPDF |
|---|---|
[page] |
{page} |
[topage] |
{total-pages} |
[date] |
{date} |
[time] |
{time} |
[title] |
{html-title} |
Mapeos de manejo de salidas
| Generador de PDF de NReco | IronPDF |
|---|---|
byte[] pdfBytes = GeneratePdf(html) |
PdfDocument pdf = RenderHtmlAsPdf(html) |
File.WriteAllBytes(path, bytes) |
pdf.SaveAs(path) |
return pdfBytes |
return pdf.BinaryData |
new MemoryStream(pdfBytes) |
pdf.Stream |
Ejemplos de migración de código
Ejemplo 1: HTML básico a PDF
Antes (NReco PDF Generator):
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;
class Program
{
static void Main()
{
var htmlToPdf = new HtmlToPdfConverter();
var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
File.WriteAllBytes("output.pdf", pdfBytes);
}
}
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;
class Program
{
static void Main()
{
var htmlToPdf = new HtmlToPdfConverter();
var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
File.WriteAllBytes("output.pdf", pdfBytes);
}
}
Imports NReco.PdfGenerator
Imports System.IO
Class Program
Shared Sub Main()
Dim htmlToPdf = New HtmlToPdfConverter()
Dim htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>"
Dim pdfBytes = htmlToPdf.GeneratePdf(htmlContent)
File.WriteAllBytes("output.pdf", pdfBytes)
End Sub
End Class
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports System.IO
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
End Sub
End Class
La diferencia fundamental radica en el tipo de retorno y el patrón de guardado. El generador de PDF NReco HtmlToPdfConverter.GeneratePdf() devuelve un byte[] que debe escribir manualmente en el disco usando File.WriteAllBytes(). ChromePdfRenderer.RenderHtmlAsPdf() deIronPDFdevuelve un objeto PdfDocument con un método SaveAs() incorporado.
Este enfoque orientado a objetos ofrece ventajas adicionales: se puede manipular el PDF (añadir marcas de agua, fusionar documentos, añadir seguridad) antes de guardarlo. Si necesita los bytes sin procesar para compatibilidad con el código existente, utilice pdf.BinaryData. Consulte la documentación HTML a PDF para obtener más opciones de conversión.
Ejemplo 2: Tamaño de página personalizado con márgenes
Antes (NReco PDF Generator):
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;
class Program
{
static void Main()
{
var htmlToPdf = new HtmlToPdfConverter();
htmlToPdf.PageWidth = 210;
htmlToPdf.PageHeight = 297;
htmlToPdf.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };
var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
File.WriteAllBytes("custom-size.pdf", pdfBytes);
}
}
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;
class Program
{
static void Main()
{
var htmlToPdf = new HtmlToPdfConverter();
htmlToPdf.PageWidth = 210;
htmlToPdf.PageHeight = 297;
htmlToPdf.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };
var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
File.WriteAllBytes("custom-size.pdf", pdfBytes);
}
}
Imports NReco.PdfGenerator
Imports System.IO
Class Program
Shared Sub Main()
Dim htmlToPdf = New HtmlToPdfConverter()
htmlToPdf.PageWidth = 210
htmlToPdf.PageHeight = 297
htmlToPdf.Margins = New PageMargins With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
Dim htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>"
Dim pdfBytes = htmlToPdf.GeneratePdf(htmlContent)
File.WriteAllBytes("custom-size.pdf", pdfBytes)
End Sub
End Class
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("custom-size.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("custom-size.pdf");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
renderer.RenderingOptions.MarginLeft = 10
renderer.RenderingOptions.MarginRight = 10
Dim htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("custom-size.pdf")
End Sub
End Class
El generador de PDF NReco utiliza dimensiones numéricas (PageWidth = 210, PageHeight = 297) y un objeto PageMargins.IronPDFutiliza la enumeración PdfPaperSize (que incluye tamaños estándar como A4, Carta, Legal) y propiedades de margen individuales en el objeto RenderingOptions.
Los cambios clave de la migración:
PageHeight→RenderingOptions.PaperSize = PdfPaperSize.A4- nuevo PageMargins { Top = 10, ... }
→ Individual properties:RenderingOptions.MarginTop = 10`
Para tamaños de papel personalizados no cubiertos por la enumeración, utilice RenderingOptions.SetCustomPaperSizeinMilimeters(width, height). Más información sobre opciones de configuración de página.
Ejemplo 3: Conversión de URL a PDF
Antes (NReco PDF Generator):
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;
class Program
{
static void Main()
{
var htmlToPdf = new HtmlToPdfConverter();
var pdfBytes = htmlToPdf.GeneratePdfFromFile("https://www.example.com", null);
File.WriteAllBytes("webpage.pdf", pdfBytes);
}
}
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;
class Program
{
static void Main()
{
var htmlToPdf = new HtmlToPdfConverter();
var pdfBytes = htmlToPdf.GeneratePdfFromFile("https://www.example.com", null);
File.WriteAllBytes("webpage.pdf", pdfBytes);
}
}
Imports NReco.PdfGenerator
Imports System.IO
Class Program
Shared Sub Main()
Dim htmlToPdf As New HtmlToPdfConverter()
Dim pdfBytes As Byte() = htmlToPdf.GeneratePdfFromFile("https://www.example.com", Nothing)
File.WriteAllBytes("webpage.pdf", pdfBytes)
End Sub
End Class
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.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://www.example.com");
pdf.SaveAs("webpage.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
NReco PDF Generator utiliza el método GeneratePdfFromFile() que tiene un nombre confuso tanto para archivos locales como para URL, con un segundo parámetro que acepta valores nulos.IronPDFproporciona métodos dedicados: RenderUrlAsPdf() para URL y RenderHtmlFileAsPdf() para archivos HTML locales.
El enfoque deIronPDFes más limpio e intuitivo. Para aplicaciones web asíncronas, use await renderer.RenderUrlAsPdfAsync(url) para evitar el bloqueo de subprocesos, algo que el generador de PDF de NReco simplemente no puede hacer.
Notas de migración críticas
Conversión de valores de zoom
NReco PDF Generator utiliza valores flotantes (0,0-2,0), mientras queIronPDFutiliza enteros porcentuales:
// NReco PDF Generator: Zoom = 0.9f (90%)
// IronPDF: Zoom = 90
// Conversion formula:
int ironPdfZoom = (int)(nrecoZoom * 100);
// NReco PDF Generator: Zoom = 0.9f (90%)
// IronPDF: Zoom = 90
// Conversion formula:
int ironPdfZoom = (int)(nrecoZoom * 100);
' NReco PDF Generator: Zoom = 0.9F (90%)
' IronPDF: Zoom = 90
' Conversion formula:
Dim ironPdfZoom As Integer = CInt(nrecoZoom * 100)
Actualización de la sintaxis de los marcadores
Deben actualizarse todos los marcadores de posición de encabezado/pie de página:
| Generador de PDF de NReco | IronPDF |
|---|---|
[page] |
{page} |
[topage] |
{total-pages} |
[date] |
{date} |
[title] |
{html-title} |
// NReco PDF Generator:
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";
// IronPDF:
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div>Page {page} of {total-pages}</div>",
MaxHeight = 20
};
// NReco PDF Generator:
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";
// IronPDF:
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div>Page {page} of {total-pages}</div>",
MaxHeight = 20
};
Imports NReco.PdfGenerator
Imports IronPdf
' NReco PDF Generator:
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>"
' IronPDF:
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div>Page {page} of {total-pages}</div>",
.MaxHeight = 20
}
Cambio de tipo de retorno
El generador de PDF NReco devuelve byte[] directamente;IronPDFdevuelve PdfDocument:
// Generador de PDF de NRecopattern:
byte[] pdfBytes = converter.GeneratePdf(html);
File.WriteAllBytes("output.pdf", pdfBytes);
//IronPDFpattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Or if you need bytes:
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
// Generador de PDF de NRecopattern:
byte[] pdfBytes = converter.GeneratePdf(html);
File.WriteAllBytes("output.pdf", pdfBytes);
//IronPDFpattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Or if you need bytes:
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
' Generador de PDF de NRecopattern:
Dim pdfBytes As Byte() = converter.GeneratePdf(html)
File.WriteAllBytes("output.pdf", pdfBytes)
' IronPDFpattern:
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
' Or if you need bytes:
Dim pdfBytes As Byte() = renderer.RenderHtmlAsPdf(html).BinaryData
Seguridad y reutilización de hilos
NReco PDF Generator suele crear un nuevo conversor por llamada. El ChromePdfRenderer deIronPDFes seguro para subprocesos y se puede reutilizar:
// Generador de PDF de NRecopattern (creates new each time):
public byte[] Generate(string html)
{
var converter = new HtmlToPdfConverter();
return converter.GeneratePdf(html);
}
//IronPDFpattern (reuse renderer, thread-safe):
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] Generate(string html)
{
return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
// Generador de PDF de NRecopattern (creates new each time):
public byte[] Generate(string html)
{
var converter = new HtmlToPdfConverter();
return converter.GeneratePdf(html);
}
//IronPDFpattern (reuse renderer, thread-safe):
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] Generate(string html)
{
return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
' Generador de PDF de NRecopattern (creates new each time):
Public Function Generate(html As String) As Byte()
Dim converter As New HtmlToPdfConverter()
Return converter.GeneratePdf(html)
End Function
' IronPDFpattern (reuse renderer, thread-safe):
Private ReadOnly _renderer As New ChromePdfRenderer()
Public Function Generate(html As String) As Byte()
Return _renderer.RenderHtmlAsPdf(html).BinaryData
End Function
Soporte asíncrono (nueva capacidad)
IronPDF admite patrones async/await que Generador de PDF de NRecono puede proporcionar:
// NReco PDF Generator: No async support available
// IronPDF: Full async support
public async Task<byte[]> GenerateAsync(string html)
{
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
// NReco PDF Generator: No async support available
// IronPDF: Full async support
public async Task<byte[]> GenerateAsync(string html)
{
var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
Imports System.Threading.Tasks
' NReco PDF Generator: No async support available
' IronPDF: Full async support
Public Async Function GenerateAsync(html As String) As Task(Of Byte())
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Function
Solución de problemas
Asunto 1: HtmlToPdfConverter no encontrado
Problema: la clase HtmlToPdfConverter no existe en IronPDF.
Solución: Utilice ChromePdfRenderer:
// NReco PDF Generator
var converter = new HtmlToPdfConverter();
// IronPDF
var renderer = new ChromePdfRenderer();
// NReco PDF Generator
var converter = new HtmlToPdfConverter();
// IronPDF
var renderer = new ChromePdfRenderer();
' NReco PDF Generator
Dim converter As New HtmlToPdfConverter()
' IronPDF
Dim renderer As New ChromePdfRenderer()
Asunto 2: GeneratePdf devuelve un tipo incorrecto
Problema: el código espera byte[] pero obtiene PdfDocument.
Solución: Acceder a la propiedad .BinaryData:
// NReco PDF Generator
byte[] pdfBytes = converter.GeneratePdf(html);
// IronPDF
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
// NReco PDF Generator
byte[] pdfBytes = converter.GeneratePdf(html);
// IronPDF
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
' NReco PDF Generator
Dim pdfBytes As Byte() = converter.GeneratePdf(html)
' IronPDF
Dim pdfBytes As Byte() = renderer.RenderHtmlAsPdf(html).BinaryData
Edición 3: Objeto PageMargins no encontrado
Problema: la clase PageMargins no existe en IronPDF.
Solución: utilice propiedades de margen individuales:
// NReco PDF Generator
converter.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };
// IronPDF
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
// NReco PDF Generator
converter.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };
// IronPDF
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
' NReco PDF Generator
converter.Margins = New PageMargins With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
' IronPDF
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
renderer.RenderingOptions.MarginLeft = 10
renderer.RenderingOptions.MarginRight = 10
Cuestión 4: Los números de página no aparecen
Problema: los marcadores de posición [page] y [topage] no funcionan.
Solución: Actualizar la sintaxis del marcador de posiciónIronPDF:
// NReco PDF Generator
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";
// IronPDF
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div>Page {page} of {total-pages}</div>",
MaxHeight = 20
};
// NReco PDF Generator
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";
// IronPDF
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div>Page {page} of {total-pages}</div>",
MaxHeight = 20
};
Imports NReco.PdfGenerator
Imports IronPdf
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>"
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div>Page {page} of {total-pages}</div>",
.MaxHeight = 20
}
Lista de comprobación de la migración
Pre-Migración
- Inventariar todos los usos de
NReco.PdfGeneratoren el código base - Documentar todos los valores
CustomWkHtmlArgsyCustomWkHtmlPageArgs - Enumere todas las plantillas HTML de encabezado/pie de página con marcadores de posición
- Identificar requisitos asincrónicos (controladores web, servicios)
- Revisar la configuración de zoom y márgenes
- Realice una copia de seguridad de las salidas PDF existentes para compararlas
- Obtener la clave de licencia de IronPDF
Cambios en el paquete
- Eliminar el paquete NuGet
NReco.PdfGenerator - Instalar
IronPdfel paquete NuGet :dotnet add package IronPdf - Actualizar las importaciones de espacios de nombres de
using NReco.PdfGenerator;ausing IronPdf;
Cambios de código
- Agregar configuración de clave de licencia al inicio
- Reemplace
HtmlToPdfConverterconChromePdfRenderer - Reemplace
GeneratePdf(html)conRenderHtmlAsPdf(html) - Reemplace
GeneratePdfFromFile(url, null)conRenderUrlAsPdf(url) - Convertir el objeto
PageMarginsen propiedades de margen individuales - Actualizar los valores de zoom de flotante a porcentaje
- Actualizar la sintaxis del marcador de posición:
[page]→{page},[topage]→{total-pages} - Reemplace
File.WriteAllBytes()conpdf.SaveAs() - Convertir llamadas sincrónicas en asincrónicas cuando sea beneficioso
Posmigración
- Eliminar los binarios wkhtmltopdf del proyecto/implementación
- Actualizar los archivos de Docker para eliminar la instalación de wkhtmltopdf
- Ejecutar pruebas de regresión comparando la salida PDF
- Verificar que los marcadores de posición de encabezado y pie de página se representen correctamente
- Prueba en todas las plataformas de destino (Windows, Linux, macOS)
- Actualizar la canalización CI/CD para eliminar los pasos wkhtmltopdf
- Actualizar el análisis de seguridad para confirmar la eliminación de CVE

