Migrar de GemBox PDF a IronPDF: VeriFactu, TicketBAI, LOPDGDD y Crea y Crece para ISVs españoles
Para los ISVs y desarrolladores de software de facturación en España, GemBox PDF presenta no solo limitaciones técnicas sino incompatibilidades regulatorias directas con el marco de facturación electrónica vigente. El Real Decreto-Ley 15/2025 (VeriFactu) sanciona a los proveedores de software de facturación no conformes con hasta 150.000 €/año — y GemBox PDF, con su API basada en coordenadas y su límite de 20 párrafos (gratuito), es incapaz de generar las representaciones gráficas de facturas que VeriFactu exige:
- Sin soporte HTML-to-PDF: GemBox PDF no puede renderizar la leyenda obligatoria
VERI*FACTUcon composición CSS3 (Flexbox/Grid) según las especificaciones técnicas de la AEAT. - Límite de 20 párrafos en gratuita: Una factura básica con cabecera, tabla de conceptos (las celdas cuentan como párrafos), pie de página y leyenda
VERI*FACTUsupera fácilmente el límite. - Sin firma digital: TicketBAI (Bizkaia, Gipuzkoa, Araba) exige firma XAdES y PAdES conforme a eIDAS — GemBox PDF no implementa firma digital nativa.
- Sin soporte PDF/A: Crea y Crece (EN 16931/CIUS-ES) requerirá Facturae XML embebido en PDF/A-3 para facturas electrónicas B2B (2027-2028).
IronPDF resuelve todos estos requisitos en un único paquete NuGet: renderizado HTML/CSS con Chromium completo, firma XAdES/PAdES con certificados FNMT-RCM para eIDAS, PDF/A y procesamiento on-premise LOPDGDD/AEPD.
Por qué migrar de GemBox PDFa IronPDF
Los retos de GemBox PDF
GemBox PDF es un componente PDF .NET capaz, pero tiene limitaciones significativas que afectan al desarrollo en el mundo real:
-
Límite de 20 párrafos en la versión gratuita: la versión gratuita lo restringe a 20 párrafos, y las celdas de la tabla cuentan para este límite. Una simple tabla de 10 filas y 5 columnas utiliza 50 "párrafos", lo que hace que la versión gratuita sea inutilizable incluso para documentos empresariales básicos.
-
No hay conversión de HTML a PDF: GemBox PDFrequiere la construcción programática de documentos. Hay que calcular las coordenadas y posicionar manualmente cada elemento, no hay una simple función de "renderizar este HTML".
-
Diseño basado en coordenadas: a diferencia de HTML/CSS, donde el diseño fluye naturalmente, GemBox PDFrequiere que calcules las posiciones X/Y exactas para cada elemento de texto, imagen y forma.
-
Conjunto de funciones limitado: en comparación con las bibliotecas de PDF completas, GemBox PDFse centra en operaciones básicas (lectura, escritura, fusión, división) sin funciones avanzadas como renderizado HTML o compatibilidad con CSS moderno.
-
Solo programático: cada cambio de diseño requiere cambios en el código. ¿Quieres ajustar el espaciado? Recalcular coordenadas. ¿Desea un tamaño de fuente diferente? Ajusta todas las posiciones Y debajo.
-
Conteo de celdas de tabla: El límite de párrafos cuenta las celdas de tabla, no solo los párrafos visibles. Esto hace que la versión gratuita sea prácticamente inútil para documentos con tablas.
- Curva de aprendizaje para el diseño: Los desarrolladores deben pensar en coordenadas en lugar de en el flujo de documentos, lo que hace que tareas simples como "agregar un párrafo" sean sorprendentemente complejas.
Comparación entre GemBox PDFe IronPDF
| Aspecto | GemBox PDF | IronPDF |
|---|---|---|
| Límites de la versión gratuita | 20 párrafos (incluye celdas de tabla) | Sólo marca de agua, sin límites de contenido |
| HTML a PDF | No soportado | Motor Chromium completo |
| Método de maquetación | Manual basado en coordenadas | Diseño de flujo HTML/CSS |
| Tablas | Cuenta para el límite de párrafos | Uso ilimitado de tablas HTML |
| CSS moderno | No procede | Flexbox, Grid, animaciones CSS3 |
| Soporte de JavaScript | No procede | Ejecución completa de JavaScript |
| Cambios de diseño | Recalcular coordenadas | Editar HTML/CSS |
| Curva de aprendizaje | Sistema de coordenadas PDF | HTML/CSS (web familiar) |
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 que aprovecha las tecnologías web conocidas para la generación de PDF.
Evaluación de la complejidad de la migración
Esfuerzo estimado por función
| Característica | Complejidad de la migración |
|---|---|
| Cargar/guardar PDF | Muy bajo |
| Fusionar PDF | Muy bajo |
| Dividir PDF | Bajo |
| Extracción de Texto | Muy bajo |
| Añadir texto | Medio |
| Tablas | Bajo |
| Imágenes | Bajo |
| Marcas de agua | Bajo |
| Protección por contraseña | Medio |
| Campos de formulario | Medio |
Cambio de paradigma
El cambio más grande en esta migración de PDF de GemBox es pasar del diseño basado en coordenadas al diseño HTML/CSS:
GemBox PDF: "Dibujar texto en la posición (100, 700)"
IronPDF: "Renderiza este HTML con estilos CSS"
Este cambio de paradigma es generalmente más fácil para los desarrolladores familiarizados con las tecnologías web, pero requiere pensar en los PDF de forma diferente.
Antes de empezar
Prerrequisitos
- Versión .NET :IronPDFes compatible con .NET Framework 4.6.2+ y .NET Core 2.0+ / .NET 5/6/7/8/9+
- Clave de licencia: Obtenga su clave de licencia deIronPDFen IronPDF
- Copia de seguridad: crear una rama para el trabajo de migración
- Conocimientos de HTML/CSS: Es útil tener conocimientos básicos, pero no es obligatorio.
Identifique todos los usos de GemBox PDF
# Find all GemBox PDFreferences
grep -r "GemBox\.Pdf\|PdfDocument\|PdfPage\|PdfFormattedText\|ComponentInfo\.SetLicense" --include="*.cs" .
# Find package references
grep -r "GemBox\.Pdf" --include="*.csproj" .
# Find all GemBox PDFreferences
grep -r "GemBox\.Pdf\|PdfDocument\|PdfPage\|PdfFormattedText\|ComponentInfo\.SetLicense" --include="*.cs" .
# Find package references
grep -r "GemBox\.Pdf" --include="*.csproj" .
Cambios en el paquete NuGet
# Remove GemBox PDF
dotnet remove package GemBox.Pdf
# Install IronPDF
dotnet add package IronPdf
# Remove GemBox PDF
dotnet remove package GemBox.Pdf
# Install IronPDF
dotnet add package IronPdf
Inicio rápido de la migración
Paso 1: Actualizar la configuración de la licencia
Antes (GemBox PDF):
// Must call before any GemBox PDFoperations
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE");
// Must call before any GemBox PDFoperations
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE");
' Must call before any GemBox PDF operations
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE")
Después (IronPDF):
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }
' Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY"
' Or in appsettings.json:
' { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }
Paso 2: Actualizar las importaciones de espacios de nombres
// Before (GemBox PDF)
using GemBox.Pdf;
using GemBox.Pdf.Content;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;
// Before (GemBox PDF)
using GemBox.Pdf;
using GemBox.Pdf.Content;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;
Imports IronPdf
Imports IronPdf.Editing
Paso 3: Patrón básico de conversión
Antes (GemBox PDF):
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim page = document.Pages.Add()
Dim formattedText As New PdfFormattedText() With {
.Text = "Hello World",
.FontSize = 24
}
page.Content.DrawText(formattedText, New PdfPoint(100, 700))
document.Save("output.pdf")
End Using
Después (IronPDF):
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>");
pdf.SaveAs("output.pdf");
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>");
pdf.SaveAs("output.pdf");
Imports IronPdf
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>")
pdf.SaveAs("output.pdf")
Diferencias Clave:
- No se necesitan cálculos de coordenadas
- HTML/CSS en lugar de diseño programático
- Sin límite de párrafos
- Código más sencillo y legible
Referencia completa de la API
Mapeo de espacios de nombres
| GemBox PDF | IronPDF |
|---|---|
GemBox.Pdf |
IronPdf |
GemBox.Pdf.Content |
IronPdf (el contenido es HTML) |
GemBox.Pdf.Security |
IronPdf (Configuración de seguridad) |
GemBox.Pdf.Forms |
IronPdf.Forms |
Mapeo de clases principales
| GemBox PDF | IronPDF | Descripción |
|---|---|---|
PdfDocument |
PdfDocument |
Clase de documento PDF principal |
PdfPage |
PdfDocument.Pages[i] |
Representación de la página |
PdfContent |
N/A (usar HTML) | Contenido de la página |
PdfFormattedText |
N/A (usar HTML) | Texto con formato |
PdfPoint |
N/A (utilizar posicionamiento CSS) | Posición de las coordenadas |
ComponentInfo.SetLicense() |
IronPdf.License.LicenseKey |
Gestión de licencias |
Operaciones de documentos
| GemBox PDF | IronPDF |
|---|---|
new PdfDocument() |
new PdfDocument() |
PdfDocument.Load(path) |
PdfDocument.FromFile(path) |
PdfDocument.Load(stream) |
PdfDocument.FromStream(stream) |
document.Save(path) |
pdf.SaveAs(path) |
document.Save(stream) |
pdf.Stream o pdf.BinaryData |
Operaciones de página
| GemBox PDF | IronPDF |
|---|---|
document.Pages.Add() |
Creación mediante renderización HTML |
document.Pages.Count |
pdf.PageCount |
document.Pages[index] |
pdf.Pages[index] |
document.Pages.AddClone(pages) |
PdfDocument.Merge() |
Operaciones de texto y contenido
| GemBox PDF | IronPDF |
|---|---|
new PdfFormattedText() |
Cadena HTML |
formattedText.FontSize = 12 |
CSS font-size: 12pt |
formattedText.Font = ... |
CSS font-family: ... |
page.Content.DrawText(text, point) |
renderer.RenderHtmlAsPdf(html) |
page.Content.GetText() |
pdf.ExtractTextFromPage(i) |
Ejemplos de migración de código
Ejemplo 1: Conversión de HTML a PDF
Antes (GemBox PDF):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
var document = PdfDocument.Load("input.html");
document.Save("output.pdf");
}
}
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
var document = PdfDocument.Load("input.html");
document.Save("output.pdf");
}
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
Module Program
Sub Main()
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Dim document = PdfDocument.Load("input.html")
document.Save("output.pdf")
End Sub
End Module
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>")
pdf.SaveAs("output.pdf")
End Sub
End Class
ChromePdfRenderer deIronPDFutiliza un motor Chromium moderno para una representación precisa de HTML/CSS/ JavaScript . A diferencia del soporte limitado de HTML de GemBox PDF,IronPDFpuede renderizar cualquier contenido HTML con soporte completo de CSS3 y JavaScript. Consulte la documentación HTML a PDF para obtener más opciones de conversión.
Ejemplo 2: Combinar archivos PDF
Antes (GemBox PDF):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using System.Linq;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var source1 = PdfDocument.Load("document1.pdf");
var source2 = PdfDocument.Load("document2.pdf");
document.Pages.AddClone(source1.Pages);
document.Pages.AddClone(source2.Pages);
document.Save("merged.pdf");
}
}
}
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using System.Linq;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var source1 = PdfDocument.Load("document1.pdf");
var source2 = PdfDocument.Load("document2.pdf");
document.Pages.AddClone(source1.Pages);
document.Pages.AddClone(source2.Pages);
document.Save("merged.pdf");
}
}
}
Imports GemBox.Pdf
Imports System.Linq
Module Program
Sub Main()
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim source1 = PdfDocument.Load("document1.pdf")
Dim source2 = PdfDocument.Load("document2.pdf")
document.Pages.AddClone(source1.Pages)
document.Pages.AddClone(source2.Pages)
document.Save("merged.pdf")
End Using
End Sub
End Module
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
End Sub
End Class
El método estático Merge deIronPDFsimplifica la operación: no es necesario crear un documento vacío ni clonar páginas individualmente. Más información sobre mezclar y dividir archivos PDF.
Ejemplo 3: Añadir texto a un PDF
Antes (GemBox PDF):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
}
}
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
}
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
Module Program
Sub Main()
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim page = document.Pages.Add()
Dim formattedText As New PdfFormattedText() With {
.Text = "Hello World",
.FontSize = 24
}
page.Content.DrawText(formattedText, New PdfPoint(100, 700))
document.Save("output.pdf")
End Using
End Sub
End Module
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>");
var stamper = new TextStamper()
{
Text = "Hello World",
FontSize = 24,
HorizontalOffset = 100,
VerticalOffset = 700
};
pdf.ApplyStamp(stamper);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>");
var stamper = new TextStamper()
{
Text = "Hello World",
FontSize = 24,
HorizontalOffset = 100,
VerticalOffset = 700
};
pdf.ApplyStamp(stamper);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports IronPdf.Editing
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>")
Dim stamper = New TextStamper() With {
.Text = "Hello World",
.FontSize = 24,
.HorizontalOffset = 100,
.VerticalOffset = 700
}
pdf.ApplyStamp(stamper)
pdf.SaveAs("output.pdf")
End Sub
End Class
Para agregar texto a archivos PDF existentes,IronPDFproporciona la clase TextStamper que ofrece un control de posicionamiento preciso. Para documentos nuevos, basta con incluir el texto en la plantilla HTML. Consulte la documentación de estampado para obtener opciones adicionales.
Ejemplo 4: Creación de tablas (¡la mayor mejora!)
Antes (GemBox PDF) - Cada celda cuenta para el límite de 20 párrafos:
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
double y = 700;
double[] xPositions = { 50, 200, 300, 400 };
// Headers (4 paragraphs)
var headers = new[] { "Product", "Price", "Qty", "Total" };
for (int i = 0; i < headers.Length; i++)
{
var text = new PdfFormattedText { Text = headers[i], FontSize = 12 };
page.Content.DrawText(text, new PdfPoint(xPositions[i], y));
}
y -= 20;
// Data rows (4 paragraphs per row!)
// Can only add a few rows before hitting 20-paragraph limit!
document.Save("products.pdf");
}
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
double y = 700;
double[] xPositions = { 50, 200, 300, 400 };
// Headers (4 paragraphs)
var headers = new[] { "Product", "Price", "Qty", "Total" };
for (int i = 0; i < headers.Length; i++)
{
var text = new PdfFormattedText { Text = headers[i], FontSize = 12 };
page.Content.DrawText(text, new PdfPoint(xPositions[i], y));
}
y -= 20;
// Data rows (4 paragraphs per row!)
// Can only add a few rows before hitting 20-paragraph limit!
document.Save("products.pdf");
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
Using document As New PdfDocument()
Dim page = document.Pages.Add()
Dim y As Double = 700
Dim xPositions As Double() = {50, 200, 300, 400}
' Headers (4 paragraphs)
Dim headers = {"Product", "Price", "Qty", "Total"}
For i As Integer = 0 To headers.Length - 1
Dim text As New PdfFormattedText With {.Text = headers(i), .FontSize = 12}
page.Content.DrawText(text, New PdfPoint(xPositions(i), y))
Next
y -= 20
' Data rows (4 paragraphs per row!)
' Can only add a few rows before hitting 20-paragraph limit!
document.Save("products.pdf")
End Using
Después (IronPDF) - Sin límites, tablas HTML adecuadas:
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var html = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
</tbody>
</table>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("products.pdf");
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var html = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
</tbody>
</table>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("products.pdf");
Imports IronPdf
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim html As String = "
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
</tbody>
</table>
</body>
</html>"
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("products.pdf")
Esta es la mejora más significativa en la migración de GemBox PDF. Las tablas que eran imposibles en la versión gratuita de GemBox PDFfuncionan a la perfección enIronPDFcon soporte completo de estilos CSS.
Notas de migración críticas
Posicionamiento de coordenadas a CSS
Si necesita un posicionamiento perfecto (similar al sistema de coordenadas de GemBox PDF), utilice el posicionamiento absoluto CSS:
<div style="position:absolute; left:50px; top:750px; font-size:24px;">
Text positioned at specific coordinates
</div>
<div style="position:absolute; left:50px; top:750px; font-size:24px;">
Text positioned at specific coordinates
</div>
Indexación de páginas
Tanto GemBox PDFcomoIronPDFutilizan páginas con índice 0, lo que facilita este aspecto de la migración:
// GemBox PDF
var page = document.Pages[0];
// IronPDF
var page = pdf.Pages[0];
// GemBox PDF
var page = document.Pages[0];
// IronPDF
var page = pdf.Pages[0];
' GemBox PDF
Dim page = document.Pages(0)
' IronPDF
Dim page = pdf.Pages(0)
Configuración de seguridad
// GemBox PDF
document.SaveOptions.SetPasswordEncryption(userPassword, ownerPassword);
// IronPDF
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
// GemBox PDF
document.SaveOptions.SetPasswordEncryption(userPassword, ownerPassword);
// IronPDF
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
' GemBox PDF
document.SaveOptions.SetPasswordEncryption(userPassword, ownerPassword)
' IronPDF
pdf.SecuritySettings.UserPassword = "userPassword"
pdf.SecuritySettings.OwnerPassword = "ownerPassword"
Solución de problemas
Asunto 1: PdfFormattedText no encontrado
Problema: PdfFormattedText no existe en IronPDF.
Solución: utilice HTML con estilo CSS:
// GemBox PDF
var text = new PdfFormattedText { Text = "Hello", FontSize = 24 };
// IronPDF
var html = "<p style='font-size:24px;'>Hello</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
// GemBox PDF
var text = new PdfFormattedText { Text = "Hello", FontSize = 24 };
// IronPDF
var html = "<p style='font-size:24px;'>Hello</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
' GemBox PDF
Dim text As New PdfFormattedText With {.Text = "Hello", .FontSize = 24}
' IronPDF
Dim html As String = "<p style='font-size:24px;'>Hello</p>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
Asunto 2: Método DrawText no encontrado
Problema: page.Content.DrawText() no disponible.
Solución: Cree contenido mediante renderizado HTML o utilice estampadores:
// For new documents - render HTML
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>");
// For existing documents - use stampers
var stamper = new TextStamper() { Text = "Added Text" };
pdf.ApplyStamp(stamper);
// For new documents - render HTML
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>");
// For existing documents - use stampers
var stamper = new TextStamper() { Text = "Added Text" };
pdf.ApplyStamp(stamper);
Imports System
' For new documents - render HTML
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>")
' For existing documents - use stampers
Dim stamper As New TextStamper() With {.Text = "Added Text"}
pdf.ApplyStamp(stamper)
Cuestión 3: Diferencias en la carga de documentos
Problema: PdfDocument.Load() no encontrado.
Solución: utilice PdfDocument.FromFile() o FromStream():
// GemBox PDF
var doc = PdfDocument.Load("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
// GemBox PDF
var doc = PdfDocument.Load("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
Imports GemBox.Pdf
Imports IronPdf
Dim doc = PdfDocument.Load("input.pdf")
Dim pdf = PdfDocument.FromFile("input.pdf")
Número 4: Diferencias en los métodos de guardado
Problema: document.Save() la firma del método difiere.
Solución: Utilice SaveAs():
// GemBox PDF
document.Save("output.pdf");
// IronPDF
pdf.SaveAs("output.pdf");
// GemBox PDF
document.Save("output.pdf");
// IronPDF
pdf.SaveAs("output.pdf");
' GemBox PDF
document.Save("output.pdf")
' IronPDF
pdf.SaveAs("output.pdf")
Lista de comprobación de la migración
Pre-Migración
- Inventariar todo el uso de PDF de GemBox en el código base
- Identificar diseños basados en coordenadas que necesitan conversión HTML
- Evaluar los límites de párrafo actuales que afectan su código
- Obtener la clave de licencia de IronPDF
- Crear rama de migración en el control de versiones
Migración de código
- Eliminar el paquete NuGet PDF de GemBox:
dotnet remove package GemBox.Pdf - Instalar el paquete NuGet deIronPDF:
dotnet add package IronPdf - Actualizar las importaciones de espacios de nombres
- Reemplace
ComponentInfo.SetLicense()conIronPdf.License.LicenseKey - Convertir
PdfDocument.Load()aPdfDocument.FromFile() - Convertir
document.Save()apdf.SaveAs() - Reemplazar texto basado en coordenadas con contenido HTML
- Convertir
PdfFormattedTexta HTML con estilo CSS - Actualizar las operaciones de fusión para usar
PdfDocument.Merge()
Pruebas
- Verificar que todos los documentos se generen correctamente
- Validar que la apariencia del documento coincida con las expectativas
- Generación de tabla de prueba (anteriormente limitada por la regla de 20 párrafos)
- Verificar que la extracción de texto funcione correctamente
- Prueba de operaciones de fusión y división
- Validar la funcionalidad de seguridad/cifrado
Posmigración
- Eliminar las claves de licencia de GemBox PDF
- Actualización de la documentación
- Capacitar al equipo sobre el enfoque HTML/CSS para archivos PDF
- ¡Disfruta de contenido ilimitado sin límite de párrafos!
Contexto regulatorio español: GemBox PDF no puede generar facturas VeriFactu
Para los ISVs españoles, la limitación más crítica de GemBox PDF es que no puede generar PDFs desde HTML, lo que lo hace fundamentalmente incompatible con el régimen VeriFactu.
Por qué GemBox PDF no es apto para VeriFactu
El régimen VeriFactu (Real Decreto-Ley 15/2025) requiere que las facturas incluyan:
- *Leyenda `VERIFACTU`**: Debe renderizarse con CSS3 moderno (Flexbox/Grid). GemBox PDF requiere posicionamiento manual con coordenadas, sin soporte CSS.
- QR de la AEAT: La URL de verificación requiere renderizado preciso de imagen en contexto HTML. GemBox PDF no soporta HTML-to-PDF.
- Firma TicketBAI XAdES: La firma digital para TicketBAI (Bizkaia, Gipuzkoa, Araba) requiere soporte explícito que GemBox PDF no tiene.
- Límite de 20 párrafos: Una factura con tabla de conceptos, cabecera, pie de VERI*FACTU y datos de cliente fácilmente supera 20 párrafos en la versión gratuita.
Generación de factura VeriFactu con IronPDF (sin límites, con NIF/CIF y EUR español)
El siguiente ejemplo muestra una factura conforme con VeriFactu que incluye NIF del emisor, CIF del receptor, formato de divisa español (EUR 1.234,56 €) e IVA al 21% — elementos que GemBox PDF no puede renderizar por su falta de soporte HTML y el límite de 20 párrafos (una factura con cabecera, tabla de 5 conceptos y leyenda VeriFactu supera fácilmente 40 "párrafos" en el conteo de GemBox PDF):
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var html = @"
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.factura-header { display: flex; justify-content: space-between; align-items: flex-start; }
.verifactu-legend {
border: 2px solid #003366;
padding: 8px 12px;
font-size: 10px;
text-align: center;
margin-top: 20px;
}
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { border: 1px solid #ccc; padding: 8px; }
th { background-color: #003366; color: white; }
</style>
</head>
<body>
<div class='factura-header'>
<div>
<strong>FACTURA Nº 2026-0001</strong><br>
Fecha: 28/05/2026<br>
NIF Emisor: B-22334455
</div>
<div>CIF Receptor: A-55443322</div>
</div>
<table>
<tr><th>Concepto</th><th>Base imponible</th><th>IVA (21%)</th><th>Total</th></tr>
<tr><td>Licencia software facturación</td><td>1.000,00 €</td><td>210,00 €</td><td>1.210,00 €</td></tr>
<tr><td>Módulo TicketBAI Bizkaia</td><td>500,00 €</td><td>105,00 €</td><td>605,00 €</td></tr>
</table>
<div class='verifactu-legend'>
<strong>VERI*FACTU</strong><br>
Factura verificable en la sede electrónica de la AEAT<br>
[QR AEAT — sede.agenciatributaria.gob.es]
</div>
</body>
</html>";
// Sin límite de párrafos, sin API de coordenadas — HTML/CSS moderno con Flexbox
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("factura-verifactu-2026-0001.pdf");
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var html = @"
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.factura-header { display: flex; justify-content: space-between; align-items: flex-start; }
.verifactu-legend {
border: 2px solid #003366;
padding: 8px 12px;
font-size: 10px;
text-align: center;
margin-top: 20px;
}
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { border: 1px solid #ccc; padding: 8px; }
th { background-color: #003366; color: white; }
</style>
</head>
<body>
<div class='factura-header'>
<div>
<strong>FACTURA Nº 2026-0001</strong><br>
Fecha: 28/05/2026<br>
NIF Emisor: B-22334455
</div>
<div>CIF Receptor: A-55443322</div>
</div>
<table>
<tr><th>Concepto</th><th>Base imponible</th><th>IVA (21%)</th><th>Total</th></tr>
<tr><td>Licencia software facturación</td><td>1.000,00 €</td><td>210,00 €</td><td>1.210,00 €</td></tr>
<tr><td>Módulo TicketBAI Bizkaia</td><td>500,00 €</td><td>105,00 €</td><td>605,00 €</td></tr>
</table>
<div class='verifactu-legend'>
<strong>VERI*FACTU</strong><br>
Factura verificable en la sede electrónica de la AEAT<br>
[QR AEAT — sede.agenciatributaria.gob.es]
</div>
</body>
</html>";
// Sin límite de párrafos, sin API de coordenadas — HTML/CSS moderno con Flexbox
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("factura-verifactu-2026-0001.pdf");
Imports IronPdf
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim renderer As New ChromePdfRenderer()
Dim html As String = "
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.factura-header { display: flex; justify-content: space-between; align-items: flex-start; }
.verifactu-legend {
border: 2px solid #003366;
padding: 8px 12px;
font-size: 10px;
text-align: center;
margin-top: 20px;
}
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { border: 1px solid #ccc; padding: 8px; }
th { background-color: #003366; color: white; }
</style>
</head>
<body>
<div class='factura-header'>
<div>
<strong>FACTURA Nº 2026-0001</strong><br>
Fecha: 28/05/2026<br>
NIF Emisor: B-22334455
</div>
<div>CIF Receptor: A-55443322</div>
</div>
<table>
<tr><th>Concepto</th><th>Base imponible</th><th>IVA (21%)</th><th>Total</th></tr>
<tr><td>Licencia software facturación</td><td>1.000,00 €</td><td>210,00 €</td><td>1.210,00 €</td></tr>
<tr><td>Módulo TicketBAI Bizkaia</td><td>500,00 €</td><td>105,00 €</td><td>605,00 €</td></tr>
</table>
<div class='verifactu-legend'>
<strong>VERI*FACTU</strong><br>
Factura verificable en la sede electrónica de la AEAT<br>
[QR AEAT — sede.agenciatributaria.gob.es]
</div>
</body>
</html>"
' Sin límite de párrafos, sin API de coordenadas — HTML/CSS moderno con Flexbox
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("factura-verifactu-2026-0001.pdf")
LOPDGDD, eIDAS y Crea y Crece: el entorno regulatorio completo para ISVs españoles
Más allá de VeriFactu y TicketBAI, los ISVs de software de facturación en España operan bajo un entorno regulatorio completo que IronPDF soporta en un único paquete:
LOPDGDD y AEPD: Las facturas contienen datos personales (NIF, CIF, domicilio fiscal) bajo la supervisión de la AEPD (Agencia Española de Protección de Datos). IronPDF procesa on-premise sin transferir datos de contribuyentes a servicios externos — simplificando el análisis de cumplimiento LOPDGDD.
eIDAS y FNMT-RCM: Para la firma digital de facturas electrónicas (TicketBAI XAdES, FACe PAdES), IronPDF soporta certificados PKCS#12 de la FNMT-RCM — la CA española reconocida por la AEAT. GemBox PDF no implementa firma digital de ningún tipo.
Crea y Crece (EN 16931/CIUS-ES): La Ley Crea y Crece establece facturación electrónica B2B obligatoria en España (2027-2028) con Facturae XML en PDF/A-3. IronPDF soporta PDF/A y adjunto de XML Facturae — evitando un segundo cambio de motor cuando entren en vigor los plazos. El SII (Suministro Inmediato de Información) ya opera en tiempo real con la AEAT para grandes empresas.
iText AGPL vs IronPDF para software de facturación: Al migrar desde GemBox PDF, algunos equipos evalúan iText/iText7. En el contexto VeriFactu (penalización 150.000 €/año), la licencia AGPL de iText obliga a los ISVs de software propietario a publicar su código fuente o adquirir licencia comercial. IronPDF ofrece licenciamiento comercial predecible sin restricciones AGPL.
Lista de comprobación de conformidad VeriFactu post-migración
- [ ] Eliminar dependencia GemBox PDF del proyecto
- [ ] Implementar leyenda
VERI*FACTUen plantillas HTML de facturas con NIF/CIF - [ ] Añadir QR de la AEAT con URL de verificación (sede.agenciatributaria.gob.es)
- [ ] Verificar renderizado CSS3 Flexbox/Grid sin límite de contenido
- [ ] Configurar firma TicketBAI XAdES si aplica (Bizkaia, Gipuzkoa, Araba)
- [ ] Integrar Facturae XML para envío a FACe si procede
- [ ] Verificar certificados FNMT-RCM para firma eIDAS
- [ ] Confirmar procesamiento on-premise LOPDGDD/AEPD
- [ ] Revisar preparación para Crea y Crece (EN 16931/CIUS-ES) 2027-2028
Preguntas Frecuentes
¿Por qué GemBox PDF es incompatible con VeriFactu (RDL 15/2025)?
GemBox PDF tiene dos incompatibilidades críticas: (1) no soporta generación de PDFs desde HTML, imposibilitando la leyenda obligatoria VERI*FACTU con CSS3/Flexbox según las especificaciones técnicas de la AEAT; (2) el límite de 20 párrafos en la versión gratuita (las celdas de tabla cuentan) hace inviable una factura básica con cabecera, tabla de conceptos y leyenda VeriFactu. Los proveedores no conformes se exponen a sanciones de hasta 150.000 €/año.
¿IronPDF puede generar facturas con leyenda VERI*FACTU y QR de la AEAT?
Sí. IronPDF renderiza HTML/CSS con motor Chromium moderno, soportando Flexbox y Grid CSS3. Permite componer la leyenda VERI*FACTU o Factura verificable en la sede electrónica de la AEAT con el QR de verificación de la AEAT según las especificaciones técnicas de VeriFactu, incluyendo NIF/CIF, formato EUR 1.234,56 € e IVA 21% sin límites de contenido.
¿IronPDF soporta firma XAdES y PAdES con certificados FNMT-RCM para TicketBAI?
Sí. IronPDF incluye XAdES, PAdES y CAdES nativo, compatible con certificados PKCS#12 de la FNMT-RCM. Las tres Haciendas Forales del País Vasco (Bizkaia, Gipuzkoa, Araba) exigen ambas firmas para TicketBAI — GemBox PDF no implementa ningún tipo de firma digital.
¿Cómo simplifica IronPDF el cumplimiento LOPDGDD al migrar desde GemBox PDF?
IronPDF procesa PDFs on-premise sin transmitir datos de facturas (NIF, CIF) a servicios externos, simplificando el análisis de cumplimiento LOPDGDD supervisado por la AEPD. Soporta Docker y Linux on-premise para mantener los datos de contribuyentes dentro del perímetro de la organización.
¿Está IronPDF preparado para los requisitos Crea y Crece (EN 16931/CIUS-ES)?
Sí. La Ley Crea y Crece exige Facturae XML en PDF/A-3 para facturas electrónicas B2B (obligatorio desde 2027-2028). IronPDF soporta PDF/A y procesamiento en un único paquete, evitando un segundo cambio de motor. El SII (Suministro Inmediato de Información) para grandes empresas ya opera en tiempo real con la AEAT y se beneficia de IronPDF on-premise headless.

