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

Migración de Aspose.PDF a IronPDF bajo VeriFactu: guía técnica para ISVs españoles

Full Comparison

Looking for a detailed feature-by-feature breakdown? See how IronPDF stacks up against Aspose PDF on pricing, HTML support, and licensing.

View Full Comparison

Migración de Aspose.PDF a IronPDF bajo el calendario VeriFactu: guía técnica para ISVs españoles

La migración de Aspose.PDF a IronPDF en el contexto del mercado español tiene una dimensión que no existe en otros mercados: el calendario de cumplimiento VeriFactu. Los ISVs que construyen software de facturación tienen fechas concretas (1 de enero de 2027 para contribuyentes del Impuesto sobre Sociedades; 1 de julio de 2027 para el resto, según RDL 15/2025) antes de las cuales su stack tecnológico debe ser capaz de generar PDFs conformes con los requisitos de visualización de la AEAT.

Esta guía aborda la migración técnica de Aspose.PDF a IronPDF con foco en las funcionalidades que el mercado español requiere: generación de facturas con VERI*FACTU y QR AEAT, firma PAdES con certificados FNMT bajo eIDAS, archivado PDF/A-3 para Facturae/FACe, y procesamiento de volumen compatible con SII.

Por qué evaluar la migración de Aspose.PDF en el contexto español

Coste acumulado vs. previsibilidad en el calendario VeriFactu

Aspose.PDF utiliza un modelo de suscripción anual (superior a 1.199 €/desarrollador/año). Para un ISV con equipo de cinco desarrolladores que trabaja bajo el calendario de cumplimiento VeriFactu, el coste de la biblioteca PDF en los próximos tres años supera los 18.000 € — sin incluir las licencias OEM para redistribución en el software de facturación.

IronPDF ofrece licencia perpetua con pago único (749 $ en el nivel Lite), lo que simplifica la planificación financiera del producto bajo un calendario de cumplimiento regulatorio con fechas fijas.

Motor HTML para plantillas de factura mantenibles

Aspose.PDF usa el motor Flying Saucer para HTML a PDF. Flying Saucer no soporta CSS Grid ni Flexbox — los dos sistemas de layout que usan las plantillas de factura modernas para alinear logotipos, datos fiscales y totales. Esto obliga a los ISVs a mantener dos versiones de la plantilla: una para la web y otra empobrecida para PDF.

El motor Chromium de IronPDF renderiza el mismo HTML/CSS que usa el navegador. Las plantillas de factura con las leyendas obligatorias VeriFactu (VERI*FACTU, Factura verificable en la sede electrónica de la AEAT) se diseñan en HTML y producen PDFs pixel-perfect sin adaptaciones.

Firma PAdES nativa para TicketBAI

Aspose.PDF soporta firma digital, pero la integración con certificados FNMT bajo eIDAS requiere configuración adicional. IronPDF proporciona PdfSignature con soporte directo para PAdES, necesario para firmar facturas en los tres territorios TicketBAI: Bizkaia (con BATUZ), Gipuzkoa y Araba.

Equivalencia técnica: Aspose.PDF → IronPDF

Configuración de licencia

// Aspose.PDF: archivo .lic
var license = new Aspose.Pdf.License();
license.SetLicense("Aspose.Pdf.lic");

// IronPDF: clave en código — apta para configuración por entorno
IronPdf.License.LicenseKey = "TU-CLAVE-IRONPDF";
// En producción: leer de variable de entorno o Azure Key Vault
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY");
// Aspose.PDF: archivo .lic
var license = new Aspose.Pdf.License();
license.SetLicense("Aspose.Pdf.lic");

// IronPDF: clave en código — apta para configuración por entorno
IronPdf.License.LicenseKey = "TU-CLAVE-IRONPDF";
// En producción: leer de variable de entorno o Azure Key Vault
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY");
Imports Aspose.Pdf
Imports IronPdf

' Aspose.PDF: archivo .lic
Dim license As New License()
license.SetLicense("Aspose.Pdf.lic")

' IronPDF: clave en código — apta para configuración por entorno
IronPdf.License.LicenseKey = "TU-CLAVE-IRONPDF"
' En producción: leer de variable de entorno o Azure Key Vault
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY")
$vbLabelText   $csharpLabel

Generación de factura VeriFactu: HTML a PDF

// Aspose.PDF: HTML a PDF via HtmlLoadOptions (motor Flying Saucer, CSS limitado)
using Aspose.Pdf;

HtmlLoadOptions htmlOpts = new HtmlLoadOptions("./assets/");
Document docAspose = new Document("plantilla_factura.html", htmlOpts);
// Flying Saucer no renderiza flexbox — la plantilla puede necesitar adaptaciones

