Dynamic report generation of RDLC reports

Source: Internet
Author: User

First of all, we must thank and Salute Waxman Zhang:

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

2. Microsoft Gotreportviewer Official case:

http://www.gotreportviewer.com/(about 20 or so, very detailed.) Sometimes it doesn't.)

The previous time, did the RDLC report, mainly is three block function:

1, extract data from the DataGrid, and then create the corresponding RDLC report file, to take advantage of the ReportViewer class of printing and typesetting function (which made a general function of extracting data, can extract any control data; As long as the mosaic into a DataTable this mesh lattice is good)

2, to a simple rdlc template to provide the table header font format and table internal data and other styles related information, and then use the data extracted from the DataGrid to populate the report

3, made a TreeView, very simple; depending on the name of the report file, toggle item on the left tree to load different reports and display the data. With a little bit of reflective knowledge.

First step: Generate the corresponding classes and namespaces according to the report Definition Language (RDL).

1, to

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

Download reportdefinition2010.xsd.

Note: There is a time difference between reportdefinition and Visual Studio, with 2005 and 2008 versions on the official website. Version 2005, VS2008 later support, 2008 version, VS2010 later support. Version 2010, to VS2012

Support later. Mine is VS2010, using the 2008 version.

2, find the XML Schema Definition Tool (Xsd.exe), the Windows operating system will bring it. 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

It's finished, it's like this.

usingSystem.Xml.Serialization; /// <remarks/>[System.CodeDom.Compiler.GeneratedCodeAttribute ("xsd","2.0.50727.3038")] [System.SerializableAttribute ()] [System.Diagnostics.DebuggerStepThroughAttribute ()] [System.componentmode L.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 classReport {Private Object[] Itemsfield; Privateitemschoicetype80[] Itemselementnamefield; Privatesystem.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

Step Two: Create the Rdlcgenerator class and the Tablixrdlcgenerator class

Based on the downloaded report Definition Language (RDL) and a simple rdlc file created, it is easy to know which parts of the rdlc file are basically composed, and then the layers are created in a nested form.

The Tablix is the key data area, gotreportviewer the above example, Dynamicmatrix and dynamictable are done according to RDL2005, RDL2008 later, is a tablix:

    /// table + matrix = Tablix     /// Microsoft uses a Tablix to support table (table), Matrix, and List (list) of three report items     /// integration of table and matrix functions
View Code

Step three: Extract data from the DataGrid

From the DataGrid, the cell width, data, Bindingpath, and headername are mostly taken. Now for DataGridColumn with DataTemplate do not know why did extract Bindingpath data, Datagridhyperlinkcolumn also do not take bindingpath. I hope someone will be helpful.

      /// <summary>        ///a DataGrid converter that extracts data sources from the DataGrid, as well as the headername, binding path, and ActualWidth/// </summary>        /// <param name= "DataGrid" >Datgrid that contain data</param>        /// <param name= "DT" >DataTable converted to DataGrid data source</param>        /// <param name= "Headernames" >Datagridcolumn.header</param>        /// <param name= "Bindingpaths" >DataGridBoundColumn.Binding.Path</param>         Public Static voidDatagridadapter ( ThisDataGrid DataGrid, DataTable DT, list<string> Headernames, list<string> Bindingpaths, list<Double>widths) {            //Remove DataGridColumn header,bingdingpath,actualwidth to prepare data for the construction RDLC fileheadernames.clear ();            Bindingpaths.clear (); Widths.            Clear ();  for(intindex =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;                stringTempbindingpath =Getdatagridcolumnbindingpath (Datagrid.columns[index]);                Bindingpaths.add (Tempbindingpath); if(String.IsNullOrEmpty (tempbindingpath) = =false) dt. Columns.Add (Tempbindingpath,typeof(string)); }             for(intRowIndex =0; RowIndex < DataGrid.Items.Count; rowindex++)            {                //To be displayed before the data is takenDataGridRow Rowcontainer =(DataGridRow) DataGrid.ItemContainerGenerator.ContainerFromIndex (RowIndex); //because of the peformance problem, Enablerowvirtualization is set to true to load only the data to be displayed//re-scroll, and then reuse these 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 (); BOOLIslastrowallempty =true;  for(intColumnIndex =0; ColumnIndex < Bindingpaths.count; columnindex++) {DataGridCell cell=(DataGridCell) presenter.                                                       Itemcontainergenerator.containerfromindex (columnindex); if(Cell! =NULL)                            {                                if(Cell. Content isTextBlock) {                                    //Todo:datagridhyperlinkcolumn data not being takenDr[bindingpaths[columnindex]] = (cell. Content asTextBlock).                                    Text; if(! String.IsNullOrEmpty (cell. Content asTextBlock). Text)) Islastrowallempty =false; }                                Else if(Cell. Content isCheckBox) {                                    stringValue = ((cell. Content asCheckBox). IsChecked = =true) ?"is a":"No"; Dr[bindingpaths[columnindex]]=value; }                                Else if(Cell. Content isComboBox) {Dr[bindingpaths[columnindex]]= (cell. Content asComboBox).                                    Text; if(! String.IsNullOrEmpty (cell. Content asComboBox). Text)) Islastrowallempty =false; }                            }                        }                        if(Datagrid.canuseraddrows && (RowIndex = = DataGrid.Items.Count-1))                        {                            //if Canuseraddrows is set to true, only the last row of data is not empty (checkbox does not count as inside) to add data to the DataTable                            if(islastrowallempty) {Continue; }} dt.                    Rows.Add (DR); }                }            }        }
extracting DataGrid Data

Fourth step: Populating the data

The key is to set the Localreport.reportpath and Localreport.datasources of the ReportViewer Class.

Not finished, to be continued (can not put all the source code, only write the key part, a little bit long code, in addition, although all I write code, but after all, is working with others, posted out is not a leak, the company opened what to do)

Dynamic report generation of RDLC reports

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.