咖啡馆

有空坐下来喝杯咖啡,放松下心情~
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

MS Local Report

Posted on 2007-06-03 09:50  mshwu  阅读(814)  评论(0编辑  收藏  举报

    最近一个项目中,涉及到很多报表的开发,以前对水晶报表搞得比较熟,但它的庞大与其它诸多功能限制,特别是发布与部置时面临的困难,实在让人无法忍受(应该很少有人买得起正版吧),决定试一下MS Reporting Services,当然在这里只使用Local Report,对微软的Reporting Services进行了一番了解,蜡人张(http://www.cnblogs.com/waxdoll/category/49402.html)老兄这里有很多很好的学习材料,我也是从蜡人兄那里对自定义报表的研究得出以下部分修正的Demo.
    对于微软提供的ReportView控件,大家都知道,不能在其中对报表的边距等进行自定义,其工具条也是根本上无法自定义控制的,每次用户打印时,都必须对页面,边距等进行调整,对用户来说,这可能是一件无法忍受的事情,这或者是为满足Reporting Services报表而这样设计的.
对蜡人张老兄提供的例子做了一些改进,主要修正以下几点:
1,修正无法使用网络打印机进行打印的问题;
2,报表使用钳入式资源加载方式;
3,提取成一用户控件ReportView,更方便于开发人员将其整合到自己的项目中

Demo文件结构:


自定义报表控件ReportView源码分如下:

  1using System;
  2using System.Collections.Generic;
  3using System.ComponentModel;
  4using System.Drawing;
  5using System.Data;
  6using System.Text;
  7using System.Windows.Forms;
  8using System.IO;
  9using Microsoft.Reporting.WinForms;
 10namespace LocalReportDemo.Report
 11{
 12    public partial class ReportViewer : UserControl
 13    {
 14
 15        private EMFStreamPrintDocument printDoc;
 16
 17        /// <summary>
 18        /// 主报表名称
 19        /// </summary>

 20        private string m_ReportName = string.Empty;
 21        public string ReportName
 22        {
 23            get
 24            {
 25                return this.m_ReportName;
 26            }

 27            set
 28            {
 29                this.m_ReportName = value;
 30            }

 31        }

 32
 33        /// <summary>
 34        /// 主报表数据源
 35        /// </summary>

 36        private object m_MainDataSet = null;
 37        public object MainDataSet
 38        {
 39            get
 40            {
 41                return this.m_MainDataSet;
 42            }

 43            set
 44            {
 45                this.m_MainDataSet = value;
 46
 47            }

 48        }

 49
 50        /// <summary>
 51        /// 主报表数据源名称
 52        /// </summary>

 53        private string m_MainDataSourceName = string.Empty;
 54        public string MainDataSourceName
 55        {
 56            get
 57            {
 58                return this.m_MainDataSourceName;
 59            }

 60            set
 61            {
 62                this.m_MainDataSourceName = value;
 63            }

 64        }
 
 65
 66        /// <summary>
 67        /// 钳入资源中的报表路径
 68        /// </summary>

 69        private string m_ReportEmbeddedResource;
 70        public string MReportEmbeddedResource
 71        {
 72            get
 73            {
 74                return m_ReportEmbeddedResource;
 75            }

 76            set
 77            {
 78                m_ReportEmbeddedResource = value;
 79            }

 80        }

 81
 82        /// <summary>
 83        /// 钻取报表数据源
 84        /// </summary>

 85        private object m_DrillDataSet = null;
 86        public object DrillDataSet
 87        {
 88            get
 89            {
 90                return this.m_DrillDataSet;
 91            }

 92            set
 93            {
 94                this.m_DrillDataSet = value;
 95            }

 96        }

 97        /// <summary>
 98        /// 钻取报表数据源名称
 99        /// </summary>

100        private string m_DrillDataSourceName = string.Empty;
101        public string DrillDataSourceName
102        {
103            get
104            {
105                return this.m_DrillDataSourceName;
106            }

107            set
108            {
109                this.m_DrillDataSourceName = value;
110            }

111        }

112
113        /// <summary>
114        /// 构造器
115        /// </summary>

116        public ReportViewer()
117        {
118            InitializeComponent();
119            this.Dock = System.Windows.Forms.DockStyle.Fill;
120        }

121
122        /// <summary>
123        /// 加载窗体事件
124        /// </summary>
125        /// <param name="sender"></param>
126        /// <param name="e"></param>

127        private void rpv1_Load(object sender, EventArgs e)
128        {
129        }

130        /// <summary>
131        /// 加载报表
132        /// </summary>

133        public  void BindReport()
134        {
135
136            System.Type type = this.MainDataSet.GetType();
137            if (this.m_MainDataSet == null)
138            {
139                MessageBox.Show("报表数据源不存在或为空!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
140                return;
141            }

142            if (type == null)
143            {
144                System.Windows.Forms.MessageBox.Show("报表数据源格式不正确!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
145                return;
146            }

147            else
148            {
149                System.Reflection.PropertyInfo[] picData = type.GetProperties();
150                bool bolExist = false;
151                foreach (System.Reflection.PropertyInfo piData in picData)
152                {
153                    if (piData.Name == "Tables")
154                    {
155                        bolExist = true;
156
157                        if (MainDataSourceName == string.Empty)
158                        {
159                            MessageBox.Show("报表数据源不存在或为空!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
160                            return;
161                        }

162
163                        this.rpv1.LocalReport.DataSources.Add(
164                            new Microsoft.Reporting.WinForms.ReportDataSource(this.MainDataSourceName,
165                            (piData.GetValue(this.MainDataSet, nullas System.Data.DataTableCollection)[0])
166                            );
167                        this.rpv1.LocalReport.ReportEmbeddedResource = this.MReportEmbeddedResource;
168                        this.rpv1.RefreshReport();
169                        this.lblTotal.Text = @"/" + (this.rpv1.LocalReport.GetTotalPages()+1).ToString();
170                        this.tbxPage.Text = "1";
171                        break;
172                    }

173                }

174
175                if (!bolExist)
176                {
177                    System.Windows.Forms.MessageBox.Show("报表数据源格式不正确!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
178                    return;
179                }

180            }

181        }

182
183        工具条事件 
368
369        /// <summary>
370        /// 钻取报表事件
371        /// </summary>
372        /// <param name="sender"></param>
373        /// <param name="e"></param>

374        private void rpv1_Drillthrough(object sender, DrillthroughEventArgs e)
375        {
376            if (DrillDataSet == null)
377            {
378                MessageBox.Show("报表数据源不存在或为空!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
379                return;
380            }

381            else
382            {
383                if (this.DrillDataSourceName == string.Empty)
384                {
385                    System.Windows.Forms.MessageBox.Show("报表数据源格式不正确!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
386                    return;
387                }

388                else
389                {
390                    Microsoft.Reporting.WinForms.LocalReport report = e.Report as Microsoft.Reporting.WinForms.LocalReport;
391                    report.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource(this.DrillDataSourceName, this.GetTableCollection(this.DrillDataSet)[0]));
392                }

393            }

394        }

395        private System.Data.DataTableCollection GetTableCollection(object ReportSource)
396        {
397            System.Type type = ReportSource.GetType();
398
399            if (type == null)
400            {
401               MessageBox.Show("报表数据源格式不正确!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
402                return null;
403            }

404            else
405            {
406                System.Reflection.PropertyInfo[] picData = type.GetProperties();
407                bool bolExist = false;
408                foreach (System.Reflection.PropertyInfo piData in picData)
409                {
410                    if (piData.Name == "Tables")
411                    {
412                        bolExist = true;
413                        return piData.GetValue(ReportSource, nullas System.Data.DataTableCollection;
414                    }

415                }

416
417                if (!bolExist)
418                {
419                    MessageBox.Show("报表数据源格式不正确!""提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
420                    return null;
421                }

422            }

423            return null;
424        }

425    }

426}

427

报表宿主窗口加载报表与数据源的方法:
1 DataSet ds = new DataSet();
2            ds.ReadXml(Application.StartupPath + @"\DataSource.xml");
3            this.reportViewer1.MainDataSet = ds;//报表主数据源
4            this.reportViewer1.MainDataSourceName = "ReportDemoDataSet_ReportDemoTable";//数据源名称
5            this.reportViewer1.MReportEmbeddedResource = "LocalReportDemo.ReportDemo.rdlc";//钳入资源的报表路径
6            this.reportViewer1.ReportName = "ReportDemo";//报表名称
7            this.reportViewer1.BindReport();//加载挷定报表

数据源名称如下图所示:


其中钳入资源的报表路径中,LocalReportDemo为报表钳入的程序集名称

报表格式配置文件ReportSettings.xml:
 1<?xml version="1.0" standalone="yes"?>
 2<ReportSettings>
 3  <ReportDemo>
 4    <ReportName>ReportDemo</ReportName>
 5    <PrinterName>Microsoft Office Document Image Writer</PrinterName>
 6    <PaperName>A4</PaperName>
 7    <PageWidth>21.01</PageWidth>
 8    <PageHeight>29.69</PageHeight>
 9    <MarginTop>0.5</MarginTop>
10    <MarginBottom>0.2</MarginBottom>
11    <MarginLeft>2.3</MarginLeft>
12    <MarginRight>0.2</MarginRight>
13    <Orientation>Z</Orientation>
14  </ReportDemo>
15</ReportSettings>

此Demo运行效果:


打印预览:


有任何问题欢迎在此提出,大家共同讨论解决

此Demo完整代码下载:
/Files/mshwu/LocalReportDemo.rar