// IronPDF: HTML a PDF via motor Chromium (CSS3 completo, JS, flexbox)
using IronPdf;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

// La plantilla HTML puede incluir los literales VeriFactu obligatorios directamente
string facturaHtml = File.ReadAllText("plantilla_factura_verifactu.html");

// Sustituir marcadores con datos del registro VeriFactu
facturaHtml = facturaHtml
    .Replace("{{VERI_FACTU_LEGEND}}", "VERI*FACTU")
    .Replace("{{AEAT_LEGEND}}", "Factura verificable en la sede electrónica de la AEAT")
    .Replace("{{QR_AEAT_BASE64}}", qrAeatBase64)
    .Replace("{{HUELLA_ENCADENADA}}", huellaVeriFactu);

using var pdfResult = renderer.RenderHtmlAsPdf(facturaHtml);
pdfResult.SaveAs($"factura_{numeroFactura}.pdf");
// Aspose.PDF: HTML a PDF via HtmlLoadOptions (motor Flying Saucer, CSS limitado)
using Aspose.Pdf;

HtmlLoadOptions htmlOpts = new HtmlLoadOptions("./assets/");
Document docAspose = new Document("plantilla_factura.html", htmlOpts);
// Flying Saucer no renderiza flexbox — la plantilla puede necesitar adaptaciones

// IronPDF: HTML a PDF via motor Chromium (CSS3 completo, JS, flexbox)
using IronPdf;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

// La plantilla HTML puede incluir los literales VeriFactu obligatorios directamente
string facturaHtml = File.ReadAllText("plantilla_factura_verifactu.html");

// Sustituir marcadores con datos del registro VeriFactu
facturaHtml = facturaHtml
    .Replace("{{VERI_FACTU_LEGEND}}", "VERI*FACTU")
    .Replace("{{AEAT_LEGEND}}", "Factura verificable en la sede electrónica de la AEAT")
    .Replace("{{QR_AEAT_BASE64}}", qrAeatBase64)
    .Replace("{{HUELLA_ENCADENADA}}", huellaVeriFactu);

using var pdfResult = renderer.RenderHtmlAsPdf(facturaHtml);
pdfResult.SaveAs($"factura_{numeroFactura}.pdf");
Imports Aspose.Pdf
Imports IronPdf
Imports System.IO

' Aspose.PDF: HTML a PDF via HtmlLoadOptions (motor Flying Saucer, CSS limitado)
Dim htmlOpts As New HtmlLoadOptions("./assets/")
Dim docAspose As New Document("plantilla_factura.html", htmlOpts)
' Flying Saucer no renderiza flexbox — la plantilla puede necesitar adaptaciones

' IronPDF: HTML a PDF via motor Chromium (CSS3 completo, JS, flexbox)
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4

' La plantilla HTML puede incluir los literales VeriFactu obligatorios directamente
Dim facturaHtml As String = File.ReadAllText("plantilla_factura_verifactu.html")

' Sustituir marcadores con datos del registro VeriFactu
facturaHtml = facturaHtml _
    .Replace("{{VERI_FACTU_LEGEND}}", "VERI*FACTU") _
    .Replace("{{AEAT_LEGEND}}", "Factura verificable en la sede electrónica de la AEAT") _
    .Replace("{{QR_AEAT_BASE64}}", qrAeatBase64) _
    .Replace("{{HUELLA_ENCADENADA}}", huellaVeriFactu)

Using pdfResult = renderer.RenderHtmlAsPdf(facturaHtml)
    pdfResult.SaveAs($"factura_{numeroFactura}.pdf")
End Using
$vbLabelText   $csharpLabel

Construcción programática: Aspose a HTML-first

Si el ISV usa Aspose.PDF con construcción programática de documentos (Document, TextFragment, Table), la migración a IronPDF implica adoptar el paradigma HTML-first — que para facturas resulta más mantenible:

// Aspose.PDF: construcción programática
using Aspose.Pdf;
using Aspose.Pdf.Text;

Document doc = new Document();
Page pagina = doc.Pages.Add();

// NIF y número de factura — manual
pagina.Paragraphs.Add(new TextFragment("Factura 2027-A-001234 — NIF: B12345678"));

Table tabla = new Table();
tabla.ColumnWidths = "220 60 80 80";
Row cabecera = tabla.Rows.Add();
cabecera.Cells.Add("Concepto");
cabecera.Cells.Add("Cant.");
cabecera.Cells.Add("Precio");
cabecera.Cells.Add("Total");
pagina.Paragraphs.Add(tabla);

// VERI*FACTU — añadir como TextFragment al final
pagina.Paragraphs.Add(new TextFragment("VERI*FACTU — Factura verificable en la sede electrónica de la AEAT"));

