Impresión y salida PDF en aplicaciones empresariales Windows — cómo elegir System.Drawing.Printing / WPF / bibliotecas de informes

· · CSharp, .NET, WinForms, WPF, Impresión, PDF, Informes, Desarrollo de Windows, Consultoría técnica

La impresión en una aplicación empresarial Windows no se resuelve simplemente «dibujando algo con PrintDocument». Los saltos de página no funcionan, los márgenes se desplazan, la vista previa no coincide con la salida real, o se abre un diálogo de impresión aunque solo se quiera un PDF: estos problemas suelen comenzar cuando se implementa sin comprender el mecanismo de impresión.

Este artículo organiza cuatro opciones —System.Drawing.Printing de WinForms, FlowDocument/FixedDocument de WPF, bibliotecas de salida PDF e informes mediante Excel/Word— desde la perspectiva de cómo elegirlas según los requisitos.

1. Conclusión primero

  • Para listados sencillos o para ampliar activos WinForms existentes, PrintDocument es suficiente. El salto de página se realiza repitiendo el evento PrintPage hasta que HasMorePages sea false; si se olvida, no se imprimen las páginas posteriores a la segunda. 12
  • El DPI de impresión no es el DPI de la pantalla. PageSettings.PrinterResolution representa la resolución de la impresora, y los márgenes se dividen entre PageSettings.HardMarginX/HardMarginY (área físicamente no imprimible de la impresora) y Margins (márgenes lógicos indicados por la aplicación). Reutilizar sin más las coordenadas de pantalla provoca desajustes por esa diferencia de DPI y sistemas de coordenadas. 345
  • En WPF, la ruta de impresión estándar de Windows se divide entre una ruta GDI y otra XPS. Las aplicaciones WPF usan originalmente la ruta XPS; al enviar a una impresora sin XPSDrv, la salida se convierte automáticamente a formato GDI. 67
  • Los documentos WPF tienen filosofías distintas: FlowDocument para contenido fluido y FixedDocument para disposición fija. FlowDocument prioriza la legibilidad y se redistribuye según el tamaño de la ventana y la resolución, mientras FixedDocument prioriza la fidelidad en el dispositivo de visualización e impresión. 89
  • En WPF se especifican papel y bandeja con PrintDialog y PrintTicket/PrintQueue. Antes de imprimir, la práctica habitual es validar y combinar la solicitud contra las capacidades reales de la impresora con PrintQueue.MergeAndValidatePrintTicket. 1011
  • Microsoft Print to PDF es un controlador de impresión pensado para operaciones interactivas. Es una cola de impresión y paquete de controlador incluido con el sistema; normalmente se muestra un diálogo para elegir el destino en cada ejecución, por lo que no es adecuado para procesos por lotes desatendidos. 12
  • Microsoft no admite ni recomienda la automatización COM de Office desde servidores o servicios. Office se diseñó para un escritorio interactivo y un perfil de usuario; en entornos desatendidos o no interactivos puede comportarse de forma inestable o bloquearse. 13
  • Los servicios Windows se ejecutan en la sesión 0, por lo que no pueden mostrar diálogos ni depender de la impresora predeterminada asociada a la sesión del usuario. Tenga presente este límite desde el principio al diseñar procesos residentes que imprimen. 14
  • Olvidar liberar objetos GDI (handles) en procesos prolongados puede alcanzar el límite por proceso y provocar caídas. El límite es finito y puede ajustarse mediante GDIProcessHandleQuota; no se puede reservar indefinidamente. 15

Tabla de decisión: requisito × medio

