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

时间:2008-10-07 22:51:33

标签: wpf printing reporting

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

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

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

8 个答案:

答案 0 :(得分:42)

RDL的限制

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

  • RDL只能创建最无聊的报告
  • 使用RDL创建报告比使用直接WPF创建报告要多得多:与Expression Blend相比,设计工具非常原始,RDL仅在表格中处理
  • 我没有能力使用ControlTemplates,DataTemplates,样式等
  • 我的报告字段和列无法根据数据大小有效调整大小和重新排列
  • 图形必须作为图像导入 - 无法将其绘制或编辑为矢量
  • 项目的定位需要代码隐藏而不是数据绑定
  • 缺乏变革
  • 非常原始的数据绑定

直接从WPF打印非常简单

由于这些限制,我考虑使用纯WPF创建报告,并发现它确实非常简单。 WPF允许您实现自己的DocumentPaginator子类,它可以生成页面。

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

DocumentPaginator详细信息

这是我的DocumentPaginator子类在初始化期间所做的事情(在获取第一个PageCount时或在第一次GetPage()调用期间调用):

  1. 扫描可视树,并在ItemsControls
  2. 中创建所有滚动面板的地图
  3. 从最外层开始,使ItemsControls中的项目最后不可见,直到Visual适合单个页面而不需要滚动。如果最外层不能减小,则减少内板直到成功或每层只有一个项目。将可见项目集记录为第一页。
  4. 隐藏已在第一页上显示的最低级别的项目,然后使后续项目可见,直到它们不再适合页面。将除最后添加的项目之外的所有项目记录为第二页。
  5. 对所有页面重复此过程,将结果存储在数据结构中。
  6. 我的DocumentPaginator的GetPage方法如下:

    1. 在初始化期间生成的数据结构中查找给定的页码
    2. 隐藏和显示可视树中的项目,如数据结构中所示
    3. 设置PageNumber和NumberOfPages附加属性,以便报告可以显示页码编号
    4. 刷新调度程序(Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} ));)以完成任何后台渲染任务
    5. 创建一个Rectangle,其大小与VisualBrush是可视化打印的页面相同
    6. 测量,排列和更新矩形,然后将其返回
    7. 事实证明这是非常简单的代码,并且允许我将使用WPF创建的任何内容转换为页面并打印出来。

      其他报告支持

      现在我的分页器正在工作,我不再需要担心我是否正在为屏幕或纸张创建WPF内容。实际上,我为数据输入和编辑构建的UI通常也非常适合打印。

      从那里我添加了一个简单的工具栏和一些代码,从而形成了一个围绕WPF构建的完整报告系统,它比RDL更强大。我的报告代码可以导出到文件,打印到打印机,剪切/粘贴页面图像,以及剪切/粘贴Excel数据。我还可以通过单击复选框将我的任何UI切换到“打印视图”,以查看打印时的外观。所有这些只需几百行C#和XAML!

      此时我认为RDL的唯一功能是我的报告代码不具备生成格式化Excel电子表格的功能。我可以看到如何做到这一点,但到目前为止还没有必要 - 单独剪切和粘贴数据就足够了。

      根据我的经验,我的建议是编写一个分页器,然后开始使用WPF本身来创建报告。

答案 1 :(得分:25)

我们遇到了同样的问题,现在最终使用RDLC / ReportViewer。没有原生的WPF报告工具(我知道)和RDLC使用非常简单,而且是免费的。它的运行时开销很小(约2Mb),但您必须记住分发它,因为它不是.NET Framework的一部分。

答案 2 :(得分:8)

答案 3 :(得分:3)

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

答案 4 :(得分:3)

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

答案 5 :(得分:2)

详细说明Ray Burns的答案,如果您正在寻找实施示例,请参阅: Custom Data Grid Document Paginator

这是一个很好的起点。

答案 6 :(得分:1)

我最近完成了开发自己的报告系统的任务,该系统基本上包括设计环境和数据源管理器。第一项任务是开发类似WYSWIG的设计环境。我使用GDI +完成了这项工作,甚至没有打印打印,因为它出来的打印/生成打印预览比我预期的最简单,通常它只需要在屏幕上绘制所有东西到打印事件的图形对象。

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

答案 7 :(得分:0)

没有对WPF的未来进行全面的政治讨论,我们发现的最佳选择是将ReportViewer包装在Windows窗体主机控件中。

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