tutorial - wpf vs windows forms
¿Cuál es el mejor enfoque para imprimir/informar de WPF? (8)
Tengo un próximo proyecto que deberá poder imprimir informes simples a partir de sus datos. Estará basado en WPF, y me pregunto qué camino tomar.
Sé que WPF presenta su propia tecnología de impresión (basada en XPS) que parece bastante fácil de usar. Sin embargo, una parte de mí se pregunta si simplemente sería más fácil usar el control ReportViewer e incrustarlo en un control de host de Windows Forms, ya que eso les dará a los usuarios la capacidad de exportar a una variedad de formatos además de imprimir.
¿Alguien ha tenido alguna experiencia con la impresión / informes de WPF? ¿Qué dirección recomendarías?
¿Qué hay de Scryber? Permite que las plantillas de informes PDF se definan utilizando xml y se vinculen a los datos de su aplicación en tiempo de ejecución. http://scryber.codeplex.com/
Eche un vistazo a PdfReports . Es un motor de informes por código, que se basa en las bibliotecas iTextSharp y EPPlus. Es compatible con aplicaciones .NET 3.5+ Web y Windows.
Para obtener más información sobre la respuesta de Ray Burns, si está buscando un ejemplo de implementación, consulte: codeproject.com/Articles/138233/…
Lo cual es un gran punto de partida.
Recientemente he logrado la tarea de desarrollar mi propio sistema de informes, que básicamente consiste en el entorno de diseño y el administrador de fuentes de datos. La primera tarea fue desarrollar el entorno de diseño WYSWIG. He hecho esto usando GDI +, sin siquiera molestarme con la impresión, ya que salió imprimiendo / generando la vista previa de impresión fue más fácil de lo que esperaba, en general solo se necesita dibujar todo en la pantalla al objeto gráfico del evento de impresión.
Creo que en el caso de WPF sería similar, por lo que todo lo que debería preocuparse es mostrar su informe en la pantalla e imprimir sería de pocas líneas de código.
Sin entrar en una discusión política completa sobre el futuro de WPF, la mejor opción que encontramos fue ajustar el ReportViewer en un control de host de Windows Forms.
http://blog.pineywoodstech.com/index.php/2012/01/using-microsoft-reportviewer-with-wpf/
Tuvimos este mismo problema, y terminamos usando RDLC / ReportViewer por el momento. No hay una herramienta nativa de informes de WPF (que yo sepa) y RDLC es bastante simple de usar, y es gratis. La sobrecarga de tiempo de ejecución para él es pequeña (alrededor de 2Mb) pero debe recordar distribuirlo ya que no forma parte de .NET Framework.
Limitaciones de RDL
Originalmente fui con RDLC / ReportViewer para imprimir con WPF, pero me pareció muy limitante. Algunas de las limitaciones que encontré fueron:
- RDL solo podía crear los informes más aburridos
- Trabajar mucho más para crear un informe utilizando RDL que en WPF directo: las herramientas de diseño son muy primitivas en comparación con Expression Blend y RDL solo se trata en tablas
- No tuve la capacidad de utilizar ControlTemplates, DataTemplates, Styles, etc.
- Mis campos y columnas de informe no pudieron cambiar el tamaño y la reorganización de manera efectiva en función del tamaño de los datos
- Los gráficos deben importarse como imágenes; no se pueden dibujar ni editar como vectores
- El posicionamiento de los elementos requiere código subyacente en lugar de vinculación de datos
- La falta de transformaciones
- Enlace de datos muy primitivo
Imprimir directamente desde WPF es muy fácil
Debido a estas limitaciones busqué crear informes usando WPF puro y descubrí que era realmente bastante trivial. WPF le permite implementar su propia subclase DocumentPaginator
que puede generar páginas.
Desarrollé una subclase DocumentPaginator simple que toma cualquier Visual, analiza el árbol visual y oculta los elementos seleccionados para crear cada página.
Detalles de DocumentPaginator
Esto es lo que hace mi subclase DocumentPaginator durante la inicialización (llamada cuando se obtiene el primer PageCount, o durante la primera llamada a GetPage ()):
- Escanea el árbol visual y crea un mapa de todos los paneles desplazados dentro de ItemsControls
- Comenzando por el más externo, hace que los elementos de los ItemsControls sean invisibles al último hasta que el Visual se ajuste a una sola página sin necesidad de desplazarse. Si el más externo no se puede reducir lo suficiente, reduce los paneles internos hasta que tenga éxito o solo tenga un elemento en cada nivel. Registre el conjunto de elementos visibles como la primera página.
- Oculte los elementos de nivel más bajo que ya se han mostrado en la primera página, luego haga visibles los elementos subsiguientes hasta que ya no quepan en la página. Grabe todo, excepto el último elemento agregado como la segunda página.
- Repita el proceso para todas las páginas, almacenando los resultados en una estructura de datos.
El método GetPage de mi DocumentPaginator es el siguiente:
- Busque el número de página dado en la estructura de datos generada durante la inicialización
- Ocultar y mostrar elementos en el árbol visual como se indica en la estructura de datos
- Establezca las propiedades adjuntas de PageNumber y NumberOfPages para que el informe pueda mostrar la numeración de las páginas
- Vaciar el despachador (
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} ));
) para completar cualquier tarea de renderizado en segundo plano - Crea un rectángulo del tamaño de la página cuyo VisualBrush es el visual que se está imprimiendo
- Medir, organizar y actualizar Diseñar el rectángulo, luego devolverlo
Resultó ser un código bastante simple y me permitió convertir prácticamente todo lo que podía crear con WPF en páginas e imprimirlo.
Soporte de informes adicional
Ahora que mi paginador está funcionando, ya no tengo que preocuparme demasiado sobre si estoy creando mi contenido WPF para pantalla o papel. De hecho, a menudo la interfaz de usuario que construyo para la entrada y edición de datos también funciona muy bien para la impresión.
A partir de ahí, agregué una barra de herramientas simple y un código detrás, lo que resultó en un sistema de informes completo construido alrededor de WPF que era mucho más capaz que RDL. Mi código de informe puede exportar a archivos, imprimir a la impresora, cortar / pegar imágenes de página y cortar / pegar datos para Excel. También puedo cambiar cualquiera de mi interfaz de usuario a "vista de impresión" con un clic en una casilla de verificación para ver cómo se verá si se imprime. ¡Todo esto en solo unos cientos de líneas de C # y XAML!
En este momento, creo que la única característica que RDL tiene que mi código de informes no tiene es la capacidad de generar una hoja de cálculo Excel formateada. Puedo ver cómo se podría hacer esto, pero hasta ahora no ha sido necesario, cortar y pegar solo los datos ha sido suficiente.
Según mi experiencia, mi recomendación sería escribir un paginador, luego comenzar a usar WPF para crear sus informes.