Requisito Medio adecuado Motivo
Imprimir unas pocas listas o comprobantes sencillos (WinForms) PrintDocument Se completa solo con clases estándar y reutiliza los activos de dibujo GDI+ existentes
Informes con muchas líneas, varios papeles o diseño complejo Biblioteca de informes, o disposición fija con FixedDocument Calcular coordenadas, controlar saltos y componer japonés internamente cuesta mucho
Impresión masiva por lotes (ejecución nocturna sin supervisión) PrintDocument.Print() programático / envío directo a XpsDocumentWriter Debe terminar sin diálogos y evitar depender de la impresora predeterminada
Solo se necesita guardar PDF (sin imprimir) Generar PDF directamente con una biblioteca PDF No depende del diálogo de impresión, impresora predeterminada ni estado del spooler
Vista previa imprescindible y flujo interno de aprobación importante PrintPreviewDialog (WinForms), DocumentViewer (WPF) Se puede usar directamente la interfaz estándar de comprobación previa
Reutilizar plantillas Excel existentes Generación directa con Open XML SDK o automatización COM limitada Permite reutilizar activos, pero debe evitarse COM en servicios residentes

Veamos ahora cada punto en detalle.

2. Lo mínimo imprescindible sobre la impresión en Windows

La arquitectura de impresión de Windows está formada por el spooler y los controladores de cada impresora. La aplicación solo llama funciones independientes del dispositivo, y puede enviar trabajos a destinos muy diversos: impresoras láser, plotters vectoriales, impresoras raster o fax. 16

Hay dos rutas principales de impresión.

  • Ruta de impresión GDI. Cuando una aplicación Win32 GDI imprime, el motor gráfico GDI coloca las instrucciones de dibujo como EMF (metarchivo mejorado) en el spooler o las renderiza directamente en una imagen imprimible junto con el controlador. Las aplicaciones WinForms tradicionales pasan por esta ruta. 166
  • Ruta de impresión XPS. Es la ruta para controladores basados en XPS (XML Paper Specification). Las aplicaciones WPF la usan originalmente y envían al spooler documentos XPS. Si la impresora objetivo no usa un controlador XPSDrv, se convierte automáticamente a GDI antes del envío. 67

Por qué difieren la pantalla y el resultado impreso. La causa más habitual es confundir los DPI. Los Graphics de pantalla suelen trabajar alrededor de 96 DPI, pero los de impresora usan la resolución indicada por PageSettings.PrinterResolution, con frecuencia alrededor de 600 DPI. 3 Si se entregan al Graphics de impresión las coordenadas en píxeles calculadas para pantalla, se dibujará mucho más pequeño (o, con otra configuración, más grande) de lo previsto. Para imprimir, es seguro construir las coordenadas siempre en centésimas de pulgada o medidas físicas (milímetros/pulgadas), sin depender de la resolución de Graphics.

Otro punto que suele pasarse por alto es el área físicamente no imprimible de la impresora. Muchas impresoras no pueden imprimir unos milímetros junto al borde del papel. Esa restricción se obtiene mediante PageSettings.HardMarginX/HardMarginY, que la documentación describe como márgenes físicos establecidos por la impresora. 4 Los márgenes lógicos que indica la aplicación son PageSettings.Margins (por defecto una pulgada en cada lado); aunque se pongan a cero, no se puede imprimir dentro del margen físico. 5 Muchos defectos de «puse el margen a cero, pero se recorta o se desplaza» proceden de ignorar estos márgenes físicos.

3. WinForms: uso práctico de System.Drawing.Printing

La impresión WinForms se construye alrededor del componente PrintDocument: se crea el documento, se configuran PrinterSettings y DefaultPageSettings, se dibuja en el evento PrintPage y se inicia la impresión con Print(). 1

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;

public sealed class ReportPrinter
{
    // Datos que se van a imprimir. Se asume un detalle de comprobante por línea.
    private readonly IReadOnlyList<string> _lines;
    private int _lineIndex;

    public ReportPrinter(IReadOnlyList<string> lines) => _lines = lines;

