Generador de informes ASP.NET para España: VeriFactu, TicketBAI y FACe con IronPDF
Generador de informes ASP.NET para España: VeriFactu, TicketBAI y FACe con IronPDF
Los desarrolladores .NET en España tienen un requisito que sus homólogos del resto de Europa no comparten en la misma escala: los informes generados por sus aplicaciones ASP.NET Core no son solo documentos de negocio — son facturas sujetas a VeriFactu, albaranes relacionados con TicketBAI, o documentos B2G para FACe que deben cumplir Facturae 3.2.2. ASP.NET Core con IronPDF es la combinación técnica más directa para generar esos informes con texto seleccionable real, código QR AEAT verificable, leyenda VERI*FACTU, y las capacidades de firma PAdES necesarias para el archivado conforme a LOPDGDD y eIDAS.
Esta guía cubre el flujo completo: desde la configuración del proyecto hasta la generación de informes PDF conformes con los requisitos del ecosistema de facturación electrónica español.
Índice del tutorial
- Crear una aplicación ASP.NET Core en Visual Studio
- Instalar IronPDF desde NuGet
- Diseñar el informe como documento HTML con elementos de cumplimiento español
- Generar el PDF con IronPDF: código QR AEAT, leyenda VERI*FACTU, firma PAdES
- Casos de uso avanzados: TicketBAI (Bizkaia, Gipuzkoa, Araba) y FACe
Contexto: por qué la generación de informes PDF tiene peso regulatorio en España
VeriFactu: los informes de facturación son territorio normativo
VeriFactu (sistema de verificación de facturas de la AEAT) requiere que los sistemas de facturación generen registros de facturación encadenados con huella (huella encadenada) y que los PDFs de facturas incluyan un código QR verificable que enlace a la sede electrónica de la AEAT. La leyenda obligatoria VERI*FACTU (con asterisco) o Factura verificable en la sede electrónica de la AEAT debe aparecer en la visualización de cada factura que haya pasado el proceso de registro.
La obligación de cumplimiento para proveedores de software de facturación entra en vigor el 1 de enero de 2027 (impuesto sobre sociedades) y el 1 de julio de 2027 (demás contribuyentes) según el Real Decreto-ley 15/2025. Los ISVs que desarrollan software de facturación ya deben tener productos conformes.
Importante: IronPDF es un componente de generación de PDF para usar DENTRO del software de facturación certificado. No es en sí mismo un sistema de facturación certificado por la AEAT.
TicketBAI: los informes de facturas del País Vasco requieren firma XAdES
TicketBAI está en vigor en el País Vasco. Cada factura debe estar firmada con XAdES y enviada a la hacienda foral correspondiente. Las tres diputaciones forales tienen implementaciones con diferencias específicas:
- Bizkaia (
bizkaia.eus): también gestiona BATUZ - Gipuzkoa (
gipuzkoa.eus) - Araba (
araba.eus)
Los desarrolladores que generen informes de facturas para clientes del País Vasco deben contemplar las tres variantes forales en su implementación ASP.NET Core.
Facturae y FACe: los informes B2G requieren formato estructurado
Para la Administración Pública española, los informes de facturación se envían a través de FACe (Punto General de Entrada de Facturas de la Administración del Estado) en formato Facturae XML 3.2.2, normalmente embebido en un PDF/A-3. IronPDF facilita la generación del contenedor PDF/A con el fichero XML adjunto.
Paso 1: Crear una aplicación ASP.NET Core en Visual Studio
Cree un nuevo proyecto ASP.NET Core. Seleccione la plantilla que corresponda a su arquitectura: Web API, MVC o Blazor Server son las opciones más habituales para aplicaciones de generación de informes de facturación.

Configure el nombre y la ubicación del proyecto.

Seleccione .NET 8 LTS (recomendado para proyectos de producción en 2026) o .NET 9+.


Paso 2: Instalar IronPDF desde NuGet
Instale IronPDF a través del administrador de paquetes de Visual Studio:

O desde la Galería NuGet:

