从WPF打印/报告的最佳方法是什么?

我有一个即将到来的项目,必须能够从其数据中打印简单的报告。 这将是基于WPF的,我想知道要走哪条路。

我知道WPF引入了自己的打印技术(基于XPS),看起来很容易使用。 但是,我想知道是否使用ReportViewer控件并将其embedded到Windows窗体主机控件中会更容易,因为这将使用户能够导出到各种格式以及打印。

有没有人有任何WPF打印/报告的经验? 你会推荐哪个方向?

我们有同样的问题,现在结束了使用RDLC / ReportViewer。 没有本地的WPF报表工具(我知道),RDLC非常简单易用,而且是免费的。 它的运行时间开销很小(大约2Mb),但是您必须记住分发它,因为它不是.NET Framework的一部分。

RDL的局限性

我最初用RDLC / ReportViewer与WPF打印,但发现它非常有限。 我发现的一些限制是:

  • RDL只能创造最无聊的报告
  • 使用RDL创build报表要比直接创build报表要复杂得多:与Expression Blend相比,devise工具非常简单,RDL仅处理表
  • 我没有能力使用ControlTemplates,DataTemplates,Styles等
  • 我的报告字段和列无法根据数据大小有效resize和重新排列
  • graphics必须作为图像导入 – 无法绘制或编辑为vector
  • 项目的定位需要代码隐藏而不是数据绑定
  • 缺乏变革
  • 非常原始的数据绑定

直接从WPF打印是非常容易的

由于这些限制,我研究了使用纯WPF创build报表,发现它确实非常简单。 WPF允许你实现你自己的可以生成页面的DocumentPaginator子类。

我开发了一个简单的DocumentPaginator子类,它接受任何Visual,分析可视化树,并隐藏选定的元素来创build每个页面。

DocumentPaginator详细信息

这是我的DocumentPaginator子类在初始化过程中所做的(在第一次获取PageCount时或在第一次GetPage()调用时调用):

  1. 扫描可视化树并制作ItemsControls中所有滚动面板的地图
  2. 从最外层开始,使ItemsControls中的项最后不可见,直到Visual适合单个页面而不需要滚动。 如果最外层不能够减小,则减less内层板直到成功或每层仅有一个项目。 将一组可见项目logging为第一页。
  3. 隐藏已经显示在第一页上的最低级别项目,然后使后续项目可见,直到它们不再适合页面。 logging除最后添加的项目以外的所有项目作为第二页。
  4. 对所有页面重复该过程,将结果存储在数据结构中。

我的DocumentPaginator的GetPage方法如下所示:

  1. 在初始化期间生成的数据结构中查找给定的页码
  2. 隐藏和显示数据结构中指示的可视化树中的项目
  3. 设置PageNumber和NumberOfPages附加属性,以便报表可以显示页码
  4. 刷新Dispatcher( Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} )); )来完成任何背景渲染任务
  5. 创build一个矩形,其VisualBrush是可视化被打印的页面的大小
  6. 测量,排列和更新矩形,然后返回

事实certificate,这是非常简单的代码,并允许我将WPF创build的任何东西转换成页面并打印出来。

额外的报告支持

现在,我的分页器正在工作,我不必再担心是否为屏幕或纸张创buildWPF内容。 实际上,我为数据input和编辑构build的UI通常也适用于打印。

从那里,我添加了一个简单的工具栏和一些代码,导致围绕WPF构build的完整报告系统比RDL更有能力。 我的报告代码可以导出到文件,打印到打印机,剪切/粘贴页面图像以及剪切/粘贴Excel数据。 我也可以切换我的任何一个用户界面到“打印视图”点击一个checkbox,看看它会看起来像打印。 所有这一切只需要几百行C#和XAML!

在这一点上,我认为RDL的唯一特性是我的报告代码没有能够生成格式化的Excel电子表格。 我可以看到如何做到这一点,但迄今为止没有必要 – 仅仅剪切和粘贴数据就足够了。

从我的经验来看,我的build议是编写一个分页器,然后开始使用WPF来创build报表。

看看PdfReports 。 这是一个代码第一报告引擎,它build立在iTextSharp和EPPlus库之上。 它与.NET 3.5+ Web和Windows应用程序兼容。

没有深入讨论WPF的未来,我们发现的最佳select是将ReportViewer包装在Windows Forms主机控件中。

http://blog.pineywoodstech.com/index.php/2012/01/using-microsoft-reportviewer-with-wpf/

要详细说明Ray Burns的答案,如果您正在查找实现示例,请参阅: 自定义数据网格文档分页程序

这是一个很好的起点。

Scryber呢? 它允许使用xml定义PDF报告模板,并在运行时绑定到应用程序中的数据。 http://scryber.codeplex.com/

我刚刚完成了开发自己的报表系统的任务,主要是devise环境和数据源pipe理器。 第一个任务是开发类似于WYSWIG的devise环境。 我已经使用GDI +完成了这个工作,甚至不用担心打印问题,因为打印/生成打印预览比我想象的要简单,一般只需要将所有东西都画在屏幕上,以便将打印事件的graphics对象绘制出来。

我认为,在WPF的情况下,它将是类似的,所以你应该担心的是要显示在屏幕上报告和打印将只有几行代码。