    public void Print(string printerName)
    {
        using var document = new PrintDocument();
        document.DocumentName = "Detalles del pedido";
        if (!string.IsNullOrEmpty(printerName))
        {
            document.PrinterSettings.PrinterName = printerName;
        }

        // Con un nombre de impresora desconocido, aquí el resultado será false (no sirve para detectar que esté sin conexión).
        if (!document.PrinterSettings.IsValid)
        {
            throw new InvalidOperationException(
                $"No se encontró la impresora especificada: {printerName}");
        }

        _lineIndex = 0;
        document.PrintPage += Document_PrintPage;
        document.Print();
    }

    private void Document_PrintPage(object? sender, PrintPageEventArgs e)
    {
        // MarginBounds es el área imprimible que refleja los márgenes lógicos (Margins).
        // PageBounds abarca toda la hoja; incluso al dibujar dentro del margen de hardware, el contenido puede recortarse.
        using var font = new Font("Segoe UI", 10);
        float lineHeight = font.GetHeight(e.Graphics);
        float y = e.MarginBounds.Top;

        while (_lineIndex < _lines.Count)
        {
            if (y + lineHeight > e.MarginBounds.Bottom)
            {
                // Esta página termina aquí. Como quedan datos, se continúa en la página siguiente.
                e.HasMorePages = true;
                return;
            }

            e.Graphics.DrawString(_lines[_lineIndex], font, Brushes.Black,
                e.MarginBounds.Left, y);
            y += lineHeight;
            _lineIndex++;
        }

        // Ya se dibujaron todas las líneas; esta es la última página.
        e.HasMorePages = false;
    }
}

El patrón típico del fallo «no aparece la segunda página» es olvidar establecer explícitamente HasMorePages en false (su valor predeterminado es false) o escribir mal una rama condicional y salir dejando siempre false. El evento PrintPage se repite hasta que la propiedad pasa a false; compruebe de forma explícita si aún quedan líneas por dibujar antes de asignarla. 12 Para aplicar ajustes distintos por página (tamaño u orientación del papel), también puede usarse el evento QueryPageSettings junto con PrintPage.

El patrón típico de «los márgenes se desplazan» es construir las coordenadas a partir de e.Graphics.VisibleClipBounds o e.PageBounds e ignorar MarginBounds (área que refleja el margen lógico) y HardMarginX/HardMarginY (restricción física). 4 En especial, una impresora de desarrollo puede tener un margen físico pequeño y ocultar el problema, mientras que en otro modelo del cliente un margen mayor hace que se corten líneas o campos. Verificar la impresión en varios modelos es una etapa que se olvida con facilidad.

Para ofrecer vista previa, asigne el mismo PrintDocument a la propiedad Document de PrintPreviewDialog; así se reutiliza sin cambios la lógica del evento PrintPage. 1 Si necesita cambiar la salida según la resolución, obtenga las opciones desde PrinterSettings.PrinterResolutions y asígnelas a PageSettings.PrinterResolution. 3

4. WPF: FlowDocument / FixedDocument y PrintDialog

En WPF, se elige entre FlowDocument y FixedDocument según la naturaleza del documento.

  • FlowDocument. Es un documento que redistribuye dinámicamente el contenido según variables de ejecución como el tamaño de la ventana o la fuente, priorizando la legibilidad. Incluye búsqueda, paginación y cambio de modo de visualización. 8
  • FixedDocument. Es un documento WYSIWYG en el que la aplicación controla por completo el diseño, priorizando la fidelidad para dispositivos de visualización e impresión. Es adecuado cuando se requiere reproducción precisa. 9

Para informes internos que priorizan la legibilidad, FlowDocument; para comprobantes o etiquetas donde se quiere fijar la posición de líneas y campos al píxel, FixedDocument: esa es la línea básica de decisión.

La impresión básica se realiza con System.Windows.Controls.PrintDialog, una clase específica de WPF distinta de System.Windows.Forms.PrintDialog. 10

using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

