🧠 Introduction
In many enterprise-grade web applications, especially those migrating from legacy systems, ActiveX reports are still used for generating and displaying detailed business reports (like invoices, financial summaries, and logs).
While ActiveX controls are traditionally used with Internet Explorer, you can still embed, generate, and dynamically bind ActiveX reports from a database in modern Angular applications using alternative integration techniques, such as:
Using a COM-based backend API (C#/.NET) to render and serve reports
Embedding report viewers (like Crystal Reports, Stimulsoft, or ActiveReports) via iframe or custom web components
Fetching data dynamically via Angular services (HttpClient)
This article explains how to generate and display dynamic ActiveX-based reports from a SQL database in an Angular frontend.
⚙️ Prerequisites
Before you start, ensure you have the following setup:
Angular 17+
.NET 6+ or .NET Framework 4.8 (for backend ActiveX/COM integration)
SQL Server Database
ActiveX or reporting tool (e.g., ActiveReports, Crystal Reports, or COM Report Engine)
Node.js and npm installed
🧩 Architecture Overview
The flow for generating the dynamic ActiveX report is as follows:
[Angular App] ---> [Web API / .NET Backend] ---> [Database (SQL Server)]
---> [ActiveX Report Engine]
Angular app sends a request (with parameters) to the backend.
Backend retrieves data from SQL Server.
Backend generates a report (ActiveX / COM report file).
Angular displays the generated report (via iframe or viewer component).
🧱 Step 1. Create a Backend API to Generate Reports
You can use a C# .NET Web API to handle the ActiveX or report engine integration.
Here’s a simple example of a backend controller (ReportController.cs):
[ApiController]
[Route("api/[controller]")]
public class ReportController : ControllerBase
{
private readonly IConfiguration _config;
public ReportController(IConfiguration config)
{
_config = config;
}
[HttpGet("GenerateReport")]
public IActionResult GenerateReport(int reportId)
{
string connectionString = _config.GetConnectionString("DefaultConnection");
// Fetch data from SQL Server
var data = new DataTable();
using (SqlConnection con = new SqlConnection(connectionString))
{
string query = "SELECT * FROM Sales WHERE ReportId = @ReportId";
using (SqlCommand cmd = new SqlCommand(query, con))
{
cmd.Parameters.AddWithValue("@ReportId", reportId);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(data);
}
}
// Use COM-based ActiveX Report Engine (e.g., ActiveReports)
var report = new ActiveXReportLib.ReportClass();
report.LoadTemplate("C:\\Reports\\SalesReport.rpt");
report.SetDataSource(data);
string pdfPath = $"C:\\Reports\\Output\\Report_{reportId}.pdf";
report.ExportToPDF(pdfPath);
return File(System.IO.File.ReadAllBytes(pdfPath), "application/pdf");
}
}
✅ This code:
💻 Step 2. Create an Angular Service to Fetch the Report
In Angular, create a ReportService to fetch the generated report.
report.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ReportService {
private apiUrl = 'https://localhost:5001/api/Report';
constructor(private http: HttpClient) {}
getReport(reportId: number) {
return this.http.get(`${this.apiUrl}/GenerateReport?reportId=${reportId}`, { responseType: 'blob' });
}
}
🧾 Step 3. Display Report in Angular Component
Now, create a component to display the generated report (PDF).
report-viewer.component.ts
import { Component } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { ReportService } from './report.service';
@Component({
selector: 'app-report-viewer',
templateUrl: './report-viewer.component.html',
styleUrls: ['./report-viewer.component.css']
})
export class ReportViewerComponent {
pdfSrc: any;
constructor(private reportService: ReportService, private sanitizer: DomSanitizer) {}
loadReport() {
const reportId = 101; // dynamic ID based on user selection
this.reportService.getReport(reportId).subscribe((data) => {
const blob = new Blob([data], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
this.pdfSrc = this.sanitizer.bypassSecurityTrustResourceUrl(url);
});
}
}
report-viewer.component.html
<div class="report-container">
<button (click)="loadReport()" class="btn btn-primary">Generate Report</button>
<iframe *ngIf="pdfSrc" [src]="pdfSrc" width="100%" height="600px"></iframe>
</div>
🎨 Step 4. Style and Integration
You can enhance the user interface by integrating Bootstrap or Angular Material:
npm install bootstrap
In angular.json:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
]
🧠 Step 5. Dynamic Report Parameters
You can allow users to select filters (like date range, department, or region) and pass them to the API dynamically:
this.reportService.getReportByParams({ startDate, endDate, region });
Your backend can then use these parameters in SQL queries or stored procedures to fetch dynamic data.
🚀 Conclusion
By combining Angular’s dynamic frontend capabilities with a .NET backend that interfaces with ActiveX or COM-based report engines, you can:
Generate dynamic reports using real-time database data
Export reports in formats like PDF or Excel
Integrate modern UI controls while preserving legacy ActiveX report compatibility
This hybrid approach enables organizations to modernize their reporting systems without completely discarding older but reliable ActiveX reporting engines.