Imagine you have a report that displays some data and the number of columns cannot be defined at the design stage, i.e. the number of columns depends on user input. That seems to cause some problems when you want to render this report with Reporting Services…
Note: The described solution applies to the case when RDLC files are used by
ReportViewer control in local mode. However, it can be simply tweaked so it works in general.
Because the number of columns that should be displayed on the report can be named only at runtime it seems reasonable to update the RDLC file and only then deliver the report. RDLC is an XML file that contains the definition of the report – styling and all fields displayed. So all you need to do is to read the RLDC file into
XmlDocument, get some nodes and update them.
This is how this can be done. In the RDLC file locate
/Report/Body/ReportItems/Table node and do the following inside it:
- define the header of a new column – add a new
- bind the column with data (from
DataTable) – add a new
- define the width of the colum – add a new
Apart from that you need to modify the definition of the
DataSet that will ship the data. It is defined as a
Field node within
The easiest way to add new nodes is to get its parent, copy its last child and update the copy with appropriate values, and add it as the new last child. This way you will probably have to update only a couple of strings instead of creating the new node which has another nodes as children etc.
Then you need to create a
DataTable object, populate it with data and bind it with the ReportViewer as its data source.
ReportDataSource rds = new ReportDataSource(DS_NAME, DATA_TABLE); ReportViewer1.LocalReport.ReportPath = string.Empty; ReportViewer1.LocalReport.DataSources.Clear(); ReportViewer1.LocalReport.DataSources.Add(rds); byte rdlBytes = Encoding.UTF8.GetBytes(XML_DOC.OuterXml); MemoryStream stream = new MemoryStream(rdlBytes); ReportViewer1.LocalReport.LoadReportDefinition(stream);
- DS_NAME – name of the data set, which is used in RDLC file (
- DATA_TABLE – DataTable object that ships data (
- XML_DOC –
XmlDocumentthat contains the (updated) definition of RDLC file
That should do the trick. However playing with
XmlDocument is not on of the most enjoyable games