码迷,mamicode.com
首页 > 其他好文 > 详细

RDLC报表之动态生成报表

时间:2016-11-06 22:04:19      阅读:731      评论:0      收藏:0      [点我收藏+]

标签:schema   字体   ida   one   官网   span   module   system   efi   

首先,必须感谢和致敬蜡人张前辈:

http://waxdoll.cnblogs.com/archive/2006/02/25/337713.html

2.微软GotReportViewer官方的案例:

http://www.gotreportviewer.com/(约有20来个,很详细。有时候会上不了)

 

前段时间,做了RDLC报表,主要是三块功能:

1、从DataGrid提取数据,然后创建对应的RDLC报表文件,以利用ReportViewer类的打印排版的功能(其中做了个提取数据的通用函数,可以提取任意控件的数据;只要拼接成DataTable这种网状的格子就好)

2、给一个简单的RDLC模板,以提供表头的字体格式和表内部数据等样式相关的信息,然后再用DataGrid里提取的数据,填充到报表里

3、做了一个TreeView,很简单;根据报表文件名称,切换左侧树上的Item,就加载不同的报表,显示数据。用了一点反射的知识

 

第一步:根据 Report Definition Language (RDL) 生成对应的类和命名空间。

1、去

http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition/

下载ReportDefinition2010.xsd。

注意:ReportDefinition和Visual Studio出的有个时间差,官网上有2005版和2008版。2005版,VS2008以后支持;2008版,VS2010以后支持。2010版,要VS2012

以后才支持。我的是VS2010,用了2008版。

 

2、找XML Schema Definition Tool (Xsd.exe),Windows操作系统会自带。For more detail,please refer to:

https://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx

 Below is my CMD in administator mode:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64>xsd

/c /n:RDLC  

/out:C:\Users\admin\Desktop\RDLCReportResearch

C:\Users\admin\Desktop\RDLCReportResearch\ReportDefinition.xsd

 完了,生成的是这么个样子

