In this example we will be creating the “Media Log” report used in ManagingEnergy.
The first step is to create a new class that extends the base Report.
/// <summary> /// The Media Log Report /// </summary> public class MediaLog : Report { /// <summary> /// The Report Title /// </summary> private const string Title = "Media Log";
/// <summary> /// Constructor /// </summary> /// <param name="dbConnectionString">The database connection string</param> /// <param name="settings">The report settings</param> public MediaLog(string dbConnectionString, ReportSettings settings) : base(MediaLog.Title, settings) { string facCodeList = Helper.CreateCommaSeperatedString(settings.Facilities); DataTable mediaLog = ReportProcedures.Media(dbConnectionString, settings.ProjectID, Helper.CreateCommaSeperatedString(settings.Facilities)); DataTable reportInfo = ReportProcedures.GetReportInfo(dbConnectionString, settings.ProjectID); this.CreateReport(mediaLog, reportInfo); } } |
Since there are no unique setting required for this report, the generic ReportSettings will passed into the constructor. If the report requires specific settings outside the scope provided by the ReportSettings implementation. Extend the ReportSettings class, adding the settings functionality your report requires.
The constructor for the MediaLog report accepts two parameters, the database connection string and the report settings. It then uses the database connection string to connect to the database and retrieve the data tables needed to create the report. In most cases the reports will be created using data directly from a database. However, we should also allow for reports to be created programmatically. To facilitate this flexibility a second constructor (like the one below) has been added to all the existing reports within the ManagingEnergy.Reports namespace.
/// <summary> /// Constructor /// </summary> /// <param name="mediaLogData">The media log data</param> /// <param name="reportInfo">The report info table</param> /// <param name="settings">The report settings</param> public MediaLog(DataTable mediaLogData, DataTable reportInfo, ReportSettings settings) : base(MediaLog.Title, settings) { this.CreateReport(mediaLogData, reportInfo); } |
The next step is to create a method that will process the report data such that it can be rendered in the final report. Following the methodology used in existing ManagingEnergy reports, this is accomplished by the CreateReport method. It accepts, as arguments, the data and report settings needed to render the report. For reports that do not require data processing, the create report method will simply add the data tables to the reports dataset. Since the MediaLog report will be displaying images located on a remote machine, we must map the file path to a valid network path allowing images to be loaded into the report when rendered.
/// <summary> /// Creates the report /// </summary> /// <param name="mediaLogData">The media log data</param> /// <param name="reportInfo">The report info table</param> private void CreateReport(DataTable mediaLogData, DataTable reportInfo) { if (!mediaLogData.Columns.Contains("NetworkPath")) { mediaLogData.Columns.Add("NetworkPath", typeof(string));
// create the network path to the media foreach (DataRow row in mediaLogData.Rows) { string networkPath = Convert.ToString(row["FilePath"]); networkPath = networkPath.Replace(@"R:\", @"\\EXCHServer\ClientMedia\"); row["NetworkPath"] = networkPath; } }
// now add the data tables to the report mediaLogData.TableName = "MediaLog"; this.ReportData.Tables.Add(mediaLogData); reportInfo.TableName = "ReportInfo"; this.ReportData.Tables.Add(reportInfo); } |
COMPONENTONE REPORTS
The report-rendering framework used in ManagingEnergy Web Reports is “Web Reports for ASP.NET” a product of ComponentOne [http://www.componentone.com/]. To make use of this framework a report class called C1ManagingEnergyReport was created which accepts as arguments the Report to render, the report definition xml (created using C1Report Designer) and the name of the report within the definition xml.
ManagingEnergy.Reports.Project.MediaLog report = new ManagingEnergy.Reports.Project.MediaLog(user.DatabaseConnectionString, reportSettings); C1ManagingEnergyReport.c1Report = new C1ManagingEnergyReport(report, reportDefinitionXml, "rptMediaLog"); |
See BossWebReports.ReportHelper class
How Data Is Passed To ComponentOne Reports
Using the C1ManagingEnergyReport class to display a ManagingEnergy Report appears to be a fairly straight forward process. However, ComponentOne also support the concept of sub reports. A sub reports as the name suggests is a report which is embedded within a parent or containing report. Since the Report class does not define nor dictate the final report appearance or structure you may be wondering how to pass data to a specific ComponentOne sub report? Though not obvious, the primary job of the C1ManagingEnergyReport class is to pass Report data to the proper sections of the ComponentOne report. The first DataTable in ReportData is passed to the main report. Sub reports will be paired with the DataTable matching its name. For instance a DataTable named “ReportInfo” will be passed to a sub report called “ReportInfo”. This matching process is attempted for each sub report.
The MediaLog report is complete. It may now be used in conjunction with a report-rendering framework to transform the report data into a viewable report.