What You Will Need
- ActiveReports.NET
- Visual Studio
- SMTP server (optional)
- Windows Task Scheduler (optional)
Tutorial Concept
Transform manual reporting tasks into an efficient, error-free process by leveraging ActiveReports.NET with C# .NET. This guide demonstrates how to schedule C# .NET reports and automate report generation, exporting, and distribution, providing timely insights to stakeholders seamlessly.
Section 1: Introduction
In today’s fast-paced development world, manual workflows can slow down reporting processes and lead to missed opportunities or delays in critical business insights. For development teams using .NET environments and ActiveReports.NET, automation presents a strategic advantage, allowing reports to be generated, scheduled, and distributed seamlessly. This blog explores best practices and techniques to help you implement automated report generation and distribution, improving your reporting workflow's efficiency and reliability.
Why Automate Reporting?
Automated reporting offers several benefits:
- Increased Efficiency: Automated workflows remove the need for repetitive manual tasks, freeing up time for more strategic work.
- Enhanced Accuracy: Reducing manual steps helps eliminate human error, making report delivery more reliable.
- Timely Insights: Scheduled reports ensure that stakeholders receive up-to-date data when needed, enabling faster and more informed decision-making.
By automating reporting processes with ActiveReports.NET, you gain better control over report timing, customization, and distribution while keeping manual intervention to a minimum.
What You'll Learn
This guide covers:
- A streamlined guide for setting up report automation using core ActiveReports.NET API calls.
- A comprehensive walkthrough of building a fully-featured report automation application.
- Scheduling your reports using Windows Task Scheduler to run automatically at intervals you define.
With these tools and techniques, you can automate your reporting processes and deliver timely, data-rich insights directly to stakeholders.
Required Tools and Libraries
To create and run the automated report solution, you’ll need the following:
1. ActiveReports.NET (The free trial is adequate for testing!)
- ActiveReports.NET is the core reporting library for creating, rendering, and exporting reports in various formats like PDF, Excel, Word, and more.
- Steps to add NuGet packages (covered in the guide sections).
- Installation (optional): You can download and install ActiveReports.NET from the MESCIUS website.
- If you are not a licensed customer, the free trial will suffice. Everything will work as expected, but exports will have watermarks.
2. Development Environment
- Visual Studio: Visual Studio is the only officially supported IDE for ActiveReports.NET.
- .NET SDK: Ensure that you have the appropriate .NET SDK installed (this guide assumes .NET 5 or later).
3. SMTP Access (optional)
- To send reports via email, you’ll need access to an SMTP service, along with the credentials and port information.
- If you’re testing locally, services like Mailtrap (free) or Gmail SMTP can be configured for development purposes.
4. Windows Task Scheduler (optional)
- This guide will use Windows Task Scheduler, but you can easily use another task-scheduling solution to run applications and pass in arguments.
Section 2: How-To Guide - Simplified Automation Code
This section provides a streamlined guide using minimal code to demonstrate only the essential ActiveReports.NET API calls. We will cover how to load an RDLX report, set a parameter, render it as a PDF, and export it to a specified directory.
This example is ideal if you want to quickly understand how ActiveReports.NET can be used for basic report automation without additional features like command-line parsing or email integration.
You can also download our pre-built simplified report automation sample.
2.1 Essential Code Snippets
The code to perform a simple report load, parameter setting, rendering, and export process is as follows:
using GrapeCity.ActiveReports;
using GrapeCity.ActiveReports.Document;
// Provide the RDLX report you want to render
var reportName = "TestReport";
var rptPath = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Reports", $"{reportName}.rdlx"));
var pageReport = new PageReport(rptPath);
var runTime = new PageDocument(pageReport);
Console.WriteLine("Loaded " + reportName);
// Set the parameter value
var parameterName = "SortBy";
var parameterValue = "StockValue";
runTime.Parameters[parameterName].CurrentValue = parameterValue;
// Create an output directory
var outputDirectory = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Exports"));
outputDirectory.Create();
// Provide settings for your rendering output
var pdfSettings = new GrapeCity.ActiveReports.Export.Pdf.Page.Settings();
// Set the rendering extension and render the report
var pdfRenderingExtension = new GrapeCity.ActiveReports.Export.Pdf.Page.PdfRenderingExtension();
var outputProvider = new GrapeCity.ActiveReports.Rendering.IO.FileStreamProvider(outputDirectory, Path.GetFileNameWithoutExtension(reportName))
{
// Overwrite output file if it already exists
OverwriteOutputFile = true
};
pageReport.Document.Render(pdfRenderingExtension, outputProvider, pdfSettings);
Console.WriteLine("Exported " + reportName);
2.2 Key Code Sections Explained
1. Loading the Report
The report file (TestReport.rdlx
) is loaded using PageReport
. The runTime
variable creates a PageDocument
instance, which is required to render and export the report.
2. Setting the Parameter
In this example, we set a parameter named SortBy
with the value StockValue
. This allows you to control report filtering or sorting dynamically at runtime.
3. Creating an Output Directory
The code checks if the Exports
folder exists, and if not, creates it. This is where the exported PDF will be saved.
4. Setting Rendering Options and Exporting the Report
- We configure the
pdfSettings
and definepdfRenderingExtension
to specify that the report should be rendered as a PDF. -
FileStreamProvider
handles the output file, saving it in theExports
folder with the report name (TestReport.pdf
). - Finally,
pageReport.Document.Render
processes and saves the report in the chosen format.
2.3 How to Run the Code
- Save this code in a new console application.
- Ensure the
Reports
andExports
folders exist in the executable directory. - Place a
.rdlx
report file namedTestReport.rdlx
in theReports
folder. - Run the console application. It will load the report, set the parameter, render it, and export it as a PDF in the
Exports
folder.
That’s all you need to know to get started with creating your own report automation application! In the next section, we’ll dive deeper, covering how to expand this application with command-line argument parsing, multi-format exporting, and email integration.
Section 3: Comprehensive Guide - Fully Functional Report Automation Console Application
This section expands on the simplified example by breaking down a fully functional report automation console application. This version includes advanced features like command-line argument parsing, multi-format exporting, and email distribution. Each component of the application is broken down to help you understand how everything works together.
You can download the full, heavily commented, pre-built sample application to follow along.
If you decide to follow along and build it yourself, much of the code will be broken until everything is put in place (due to breaking it down for the sake of creating this guide), but everything will come together by the end!
3.1 Project Structure and Initial Setup
1. Create the Project
- In Visual Studio, create a new Console Application project.
2. Create Resource Folders
- To keep the project organized, open the project in File Explorer and add two specific folders:
Reports
andExports
. - In our project, we’ve configured the folder paths to exist in the same directory as the executable file so that after deployment, all of them will be in the same directory.
- In our case, this directory is
ReportAutomation\bin\Debug\net8.0
. - Feel free to place them somewhere else—just remember to change the paths in the code as well!
- In our case, this directory is
3. Add NuGet Packages
Open the NuGet Package Manager and browse for the following ActiveReports.NET NuGet packages:
-
MESCIUS.ActiveReports
- Any ActiveReports export dependencies that you wish to include, such as:
-
MESCIUS.ActiveReports.Export.Excel
-
MESCIUS.ActiveReports.Export.Html
-
MESCIUS.ActiveReports.Export.Pdf
-
MESCIUS.ActiveReports.Export.Word
-
MESCIUS.ActiveReports.Export.Excel
-
4. Add Using Statements
- Add the System/.NET and ActiveReports.NET using statements to the beginning of
Program.cs
:
using System.Text;
using System.Net;
using System.Net.Mail;
using System.Collections.Specialized;
using GrapeCity.ActiveReports;
using GrapeCity.ActiveReports.Extensibility.Rendering;
3.2 Defining the Workflow in the Main Method
The Main
method is where everything comes together. It takes the command-line arguments, processes them, and uses each of the methods we’ll cover in the following sections to complete the report generation, export, and emailing tasks. This method acts as the control center for the application, handling the sequence of operations and checking for conditions (like email addresses) before proceeding with each step.
Below is the full Main
method from Program.cs
:
static void Main(string[] args)
{
// Inject arguments for testing if no arguments are provided
InjectTestArguments(ref args);
// Extract the report name from the arguments
string reportName = args[0];
// Extract the report parameters and email addresses from the arguments
var parameters = new Dictionary<string, object>();
var emails = new List<string>();
// Define default export type as PDF
string exportType = "pdf";
// Parse the arguments to extract parameters, emails, and export type
ParseArguments(args, parameters, emails, ref exportType);
// Set rendering extension and settings based on export file format defined in args
IRenderingExtension renderingExtension;
NameValueCollection settings;
GetRenderingSettings(exportType, out renderingExtension, out settings);
// Define the date and time of report rendering beforehand to ensure that the same time is used in all places
var currentDateTime = DateTime.Now;
// Define what the exported file will be called
var exportFileName = reportName + " " + currentDateTime.ToString("yyyy-MM-dd HH.mm.ss");
// Call method to process the report: load, set parameters, and export
var (report, reportRunTime) = LoadReport(reportName);
SetReportParameters(reportRunTime, parameters);
CreateOutputDirectory();
RenderAndExportReport(report, exportFileName, renderingExtension, settings);
// Check if any emails were provided. If so, call the method to send out emails
if (emails.Count > 0)
{
var exportedFilePath = Path.Combine(GetAppDirectory(), "Exports", exportFileName + "." + exportType.ToLower());
EmailReport(reportName, exportedFilePath, currentDateTime, emails, parameters);
}
}
Explanation of the Main Method
We will cover each of these in more detail with code examples in the following sections as we dive into the methods called by Main
.
1. Inject Test Arguments
- The
InjectTestArguments
method is called if no arguments are provided. This is useful for development and testing purposes, allowing the application to run with preset arguments instead of requiring input every time. - For production use, arguments would typically be supplied when executing the application, bypassing this function.
2. Extracting the Report Name
- The first argument (
args[0]
) is always assumed to be the report name. This name is used to locate the report file in theReports
directory. - The report name also serves as the basis for the export file name, making it easy to identify exports.
3. Initializing Parameters and Email Lists
-
parameters
andemails
dictionaries are initialized to hold parsed command-line arguments for report parameters and email addresses.
4. Setting Default Export Type
- The
exportType
variable is initialized to"pdf"
as the default format. If theformat
argument is supplied, this value will be overwritten in the next step.
5. Parsing Arguments
- The
ParseArguments
method processesargs
, updatingparameters
,emails
, andexportType
based on the provided values. - After parsing, the application has all the details it needs to configure the report, including specific parameters, the export format, and email recipients.
6. Defining Rendering Extension and Settings
- Based on the
exportType
, theGetRenderingSettings
method sets the appropriaterenderingExtension
andsettings
. These determine how the report is rendered (PDF, Excel, CSV, etc.).
7. Setting the Export File Name with a Timestamp
-
currentDateTime
is captured before rendering to ensure consistency in timestamps. -
exportFileName
combines the report name and date-time stamp, helping prevent overwrites and aiding version tracking.
8. Loading the Report
- The
LoadReport
method loads the specified.rdlx
file and returns both thePageReport
instance (report definition) andPageDocument
(runtime instance). - These instances are needed to configure the report with dynamic parameters and export it.
9. Setting Parameters
-
SetReportParameters
applies any parsed parameters to the report. This step customizes the report’s data, filtering, or sorting based on the user’s input.
10. Creating the Output Directory
- The
CreateOutputDirectory
method ensures that theExports
folder exists, so the export can be saved without errors.
11. Rendering and Exporting the Report
-
RenderAndExportReport
handles the actual rendering and saving of the report, using the configuredrenderingExtension
,settings
, andexportFileName
. - This step completes the report generation and saves the output to the
Exports
directory.
12. Sending the Exported Report via Email
- After exporting, the method checks if any email addresses were provided.
- If there are recipients in the
emails
list,EmailReport
is called to send the exported file to each address. -
exportedFilePath
is constructed to specify the exact location of the exported report file, which is attached to the email.
3.3 Command-Line Argument Parsing
Our application will accept arguments for various report settings, making it flexible and easy to integrate with other systems. These command-line arguments let users specify:
- The report name to load
- Report parameters
- Email addresses for report distribution
- The export format (PDF, Excel, etc.)
The code for parsing command-line arguments, as seen in the Program.cs
file, is as follows:
static void ParseArguments(string[] args, Dictionary<string, object> parameters, List<string> emails, ref string exportType)
{
for (int i = 1; i < args.Length; i++)
{
// Isolate emails from arguments
if (args[i].StartsWith("email:", StringComparison.OrdinalIgnoreCase))
{
// Add email addresses
var email = args[i].Substring("email:".Length);
emails.Add(email);
}
// Isolate export format from arguments
else if (args[i].StartsWith("format:", StringComparison.OrdinalIgnoreCase))
{
// Set export format type
exportType = args[i].Substring("format:".Length);
}
else
{
// Process as parameter in the form "ParameterName=Value1,Value2"
var paramParts = args[i].Split('=');
if (paramParts.Length == 2)
{
var paramName = paramParts[0];
var paramValue = paramParts[1];
// Check for multi-value parameter (comma-separated)
if (paramValue.Contains(','))
{
parameters[paramName] = paramValue.Split(','); // Store as array for multi-value
}
else
{
parameters[paramName] = paramValue; // Store as single value
}
}
else
{
Console.WriteLine($"Invalid parameter format: {args[i]}");
}
}
}
}
Explanation of Argument Parsing Code
1. Extracting Emails
Each argument that starts with "email:"
is identified as an email address. The application strips the "email:"
prefix and adds the email address to a list of recipient addresses.
2. Determining Export Format
The "format:"
prefix is used to specify the export type (e.g., PDF, Excel, CSV). If this argument is present, the application sets the exportType
variable to the specified format.
3. Setting Report Parameters
Other arguments, structured as ParameterName=Value
, are assumed to be report parameters. If a parameter contains multiple values separated by commas (e.g., Categories=Beverages,Seafood
), it’s stored as an array. Single values are stored as strings.
4. Error Handling
If an argument isn’t in the expected format, the application logs a warning to indicate that it couldn’t parse the argument correctly.
Example of Command-Line Usage
Below is an example of how to pass command-line arguments to the application:
ReportAutomation.exe TestReport Categories=Beverages,Seafood SortBy=StockValue email:example@example.com format:pdf
In this example:
-
TestReport
: Specifies the report name. -
Categories=Beverages,Seafood
: Sets theCategories
parameter with multiple values. -
SortBy=StockValue
: Sets theSortBy
parameter toStockValue
. -
email:example@example.com
: Adds an email address to the recipient list. -
format:pdf
: Sets the export format to PDF.
This flexible argument parsing enables users to customize each report generation without modifying the code, making the application adaptable to various workflows and easy to integrate with existing task scheduling tools.
3.4 Loading the Report and Setting Parameters
Once the application parses the command-line arguments, the next step is to load the specified report and set any provided parameters. This section focuses on handling the report file and configuring it with dynamic parameters to customize the data presented in each export.
Loading the Report
The application loads the report using the PageReport
and PageDocument
classes from ActiveReports.NET. This setup allows the application to handle .rdlx
report definition files and render them in various formats.
static (PageReport report, GrapeCity.ActiveReports.Document.PageDocument reportRunTime) LoadReport(string reportName)
{
Console.WriteLine(reportName);
// Provide the Page report you want to render.
var reportPath = new FileInfo(Path.Combine(GetAppDirectory(), "Reports", $"{reportName}.rdlx"));
var report = new PageReport(reportPath);
var reportRunTime = new PageDocument(report);
Console.WriteLine(" - Loaded");
return (report, reportRunTime);
}
Explanation of the LoadReport Method
1. Report Path Construction
- The report’s path is generated by combining the base directory with the
Reports
folder and the report file name (e.g.,TestReport.rdlx
). - This allows the application to load different reports based on the
reportName
argument passed.
2. PageReport and PageDocument Instances
-
PageReport
loads the.rdlx
file, whilePageDocument
provides a runtime instance that enables rendering. - This setup is essential for loading, rendering, and exporting the report.
3. Return Values
- The method returns a tuple with the
PageReport
andPageDocument
instances, making them accessible for rendering and setting parameters in subsequent steps.
Setting Report Parameters
Once the report is loaded, the application can configure parameters that control the report's filtering, sorting, or data customization. The SetReportParameters
method takes the parameters dictionary (parsed from the command line) and applies these to the report.
static void SetReportParameters(GrapeCity.ActiveReports.Document.PageDocument reportRunTime, Dictionary<string, object> parameters)
{
// Set parameters in the report
foreach (var param in parameters)
{
if (reportRunTime.Parameters.Contains(param.Key))
{
var parameter = reportRunTime.Parameters[param.Key];
// Check if the parameter value is a string[] (multi-value) or a single value
if (param.Value is string[] multiValueArray)
{
// Set multi-value parameter
parameter.CurrentValue = multiValueArray;
}
else if (param.Value is string singleValue)
{
// Set single-value parameter
parameter.CurrentValue = singleValue;
}
else
{
Console.WriteLine($"Parameter '{param.Key}' not found in the report.");
}
}
else
{
Console.WriteLine($"Parameter '{param.Key}' not found in the report.");
}
}
}
Explanation of the SetReportParameters Method
1. Iterating Over Parameters
- The method iterates through each key-value pair in the
parameters
dictionary. Each entry represents a report parameter specified via the command line.
2. Checking for Valid Parameters
- For each parameter, the application checks if it exists in the report (
reportRunTime.Parameters.Contains(param.Key)
). If it does, it retrieves the corresponding parameter object.
3. Handling Multi-Value Parameters
- If the parameter’s value is an array (e.g.,
Categories=Beverages,Seafood
), it’s treated as a multi-value parameter. This enables filtering or sorting based on multiple criteria.
4. Setting Single-Value Parameters
- If the parameter’s value is a single string, it’s assigned directly to
CurrentValue
of the report parameter. This supports simple, single-value filtering (e.g.,SortBy=StockValue
).
5. Error Messages for Missing Parameters
- If a parameter specified in the command-line arguments is not found in the report definition, the application logs a message to the console. This helps identify issues with incorrect or outdated parameter names.
Example Scenario
Suppose you want to generate a report with the following parameters:
Categories=Beverages,Seafood SortBy=StockValue
The application will:
- Find the
Categories
parameter in the report and set it with multiple values:Beverages
andSeafood
. - Locate the
SortBy
parameter and set it toStockValue
.
3.5 Defining Export Formats and Rendering the Report
In this section, we’ll define how the application handles multiple export formats. ActiveReports.NET supports a variety of formats (PDF, Excel, Word, etc.), and this flexibility is essential for generating reports that meet different requirements.
The GetRenderingSettings
method in the code configures the rendering settings based on the specified format. This function selects the appropriate ActiveReports.NET rendering extension and applies custom settings as needed.
Supported Export Formats
The application can export reports in the following formats:
- PDF (
pdf
) - Excel (
xlsx
) - CSV (
csv
) - Word (
docx
) - HTML (MHT) (
mht
) - JSON (
json
)
Setting the Rendering Extension and Settings
Below is the code for configuring the rendering extension and settings based on the selected export format:
static void GetRenderingSettings(string exportType, out IRenderingExtension renderingExtension, out NameValueCollection settings)
{
var exportTypeLower = exportType.ToLower();
switch (exportTypeLower)
{
case "pdf":
// Use PDF rendering extension and settings
renderingExtension = new GrapeCity.ActiveReports.Export.Pdf.Page.PdfRenderingExtension();
settings = new GrapeCity.ActiveReports.Export.Pdf.Page.Settings();
break;
case "xlsx":
// Use Excel rendering extension and settings
renderingExtension = new GrapeCity.ActiveReports.Export.Excel.Page.ExcelRenderingExtension();
var excelSettings = new GrapeCity.ActiveReports.Export.Excel.Page.ExcelRenderingExtensionSettings()
{
FileFormat = GrapeCity.ActiveReports.Export.Excel.Page.FileFormat.Xlsx
};
settings = excelSettings.GetSettings();
break;
case "csv":
// Use CSV rendering extension and settings
settings = new GrapeCity.ActiveReports.Export.Text.Page.CsvRenderingExtension.Settings()
{
ColumnsDelimiter = ",",
RowsDelimiter = "\r\n",
QuotationSymbol = '"',
Encoding = Encoding.UTF8
};
renderingExtension = new GrapeCity.ActiveReports.Export.Text.Page.CsvRenderingExtension();
break;
case "docx":
// Use Word rendering extension and settings
renderingExtension = new GrapeCity.ActiveReports.Export.Word.Page.WordRenderingExtension();
settings = new GrapeCity.ActiveReports.Export.Word.Page.Settings() { FileFormat = GrapeCity.ActiveReports.Export.Word.Page.FileFormat.OOXML };
break;
case "mht":
// Use HTML rendering extension with MHT settings
renderingExtension = new GrapeCity.ActiveReports.Export.Html.Page.HtmlRenderingExtension();
settings = new GrapeCity.ActiveReports.Export.Html.Page.Settings() { MhtOutput = true, OutputTOC = true, Fragment = false };
break;
case "json":
// Use JSON rendering extension and settings
settings = new GrapeCity.ActiveReports.Export.Text.Page.JsonRenderingExtension.Settings() { Formatted = true };
renderingExtension = new GrapeCity.ActiveReports.Export.Text.Page.JsonRenderingExtension();
break;
default:
// Default to PDF rendering extension and settings if none of the above cases are satisfied
renderingExtension = new GrapeCity.ActiveReports.Export.Pdf.Page.PdfRenderingExtension();
settings = new GrapeCity.ActiveReports.Export.Pdf.Page.Settings();
break;
}
}
Explanation of the GetRenderingSettings Method
1. Handling Different Formats
- Each
case
in theswitch
statement corresponds to a different export format. - Based on the value of
exportType
, the application selects the correct rendering extension and settings.
2. Rendering Extensions and Settings
- Each format has a unique
RenderingExtension
class (e.g.,PdfRenderingExtension
,ExcelRenderingExtension
) and settings. - The settings allow for additional customization, such as defining delimiters for CSV, setting encoding for JSON, or specifying the file format for Excel.
3. Default Format
- If an unsupported or unspecified format is provided, the application defaults to PDF.
Rendering and Exporting the Report
Once the appropriate rendering extension and settings are configured, the application can proceed to render and export the report. The RenderAndExportReport
method performs this task by combining the rendering extension, settings, and output file provider.
static void RenderAndExportReport(PageReport report, string exportFileName, IRenderingExtension renderingExtension, NameValueCollection settings)
{
// Configure the output provider to handle the exported file
var outputDirectory = new DirectoryInfo(Path.Combine(GetAppDirectory(), "Exports"));
var outputProvider = new FileStreamProvider(outputDirectory, Path.GetFileName(exportFileName))
{
// Overwrite output file if it already exists
OverwriteOutputFile = true
};
// Render the report and export it to the specified format
report.Document.Render(renderingExtension, outputProvider, settings);
Console.WriteLine(" - Exported");
}
Explanation of the RenderAndExportReport Method
1. Output Directory and FileStreamProvider
- The
FileStreamProvider
is set up to store the exported file in theExports
folder. - The
OverwriteOutputFile
property ensures that if an existing file has the same name, it will be replaced with the new export.
2. Rendering and Exporting
-
report.Document.Render
takes the configuredrenderingExtension
,outputProvider
, andsettings
and generates the output file in the specified format. - A confirmation message is logged to indicate that the export was successful.
Example of Specifying Export Formats
When running the application, you can specify the format using the format
argument. For example, setting the format to PDF:
ReportAutomation.exe TestReport format:pdf
3.6 Exporting the Report
Once the rendering settings are configured, the application proceeds to export the rendered report. This section focuses on setting up the output directory, defining the export file name, and saving the exported report in the correct location.
Creating the Output Directory
The application uses the CreateOutputDirectory
method to ensure that the designated export folder exists. If the folder doesn’t exist, the method creates it automatically. This setup keeps exports organized and centralized.
static void CreateOutputDirectory()
{
var outputDirectory = new DirectoryInfo(Path.Combine(GetAppDirectory(), "Exports"));
outputDirectory.Create();
}
Explanation of the CreateOutputDirectory Method
- Directory Path
- The output directory is created inside the application’s base directory under a folder named
Exports
. - This directory structure makes it easy to locate exported files, as all exports are saved in a consistent location.
- The output directory is created inside the application’s base directory under a folder named
- Folder Creation
- If the
Exports
folder already exists, nothing changes; otherwise, it creates the folder.
- If the
File Naming and Storage
The application constructs a unique file name for each export using the report name and current date-time. This ensures that each export file is timestamped and easy to identify.
var currentDateTime = DateTime.Now;
var exportFileName = reportName + " " + currentDateTime.ToString("yyyy-MM-dd HH.mm.ss");
- Date-Time Stamp
- Including the date and time in the filename (formatted as yyyy-MM-dd HH.mm.ss) ensures uniqueness, preventing accidental overwrites of previous exports.
- This also helps with version tracking, as each exported file reflects the exact time it was generated.
Full Export Code
The RenderAndExportReport
method, covered in Section 3.4, handles the actual export process, saving the rendered report file in the Exports
directory with the appropriate format and name.
3.7 Emailing the Report
After exporting the report, the application can send the exported file to specified recipients via email. This is done using the EmailReport
method, which uses SMTP to send an email with the report attached.
Setting Up SMTP for Email
To send reports by email, you need access to an SMTP server, along with credentials, server address, and port. For this example, we’ll use placeholders that you should replace with your own SMTP server details. The code is as follows:
static void EmailReport(string reportName, string exportedFilePath, DateTime currentDateTime, List<string> emails, Dictionary<string, object> parameters)
{
// Build the email body with report details
var emailBody = new StringBuilder();
emailBody.AppendLine("Report: " + reportName);
emailBody.AppendLine("Executed at: " + currentDateTime.ToString());
if (parameters.Count > 0)
{
emailBody.AppendLine("Parameters:");
foreach (var param in parameters)
{
if (param.Value is string[])
{
emailBody.AppendLine($" - {param.Key}: {string.Join(", ", (string[])param.Value)}");
}
else
{
emailBody.AppendLine($" - {param.Key}: {param.Value}");
}
}
}
// Provide information and credentials for SMTP
using (var smtpClient = new SmtpClient("smtp.yoursmp.com") // Set your SMTP server
{
Port = 587,
Credentials = new NetworkCredential("YourUsername", "YourPassword"), // Set your credentials
EnableSsl = true
})
{
foreach (var email in emails)
{
using (var mailMessage = new MailMessage("yoursender@email.com", email) // Set your sender address
{
Subject = reportName + " - " + currentDateTime.ToString(),
Body = emailBody.ToString(),
})
{
// Try to send the email
try
{
Console.WriteLine(" - sending to " + email);
mailMessage.Attachments.Add(new Attachment(exportedFilePath));
smtpClient.Send(mailMessage);
Console.WriteLine(" - " + reportName + " sent to " + email);
}
catch (Exception e)
{
Console.WriteLine(" - Error: " + e.Message);
}
}
}
}
// Preview email content in console
Console.WriteLine("");
Console.WriteLine("-------------------------------");
Console.WriteLine("");
Console.WriteLine("Email Content:");
Console.WriteLine("");
Console.WriteLine("Subject:");
Console.WriteLine(reportName + " - " + currentDateTime.ToString());
Console.WriteLine("");
Console.WriteLine("Body:");
Console.WriteLine(emailBody);
}
Explanation of the EmailReport Method
1. Constructing the Email Body
- The
StringBuilder
object (emailBody
) contains information about the report, including its name, execution date-time, and any parameters used during generation. - Each parameter is formatted as a list item, allowing recipients to review the report’s context easily.
2. SMTP Client Configuration
- The
SmtpClient
is configured with the server address (sandbox.smtp.mailtrap.io
), port (587), and credentials. - Note: Replace the SMTP server and credentials with your own settings before deploying.
3. Creating and Sending the Email
- For each email in the
emails
list, the application creates aMailMessage
object and attaches the exported report file. - The email subject includes the report name and execution date-time for easy identification.
- Each email is sent individually within a
try-catch
block. If an error occurs during sending, it’s logged to the console.
4. Console Preview of Email Content
- A preview of the email content (subject and body) is printed to the console for debugging purposes. This can help ensure that the email content is correct before deployment.
Testing and Using the Email Feature
To test the email feature, run the application with the email
argument, specifying one or more recipient addresses:
ReportAutomation.exe TestReport email:example1@example.com email:example2@example.com
This command:
- Exports
TestReport
and emails it to bothexample1@example.com
andexample2@example.com
. - Ensures that each email contains the report, parameters, and other details as specified in the body.
Section 4: Integrating With a Task Scheduling Application to Schedule Reports
Automating your report generation workflow can save time and ensure that reports are generated and sent out at regular intervals. This sample application was designed to be compatible with almost any task scheduling solution, but for our example, we will use Windows Task Scheduler as it is easily available to anyone using Windows.
Windows Task Scheduler is a powerful tool for scheduling applications to run automatically on a recurring basis. By integrating your report automation application with Task Scheduler, you can schedule tasks to run daily, weekly, monthly, or at custom intervals.
This section provides step-by-step instructions for setting up a scheduled task to execute your report automation application.
4.1 Configuring Task Scheduler
1. Open Windows Task Scheduler
- Press
Win + S
, type “Task Scheduler,” and press Enter to open the Windows Task Scheduler.
2. Create a New Task
- In the Task Scheduler window, select Action > Create Task.
- Give your task a meaningful Name (e.g., “Monthly Sales Report”) and Description.
- Note: You can also create Folders in Task Scheduler, which we recommend if you plan to ultimately have several report automation tasks to facilitate easier tracking of them.
3. Setting Task Security Options
- Under the General tab, select the Run whether user is logged on or not option to ensure the task runs in the background, even if the user is logged out.
- Optionally, select Run with highest privileges if your application requires elevated permissions.
4.2 Setting the Trigger
The Trigger defines when and how frequently the task runs. You can set this based on your report distribution needs (e.g., daily, weekly, monthly).
1. Add a Trigger
- Go to the Triggers tab and click New.
- Set the Begin the task dropdown to On a schedule.
2. Define the Schedule
- Choose Daily, Weekly, or Monthly based on your requirements.
- For example, if you want to generate a report daily at 8:00 a.m., select Daily, then set the Start time to 8:00 a.m.
- Customize the recurrence interval as needed.
3. Optional: Add Multiple Triggers
- If you need the task to run at different times, you can add multiple triggers.
4.3 Configuring the Action
1. Define the Action
- Go to the Actions tab and click New.
- In the Action dropdown, select Start a program.
2. Specify the Program Path
- In the Program/script field, enter the path to your report automation executable (e.g.,
C:\path\\to\ReportAutomation.exe
). - You can find this path by right-clicking the application in Windows Explorer, selecting Properties, and copying the Target path.
3. Add Arguments
- In the Add arguments (optional) field, specify any arguments required for the report. This includes:
- The report name
- Any parameters or sorting options
- The export format
- Email addresses if you want the report to be emailed automatically
For example:
TestReport Categories=Beverages,Seafood SortBy=StockValue email:example1@example.com format:pdf
This example will run the task to:
- Generate
TestReport
- Filter by
Categories
(Beverages, Seafood) and sort byStockValue
- Export it as a PDF
- Email it to
example1@example.com
Example of a Complete Command with Arguments
If the executable is located in C:\ReportAutomation\ReportAutomation.exe
, and you want to generate a report named SalesReport
and export it as an Excel file every Friday at 5:00 p.m., the setup in Task Scheduler would look like this:
- Program/script:
C:\ReportAutomation\ReportAutomation.exe
- Arguments:
SalesReport format:xlsx email:stakeholder@example.com
4.4 Testing and Troubleshooting the Scheduled Task
1. Run the Task Manually
- After configuring the task, you can test it by selecting the task in Task Scheduler and clicking Run in the Actions pane.
- This lets you verify that the task works as expected and allows you to troubleshoot any issues before scheduling it for production.
2. Checking Task History and Logs
- Go to the History tab to view task logs. Task Scheduler logs each execution attempt, along with any errors or warnings.
- Review the logs if the task fails to run or does not perform as expected.
3. Common Issues and Solutions
- File Path Issues: Ensure the executable path and arguments are correct. Incorrect paths are a common cause of failure.
- Permission Issues: If the task requires elevated permissions, ensure Run with highest privileges is selected.
- Network or SMTP Issues: If emailing fails, check SMTP settings, firewall settings, and internet connectivity.
4. Enable Logging in the Application (Optional)
- You can add logging to your application (e.g., by writing to a log file) to capture details about each execution, which can help with troubleshooting any unexpected behavior.
By configuring Windows Task Scheduler with these steps, you’ll have a fully automated report generation and distribution system. The Task Scheduler will run the application on the specified schedule, generating the report, exporting it, and optionally emailing it to stakeholders.
This setup completes the automation loop, allowing your reports to be generated and distributed on a recurring basis without any manual intervention.
Conclusion
In this guide, we’ve walked through the process of creating a fully automated report generation and distribution system using ActiveReports.NET and Windows Task Scheduler. With the solution we’ve built, you can:
- Automate Report Generation: Run reports on a set schedule, ensuring that stakeholders receive timely insights without any manual effort.
- Customize Reports with Parameters: Use dynamic parameters to tailor each report based on user input, giving you control over data filtering, sorting, and presentation.
- Export to Multiple Formats: Export reports in PDF, Excel, Word, CSV, and more to meet different reporting needs and preferences.
- Email Reports to Stakeholders: Automatically email exported reports to specified recipients, making report distribution seamless and efficient.
Key Benefits of Report Automation
Automating reports saves time, minimizes errors, and ensures consistency in data reporting. Whether you’re generating daily operational reports, monthly financial summaries, or customized client reports, automation lets you focus on analysis and decision-making rather than repetitive tasks.
Further Customization
The solution presented in this blog is just the foundation of what’s possible with ActiveReports.NET. Below are a few ideas for expanding its capabilities:
- Add More Export Formats: Explore ActiveReports.NET’s range of formats and choose those that best fit your needs.
- Advanced Scheduling: Use Task Scheduler’s options for more complex scheduling scenarios, such as conditional execution based on specific events.
- Enhanced Logging and Error Handling: Implement robust logging to monitor each run of the automation application and capture details about export times, email success or failures, and any issues encountered.
- Integrate with Other Applications: Consider integrating this solution with other applications or services, such as a CRM or data visualization tools, to further streamline reporting workflows.
Final Thoughts
Automated reporting is a powerful way to make sure that accurate and up-to-date information reaches the right people at the right time. With the flexibility of ActiveReports.NET and the scheduling power of Windows Task Scheduler, this solution is adaptable to a wide range of business needs. By following this guide, you can build a custom report automation solution tailored to your unique workflow.
Feel free to explore more features of ActiveReports.NET, experiment with additional report customization options, and adjust this solution to best suit your organization’s needs.
Happy automating!
Top comments (0)