技术分享
using System.Xml.Serialization;
    
    
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition", IsNullable=false)]
    public partial class Report {
        
        private object[] itemsField;
        
        private ItemsChoiceType80[] itemsElementNameField;
        
        private System.Xml.XmlAttribute[] anyAttrField;
        
        /// <remarks/>
        [System.Xml.Serialization.XmlAnyElementAttribute()]
        [System.Xml.Serialization.XmlElementAttribute("Author", typeof(string))]
        [System.Xml.Serialization.XmlElementAttribute("AutoRefresh", typeof(uint))]
        [System.Xml.Serialization.XmlElementAttribute("Body", typeof(BodyType))]
        [System.Xml.Serialization.XmlElementAttribute("Classes", typeof(ClassesType))]
        [System.Xml.Serialization.XmlElementAttribute("Code", typeof(string))]
        [System.Xml.Serialization.XmlElementAttribute("CodeModules", typeof(CodeModulesType))]
        [System.Xml.Serialization.XmlElementAttribute("ConsumeContainerWhitespace", typeof(bool))]
ReportDefinition.cs

 

第二步:创建RDLCGenerator类和TablixRDLCGenerator类

根据下载的Report Definition Language(RDL)和一个创建的简单的RDLC文件,知道RDLC文件基本要有哪几部分组成;然后层层嵌套创建就出来了,很简单。

Tablix是关键数据区,GotReportViewer上面的例子,DynamicMatrix和DynamicTable是根据RDL2005来做的,RDL2008以后,就是一个Tablix:

技术分享
    /// table + matrix = tablix
    /// Microsoft 用一个tablix来支持Table(表), Matrix(矩阵) and List(列表)这三种报表项
    /// 整合了table和matrix的功能
View Code

 

第三步:提取DataGrid的数据

从DataGrid主要拿单元格Width、数据、BindingPath和HeaderName。现在对于DataGridColumn用DataTemplate的不知道咋个提取BindingPath数据,对DataGridHyperlinkColumn也取不到BindingPath。希望有人能热心帮忙

技术分享
      /// <summary>
        /// DataGrid的转换器,从DataGrid里提取出数据源,以及HeaderName、Binding的Path和ActualWidth
        /// </summary>
        /// <param name="dataGrid">包含数据的DatGrid</param>
        /// <param name="dt">DataGrid数据源转换成的DataTable</param>
        /// <param name="headerNames">DataGridColumn.Header</param>
        /// <param name="bindingPaths"> DataGridBoundColumn.Binding.Path</param>
        public static void DataGridAdapter(this DataGrid dataGrid, DataTable dt, List<string> headerNames, List<string> bindingPaths, List<double> widths)
        {
            // 取出DataGridColumn的Header,BingdingPath,ActualWidth为构造rdlc文件准备数据
            headerNames.Clear();
            bindingPaths.Clear();
            widths.Clear();
            for (int index = 0; index < dataGrid.Columns.Count; index++)
            {
                headerNames.Add(dataGrid.Columns[index].Header as string);
                widths.Add(dataGrid.Columns[index].ActualWidth);
                //string tempBindingPath = ((dataGrid.Columns[index] as DataGridBoundColumn).Binding as Binding).Path.Path;
                string tempBindingPath = GetDataGridColumnBindingPath(dataGrid.Columns[index]);
                bindingPaths.Add(tempBindingPath);

                if (String.IsNullOrEmpty(tempBindingPath) == false)
                    dt.Columns.Add(tempBindingPath, typeof(string));
            }

            for (int rowIndex = 0; rowIndex < dataGrid.Items.Count; rowIndex++)
            {
                // 要显示后,才能取到数据
                DataGridRow rowContainer = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex);
                // 因为Peformance问题,EnableRowVirtualization被设置为true,只加载要显示的数据
                // 重新滚动,然后再重用这些DataGridRow
                if (rowContainer == null)
                {
                    dataGrid.UpdateLayout();
                    dataGrid.ScrollIntoView(dataGrid.Items[rowIndex]);
                    rowContainer = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex);
                }
                if (rowContainer != null)
                {
                    DataGridCellsPresenter presenter = DataGridHelper.GetVisualChild<DataGridCellsPresenter>(rowContainer);
                    if (presenter != null)
                    {
                        DataRow dr = dt.NewRow();
                        bool isLastRowAllEmpty = true;
                        for (int columnIndex = 0; columnIndex < bindingPaths.Count; columnIndex++)
                        {
                            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);                           
                            if (cell != null)
                            {
                                if (cell.Content is TextBlock)
                                {
                                    //TODO: DataGridHyperlinkColumn取不到数据
                                    dr[bindingPaths[columnIndex]] = (cell.Content as TextBlock).Text;
                                    if (!String.IsNullOrEmpty((cell.Content as TextBlock).Text)) isLastRowAllEmpty = false;
                                }
                                else if (cell.Content is CheckBox)
                                {
                                    string value = ((cell.Content as CheckBox).IsChecked == true) ? "" : "";
                                    dr[bindingPaths[columnIndex]] = value;
                                }
                                else if (cell.Content is ComboBox)
                                {
                                    dr[bindingPaths[columnIndex]] = (cell.Content as ComboBox).Text;
                                    if (!String.IsNullOrEmpty((cell.Content as ComboBox).Text)) isLastRowAllEmpty = false;
                                }
                            }
                        }

                        if (dataGrid.CanUserAddRows && (rowIndex == dataGrid.Items.Count - 1))
                        {
                            // 如果CanUserAddRows被设置为true,只有最后一行的数据都不为空(CheckBox不算作内),才把数据添加到DataTable
                            if (isLastRowAllEmpty)
                            {
                                continue;
                            }
                        }
                        dt.Rows.Add(dr);
                    }
                }
            }
        }
提取DataGrid数据

 

第四步:填充数据

关键在设置ReportViewer类的LocalReport.ReportPath 和LocalReport.DataSources这两项。

未完,待续(不能把全部源代码贴出来,只写关键部分,一个代码稍稍有点长;另外,虽说全是我写的代码,但毕竟是跟别人打工的,贴出来算不算泄密,被公司开了咋办)

RDLC报表之动态生成报表

标签:schema   字体   ida   one   官网   span   module   system   efi   

原文地址:http://www.cnblogs.com/NaughtyCat/p/6036379.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!