doc.Save("factura_aspose.pdf");

// IronPDF: HTML-first — misma información, más legible y mantenible
using IronPdf;

string htmlFactura = @"
<html lang='es'>
<head>
    <style>
        body { font-family: Arial; font-size: 11px; margin: 30px; }
        table { width:100%; border-collapse:collapse; }
        th { background:#2c3e50; color:#fff; padding:5px; }
        td { padding:5px; border:1px solid #ddd; }
        .verifactu { border:2px solid #000; padding:8px; text-align:center;
                     font-weight:bold; margin-top:15px; }
    </style>
</head>
<body>
    <h2>Factura 2027-A-001234 — NIF: B12345678</h2>
    <table>
        <tr><th>Concepto</th><th>Cant.</th><th>Precio</th><th>Total</th></tr>
        <tr><td>Módulo facturación</td><td>1</td><td>1.200,00 €</td><td>1.200,00 €</td></tr>
    </table>
    <div class='verifactu'>
        VERI*FACTU<br/>
        Factura verificable en la sede electrónica de la AEAT
    </div>
</body>
</html>";

var renderer2 = new ChromePdfRenderer();
using var pdf2 = renderer2.RenderHtmlAsPdf(htmlFactura);
pdf2.SaveAs("factura_ironpdf.pdf");
// Aspose.PDF: construcción programática
using Aspose.Pdf;
using Aspose.Pdf.Text;

Document doc = new Document();
Page pagina = doc.Pages.Add();

// NIF y número de factura — manual
pagina.Paragraphs.Add(new TextFragment("Factura 2027-A-001234 — NIF: B12345678"));

Table tabla = new Table();
tabla.ColumnWidths = "220 60 80 80";
Row cabecera = tabla.Rows.Add();
cabecera.Cells.Add("Concepto");
cabecera.Cells.Add("Cant.");
cabecera.Cells.Add("Precio");
cabecera.Cells.Add("Total");
pagina.Paragraphs.Add(tabla);

// VERI*FACTU — añadir como TextFragment al final
pagina.Paragraphs.Add(new TextFragment("VERI*FACTU — Factura verificable en la sede electrónica de la AEAT"));

doc.Save("factura_aspose.pdf");

// IronPDF: HTML-first — misma información, más legible y mantenible
using IronPdf;

string htmlFactura = @"
<html lang='es'>
<head>
    <style>
        body { font-family: Arial; font-size: 11px; margin: 30px; }
        table { width:100%; border-collapse:collapse; }
        th { background:#2c3e50; color:#fff; padding:5px; }
        td { padding:5px; border:1px solid #ddd; }
        .verifactu { border:2px solid #000; padding:8px; text-align:center;
                     font-weight:bold; margin-top:15px; }
    </style>
</head>
<body>
    <h2>Factura 2027-A-001234 — NIF: B12345678</h2>
    <table>
        <tr><th>Concepto</th><th>Cant.</th><th>Precio</th><th>Total</th></tr>
        <tr><td>Módulo facturación</td><td>1</td><td>1.200,00 €</td><td>1.200,00 €</td></tr>
    </table>
    <div class='verifactu'>
        VERI*FACTU<br/>
        Factura verificable en la sede electrónica de la AEAT
    </div>
</body>
</html>";

var renderer2 = new ChromePdfRenderer();
using var pdf2 = renderer2.RenderHtmlAsPdf(htmlFactura);
pdf2.SaveAs("factura_ironpdf.pdf");
Imports Aspose.Pdf
Imports Aspose.Pdf.Text
Imports IronPdf

Dim doc As New Document()
Dim pagina As Page = doc.Pages.Add()

' NIF y número de factura — manual
pagina.Paragraphs.Add(New TextFragment("Factura 2027-A-001234 — NIF: B12345678"))

Dim tabla As New Table()
tabla.ColumnWidths = "220 60 80 80"
Dim cabecera As Row = tabla.Rows.Add()
cabecera.Cells.Add("Concepto")
cabecera.Cells.Add("Cant.")
cabecera.Cells.Add("Precio")
cabecera.Cells.Add("Total")
pagina.Paragraphs.Add(tabla)

' VERI*FACTU — añadir como TextFragment al final
pagina.Paragraphs.Add(New TextFragment("VERI*FACTU — Factura verificable en la sede electrónica de la AEAT"))

doc.Save("factura_aspose.pdf")

Dim htmlFactura As String = "
<html lang='es'>
<head>
    <style>
        body { font-family: Arial; font-size: 11px; margin: 30px; }
        table { width:100%; border-collapse:collapse; }
        th { background:#2c3e50; color:#fff; padding:5px; }
        td { padding:5px; border:1px solid #ddd; }
        .verifactu { border:2px solid #000; padding:8px; text-align:center;
                     font-weight:bold; margin-top:15px; }
    </style>
</head>
<body>
    <h2>Factura 2027-A-001234 — NIF: B12345678</h2>
    <table>
        <tr><th>Concepto</th><th>Cant.</th><th>Precio</th><th>Total</th></tr>
        <tr><td>Módulo facturación</td><td>1</td><td>1.200,00 €</td><td>1.200,00 €</td></tr>
    </table>
    <div class='verifactu'>
        VERI*FACTU<br/>
        Factura verificable en la sede electrónica de la AEAT
    </div>
</body>
</html>"

Dim renderer2 As New ChromePdfRenderer()
Using pdf2 = renderer2.RenderHtmlAsPdf(htmlFactura)
    pdf2.SaveAs("factura_ironpdf.pdf")
End Using
$vbLabelText   $csharpLabel

Fusión de PDFs (facturas de varios módulos)

// Aspose.PDF: PdfFileEditor
using Aspose.Pdf.Facades;

PdfFileEditor editor = new PdfFileEditor();
string[] archivos = { "factura_principal.pdf", "anexo_desglose.pdf" };
editor.Concatenate(archivos, "factura_completa.pdf");

// IronPDF: Merge estático
using IronPdf;

var pdfs = new[] { "factura_principal.pdf", "anexo_desglose.pdf" }
    .Select(PdfDocument.FromFile)
    .ToList();
var fusionado = PdfDocument.Merge(pdfs);
fusionado.SaveAs("factura_completa.pdf");
pdfs.ForEach(p => p.Dispose());
// Aspose.PDF: PdfFileEditor
using Aspose.Pdf.Facades;

PdfFileEditor editor = new PdfFileEditor();
string[] archivos = { "factura_principal.pdf", "anexo_desglose.pdf" };
editor.Concatenate(archivos, "factura_completa.pdf");

// IronPDF: Merge estático
using IronPdf;

var pdfs = new[] { "factura_principal.pdf", "anexo_desglose.pdf" }
    .Select(PdfDocument.FromFile)
    .ToList();
var fusionado = PdfDocument.Merge(pdfs);
fusionado.SaveAs("factura_completa.pdf");
pdfs.ForEach(p => p.Dispose());
Imports Aspose.Pdf.Facades
Imports IronPdf

Dim editor As New PdfFileEditor()
Dim archivos As String() = {"factura_principal.pdf", "anexo_desglose.pdf"}
editor.Concatenate(archivos, "factura_completa.pdf")

Dim pdfs = archivos.Select(Function(file) PdfDocument.FromFile(file)).ToList()
Dim fusionado = PdfDocument.Merge(pdfs)
fusionado.SaveAs("factura_completa.pdf")
pdfs.ForEach(Sub(p) p.Dispose())
$vbLabelText   $csharpLabel

Extracción de texto (validación de contenido de facturas)

// Aspose.PDF: TextFragmentAbsorber
using Aspose.Pdf;
using Aspose.Pdf.Text;

Document doc = new Document("factura.pdf");
TextFragmentAbsorber absorber = new TextFragmentAbsorber();
doc.Pages.Accept(absorber);
string texto = string.Join(" ", absorber.TextFragments.Select(f => f.Text));

// IronPDF: ExtractAllText
using IronPdf;

var pdf = PdfDocument.FromFile("factura.pdf");
string texto2 = pdf.ExtractAllText();
// Aspose.PDF: TextFragmentAbsorber
using Aspose.Pdf;
using Aspose.Pdf.Text;

Document doc = new Document("factura.pdf");
TextFragmentAbsorber absorber = new TextFragmentAbsorber();
doc.Pages.Accept(absorber);
string texto = string.Join(" ", absorber.TextFragments.Select(f => f.Text));

// IronPDF: ExtractAllText
using IronPdf;

var pdf = PdfDocument.FromFile("factura.pdf");
string texto2 = pdf.ExtractAllText();
Imports Aspose.Pdf
Imports Aspose.Pdf.Text
Imports IronPdf

Dim doc As New Document("factura.pdf")
Dim absorber As New TextFragmentAbsorber()
doc.Pages.Accept(absorber)
Dim texto As String = String.Join(" ", absorber.TextFragments.Select(Function(f) f.Text))

Dim pdf = PdfDocument.FromFile("factura.pdf")
Dim texto2 As String = pdf.ExtractAllText()
$vbLabelText   $csharpLabel

Indexación de páginas: diferencia crítica en migración

Una diferencia operativa importante al migrar de Aspose.PDF a IronPDF es la indexación de páginas:

// Aspose.PDF: páginas indexadas desde 1 (como PDF spec)
Page primeraAspose = doc.Pages[1];   // índice 1
Page ultimaAspose  = doc.Pages[doc.Pages.Count]; // no Pages[Count - 1]

// IronPDF: páginas indexadas desde 0 (convención .NET)
var pdfIron = PdfDocument.FromFile("factura.pdf");
var primera = pdfIron.Pages[0];         // índice 0
var ultima  = pdfIron.Pages[pdfIron.Pages.Count - 1];
// Aspose.PDF: páginas indexadas desde 1 (como PDF spec)
Page primeraAspose = doc.Pages[1];   // índice 1
Page ultimaAspose  = doc.Pages[doc.Pages.Count]; // no Pages[Count - 1]

// IronPDF: páginas indexadas desde 0 (convención .NET)
var pdfIron = PdfDocument.FromFile("factura.pdf");
var primera = pdfIron.Pages[0];         // índice 0
var ultima  = pdfIron.Pages[pdfIron.Pages.Count - 1];
' Aspose.PDF: páginas indexadas desde 1 (como PDF spec)
Dim primeraAspose As Page = doc.Pages(1)   ' índice 1
Dim ultimaAspose As Page = doc.Pages(doc.Pages.Count) ' no Pages(Count - 1)

' IronPDF: páginas indexadas desde 0 (convención .NET)
Dim pdfIron = PdfDocument.FromFile("factura.pdf")
Dim primera = pdfIron.Pages(0)         ' índice 0
Dim ultima = pdfIron.Pages(pdfIron.Pages.Count - 1)
$vbLabelText   $csharpLabel

Firma PAdES con certificado FNMT para TicketBAI

La firma digital bajo eIDAS es obligatoria para documentos TicketBAI en las tres provincias vascas. Con IronPDF, la firma PAdES usa directamente el certificado X.509 de la FNMT (u otra CA acreditada):

// Aspose.PDF: firma digital (requiere más configuración)
using Aspose.Pdf.Facades;

PdfFileSignature pdfFirmaAspose = new PdfFileSignature();
pdfFirmaAspose.BindPdf("factura_sin_firmar.pdf");
PKCS12 firmante = new PKCS12("certificado_fnmt.pfx", "password");
pdfFirmaAspose.Sign(1, true, new System.Drawing.Rectangle(100, 100, 200, 150), firmante);
pdfFirmaAspose.Save("factura_firmada_aspose.pdf");

// IronPDF: PdfSignature — API más directa
using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;

var certFNMT = new X509Certificate2(
    "certificado_fnmt.pfx", "password", X509KeyStorageFlags.Exportable);

var firma = new PdfSignature(certFNMT)
{
    SigningContact  = "facturacion@empresa.es",
    SigningLocation = "España — TicketBAI/VeriFactu",
    SigningReason   = "Factura electrónica eIDAS"
};

var pdfParaFirmar = PdfDocument.FromFile("factura_sin_firmar.pdf");
pdfParaFirmar.Sign(firma);
pdfParaFirmar.SaveAs("factura_firmada_fnmt.pdf");
// Aspose.PDF: firma digital (requiere más configuración)
using Aspose.Pdf.Facades;

PdfFileSignature pdfFirmaAspose = new PdfFileSignature();
pdfFirmaAspose.BindPdf("factura_sin_firmar.pdf");
PKCS12 firmante = new PKCS12("certificado_fnmt.pfx", "password");
pdfFirmaAspose.Sign(1, true, new System.Drawing.Rectangle(100, 100, 200, 150), firmante);
pdfFirmaAspose.Save("factura_firmada_aspose.pdf");

// IronPDF: PdfSignature — API más directa
using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;

var certFNMT = new X509Certificate2(
    "certificado_fnmt.pfx", "password", X509KeyStorageFlags.Exportable);

var firma = new PdfSignature(certFNMT)
{
    SigningContact  = "facturacion@empresa.es",
    SigningLocation = "España — TicketBAI/VeriFactu",
    SigningReason   = "Factura electrónica eIDAS"
};

var pdfParaFirmar = PdfDocument.FromFile("factura_sin_firmar.pdf");
pdfParaFirmar.Sign(firma);
pdfParaFirmar.SaveAs("factura_firmada_fnmt.pdf");
Imports Aspose.Pdf.Facades
Imports IronPdf
Imports IronPdf.Signing
Imports System.Security.Cryptography.X509Certificates
Imports System.Drawing

' Aspose.PDF: firma digital (requiere más configuración)
Dim pdfFirmaAspose As New PdfFileSignature()
pdfFirmaAspose.BindPdf("factura_sin_firmar.pdf")
Dim firmante As New PKCS12("certificado_fnmt.pfx", "password")
pdfFirmaAspose.Sign(1, True, New Rectangle(100, 100, 200, 150), firmante)
pdfFirmaAspose.Save("factura_firmada_aspose.pdf")

' IronPDF: PdfSignature — API más directa
Dim certFNMT As New X509Certificate2("certificado_fnmt.pfx", "password", X509KeyStorageFlags.Exportable)

Dim firma As New PdfSignature(certFNMT) With {
    .SigningContact = "facturacion@empresa.es",
    .SigningLocation = "España — TicketBAI/VeriFactu",
    .SigningReason = "Factura electrónica eIDAS"
}

Dim pdfParaFirmar As PdfDocument = PdfDocument.FromFile("factura_sin_firmar.pdf")
pdfParaFirmar.Sign(firma)
pdfParaFirmar.SaveAs("factura_firmada_fnmt.pdf")
$vbLabelText   $csharpLabel

Archivado PDF/A-3 para Facturae + FACe (Crea y Crece)

La conversión a PDF/A es necesaria para el archivado bajo el calendario de Crea y Crece y para los envíos a la plataforma FACe del sector público (B2G). El formato PDF/A-3 permite embeber el XML Facturae 3.2.2 como adjunto, siguiendo el patrón híbrido conforme con EN 16931 / CIUS-ES:

// Aspose.PDF: conversión a PDF/A con validación
using Aspose.Pdf;

Document docPdfa = new Document("factura_base.pdf");
docPdfa.Convert("conversion_log.xml", PdfFormat.PDF_A_3B, ConvertErrorAction.Delete);
docPdfa.Save("factura_pdfa3b_aspose.pdf");

// IronPDF: SaveAsPdfA con archivos embebidos
using IronPdf;

var pdfIron = PdfDocument.FromFile("factura_base.pdf");

// Embeber XML Facturae 3.2.2 (firmado con XAdES externamente)
byte[] xmlFacturae = File.ReadAllBytes("factura_B12345678.xml");
pdfIron.EmbedFile(xmlFacturae, "factura.xml", "application/xml");

// PDF/A-3B: conforme para FACe, Crea y Crece, SII
pdfIron.SaveAsPdfA("factura_pdfa3b_ironpdf.pdf", PdfAVersions.PdfA3B);
// Aspose.PDF: conversión a PDF/A con validación
using Aspose.Pdf;

Document docPdfa = new Document("factura_base.pdf");
docPdfa.Convert("conversion_log.xml", PdfFormat.PDF_A_3B, ConvertErrorAction.Delete);
docPdfa.Save("factura_pdfa3b_aspose.pdf");

// IronPDF: SaveAsPdfA con archivos embebidos
using IronPdf;

var pdfIron = PdfDocument.FromFile("factura_base.pdf");

// Embeber XML Facturae 3.2.2 (firmado con XAdES externamente)
byte[] xmlFacturae = File.ReadAllBytes("factura_B12345678.xml");
pdfIron.EmbedFile(xmlFacturae, "factura.xml", "application/xml");

// PDF/A-3B: conforme para FACe, Crea y Crece, SII
pdfIron.SaveAsPdfA("factura_pdfa3b_ironpdf.pdf", PdfAVersions.PdfA3B);
Imports Aspose.Pdf
Imports IronPdf
Imports System.IO

' Aspose.PDF: conversión a PDF/A con validación
Dim docPdfa As New Document("factura_base.pdf")
docPdfa.Convert("conversion_log.xml", PdfFormat.PDF_A_3B, ConvertErrorAction.Delete)
docPdfa.Save("factura_pdfa3b_aspose.pdf")

' IronPDF: SaveAsPdfA con archivos embebidos
Dim pdfIron = PdfDocument.FromFile("factura_base.pdf")

' Embeber XML Facturae 3.2.2 (firmado con XAdES externamente)
Dim xmlFacturae As Byte() = File.ReadAllBytes("factura_B12345678.xml")
pdfIron.EmbedFile(xmlFacturae, "factura.xml", "application/xml")

' PDF/A-3B: conforme para FACe, Crea y Crece, SII
pdfIron.SaveAsPdfA("factura_pdfa3b_ironpdf.pdf", PdfAVersions.PdfA3B)
$vbLabelText   $csharpLabel

Cifrado bajo LOPDGDD

Las facturas contienen datos personales sujetos a LOPDGDD y supervisión de la AEPD. El cifrado del documento es una medida técnica recomendada en la estrategia de protección de datos del ISV:

// Aspose.PDF: cifrado
Document docEnc = new Document("factura.pdf");
docEnc.Encrypt(
    "password-usuario",
    "password-propietario",
    DocumentPrivilege.ForbidAll,
    CryptoAlgorithm.AESx256,
    false);
docEnc.Save("factura_cifrada_aspose.pdf");

// IronPDF: SecuritySettings
var pdfSec = PdfDocument.FromFile("factura.pdf");
pdfSec.SecuritySettings.OwnerPassword = "password-propietario";
pdfSec.SecuritySettings.UserPassword  = "password-usuario";
pdfSec.SecuritySettings.AllowUserPrinting       = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
pdfSec.SecuritySettings.AllowUserCopyPasteContent = false;
pdfSec.SaveAs("factura_cifrada_ironpdf.pdf");
// Aspose.PDF: cifrado
Document docEnc = new Document("factura.pdf");
docEnc.Encrypt(
    "password-usuario",
    "password-propietario",
    DocumentPrivilege.ForbidAll,
    CryptoAlgorithm.AESx256,
    false);
docEnc.Save("factura_cifrada_aspose.pdf");

// IronPDF: SecuritySettings
var pdfSec = PdfDocument.FromFile("factura.pdf");
pdfSec.SecuritySettings.OwnerPassword = "password-propietario";
pdfSec.SecuritySettings.UserPassword  = "password-usuario";
pdfSec.SecuritySettings.AllowUserPrinting       = IronPdf.Security.PdfPrintSecurity.FullPrintRights;
pdfSec.SecuritySettings.AllowUserCopyPasteContent = false;
pdfSec.SaveAs("factura_cifrada_ironpdf.pdf");
Imports Aspose.Pdf
Imports IronPdf

' Aspose.PDF: cifrado
Dim docEnc As New Document("factura.pdf")
docEnc.Encrypt("password-usuario", "password-propietario", DocumentPrivilege.ForbidAll, CryptoAlgorithm.AESx256, False)
docEnc.Save("factura_cifrada_aspose.pdf")

' IronPDF: SecuritySettings
Dim pdfSec = PdfDocument.FromFile("factura.pdf")
pdfSec.SecuritySettings.OwnerPassword = "password-propietario"
pdfSec.SecuritySettings.UserPassword = "password-usuario"
pdfSec.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights
pdfSec.SecuritySettings.AllowUserCopyPasteContent = False
pdfSec.SaveAs("factura_cifrada_ironpdf.pdf")
$vbLabelText   $csharpLabel

Proceso de migración: pasos prácticos

Auditoría de uso de Aspose.PDF en el proyecto

# Identificar todas las referencias a Aspose.PDF en el proyecto
Select-String -Path "**/*.cs" -Pattern "using Aspose\.Pdf" -Recurse
Select-String -Path "**/*.cs" -Pattern "HtmlLoadOptions|TextFragment|PdfFileEditor" -Recurse
Select-String -Path "**/*.cs" -Pattern "Aspose\.Pdf\.License" -Recurse

Actualización de paquetes NuGet

# En Package Manager Console de Visual Studio
Uninstall-Package Aspose.PDF
Install-Package IronPdf

Tabla de equivalencias para la migración

Aspose.PDF IronPDF Notas
new Document() + Pages.Add() ChromePdfRenderer.RenderHtmlAsPdf() Cambio de paradigma: HTML-first
HtmlLoadOptions ChromePdfRenderer Motor Chromium vs Flying Saucer
TextFragment + posición manual HTML/CSS en plantilla CSS más mantenible
PdfFileEditor.Concatenate() PdfDocument.Merge() API estática más limpia
TextFragmentAbsorber pdf.ExtractAllText() Extracción directa
doc.Pages[1] (1-indexed) pdf.Pages[0] (0-indexed) Diferencia crítica
PKCS12 + PdfFileSignature PdfSignature(X509Certificate2) API más directa para FNMT
Convert(PdfFormat.PDF_A_3B) SaveAsPdfA(PdfAVersions.PdfA3B) + EmbedFile() para XML Facturae
license.SetLicense(".lic") License.LicenseKey = "..." Clave por código / variable entorno

Rendimiento para volúmenes SII

El SII obliga a comunicar el detalle de facturas en tiempo real. Para el ISV que sirve a clientes con obligación SII, el pipeline de generación PDF debe procesar altos volúmenes sin cuellos de botella. IronPDF permite reutilizar el renderer para minimizar la sobrecarga de inicialización del motor Chromium:

// Patrón de alto rendimiento para generación masiva (SII / Crea y Crece)
public class GeneradorFacturasVeriFactu
{
    // Instancia compartida — inicialización única del motor Chromium
    private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer
    {
        RenderingOptions = new ChromePdfRenderOptions
        {
            PaperSize        = IronPdf.Rendering.PdfPaperSize.A4,
            EnableJavaScript = false,
            Timeout          = 8000
        }
    };

    public async Task<byte[]> GenerarPdfAsync(DatosFacturaVeriFactu datos)
    {
        string html = await _plantillaService.RenderizarHtmlAsync(datos);
        using var pdf = _renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
}
// Patrón de alto rendimiento para generación masiva (SII / Crea y Crece)
public class GeneradorFacturasVeriFactu
{
    // Instancia compartida — inicialización única del motor Chromium
    private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer
    {
        RenderingOptions = new ChromePdfRenderOptions
        {
            PaperSize        = IronPdf.Rendering.PdfPaperSize.A4,
            EnableJavaScript = false,
            Timeout          = 8000
        }
    };

    public async Task<byte[]> GenerarPdfAsync(DatosFacturaVeriFactu datos)
    {
        string html = await _plantillaService.RenderizarHtmlAsync(datos);
        using var pdf = _renderer.RenderHtmlAsPdf(html);
        return pdf.BinaryData;
    }
}
Imports System.Threading.Tasks
Imports IronPdf

' Patrón de alto rendimiento para generación masiva (SII / Crea y Crece)
Public Class GeneradorFacturasVeriFactu
    ' Instancia compartida — inicialización única del motor Chromium
    Private Shared ReadOnly _renderer As New ChromePdfRenderer With {
        .RenderingOptions = New ChromePdfRenderOptions With {
            .PaperSize = IronPdf.Rendering.PdfPaperSize.A4,
            .EnableJavaScript = False,
            .Timeout = 8000
        }
    }

    Public Async Function GenerarPdfAsync(datos As DatosFacturaVeriFactu) As Task(Of Byte())
        Dim html As String = Await _plantillaService.RenderizarHtmlAsync(datos)
        Using pdf = _renderer.RenderHtmlAsPdf(html)
            Return pdf.BinaryData
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

Recursos para el mercado español

Inicia tu evaluación técnica con acceso completo durante 30 días para validar la migración en tu arquitectura de facturación.

Por favor notaAspose es una marca registrada de sus respectivos propietarios. Este sitio no está afiliado, respaldado ni patrocinado por Aspose. Todos los nombres de producto, logotipos y marcas son propiedad de sus respectivos dueños. Las comparaciones son a título informativo. IronPDF es un componente que se integra dentro de sistemas de facturación; no es en sí mismo un sistema de facturación certificado bajo VeriFactu.

Preguntas Frecuentes

¿Por qué los ISVs españoles migran de Aspose.PDF a IronPDF bajo VeriFactu?

El calendario VeriFactu (RDL 15/2025) con fechas límite en 2027 obliga a los ISVs a revisar su stack de generación de PDF. Los motivadores principales son: el motor Chromium de IronPDF renderiza plantillas HTML modernas con CSS3/Flexbox/Grid (Flying Saucer de Aspose no soporta estos), y el modelo de licencia perpetua de IronPDF simplifica la planificación financiera frente a la suscripción anual de Aspose.

¿IronPDF es un sistema de facturación certificado VeriFactu?

No. IronPDF es un componente que se integra dentro del software de facturación del ISV. La certificación VeriFactu es responsabilidad del sistema de facturación completo.

¿Cuál es la diferencia de indexación de páginas entre Aspose.PDF e IronPDF?

Aspose.PDF usa indexación 1-based para páginas (Page(1) = primera página). IronPDF usa indexación 0-based (Pages[0] = primera página). Este cambio debe aplicarse sistemáticamente al migrar código que manipule páginas individuales.

¿IronPDF soporta firma PAdES con certificados FNMT para TicketBAI?

Sí. IronPDF proporciona PdfSignature con soporte para X509Certificate2, compatible con certificados FNMT y otras CAs acreditadas bajo eIDAS. La firma PAdES resultante es válida para TicketBAI en Bizkaia (BATUZ), Gipuzkoa y Araba.

¿Cómo genera IronPDF el formato PDF/A-3 para Facturae y FACe?

IronPDF incluye SaveAsPdfA() con soporte para PDF/A-3B y EmbedFile() para adjuntar el XML Facturae 3.2.2 como adjunto conforme. Este formato es el requerido para envíos a FACe (B2G) y archivado bajo Crea y Crece (EN 16931/CIUS-ES).

¿Cómo gestiona IronPDF el cifrado para cumplimiento LOPDGDD?

IronPDF incluye SecuritySettings con encriptación AES-256. Los documentos fiscales con datos personales (DNI/NIF del receptor) quedan protegidos conforme a los requisitos de seguridad de la LOPDGDD supervisados por la AEPD.

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

Equipo de soporte de Iron

Estamos disponibles online las 24 horas, 5 días a la semana.
Chat
Email
Llámame