public static class FlowDocumentPrinter
{
    public static void Print(FlowDocument document, string jobName)
    {
        var printDialog = new PrintDialog();

        // Imprimir solo si el usuario pulsa Aceptar.
        if (printDialog.ShowDialog() != true)
        {
            return;
        }

        // FlowDocument usa supuestos distintos de tamaño de página para pantalla e impresión, por lo que
        // se ajustan el tamaño de página y los márgenes del contenido al área imprimible de la impresora.
        var paginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
        paginator.PageSize = new Size(
            printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);

        printDialog.PrintDocument(paginator, jobName);
    }
}

Para indicar con detalle el tamaño de papel, la bandeja o la impresión a doble cara, use PrintQueue y PrintTicket/PrintCapabilities. PrintTicket contiene las instrucciones para el trabajo y PrintCapabilities representa las funciones realmente compatibles con la impresora. Lo habitual es combinar y validar los ajustes solicitados con valores válidos de la impresora mediante PrintQueue.MergeAndValidatePrintTicket. 711

using System.Linq;
using System.Printing;

public static class DuplexPrintTicketBuilder
{
    public static PrintTicket BuildDuplexTicket(PrintQueue printQueue)
    {
        PrintCapabilities capabilities = printQueue.GetPrintCapabilities();

        // Comprobar previamente si la impresora admite impresión a doble cara (encuadernación por el borde largo).
        bool supportsDuplex = capabilities.DuplexingCapability
            .Contains(Duplexing.TwoSidedLongEdge);

        var requestedTicket = new PrintTicket();
        if (supportsDuplex)
        {
            requestedTicket.Duplexing = Duplexing.TwoSidedLongEdge;
        }

        // Combinar solo la solicitud de impresión a doble cara con el PrintTicket predeterminado del usuario.
        // Los elementos no admitidos se sustituyen automáticamente por valores válidos.
        ValidationResult result = printQueue.MergeAndValidatePrintTicket(
            printQueue.UserPrintTicket, requestedTicket);

        return result.ValidatedPrintTicket;
    }
}

Si se crea un informe de disposición fija con FixedDocument y se envía directamente por la ruta XPS, se añade el trabajo a PrintQueue con los métodos Write/WriteAsync de XpsDocumentWriter. Si la impresora no admite XPSDrv, se convierte internamente a GDI antes del envío, así que el llamador no necesita preocuparse por la ruta. 7

5. Opciones de salida PDF

El requisito «quiero sacar PDF» cambia de diseño según cuál de estos tres significados tenga.

  1. Como extensión de la impresión, basta con que el usuario pueda elegir manualmente guardar en PDF.
  2. Se quiere generar PDF desde la aplicación, pasando por el diálogo de impresión.
  3. No se imprimirá en absoluto: solo se crearán muchos archivos PDF en un lote desatendido.

Microsoft Print to PDF sirve para los casos 1 y 2. Es una función incluida desde Windows 10, compuesta por una cola de impresión y un paquete de controlador, y la aplicación la ve como una impresora normal. 12 Sin embargo, está pensado para un funcionamiento interactivo que pregunta el nombre de archivo de destino en cada impresión; incluso oficialmente las opciones de control se ofrecen solo como gestión de esa cola y paquete de controlador. 12 No está diseñado para el caso 3, donde se fija una ruta y se producen PDF silenciosamente en grandes lotes. Para ello, lo natural es usar una biblioteca que genere PDF directamente sin atravesar la canalización de impresión.

Para elegir una biblioteca PDF, antes de recomendar un producto concreto conviene ordenar los requisitos de la empresa con estos ejes.

