Angular  

🧾 Dynamic ActiveX Report Using Database in Angular

🧠 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]
  1. Angular app sends a request (with parameters) to the backend.

  2. Backend retrieves data from SQL Server.

  3. Backend generates a report (ActiveX / COM report file).

  4. 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:

  • Connects to SQL Server

  • Loads an ActiveX-based report template

  • Fills it with data

  • Exports it as PDF

  • Returns it to the frontend

💻 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.