dotnet add package IronPdf
dotnet add package IronPdf
Paso 3: Diseñar el informe como documento HTML con elementos de cumplimiento español
Los informes de facturación conformes con VeriFactu deben incluir en su estructura HTML:
- La leyenda
VERI*FACTU(con asterisco, preservada verbatim) - El código QR que enlaza al endpoint de verificación de la AEAT
- El texto
Factura verificable en la sede electrónica de la AEAT
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<style>
body { font-family: Arial, sans-serif; font-size: 10pt; }
.factura-header { display: flex; justify-content: space-between; align-items: flex-start; }
.datos-emisor { flex: 2; }
.verifactu-block { flex: 1; text-align: right; }
.verifactu-legend { font-weight: bold; font-size: 9pt; color: #000; }
.qr-aeat { width: 80px; height: 80px; display: block; margin-left: auto; }
.tabla-lineas { width: 100%; border-collapse: collapse; margin-top: 20px; }
.tabla-lineas th, .tabla-lineas td { border: 1px solid #ccc; padding: 4px 8px; }
.totales { text-align: right; margin-top: 10px; }
.pie-factura { margin-top: 30px; font-size: 8pt; color: #555; }
</style>
</head>
<body>
<div class="factura-header">
<div class="datos-emisor">
<h2>Mi Empresa S.L.</h2>
<p>NIF: B12345678<br>
Calle Ejemplo, 1 — 28001 Madrid<br>
facturacion@miempresa.com</p>
</div>
<div class="verifactu-block">
<img class="qr-aeat" src="data:image/png;base64,@Model.QrAeatBase64"
alt="Código QR verificación AEAT" />
<p class="verifactu-legend">VERI*FACTU</p>
<p style="font-size:7pt;">Factura verificable en la sede electrónica de la AEAT</p>
</div>
</div>
<hr/>
<table style="width:100%">
<tr>
<td><strong>Factura Nº:</strong> @Model.NumeroFactura</td>
<td><strong>Fecha:</strong> @Model.Fecha.ToString("dd/MM/yyyy")</td>
<td><strong>NIF Destinatario:</strong> @Model.NifDestinatario</td>
</tr>
</table>
<table class="tabla-lineas">
<thead>
<tr><th>Descripción</th><th>Cantidad</th><th>Precio</th><th>IVA</th><th>Total</th></tr>
</thead>
<tbody>
@foreach (var linea in Model.Lineas)
{
<tr>
<td>@linea.Descripcion</td>
<td style="text-align:right">@linea.Cantidad</td>
<td style="text-align:right">@linea.PrecioUnitario.ToString("N2") €</td>
<td style="text-align:right">@linea.TipoIva%</td>
<td style="text-align:right">@linea.Total.ToString("N2") €</td>
</tr>
}
</tbody>
</table>
<div class="totales">
<p><strong>Base imponible:</strong> @Model.BaseImponible.ToString("N2") €</p>
<p><strong>IVA (21%):</strong> @Model.CuotaIva.ToString("N2") €</p>
<p><strong>Total factura:</strong> @Model.TotalFactura.ToString("N2") €</p>
</div>
<div class="pie-factura">
<p>Huella: @Model.HuellaEncadenada | Fecha registro: @Model.FechaRegistro</p>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<style>
body { font-family: Arial, sans-serif; font-size: 10pt; }
.factura-header { display: flex; justify-content: space-between; align-items: flex-start; }
.datos-emisor { flex: 2; }
.verifactu-block { flex: 1; text-align: right; }
.verifactu-legend { font-weight: bold; font-size: 9pt; color: #000; }
.qr-aeat { width: 80px; height: 80px; display: block; margin-left: auto; }
.tabla-lineas { width: 100%; border-collapse: collapse; margin-top: 20px; }
.tabla-lineas th, .tabla-lineas td { border: 1px solid #ccc; padding: 4px 8px; }
.totales { text-align: right; margin-top: 10px; }
.pie-factura { margin-top: 30px; font-size: 8pt; color: #555; }
</style>
</head>
<body>
<div class="factura-header">
<div class="datos-emisor">
<h2>Mi Empresa S.L.</h2>
<p>NIF: B12345678<br>
Calle Ejemplo, 1 — 28001 Madrid<br>
facturacion@miempresa.com</p>
</div>
<div class="verifactu-block">
<img class="qr-aeat" src="data:image/png;base64,@Model.QrAeatBase64"
alt="Código QR verificación AEAT" />
<p class="verifactu-legend">VERI*FACTU</p>
<p style="font-size:7pt;">Factura verificable en la sede electrónica de la AEAT</p>
</div>
</div>
<hr/>
<table style="width:100%">
<tr>
<td><strong>Factura Nº:</strong> @Model.NumeroFactura</td>
<td><strong>Fecha:</strong> @Model.Fecha.ToString("dd/MM/yyyy")</td>
<td><strong>NIF Destinatario:</strong> @Model.NifDestinatario</td>
</tr>
</table>
<table class="tabla-lineas">
<thead>
<tr><th>Descripción</th><th>Cantidad</th><th>Precio</th><th>IVA</th><th>Total</th></tr>
</thead>
<tbody>
@foreach (var linea in Model.Lineas)
{
<tr>
<td>@linea.Descripcion</td>
<td style="text-align:right">@linea.Cantidad</td>
<td style="text-align:right">@linea.PrecioUnitario.ToString("N2") €</td>
<td style="text-align:right">@linea.TipoIva%</td>
<td style="text-align:right">@linea.Total.ToString("N2") €</td>
</tr>
}
</tbody>
</table>
<div class="totales">
<p><strong>Base imponible:</strong> @Model.BaseImponible.ToString("N2") €</p>
<p><strong>IVA (21%):</strong> @Model.CuotaIva.ToString("N2") €</p>
<p><strong>Total factura:</strong> @Model.TotalFactura.ToString("N2") €</p>
</div>
<div class="pie-factura">
<p>Huella: @Model.HuellaEncadenada | Fecha registro: @Model.FechaRegistro</p>
</div>
</body>
</html>
El motor Chromium de IronPDF renderiza correctamente el CSS Flexbox utilizado en el encabezado de la factura. Otros generadores de PDF basados en motores obsoletos (IE) fallan en este tipo de maquetación.
Paso 4: Generar el informe PDF con IronPDF
Generación básica de informe VeriFactu
using IronPdf;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class FacturasController : ControllerBase
{
[HttpGet("generar/{id}")]
public IActionResult GenerarFacturaPdf(int id)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Obtener datos de la factura (incluyendo código QR AEAT en base64)
var modeloFactura = ObtenerModeloFactura(id);
// Renderizar la vista Razor a HTML
var renderer = new ChromePdfRenderer();
// Configurar para facturas A4
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 15;
renderer.RenderingOptions.MarginRight = 15;
// Generar HTML de la factura (en producción, usar Razor View Engine)
string htmlFactura = RenderizarPlantillaFactura(modeloFactura);
var pdf = renderer.RenderHtmlAsPdf(htmlFactura);
// Devolver el PDF directamente al cliente
return File(pdf.BinaryData, "application/pdf",
$"factura_{modeloFactura.NumeroFactura}.pdf");
}
private string RenderizarPlantillaFactura(ModeloFactura modelo)
{
// En una aplicación real, usar IViewRenderService para renderizar Razor Views
// o Razor Pages a HTML string
return $@"<html>...</html>"; // Ver plantilla completa en Paso 3
}
private ModeloFactura ObtenerModeloFactura(int id)
{
// Obtener de base de datos
return new ModeloFactura();
}
}
using IronPdf;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class FacturasController : ControllerBase
{
[HttpGet("generar/{id}")]
public IActionResult GenerarFacturaPdf(int id)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Obtener datos de la factura (incluyendo código QR AEAT en base64)
var modeloFactura = ObtenerModeloFactura(id);
// Renderizar la vista Razor a HTML
var renderer = new ChromePdfRenderer();
// Configurar para facturas A4
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 15;
renderer.RenderingOptions.MarginRight = 15;
// Generar HTML de la factura (en producción, usar Razor View Engine)
string htmlFactura = RenderizarPlantillaFactura(modeloFactura);
var pdf = renderer.RenderHtmlAsPdf(htmlFactura);
// Devolver el PDF directamente al cliente
return File(pdf.BinaryData, "application/pdf",
$"factura_{modeloFactura.NumeroFactura}.pdf");
}
private string RenderizarPlantillaFactura(ModeloFactura modelo)
{
// En una aplicación real, usar IViewRenderService para renderizar Razor Views
// o Razor Pages a HTML string
return $@"<html>...</html>"; // Ver plantilla completa en Paso 3
}
private ModeloFactura ObtenerModeloFactura(int id)
{
// Obtener de base de datos
return new ModeloFactura();
}
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc
<ApiController>
<Route("api/[controller]")>
Public Class FacturasController
Inherits ControllerBase
<HttpGet("generar/{id}")>
Public Function GenerarFacturaPdf(id As Integer) As IActionResult
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
' Obtener datos de la factura (incluyendo código QR AEAT en base64)
Dim modeloFactura = ObtenerModeloFactura(id)
' Renderizar la vista Razor a HTML
Dim renderer = New ChromePdfRenderer()
' Configurar para facturas A4
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
renderer.RenderingOptions.MarginLeft = 15
renderer.RenderingOptions.MarginRight = 15
' Generar HTML de la factura (en producción, usar Razor View Engine)
Dim htmlFactura As String = RenderizarPlantillaFactura(modeloFactura)
Dim pdf = renderer.RenderHtmlAsPdf(htmlFactura)
' Devolver el PDF directamente al cliente
Return File(pdf.BinaryData, "application/pdf", $"factura_{modeloFactura.NumeroFactura}.pdf")
End Function
Private Function RenderizarPlantillaFactura(modelo As ModeloFactura) As String
' En una aplicación real, usar IViewRenderService para renderizar Razor Views
' o Razor Pages a HTML string
Return "<html>...</html>" ' Ver plantilla completa en Paso 3
End Function
Private Function ObtenerModeloFactura(id As Integer) As ModeloFactura
' Obtener de base de datos
Return New ModeloFactura()
End Function
End Class
Explicación del código
ChromePdfRenderer: convierte el HTML de la plantilla de factura a PDF usando el motor Chromium, garantizando texto real seleccionable — esencial para la indexación por sistemas AEAT.RenderingOptions.PaperSize: configura el tamaño A4 estándar para facturas en España.pdf.BinaryData: devuelve el PDF como array de bytes para enviarlo directamente como respuesta HTTP.
Resultado


Paso 5: Casos de uso avanzados para el ecosistema español
Firma PAdES para archivado conforme a LOPDGDD y eIDAS
Las facturas electrónicas deben conservarse con garantías de integridad. La firma PAdES-LTV permite el archivado a largo plazo conforme a eIDAS y LOPDGDD:
using IronPdf;
using IronPdf.Signing;
public class GeneradorFacturasConFirma
{
public byte[] GenerarYFirmarFactura(string htmlFactura, string rutaCertificado, string passwordCert)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlFactura);
// Aplicar firma PAdES con certificado FNMT o equivalente
var firma = new PdfSignature(rutaCertificado, passwordCert)
{
SigningReason = "Factura electrónica — archivado conforme LOPDGDD/eIDAS",
SigningContact = "facturacion@miempresa.com",
SigningLocation = "Madrid, España"
};
pdf.Sign(firma);
return pdf.BinaryData;
}
}
using IronPdf;
using IronPdf.Signing;
public class GeneradorFacturasConFirma
{
public byte[] GenerarYFirmarFactura(string htmlFactura, string rutaCertificado, string passwordCert)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlFactura);
// Aplicar firma PAdES con certificado FNMT o equivalente
var firma = new PdfSignature(rutaCertificado, passwordCert)
{
SigningReason = "Factura electrónica — archivado conforme LOPDGDD/eIDAS",
SigningContact = "facturacion@miempresa.com",
SigningLocation = "Madrid, España"
};
pdf.Sign(firma);
return pdf.BinaryData;
}
}
Imports IronPdf
Imports IronPdf.Signing
Public Class GeneradorFacturasConFirma
Public Function GenerarYFirmarFactura(htmlFactura As String, rutaCertificado As String, passwordCert As String) As Byte()
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlFactura)
' Aplicar firma PAdES con certificado FNMT o equivalente
Dim firma As New PdfSignature(rutaCertificado, passwordCert) With {
.SigningReason = "Factura electrónica — archivado conforme LOPDGDD/eIDAS",
.SigningContact = "facturacion@miempresa.com",
.SigningLocation = "Madrid, España"
}
pdf.Sign(firma)
Return pdf.BinaryData
End Function
End Class
Generación de informe de factura para TicketBAI (País Vasco)
Para clientes del País Vasco, el PDF de la factura se genera después de que el XML TicketBAI haya sido firmado con XAdES y registrado en la hacienda foral correspondiente:
public class GeneradorFacturasTicketBai
{
// Genera el PDF de la factura TicketBAI tras el registro foral
public byte[] GenerarPdfPostRegistro(
string htmlFactura,
string provinciaForal, // "Bizkaia", "Gipuzkoa" o "Araba"
string identificadorTicketBai)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Añadir al HTML el identificador TicketBAI del registro foral
string htmlConTicketBai = htmlFactura
.Replace("{{TBAI_ID}}", identificadorTicketBai)
.Replace("{{PROVINCIA_FORAL}}", provinciaForal);
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlConTicketBai);
// Para TicketBAI, la firma PAdES del PDF es opcional pero recomendada
// La firma obligatoria XAdES ya está en el XML TicketBAI
return pdf.BinaryData;
}
}
public class GeneradorFacturasTicketBai
{
// Genera el PDF de la factura TicketBAI tras el registro foral
public byte[] GenerarPdfPostRegistro(
string htmlFactura,
string provinciaForal, // "Bizkaia", "Gipuzkoa" o "Araba"
string identificadorTicketBai)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Añadir al HTML el identificador TicketBAI del registro foral
string htmlConTicketBai = htmlFactura
.Replace("{{TBAI_ID}}", identificadorTicketBai)
.Replace("{{PROVINCIA_FORAL}}", provinciaForal);
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlConTicketBai);
// Para TicketBAI, la firma PAdES del PDF es opcional pero recomendada
// La firma obligatoria XAdES ya está en el XML TicketBAI
return pdf.BinaryData;
}
}
Public Class GeneradorFacturasTicketBai
' Genera el PDF de la factura TicketBAI tras el registro foral
Public Function GenerarPdfPostRegistro(
htmlFactura As String,
provinciaForal As String, ' "Bizkaia", "Gipuzkoa" o "Araba"
identificadorTicketBai As String) As Byte()
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
' Añadir al HTML el identificador TicketBAI del registro foral
Dim htmlConTicketBai As String = htmlFactura _
.Replace("{{TBAI_ID}}", identificadorTicketBai) _
.Replace("{{PROVINCIA_FORAL}}", provinciaForal)
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlConTicketBai)
' Para TicketBAI, la firma PAdES del PDF es opcional pero recomendada
' La firma obligatoria XAdES ya está en el XML TicketBAI
Return pdf.BinaryData
End Function
End Class
Generación de informe en lote para cierre mensual y SII
El SII (Suministro Inmediato de Información) requiere que las grandes empresas comuniquen sus libros de registro a la AEAT. Los ISVs que generan informes para sistemas SII frecuentemente necesitan procesar lotes de facturas:
public class GeneradorLoteFacturas
{
public async Task<byte[]> GenerarInformeResumenMensual(
List<ModeloFactura> facturas,
int anio, int mes)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdfsIndividuales = new List<PdfDocument>();
foreach (var factura in facturas)
{
string html = RenderizarPlantillaFactura(factura);
var pdfFactura = renderer.RenderHtmlAsPdf(html);
pdfsIndividuales.Add(pdfFactura);
}
// Fusionar todas las facturas del mes en un único PDF
var informeMensual = PdfDocument.Merge(pdfsIndividuales.ToArray());
informeMensual.SaveAs($"informe_sii_{anio}_{mes:D2}.pdf");
return informeMensual.BinaryData;
}
private string RenderizarPlantillaFactura(ModeloFactura modelo)
{
return string.Empty; // Implementación con Razor View Engine
}
}
public class GeneradorLoteFacturas
{
public async Task<byte[]> GenerarInformeResumenMensual(
List<ModeloFactura> facturas,
int anio, int mes)
{
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdfsIndividuales = new List<PdfDocument>();
foreach (var factura in facturas)
{
string html = RenderizarPlantillaFactura(factura);
var pdfFactura = renderer.RenderHtmlAsPdf(html);
pdfsIndividuales.Add(pdfFactura);
}
// Fusionar todas las facturas del mes en un único PDF
var informeMensual = PdfDocument.Merge(pdfsIndividuales.ToArray());
informeMensual.SaveAs($"informe_sii_{anio}_{mes:D2}.pdf");
return informeMensual.BinaryData;
}
private string RenderizarPlantillaFactura(ModeloFactura modelo)
{
return string.Empty; // Implementación con Razor View Engine
}
}
Imports System.Collections.Generic
Imports System.Threading.Tasks
Imports IronPdf
Public Class GeneradorLoteFacturas
Public Async Function GenerarInformeResumenMensual(
facturas As List(Of ModeloFactura),
anio As Integer, mes As Integer) As Task(Of Byte())
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim renderer = New ChromePdfRenderer()
Dim pdfsIndividuales = New List(Of PdfDocument)()
For Each factura In facturas
Dim html As String = RenderizarPlantillaFactura(factura)
Dim pdfFactura = renderer.RenderHtmlAsPdf(html)
pdfsIndividuales.Add(pdfFactura)
Next
' Fusionar todas las facturas del mes en un único PDF
Dim informeMensual = PdfDocument.Merge(pdfsIndividuales.ToArray())
informeMensual.SaveAs($"informe_sii_{anio}_{mes:D2}.pdf")
Return informeMensual.BinaryData
End Function
Private Function RenderizarPlantillaFactura(modelo As ModeloFactura) As String
Return String.Empty ' Implementación con Razor View Engine
End Function
End Class
Configuración de licencia en ASP.NET Core
Coloque la clave de licencia de IronPDF en el fichero appsettings.json de su aplicación:
{
"IronPdf.LicenseKey": "your license key"
}
O configúrela programáticamente en Program.cs:
var builder = WebApplication.CreateBuilder(args);
IronPdf.License.LicenseKey = builder.Configuration["IronPdf:LicenseKey"]
?? throw new InvalidOperationException("IronPDF license key not configured");
var builder = WebApplication.CreateBuilder(args);
IronPdf.License.LicenseKey = builder.Configuration["IronPdf:LicenseKey"]
?? throw new InvalidOperationException("IronPDF license key not configured");
Imports IronPdf
Dim builder = WebApplication.CreateBuilder(args)
IronPdf.License.LicenseKey = If(builder.Configuration("IronPdf:LicenseKey"), Throw New InvalidOperationException("IronPDF license key not configured"))
Puede obtener una clave de prueba gratuita sin necesidad de tarjeta de crédito en la página de licencias de IronPDF.
Herramientas de informes habituales en ASP.NET Core (contexto ecosistema español)
Los generadores de informes de terceros (SSRS, DevExpress Reporting, Syncfusion, Telerik Reporting, GrapeCity ActiveReports, Crystal Reports, Stimulsoft) producen sus salidas en HTML o en formatos propietarios. IronPDF actúa como la capa de generación PDF final que transforma esas salidas en documentos conformes con los requisitos del ecosistema español: texto seleccionable real, capacidad de firma PAdES, y maquetación CSS3 para los elementos de cumplimiento (QR AEAT, leyenda VERI*FACTU).
Al seleccionar la combinación de herramientas para su proyecto, considere:
- SSRS + IronPDF: SSRS genera el HTML del informe, IronPDF lo convierte a PDF con firma
- Razor Views + IronPDF: solución directa para equipos ASP.NET Core — mayor control sobre el HTML de la factura
- DevExpress / Syncfusion + IronPDF: combina el diseñador visual con la generación PDF conforme
Conclusión
ASP.NET Core con IronPDF es la base técnica para sistemas de generación de informes de facturación en España que deben ser conformes con VeriFactu (AEAT QR, leyenda VERI*FACTU, huella encadenada), TicketBAI (firma XAdES foral en Bizkaia, Gipuzkoa y Araba), FACe (Facturae 3.2.2 en PDF/A-3) y el archivado conforme a LOPDGDD y eIDAS (firma PAdES-LTV).
IronPDF aporta el motor de renderizado Chromium que garantiza texto PDF real seleccionable, el soporte CSS3 completo que permite las plantillas de factura modernas, y la API de firma PAdES que integra la cadena de certificados FNMT. Inicie la evaluación técnica con la prueba gratuita de IronPDF.
Preguntas Frecuentes
¿Cómo se genera un informe de factura conforme con VeriFactu en ASP.NET Core?
Se usa ChromePdfRenderer de IronPDF para convertir la plantilla HTML de la factura a PDF. La plantilla debe incluir el código QR AEAT (generado con IronQR), la leyenda VERI*FACTU con asterisco, y el texto 'Factura verificable en la sede electrónica de la AEAT'. El motor Chromium garantiza texto real seleccionable.
¿Cómo se manejan las tres variantes forales de TicketBAI en ASP.NET Core?
Cada factura para el País Vasco se genera tras el registro del XML TicketBAI firmado con XAdES en la hacienda foral correspondiente (bizkaia.eus, gipuzkoa.eus o araba.eus). IronPDF genera el PDF de presentación con el identificador TicketBAI incluido. Para la firma PAdES del PDF, el SigningLocation se configura con la provincia foral.
¿Qué diferencia hay entre generar informes para VeriFactu vs Facturae (FACe)?
Para VeriFactu, el PDF debe incluir QR AEAT y leyenda VERI*FACTU. Para FACe (B2G), el formato es Facturae XML 3.2.2, normalmente embebido en un contenedor PDF/A-3. IronPDF soporta ambos casos: generación de PDFs con elementos VeriFactu y generación de contenedores PDF/A para Facturae.
¿Cómo se firma un informe PDF para archivado conforme a LOPDGDD?
Se usa PdfSignature de IronPDF con un certificado FNMT o equivalente reconocido por la AEAT. La firma PAdES-LTV garantiza la validez a largo plazo del documento archivado, conforme a los requisitos de integridad de LOPDGDD y eIDAS.