Aspecto Qué comprobar
Licencia Si es OSS (MIT/Apache o GPL/AGPL) o comercial. Al distribuir o vender la aplicación fuera de la empresa, comprobar en fuentes primarias —texto de licencia y sitio oficial del proveedor— que la obligación de abrir código, las condiciones de redistribución y el uso comercial no contradigan la forma de distribución propia
Fuentes japonesas Soporte para incrustación parcial de fuentes japonesas, posibilidad de llevar la fuente dentro del PDF para evitar caracteres corruptos en equipos sin ella y, si el negocio lo necesita, escritura vertical y variantes IVS
Funciones de informes Definición de informes mediante plantillas, códigos de barras y QR, firma electrónica, PDF/A para conservación a largo plazo y facilidad para trasladar el diseño del informe de papel existente
Dependencias y entorno de ejecución Si funciona en servidores sin GUI (Windows Server, contenedores), si requiere bibliotecas nativas y experiencia de funcionamiento en .NET Core/.NET fuera de Framework
Rendimiento Uso de memoria en generación por lotes de muchas páginas o trabajos y comportamiento al generar en paralelo

Las condiciones de licencia varían según producto y versión. Confirme siempre la documentación oficial o el texto mismo de la licencia antes de adoptar un producto. Aquí no se recomienda un nombre de biblioteca ni producto concreto; solo se muestran criterios de comparación.

6. Informes mediante Excel / Word

Cuando ya existe un informe administrado con una plantilla Excel, puede ser más realista reutilizar ese activo que reconstruirlo desde cero. Hay dos enfoques principales.

  • Generar o editar directamente xlsx/docx con Open XML SDK u otro medio. Como se lee y escribe directamente el formato de archivo (ZIP + XML) sin iniciar el ejecutable de Excel/Word, funciona de forma estable incluso en servidores. Encaja bien con una configuración que conserva líneas y formato de una plantilla e inserta solo valores; se explica con más detalle en «Cómo crear salida de informes Excel: COM/Open XML/plantillas».
  • Controlar Excel.Application real mediante Excel COM Interop. Se elige cuando se necesitan reutilizar libros Excel existentes con macros o recálculos complejos, pero es frecuente que procesos EXCEL.EXE permanezcan activos por no liberar referencias COM. Las medidas y criterios aparecen en «El problema de que EXCEL.EXE permanezca al operar Excel desde C#».

Lo importante aquí es que Microsoft declara oficialmente que la automatización Office en servidores o servicios Windows no está recomendada ni admitida. Las aplicaciones Office están diseñadas para escritorio interactivo y perfiles de usuarios con sesión iniciada, y pueden comportarse de forma inestable o bloquearse en entornos desatendidos/no interactivos. 13 Por licencia también, las EULA habituales no prevén proporcionar a clientes funciones Office mediante automatización del lado servidor. 13

Por tanto, al integrar salida de informes en un servicio residente o un trabajo por lotes, aunque se reutilice una plantilla Excel, es más seguro evitar una configuración que inicie realmente Excel.exe (COM Interop) y optar por generación directa de archivos con Open XML SDK u otra herramienta. Si COM Interop es indispensable, una separación realista es ejecutarlo como aplicación residente —no servicio— en una sesión de usuario iniciada interactivamente.

7. Trampas prácticas

Imprimir desde un servicio Windows o sesión 0

No son raras las consultas para incorporar impresión a un servicio residente, pero los servicios Windows se ejecutan en la sesión 0. Desde Windows Vista, la sesión 0 está reservada a servicios y procesos no asociados a usuarios interactivos, y se mantiene aislada de la sesión del usuario. 14 Por esa separación, aunque el servicio muestre un cuadro de diálogo, el usuario no lo verá; código que espere entrada del usuario, por ejemplo un diálogo de impresión, puede parecer bloqueado. 14

Otro problema práctico es la visibilidad de impresoras de red o impresoras asignadas a cada usuario. Una impresora de red conectada por un usuario suele ser visible dentro de su sesión interactiva, pero no necesariamente desde otro contexto, como el proceso del servicio en sesión 0. Al diseñar un proceso residente que imprime, confirme desde el inicio qué impresoras se ven para qué cuenta y sesión. La separación de sesiones se trata en «Cómo entender el aislamiento de sesiones Windows», y la base de implementación y operación de servicios en «Cómo crear y operar servicios Windows».

Cuando no hay impresora o está desconectada

