Migrar de RawPrint a IronPDF: Generación Completa VeriFactu, TicketBAI y LOPDGDD en .NET
La migración de RawPrint a IronPDF transforma su flujo de trabajo documental de una transmisión de bytes de impresora de bajo nivel a una solución completa de creación e impresión de PDF. Para los ISVs y desarrolladores españoles que necesitan generar facturas VeriFactu, documentos Facturae para FACe o PDFs conformes con TicketBAI, RawPrint no es una opción viable: solo envía bytes a impresoras, no puede generar PDFs conformes con los requisitos del Real Decreto-Ley 15/2025. Esta guía proporciona una ruta de migración completa, paso a paso, que le permite crear, manipular e imprimir PDF con API de alto nivel en lugar de la gestión manual de la impresora.
Por qué migrar de RawPrint a IronPDF
Entender RawPrint
RawPrint es una colección de implementaciones que permiten enviar datos sin procesar directamente a una impresora. Es esencial para las aplicaciones que requieren la transmisión directa de comandos a las impresoras, evitando los controladores de impresora convencionales. Esta funcionalidad es especialmente útil en escenarios en los que se emplean impresoras especializadas, como creadores de etiquetas que utilizan ZPL (Zebra Programming Language) o EPL (Eltron Programming Language).
Uno de los puntos fuertes de RawPrint es su sencillez a la hora de enviar flujos de datos directamente a una impresora. Para los desarrolladores que se dirijan a entornos específicos de Windows y necesiten una comunicación directa con la impresora, RawPrint ofrece una vía eficaz que evita capas intermedias como controladores o interfaces gráficas.
Sin embargo, RawPrint NO es una biblioteca PDF, sólo envía datos a las impresoras. Esta limitación fundamental lo convierte en la elección equivocada para la mayoría de los escenarios de generación de documentos, y en particular para los flujos de cumplimiento regulatorio español.
El problema principal: no hay creación de PDF
RawPrint tiene notables limitaciones que lo hacen inadecuado para los flujos de trabajo documentales modernos:
-
No hay creación de PDF: RawPrint se centra únicamente en la transmisión de datos y carece de funcionalidad para la creación, representación o manipulación de PDF.
-
Nivel muy bajo: al tratar directamente con bytes sin procesar, los desarrolladores deben tener un conocimiento profundo del lenguaje de comandos de la impresora, lo que la hace menos adecuada para tareas sencillas de impresión de documentos.
-
Específico de la plataforma: depende de los administradores de impresión de Windows, lo que limita su aplicabilidad multiplataforma.
-
Sin procesamiento de documentos: solo transmisión de bytes sin capacidades de renderizado.
- Control limitado: opciones mínimas de configuración de trabajos de impresión.
Comparación entre RawPrint e IronPDF
| Característica | RawPrint | IronPDF |
|---|---|---|
| Funcionalidad | Envía datos de impresión sin procesar directamente a la impresora | Creación y manipulación integral de PDF |
| Caso práctico | Impresión especializada, como etiquetas | Gestión y creación general de documentos |
| Dependencia de la plataforma | Específico de Windows | Plataforma cruzada |
| Complejidad | Bajo nivel, requiere conocimientos de comandos de impresora | API de alto nivel y fácil de usar |
| Creación de PDF | No | Sí |
| Crear PDF a partir de HTML | No | Sí |
| Crear PDF a partir de URL | No | Sí |
| Editar/Modificar PDF | No | Sí |
| Fusionar/Dividir PDF | No | Sí |
| Imprimir PDF existente | Sí (bytes brutos) | Sí (API de alto nivel) |
| Control de impresión | Básico | Opciones completas |
| Ideal para | Necesidades de acceso directo a la impresora | Tareas relacionadas con PDF en aplicaciones web y de escritorio |
| Flexibilidad | Limitado debido al manejo de bytes sin procesar | Extensa con múltiples funcionalidades |
A diferencia de RawPrint, IronPDF ofrece una API robusta y versátil para manejar PDFs de forma integral. IronPDF, un nombre consolidado en el entorno .NET, permite a los desarrolladores crear, editar y convertir archivos PDF sin esfuerzo en todas las plataformas.
Para los equipos que planean la adopción de .NET 10 y C# 14 hasta 2025 y 2026, IronPDF proporciona una compatibilidad entre plataformas que RawPrint no puede ofrecer.
Contexto regulatorio español: por qué RawPrint no es viable para VeriFactu
La normativa española de facturación electrónica requiere capacidades que van mucho más allá de la transmisión de bytes a impresoras:
VeriFactu (Real Decreto-Ley 15/2025): los sistemas de facturación deben generar representaciones gráficas de facturas que incluyan la leyenda VERI*FACTU o Factura verificable en la sede electrónica de la AEAT, junto con el QR de la AEAT. RawPrint no puede generar PDFs con estos elementos; solo puede enviar bytes a una impresora. La penalización para proveedores no conformes asciende a 150.000 €/año.
TicketBAI (Bizkaia, Gipuzkoa, Araba): la generación de facturas TicketBAI requiere PDFs con firma XAdES incrustada y QR específico por territorio histórico. RawPrint no soporta firmas digitales ni generación de QR en PDFs. IronPDF incluye ambas capacidades en el mismo paquete.
Facturae XML / FACe: para el sector público, los PDFs que acompañan a los XML Facturae requieren composición precisa con CSS moderno. RawPrint no puede generar este tipo de documentos.
Solución con IronPDF: el flujo completo de generación de factura VeriFactu, desde el HTML hasta el PDF con leyenda y QR, se realiza en pocas líneas de C#:
using IronPdf;
// Generar factura con leyenda VERI*FACTU en IronPDF
// (imposible con RawPrint — solo envía bytes a impresoras)
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; }
.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</strong> Nº 2026-0101</div>
<div>Fecha: 20/05/2026</div>
</div>
<table>
<tr><th>Concepto</th><th>Cantidad</th><th>Precio</th><th>Total</th></tr>
<tr><td>Servicio técnico</td><td>5 h</td><td>70,00 €</td><td>350,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 placeholder]
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
// Guardar e imprimir en un solo flujo
pdf.SaveAs("factura-verifactu-2026-0101.pdf");
pdf.Print("HP LaserJet"); // También puede imprimir directamente
using IronPdf;
// Generar factura con leyenda VERI*FACTU en IronPDF
// (imposible con RawPrint — solo envía bytes a impresoras)
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; }
.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</strong> Nº 2026-0101</div>
<div>Fecha: 20/05/2026</div>
</div>
<table>
<tr><th>Concepto</th><th>Cantidad</th><th>Precio</th><th>Total</th></tr>
<tr><td>Servicio técnico</td><td>5 h</td><td>70,00 €</td><td>350,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 placeholder]
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
// Guardar e imprimir en un solo flujo
pdf.SaveAs("factura-verifactu-2026-0101.pdf");
pdf.Print("HP LaserJet"); // También puede imprimir directamente
Imports IronPdf
' Generar factura con leyenda VERI*FACTU en IronPDF
' (imposible con RawPrint — solo envía bytes a impresoras)
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; }
.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</strong> Nº 2026-0101</div>
<div>Fecha: 20/05/2026</div>
</div>
<table>
<tr><th>Concepto</th><th>Cantidad</th><th>Precio</th><th>Total</th></tr>
<tr><td>Servicio técnico</td><td>5 h</td><td>70,00 €</td><td>350,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 placeholder]
</div>
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
' Guardar e imprimir en un solo flujo
pdf.SaveAs("factura-verifactu-2026-0101.pdf")
pdf.Print("HP LaserJet") ' También puede imprimir directamente
Antes de empezar
Prerrequisitos
- Entorno .NET: .NET Framework 4.6.2+ o .NET Core 3.1+ / .NET 5/6/7/8/9+
- Acceso a NuGet: Capacidad para instalar paquetes NuGet
- Licencia de IronPDF: Obtenga su clave de licencia en IronPDF
Cambios en el paquete NuGet
# Remove RawPrint
dotnet remove package RawPrint
# Install IronPDF
dotnet add package IronPdf
# Remove RawPrint
dotnet remove package RawPrint
# Install IronPDF
dotnet add package IronPdf
Configuración de licencias
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Buscar el uso de RawPrint
# Identify all RawPrint usage
grep -r "using RawPrint" --include="*.cs" .
grep -r "Printer\|SendBytesToPrinter" --include="*.cs" .
# Identify all RawPrint usage
grep -r "using RawPrint" --include="*.cs" .
grep -r "Printer\|SendBytesToPrinter" --include="*.cs" .
Referencia completa de la API
Cambios en el espacio de nombres
// Before: RawPrint (Windows interop)
using System.Runtime.InteropServices;
using System.Drawing.Printing;
// After: IronPDF
using IronPdf;
// Before: RawPrint (Windows interop)
using System.Runtime.InteropServices;
using System.Drawing.Printing;
// After: IronPDF
using IronPdf;
' Before: RawPrint (Windows interop)
Imports System.Runtime.InteropServices
Imports System.Drawing.Printing
' After: IronPDF
Imports IronPdf
Mapeos de API principales
| RawPrint | IronPDF | Notas |
|---|---|---|
Printer.SendBytesToPrinter() |
pdf.Print() |
Impresión de alto nivel |
Printer.OpenPrinter() |
N/A | No es necesario |
Printer.ClosePrinter() |
N/A | Automático |
Printer.StartDocPrinter() |
N/A | Automático |
Printer.WritePrinter() |
N/A | Automático |
Printer.EndDocPrinter() |
N/A | Automático |
| N/A | ChromePdfRenderer |
Creación de PDF |
| N/A | PdfDocument.Merge() |
Fusionar PDF |
| N/A | pdf.ApplyWatermark() |
Añadir marcas de agua |
Ejemplos de migración de código
Ejemplo 1: Conversión de HTML a PDF
Antes (RawPrint):
// NuGet: Install-Package System.Drawing.Common
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Text;
class RawPrinterHelper
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)] public string pDocName;
[MarshalAs(UnmanagedType.LPStr)] public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)] public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
dwCount = szString.Length;
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
IntPtr hPrinter;
if (OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero))
{
DOCINFOA di = new DOCINFOA();
di.pDocName = "HTML Document";
di.pDataType = "RAW";
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
Int32 dwWritten;
WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
return false;
}
}
class Program
{
static void Main()
{
string html = "<html><body><h1>Hello World</h1></body></html>";
// RawPrint cannot directly convert HTML to PDF
// It sends raw data to printer, no PDF generation capability
RawPrinterHelper.SendStringToPrinter("Microsoft Print to PDF", html);
}
}
// NuGet: Install-Package System.Drawing.Common
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Text;
class RawPrinterHelper
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)] public string pDocName;
[MarshalAs(UnmanagedType.LPStr)] public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)] public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
dwCount = szString.Length;
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
IntPtr hPrinter;
if (OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero))
{
DOCINFOA di = new DOCINFOA();
di.pDocName = "HTML Document";
di.pDataType = "RAW";
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
Int32 dwWritten;
WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
return false;
}
}
class Program
{
static void Main()
{
string html = "<html><body><h1>Hello World</h1></body></html>";
// RawPrint cannot directly convert HTML to PDF
// It sends raw data to printer, no PDF generation capability
RawPrinterHelper.SendStringToPrinter("Microsoft Print to PDF", html);
}
}
Imports System
Imports System.Drawing
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Imports System.Text
Class RawPrinterHelper
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)>
Public Class DOCINFOA
<MarshalAs(UnmanagedType.LPStr)> Public pDocName As String
<MarshalAs(UnmanagedType.LPStr)> Public pOutputFile As String
<MarshalAs(UnmanagedType.LPStr)> Public pDataType As String
End Class
<DllImport("winspool.Drv", EntryPoint:="OpenPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function OpenPrinter(<MarshalAs(UnmanagedType.LPStr)> szPrinter As String, ByRef hPrinter As IntPtr, pd As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function ClosePrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function StartDocPrinter(hPrinter As IntPtr, level As Integer, <[In], MarshalAs(UnmanagedType.LPStruct)> di As DOCINFOA) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function EndDocPrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function StartPagePrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function EndPagePrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="WritePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function WritePrinter(hPrinter As IntPtr, pBytes As IntPtr, dwCount As Integer, ByRef dwWritten As Integer) As Boolean
End Function
Public Shared Function SendStringToPrinter(szPrinterName As String, szString As String) As Boolean
Dim pBytes As IntPtr
Dim dwCount As Integer
dwCount = szString.Length
pBytes = Marshal.StringToCoTaskMemAnsi(szString)
Dim hPrinter As IntPtr
If OpenPrinter(szPrinterName, hPrinter, IntPtr.Zero) Then
Dim di As New DOCINFOA()
di.pDocName = "HTML Document"
di.pDataType = "RAW"
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
Dim dwWritten As Integer
WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
Marshal.FreeCoTaskMem(pBytes)
Return True
End If
Return False
End Function
End Class
Class Program
Shared Sub Main()
Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
' RawPrint cannot directly convert HTML to PDF
' It sends raw data to printer, no PDF generation capability
RawPrinterHelper.SendStringToPrinter("Microsoft Print to PDF", html)
End Sub
End Class
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End Class
Este ejemplo demuestra la diferencia arquitectónica fundamental. RawPrint requiere más de 60 líneas de código con múltiples importaciones de DLL desde winspool.Drv, administración manual del controlador de impresora (OpenPrinter, StartDocPrinter, WritePrinter, EndDocPrinter, ClosePrinter) y almacenamiento en memoria, y aún así no puede crear un PDF. Solo envía datos sin procesar a la impresora, sin capacidad de renderizado.
IronPDF realiza la tarea en 5 líneas: crea un ChromePdfRenderer, llama a RenderHtmlAsPdf() y SaveAs(). Consulte la documentación HTML a PDF para ver ejemplos completos.
Ejemplo 2: Conversión de URL a PDF
Antes (RawPrint):
// NuGet: Install-Package System.Drawing.Common
using System;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
class RawPrinterHelper
{
// ... (same DLL imports as above) ...
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes = Marshal.StringToCoTaskMemAnsi(szString);
IntPtr hPrinter;
if (OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero))
{
DOCINFOA di = new DOCINFOA();
di.pDocName = "Web Page";
di.pDataType = "RAW";
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
Int32 dwWritten;
WritePrinter(hPrinter, pBytes, szString.Length, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
return false;
}
}
class Program
{
static void Main()
{
// RawPrint cannot render web pages - only sends raw text/data
// This would just print HTML source code, not rendered content
using (WebClient client = new WebClient())
{
string htmlSource = client.DownloadString("https://example.com");
// This prints raw HTML, not a rendered PDF
RawPrinterHelper.SendStringToPrinter("Microsoft Print to PDF", htmlSource);
Console.WriteLine("Raw HTML sent to printer (not rendered)");
}
}
}
// NuGet: Install-Package System.Drawing.Common
using System;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
class RawPrinterHelper
{
// ... (same DLL imports as above) ...
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes = Marshal.StringToCoTaskMemAnsi(szString);
IntPtr hPrinter;
if (OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero))
{
DOCINFOA di = new DOCINFOA();
di.pDocName = "Web Page";
di.pDataType = "RAW";
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
Int32 dwWritten;
WritePrinter(hPrinter, pBytes, szString.Length, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
return false;
}
}
class Program
{
static void Main()
{
// RawPrint cannot render web pages - only sends raw text/data
// This would just print HTML source code, not rendered content
using (WebClient client = new WebClient())
{
string htmlSource = client.DownloadString("https://example.com");
// This prints raw HTML, not a rendered PDF
RawPrinterHelper.SendStringToPrinter("Microsoft Print to PDF", htmlSource);
Console.WriteLine("Raw HTML sent to printer (not rendered)");
}
}
}
' NuGet: Install-Package System.Drawing.Common
Imports System
Imports System.Net
Imports System.Runtime.InteropServices
Imports System.Text
Class RawPrinterHelper
' ... (same DLL imports as above) ...
Public Shared Function SendStringToPrinter(ByVal szPrinterName As String, ByVal szString As String) As Boolean
Dim pBytes As IntPtr = Marshal.StringToCoTaskMemAnsi(szString)
Dim hPrinter As IntPtr
If OpenPrinter(szPrinterName, hPrinter, IntPtr.Zero) Then
Dim di As New DOCINFOA()
di.pDocName = "Web Page"
di.pDataType = "RAW"
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
Dim dwWritten As Integer
WritePrinter(hPrinter, pBytes, szString.Length, dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
Marshal.FreeCoTaskMem(pBytes)
Return True
End If
Return False
End Function
End Class
Class Program
Shared Sub Main()
' RawPrint cannot render web pages - only sends raw text/data
' This would just print HTML source code, not rendered content
Using client As New WebClient()
Dim htmlSource As String = client.DownloadString("https://example.com")
' This prints raw HTML, not a rendered PDF
RawPrinterHelper.SendStringToPrinter("Microsoft Print to PDF", htmlSource)
Console.WriteLine("Raw HTML sent to printer (not rendered)")
End Using
End Sub
End Class
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Render a live website directly to PDF with full CSS, JavaScript, and images
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("Website rendered to PDF successfully");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
// Render a live website directly to PDF with full CSS, JavaScript, and images
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("Website rendered to PDF successfully");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
' Render a live website directly to PDF with full CSS, JavaScript, and images
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
Console.WriteLine("Website rendered to PDF successfully")
End Sub
End Class
RawPrint no puede procesar páginas web, sólo envía texto/datos sin procesar. El método RawPrint descarga el código fuente HTML y lo envía directamente a la impresora, con lo que se imprime código HTML sin procesar, no contenido renderizado. RenderUrlAsPdf() de IronPDF captura la página web completamente renderizada con CSS, JavaScript e imágenes. Más información en nuestros tutoriales.
Ejemplo 3: Formato del documento
Antes (RawPrint):
// NuGet: Install-Package System.Drawing.Common
using System;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Text;
class RawPrinterHelper
{
// ... (same DLL imports) ...
public static bool SendBytesToPrinter(string szPrinterName, byte[] pBytes)
{
IntPtr pUnmanagedBytes = Marshal.AllocCoTaskMem(pBytes.Length);
Marshal.Copy(pBytes, 0, pUnmanagedBytes, pBytes.Length);
IntPtr hPrinter;
if (OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero))
{
DOCINFOA di = new DOCINFOA();
di.pDocName = "Raw Document";
di.pDataType = "RAW";
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
Int32 dwWritten;
WritePrinter(hPrinter, pUnmanagedBytes, pBytes.Length, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return true;
}
return false;
}
}
class Program
{
static void Main()
{
// RawPrint requires manual PCL/PostScript commands for formatting
string pclCommands = "\x1B&l0O\x1B(s0p16.66h8.5v0s0b3T";
string text = "Plain text document - limited formatting";
byte[] data = Encoding.ASCII.GetBytes(pclCommands + text);
RawPrinterHelper.SendBytesToPrinter("HP LaserJet", data);
}
}
// NuGet: Install-Package System.Drawing.Common
using System;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Text;
class RawPrinterHelper
{
// ... (same DLL imports) ...
public static bool SendBytesToPrinter(string szPrinterName, byte[] pBytes)
{
IntPtr pUnmanagedBytes = Marshal.AllocCoTaskMem(pBytes.Length);
Marshal.Copy(pBytes, 0, pUnmanagedBytes, pBytes.Length);
IntPtr hPrinter;
if (OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero))
{
DOCINFOA di = new DOCINFOA();
di.pDocName = "Raw Document";
di.pDataType = "RAW";
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
Int32 dwWritten;
WritePrinter(hPrinter, pUnmanagedBytes, pBytes.Length, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return true;
}
return false;
}
}
class Program
{
static void Main()
{
// RawPrint requires manual PCL/PostScript commands for formatting
string pclCommands = "\x1B&l0O\x1B(s0p16.66h8.5v0s0b3T";
string text = "Plain text document - limited formatting";
byte[] data = Encoding.ASCII.GetBytes(pclCommands + text);
RawPrinterHelper.SendBytesToPrinter("HP LaserJet", data);
}
}
' NuGet: Install-Package System.Drawing.Common
Imports System
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Imports System.Text
Class RawPrinterHelper
' ... (same DLL imports) ...
Public Shared Function SendBytesToPrinter(szPrinterName As String, pBytes As Byte()) As Boolean
Dim pUnmanagedBytes As IntPtr = Marshal.AllocCoTaskMem(pBytes.Length)
Marshal.Copy(pBytes, 0, pUnmanagedBytes, pBytes.Length)
Dim hPrinter As IntPtr
If OpenPrinter(szPrinterName, hPrinter, IntPtr.Zero) Then
Dim di As New DOCINFOA()
di.pDocName = "Raw Document"
di.pDataType = "RAW"
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
Dim dwWritten As Int32
WritePrinter(hPrinter, pUnmanagedBytes, pBytes.Length, dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
Marshal.FreeCoTaskMem(pUnmanagedBytes)
Return True
End If
Return False
End Function
End Class
Class Program
Shared Sub Main()
' RawPrint requires manual PCL/PostScript commands for formatting
Dim pclCommands As String = Chr(&H1B) & "&l0O" & Chr(&H1B) & "(s0p16.66h8.5v0s0b3T"
Dim text As String = "Plain text document - limited formatting"
Dim data As Byte() = Encoding.ASCII.GetBytes(pclCommands & text)
RawPrinterHelper.SendBytesToPrinter("HP LaserJet", data)
End Sub
End Class
Después (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = @"
<html>
<head>
<style>
body { font-family: Arial; margin: 40px; }
h1 { color: #2c3e50; font-size: 24px; }
p { line-height: 1.6; color: #34495e; }
.highlight { background-color: yellow; font-weight: bold; }
</style>
</head>
<body>
<h1>Formatted Document</h1>
<p>This is a <span class='highlight'>beautifully formatted</span> document with CSS styling.</p>
<p>Complex layouts, fonts, colors, and images are fully supported.</p>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("formatted.pdf");
Console.WriteLine("Formatted PDF created successfully");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = @"
<html>
<head>
<style>
body { font-family: Arial; margin: 40px; }
h1 { color: #2c3e50; font-size: 24px; }
p { line-height: 1.6; color: #34495e; }
.highlight { background-color: yellow; font-weight: bold; }
</style>
</head>
<body>
<h1>Formatted Document</h1>
<p>This is a <span class='highlight'>beautifully formatted</span> document with CSS styling.</p>
<p>Complex layouts, fonts, colors, and images are fully supported.</p>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("formatted.pdf");
Console.WriteLine("Formatted PDF created successfully");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html As String = "
<html>
<head>
<style>
body { font-family: Arial; margin: 40px; }
h1 { color: #2c3e50; font-size: 24px; }
p { line-height: 1.6; color: #34495e; }
.highlight { background-color: yellow; font-weight: bold; }
</style>
</head>
<body>
<h1>Formatted Document</h1>
<p>This is a <span class='highlight'>beautifully formatted</span> document with CSS styling.</p>
<p>Complex layouts, fonts, colors, and images are fully supported.</p>
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("formatted.pdf")
Console.WriteLine("Formatted PDF created successfully")
End Sub
End Class
RawPrint requiere comandos PCL/PostScript manuales ("\x1B&l0O\x1B(s0p16.66h8.5v0s0b3T") incluso para el formato básico. Los desarrolladores deben conocer en profundidad el lenguaje de comandos de la impresora. IronPDF utiliza HTML y CSS estándar para el formateo: los diseños, fuentes, colores e imágenes complejos son totalmente compatibles sin necesidad de conocimientos específicos de impresión.
Resumen comparativo de características
| Característica | RawPrint | IronPDF |
|---|---|---|
| HTML a PDF | No | Sí |
| URL a PDF | No | Sí |
| Crear desde cero | No | Sí |
| Fusionar PDF | No | Sí |
| Dividir PDF | No | Sí |
| Añadir marcas de agua | No | Sí |
| Editar existente | No | Sí |
| Imprimir PDF | Sí (en bruto) | Sí (alto nivel) |
| Imprimir diálogo | No | Sí |
| Múltiples copias | Limitado | Sí |
| Control de PPP | No | Sí |
| Dúplex | No | Sí |
| Windows | Sí | Sí |
| Linux | No | Sí |
| macOS | No | Sí |
| Docker | No | Sí |
| Seguridad | No | Sí |
| Firmas digitales | No | Sí |
| PDF/A | No | Sí |
Nuevas capacidades tras la migración
Tras migrar a IronPDF, obtendrá funciones que RawPrint no puede ofrecer:
Fusión de PDF
var pdfs = pdfFiles.Select(f => PdfDocument.FromFile(f)).ToList();
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs("complete.pdf");
var pdfs = pdfFiles.Select(f => PdfDocument.FromFile(f)).ToList();
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs("complete.pdf");
Dim pdfs = pdfFiles.Select(Function(f) PdfDocument.FromFile(f)).ToList()
Dim merged = PdfDocument.Merge(pdfs)
merged.SaveAs("complete.pdf")
Imprimir con ajustes
var pdf = PdfDocument.FromFile("report.pdf");
pdf.Print(new PrintOptions
{
PrinterName = "HP LaserJet",
NumberOfCopies = 2,
DPI = 300,
GrayScale = false
});
var pdf = PdfDocument.FromFile("report.pdf");
pdf.Print(new PrintOptions
{
PrinterName = "HP LaserJet",
NumberOfCopies = 2,
DPI = 300,
GrayScale = false
});
Dim pdf = PdfDocument.FromFile("report.pdf")
pdf.Print(New PrintOptions With {
.PrinterName = "HP LaserJet",
.NumberOfCopies = 2,
.DPI = 300,
.GrayScale = False
})
Crear e imprimir en un solo flujo de trabajo
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(@"
<h1>Invoice #12345</h1>
<p>Customer: John Doe</p>
<p>Amount: $150.00</p>
");
// Print directly
pdf.Print("HP LaserJet");
// Or save first
pdf.SaveAs("invoice.pdf");
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(@"
<h1>Invoice #12345</h1>
<p>Customer: John Doe</p>
<p>Amount: $150.00</p>
");
// Print directly
pdf.Print("HP LaserJet");
// Or save first
pdf.SaveAs("invoice.pdf");
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("
<h1>Invoice #12345</h1>
<p>Customer: John Doe</p>
<p>Amount: $150.00</p>
")
' Print directly
pdf.Print("HP LaserJet")
' Or save first
pdf.SaveAs("invoice.pdf")
Lista de comprobación de la migración
Pre-Migración
- Identificar todo el uso de RawPrint (
SendBytesToPrinter,OpenPrinter, etc.) - Nombres de impresoras de documentos utilizados en su aplicación
- Tenga en cuenta cualquier código de creación de PDF externo que se pueda consolidar
- Obtenga la clave de licencia de IronPDF en IronPDF
- Si el software gestiona facturación española: planificar integración de leyenda
VERI*FACTUoFactura verificable en la sede electrónica de la AEATcon QR de la AEAT (requerido por RDL 15/2025)
Actualizaciones de código
- Eliminar el paquete RawPrint:
dotnet remove package RawPrint - Instalar el paquete IronPDF:
dotnet add package IronPdf - Reemplace la impresión sin procesar con
pdf.Print() - Eliminar la gestión manual de identificadores (
OpenPrinter,ClosePrinter, etc.) - Consolide la creación e impresión de PDF en un único flujo de trabajo
- Agregar inicialización de licencia al iniciar la aplicación
Pruebas
- Prueba de impresión en impresoras de destino
- Verificar la calidad de impresión
- Probar varias copias
- Prueba de impresión silenciosa
- Verificación multiplataforma si es necesario
- Para facturación española: verificar que la leyenda VERI*FACTU, el QR de la AEAT y los datos de TicketBAI (Bizkaia, Gipuzkoa, Araba) se renderizan correctamente en el PDF impreso
Preguntas Frecuentes
¿Por qué RawPrint no sirve para cumplir con VeriFactu?
RawPrint solo transmite bytes crudos a impresoras mediante winspool.Drv: no puede generar PDFs, no puede incluir la leyenda VERI*FACTU, no puede añadir el QR de la AEAT ni firmar documentos. El Real Decreto-Ley 15/2025 exige que el software de facturación genere estos elementos activamente. Las sanciones para software incumplidor alcanzan 150.000 €/año.
¿Puede IronPDF generar facturas con TicketBAI para Bizkaia, Gipuzkoa y Araba?
Sí. IronPDF incluye firmas digitales XAdES requeridas por TicketBAI en los tres territorios históricos vascos. RawPrint no tiene ninguna capacidad de firma digital ni de generación de PDF.
¿Cómo cumple IronPDF con la LOPDGDD al procesar facturas?
IronPDF genera PDFs localmente sin enviar datos a servidores externos. Los datos de NIF/CIF, importes y datos de clientes permanecen en su infraestructura, bajo supervisión de la AEPD. RawPrint, al limitarse a la transmisión de bytes por la red de impresión, puede exponer datos en tránsito.
¿Qué es Facturae y cómo lo soporta IronPDF?
Facturae es el formato XML de factura electrónica estándar en España para FACe (plataforma de facturas del sector público). IronPDF genera PDF/A-3 con Facturae XML embebido, cubriendo los requisitos de la Ley Crea y Crece para factura electrónica B2B a partir de 2027.
¿Puede IronPDF realizar la impresión silenciosa que hace RawPrint?
Sí. IronPDF incluye capacidades de impresión de alto nivel (pdf.Print()) que reemplazan la impresión silenciosa de RawPrint, pero además permiten generar el PDF previamente con leyenda VERI*FACTU, firma digital y formato correcto. Es posible generar e imprimir en un único flujo de trabajo desde C#.

