Search results
PDF

Render subreport

You can display another report inside the body of main report using the Report Viewer. The following steps help you to customize the subreport properties such as data source, report path, and parameters.

  1. Add the sub report and main reports to the application wwwroot/Resources folder. In this tutorial, the already created reports are used. Refer to the Create RDL Report section or Create RDLC Report section section.

    Download the Side_By_SideMainReport.rdl, Side_By_SideSubReport.rdl reports from here. You can add a report from the Bold Reports installation location. For more information, refer to Samples and demos. The reports used from installed location requires NorthwindIO_Reports.sdf database to run, so add the database to your application.

  • Set the report-path, processing-mode, and report-service-url properties of the Report Viewer as in the following code snippet.

    The following code example demonstrates how to load a subreport in the Report Viewer at client side.

        <bold-report-viewer id="viewer" report-service-url="/api/ReportViewer" report-path="Side_By_SideMainReport.rdl" processing-mode="Remote"></bold-report-viewer>

    The following code example demonstrates how to load a subreport in the Report Viewer at server side.

        public class ReportViewerController : Controller, IReportController
        {
            // Report viewer requires a memory cache to store the information of consecutive client request and
            // have the rendered report viewer information in server.
            private Microsoft.Extensions.Caching.Memory.IMemoryCache _cache;
    
            // IWebHostEnvironment used with sample to get the application data from wwwroot.
            private Microsoft.AspNetCore.Hosting.IWebHostEnvironment _hostingEnvironment;
    
            // Post action to process the report from server based json parameters and send the result back to the client.
            public ReportViewerController(Microsoft.Extensions.Caching.Memory.IMemoryCache memoryCache,
                Microsoft.AspNetCore.Hosting.IWebHostEnvironment hostingEnvironment)
            {
                _cache = memoryCache;
                _hostingEnvironment = hostingEnvironment;
            }
    
            // Post action to process the report from server based json parameters and send the result back to the client.
            [HttpPost]
            public object PostReportAction([FromBody] Dictionary<string, object> jsonArray)
            {
                return ReportHelper.ProcessReport(jsonArray, this, this._cache);
            }
    
            // Method will be called to initialize the report information to load the report with ReportHelper for processing.
            [NonAction]
            public void OnInitReportOptions(ReportViewerOptions reportOption)
            {
                string basePath = _hostingEnvironment.WebRootPath;
                // Here, we have loaded the Side_By_SideSubReport.rdl report from application the folder wwwroot\Resources and loads the sub report stream.
                if (reportOption.SubReportModel != null)
                {
                    FileStream inputSubStream = new FileStream(basePath + @"\Resources\" + reportOption.SubReportModel.ReportPath, FileMode.Open, FileAccess.Read);
                    MemoryStream SubStream = new MemoryStream();
                    inputSubStream.CopyTo(SubStream);
                    SubStream.Position = 0;
                    inputSubStream.Close();
                    reportOption.SubReportModel.Stream = SubStream;
                }
                else
                {
                    FileStream inputStream = new FileStream(basePath + @"\Resources\" + reportOption.ReportModel.ReportPath, FileMode.Open, FileAccess.Read);
                    MemoryStream reportStream = new MemoryStream();
                    inputStream.CopyTo(reportStream);
                    reportStream.Position = 0;
                    inputStream.Close();
                    reportOption.ReportModel.Stream = reportStream;
                }
            }
    
            // Method will be called when reported is loaded with internally to start to layout process with ReportHelper.
            [NonAction]
            public void OnReportLoaded(ReportViewerOptions reportOption)
            {
            }
    
            //Get action for getting resources from the report
            [ActionName("GetResource")]
            [AcceptVerbs("GET")]
            // Method will be called from Report Viewer client to get the image src for Image report item.
            public object GetResource(ReportResource resource)
            {
                return ReportHelper.GetResource(resource, this, _cache);
            }
    
            [HttpPost]
            public object PostFormReportAction()
            {
                return ReportHelper.ProcessReport(null, this, _cache);
            }
        }

Change subreport path

To change the subreport file path, set the Stream property of SubReportModel in the OnInitReportOptions method.

        [NonAction]
        public void OnInitReportOptions(ReportViewerOptions reportOption)
        {
            if (reportOption.SubReportModel != null)
            {
                FileStream inputSubStream = new FileStream(basePath + @"\Resources\" + reportOption.SubReportModel.ReportPath, FileMode.Open, FileAccess.Read);
                MemoryStream SubStream = new MemoryStream();
                inputSubStream.CopyTo(SubStream);
                SubStream.Position = 0;
                inputSubStream.Close();
                reportOption.SubReportModel.Stream = SubStream;
            }
        }

Set subreport parameter

You can change the parameter default values of a subreport in the OnReportLoaded method of the Web API Controller as given in the following code snippet.

        [NonAction]
        public void OnReportLoaded(ReportViewerOptions reportOption)
        {
            if (reportOption.SubReportModel != null)
            {
                reportOption.SubReportModel.Parameters = new BoldReports.Web.ReportParameterInfoCollection();
                reportOption.SubReportModel.Parameters.Add(new BoldReports.Web.ReportParameterInfo()
                {
                    Name = "SalesPersonID",
                    Values = new List<string>() { "2" }
                });
            }
        }

Modify subreport data source connection string

You can change the credential and connection information of the data sources used in the subreport using the SubReportModel in the OnInitReportOptions method.

        [NonAction]
        public void OnInitReportOptions(ReportViewerOptions reportOption)
        {
            if (reportOption.SubReportModel != null)
            {
                reportOption.SubReportModel.DataSourceCredentials = new List<BoldReports.Web.DataSourceCredentials>();
                BoldReports.Web.DataSourceCredentials dataSourceCredentials = new BoldReports.Web.DataSourceCredentials();
                dataSourceCredentials.Name = "<database>";
                dataSourceCredentials.ConnectionString = "Data Source=<instancename>;Initial Catalog=<database>;user id=<username>;password=<password>";
                reportOption.SubReportModel.DataSourceCredentials.Add(dataSourceCredentials);
            }
        }

Set subreport data source

You can bind local business object data source collection only for RDLC reports. To specify data source of a RDLC subreport, set the ReportDataSource property in the OnReportLoaded method.

The RDL report has the connection information in report definition itself, so no need to bind data source.

  1. Add the RDLC sub report and main reports to your application wwwroot/Resources folder. You can downloaded it from here.

  2. Set the report-path, processing-mode, and report-service-url properties of the Report Viewer as shown in following code snippet.

        <bold-report-viewer id="viewer" report-service-url="/api/ReportViewer" report-path="Product List Main.rdlc" processing-mode="Local"></bold-report-viewer>
  3. Create a class and methods that returns business object data collection. Use the following code in the application Web API Service.

    public class ProductList
    {
        public string ProductName { get; set; }
        public string OrderId { get; set; }
        public double Price { get; set; }
        public string Category { get; set; }
        public string Ingredients { get; set; }
        public string ProductImage { get; set; }
    
        public static IList GetData()
        {
            List<ProductList> datas = new List<ProductList>();
            ProductList data = null;
            data = new ProductList()
            {
                ProductName = "Baked Chicken and Cheese",
                OrderId = "323B60",
                Price = 55,
                Category = "Non-Veg",
                Ingredients = "grilled chicken, corn and olives.",
                ProductImage = ""
            };
            datas.Add(data);
            data = new ProductList()
            {
                ProductName = "Chicken Delite",
                OrderId = "323B61",
                Price = 100,
                Category = "Non-Veg",
                Ingredients = "cheese, chicken chunks, onions & pineapple chunks.",
                ProductImage = ""
            };
            datas.Add(data);
            data = new ProductList()
            {
                ProductName = "Chicken Tikka",
                OrderId = "323B62",
                Price = 64,
                Category = "Non-Veg",
                Ingredients = "onions, grilled chicken, chicken salami & tomatoes.",
                ProductImage = ""
            };
            datas.Add(data);
    
            return datas;
        }
    }
  4. Bind the business object data values collection to the subreport by adding a new item to the DataSources as shown in the following code snippet.

        [NonAction]
        public void OnReportLoaded(ReportViewerOptions reportOption)
        {
            //Assigning the data source for 'Product List.rdlc'
            if (reportOption.SubReportModel != null)
            {
                reportOption.SubReportModel.DataSources = new BoldReports.Web.ReportDataSourceCollection();
                reportOption.SubReportModel.DataSources.Add(new BoldReports.Web.ReportDataSource { Name = "list", Value = ProductList.GetData() });
            }
        }

The data source name is case sensitive, it should be same as in the report definition.

Load subreport stream

To load subreport as stream, set the Stream property in the OnInitReportOptions method.

        [NonAction]
        public void OnInitReportOptions(ReportViewerOptions reportOption)
        {
            string basePath = _hostingEnvironment.WebRootPath;

            if (reportOption.SubReportModel != null)
            {
                // Here, we have loaded the Product List.rdlc report from application the folder wwwroot\Resources and loads the sub report stream.
                FileStream inputSubStream = new FileStream(basePath + @"\Resources\" + reportOption.SubReportModel.ReportPath, FileMode.Open, FileAccess.Read);
                MemoryStream SubStream = new MemoryStream();
                inputSubStream.CopyTo(SubStream);
                SubStream.Position = 0;
                inputSubStream.Close();
                reportOption.SubReportModel.Stream = SubStream;
            }
            else
            {
                FileStream inputStream = new FileStream(basePath + @"\Resources\" + reportOption.ReportModel.ReportPath, FileMode.Open, FileAccess.Read);
                MemoryStream reportStream = new MemoryStream();
                inputStream.CopyTo(reportStream);
                reportStream.Position = 0;
                inputStream.Close();
                reportOption.ReportModel.Stream = reportStream;
            }
        }
        [NonAction]
        public void OnReportLoaded(ReportViewerOptions reportOption)
        {
            //Assigning the data source for 'Product List.rdlc'
            if (reportOption.SubReportModel != null)
            {
                reportOption.SubReportModel.DataSources = new BoldReports.Web.ReportDataSourceCollection();
                reportOption.SubReportModel.DataSources.Add(new BoldReports.Web.ReportDataSource { Name = "list", Value = ProductList.GetData() });
            }
        }