Si se indica un nombre inexistente en PrinterSettings.PrinterName, o se ejecuta en un entorno sin impresora predeterminada, puede producirse una excepción o fallo al intentar imprimir. Como mínimo, valide antes con PrinterSettings.IsValid y diseñe reintentos y avisos de error suponiendo fallos de impresión. Si una impresora de red queda temporalmente fuera de línea, el trabajo puede quedar en el spooler sin producir salida; no termine la comprobación en «se pudo enviar», y considere consultar el estado del trabajo cuando haga falta.

El riesgo de depender de la impresora predeterminada

Una implementación que no especifica PrinterSettings.PrinterName y depende siempre de la «impresora predeterminada» acumula riesgos con el tiempo. El usuario puede cambiarla, o un portátil puede cambiar de predeterminada al usarse en otro sitio, enviando documentos a un destino no previsto. Para informes empresariales importantes, guarde explícitamente el nombre de impresora de destino en configuración o en una pantalla de ajustes, para no quedar arrastrado por cambios de la predeterminada.

Fugas de handles GDI en ejecuciones prolongadas

Si se escriben rutinas de impresión que no liberan con seguridad recursos GDI/GDI+ como Graphics, Font, Brush y Pen mediante using o Dispose(), los handles de objetos GDI se agotan tras una ejecución prolongada y empiezan a fallar las llamadas de dibujo. Los handles tienen un límite predeterminado por proceso, un recurso finito ajustable entre 256 y 65.536 mediante la clave de registro GDIProcessHandleQuota. 15 Cuanto más imprima una aplicación residente, más probable es que este tipo de fuga aparezca solo en producción. «Investigación de caídas prolongadas de cámaras industriales: fugas de handles» explica una investigación y un método de aislamiento concretos.

Artículos relacionados

Áreas de consulta relacionadas

Komura Soft LLC ofrece consultas técnicas sobre diseño de funciones de impresión y salida de informes para aplicaciones empresariales Windows, reconstrucción de informes que aprovecha activos Excel existentes y diseño de impresión/salida desde servicios residentes.

Referencias

  1. Microsoft Learn, PrintDocument Class. Sobre el papel de PrintDocument (configurar DocumentName y PrinterSettings, e iniciar la impresión con Print()), y la indicación de usar el espacio de nombres System.Printing para imprimir desde WPF.  2 3 4

  2. Microsoft Learn, PrintPageEventArgs.HasMorePages Property. Sobre que el valor predeterminado es false y el evento PrintPage se repite hasta que esta propiedad es false 2

  3. Microsoft Learn, PageSettings.PrinterResolution Property. Sobre que la resolución de impresión predeterminada de la página es la resolución predeterminada de la impresora y que se pueden obtener opciones desde PrinterSettings.PrinterResolutions 2 3

  4. Microsoft Learn, PageSettings.HardMarginX Property. Sobre que el margen físico representa el margen establecido por la impresora.  2 3

  5. Microsoft Learn, PageSettings.Margins Property. Sobre que el valor predeterminado de los márgenes es una pulgada en cada lado y que el área imprimible puede calcularse junto con Bounds en el evento PrintPage 2

  6. Microsoft Learn, Windows Print Path Overview. Sobre la existencia en Windows de dos rutas principales: GDI (aplicaciones Win32) y XPS (aplicaciones WPF o XPS Print API).  2 3

  7. Microsoft Learn, Printing documents overview. Sobre que WPF usa la ruta XPS, impresión básica con PrintDialog, impresión avanzada con PrintTicket/PrintCapabilities/PrintQueue/XpsDocumentWriter y conversión automática a GDI para impresoras sin XPSDrv.  2 3 4

  8. Microsoft Learn, Flow Document Overview. Sobre que FlowDocument redistribuye el contenido según variables de ejecución como tamaño de ventana y resolución, priorizando legibilidad.  2

  9. Microsoft Learn, FixedDocument Class. Sobre que FixedDocument prioriza una reproducción WYSIWYG fiel para dispositivos de visualización e impresión, con una filosofía distinta de FlowDocument 2

  10. Microsoft Learn, PrintDialog Class. Sobre que System.Windows.Controls.PrintDialog configura PrintTicket y PrintQueue según la entrada del usuario y es distinto de System.Windows.Forms.PrintDialog 2

  11. Microsoft Learn, How to: Validate and Merge PrintTickets. Sobre comprobar funciones compatibles con PrintQueue.GetPrintCapabilities y combinar/validar solicitudes con MergeAndValidatePrintTicket 2

  12. Microsoft Learn, RemoveMPDW. Sobre que Microsoft Print to PDF es una función opcional instalada por defecto y se configura/elimina como cola de impresión y paquete de controlador.  2 3

  13. Microsoft Support, Considerations for server-side Automation of Office. Sobre que Microsoft no recomienda ni admite automatizar Office desde aplicaciones cliente desatendidas/no interactivas, incluidos ASP/ASP.NET/DCOM/servicios NT, y que Office presupone escritorio interactivo y perfil de usuario.  2 3

  14. Microsoft Learn, Service Changes for Windows Vista - Session 0 Isolation. Sobre que desde Windows Vista la sesión 0 está reservada a servicios y aplicaciones no asociadas a usuarios interactivos, y los servicios no pueden mostrar directamente cuadros de diálogo.  2 3

  15. Microsoft Learn, GDI Objects. Sobre que los handles de objetos GDI tienen un límite predeterminado por proceso y que GDIProcessHandleQuota permite ajustarlo entre 256 y 65.536.  2

  16. Microsoft Learn, Introduction to printing. Sobre que la arquitectura de impresión Windows está formada por spooler y controladores, y que las instrucciones de dibujo de aplicaciones Win32 GDI se envían como EMF al spooler.  2

Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.

Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.

El artículo está directamente relacionado con los siguientes servicios.

Preguntas frecuentes

Preguntas habituales en las consultas sobre el tema del artículo.

¿Debo usar PrintDocument o la impresión de WPF?
Si la interfaz es WinForms, PrintDocument; si es WPF, FlowDocument o FixedDocument es la opción natural. No es necesario mezclar tecnologías: el criterio práctico es seguir el framework de pantalla de la aplicación existente. Si se elige WPF para un proyecto nuevo, conviene decidir desde el principio si el informe se basa en contenido fluido o en un diseño fijo, y elegir FlowDocument o FixedDocument en consecuencia.
¿Conviene comprar una biblioteca de informes?
Cuando es alto el coste de crear internamente, con dibujo GDI+ o WPF, informes complejos con muchas líneas, varios tamaños de papel, incrustación de fuentes japonesas o escritura vertical, el coste de una biblioteca de informes suele resultar menor. En cambio, para un listado sencillo en A4, PrintDocument o FixedDocument puede ser suficiente. Lo seguro es estimar primero la complejidad de los requisitos.
¿Es viable generar solo PDF y no usar impresión?
Sí, plenamente. PDF es solo uno de los formatos de salida; para procesos por lotes y automatización, la generación directa con una biblioteca PDF que no dependa del diálogo de impresión ni de la impresora predeterminada suele encajar mejor. Microsoft Print to PDF es un controlador pensado para operaciones interactivas, por lo que no es apropiado para generar PDF sin intervención.
¿También se pueden admitir impresoras de etiquetas o de recibos?
Es posible, pero puede resultar difícil resolverlo como una simple extensión de PrintDocument o FixedDocument. Muchas impresoras de etiquetas tienen su propio lenguaje de comandos o SDK y se controlan por una ruta distinta de la impresión estándar de Windows. Empiece por comprobar si el modelo objetivo se comporta como una impresora Windows normal o necesita control mediante un SDK específico.

Perfil del autor

Página de presentación del autor del artículo.

Go Komura

Representante de KomuraSoft LLC

Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.

Volver al blog