Report Viewer

TsgcHTMLComponent_ReportViewer shows a report in a web page, with a parameters panel, a PDF preview, Download PDF, Print and Export to Excel. The report is a TsgcHTMLReport, a banded report engine that prints groups, totals, charts, barcodes and subreports to PDF with the PDF engine of sgcHTML, with no external reporting tool, printer driver or DLL, in Delphi, C++ Builder and .NET.

TsgcHTMLComponent_ReportViewer and TsgcHTMLReport

Define the report with its bands and Parameters, link it to the viewer and render it. The viewer builds a form from the parameters, and the preview, the download and the print are the same PDF, generated on the server with the values the user applied, so what the user sees is what the user prints. Nothing is kept on the server between requests.

Component classes

TsgcHTMLComponent_ReportViewer, the viewer, and TsgcHTMLReport, the non visual report engine it shows

Renders

A parameters panel, a preview drawn with the embedded pdf.js of the PDF viewer, and the Download PDF, Print and Export to Excel links

Languages

Delphi, C++ Builder, .NET

A sales report with parameters, in the browser

The report declares a required period and a region. The viewer turns them into fields, and the report filters its data in its own OnBeforeGenerate event with the values the user applies.

uses
  sgcHTML_Export_PDF, sgcHTML_Report, sgcHTML_Component_ReportViewer;

// the report
oReport := TsgcHTMLReport.Create(Self);
oReport.Title := 'Sales';
oReport.FileName := 'sales';
oReport.DataSet := qrySales;
oParam := oReport.Parameters.Add;
oParam.Name := 'Period';
oParam.Caption := 'Period';
oParam.Kind := rpkDateRange;
oParam.DefaultValue := '2026-01-01;2026-12-31';
oParam.Required := True;
oParam := oReport.Parameters.Add;
oParam.Name := 'Region';
oParam.Caption := 'Region';
oParam.Kind := rpkSelect;
oParam.Options.Add('EU=Europe');
oParam.Options.Add('US=United States');
oReport.OnBeforeGenerate := ReportBeforeGenerate;

// a detail band: one line per row
oBand := oReport.Bands.Add;
oBand.Kind := rbkDetail;
oItem := oBand.Items.Add;
oItem.Text := '[Product]';
oItem.Width := 100;
oItem := oBand.Items.Add;
oItem.Text := '[Amount:#,##0.00]';
oItem.Left := 100;
oItem.Width := 80;
oItem.Align := paRight;

// the viewer
oViewer := TsgcHTMLComponent_ReportViewer.Create(Self);
oViewer.Name := 'SalesViewer';
oViewer.HTMXEngine := sgcHTMXEngine1;
oViewer.Report := oReport;
oViewer.TokenSecret := LoadSecretFromConfig;
oTemplate.BodyContent := oViewer.HTML;

// the report filters its data with the values of the viewer
procedure TForm1.ReportBeforeGenerate(Sender: TObject; aParams: TStrings);
var
  vPeriod: string;
begin
  vPeriod := aParams.Values['Period'];   // from;to
  qrySales.Close;
  qrySales.ParamByName('FromDate').AsString := Copy(vPeriod, 1, Pos(';', vPeriod) - 1);
  qrySales.ParamByName('ToDate').AsString := Copy(vPeriod, Pos(';', vPeriod) + 1, 10);
  qrySales.ParamByName('Region').AsString := aParams.Values['Region'];
  qrySales.Open;
end;
@* Views/Reports/Sales.cshtml: SalesReport is a long-lived TsgcHTMLReport *@
@model ReportsModel

<sgc-report-viewer name="sales" report="@Model.SalesReport"
                   show-export-xlsx="true" zoom="page-width"
                   css-height="720px" token-lifetime="300"
                   on-before-generate="Model.CheckAccess" />
using esegece.sgcWebSockets;

// the report
var report = new TsgcHTMLReport();
report.Title = "Sales";
report.FileName = "sales";
var param = report.Parameters.Add();
param.Name = "Period";
param.Caption = "Period";
param.Kind = TsgcHTMLReportParameterKind.rpkDateRange;
param.DefaultValue = "2026-01-01;2026-12-31";
param.Required = true;
report.OnBeforeGenerate += (sender, values) => LoadSales(values);

// the viewer
var viewer = new TsgcHTMLComponent_ReportViewer();
viewer.Name = "SalesViewer";
viewer.HTMXEngine = engine;
viewer.Report = report;
viewer.TokenSecret = configuration["Reports:Secret"];
template.BodyContent = viewer.HTML;

// the same report, without the viewer: a PDF of the third quarter
var values = new List<string> { "Period=2026-07-01;2026-09-30" };
report.SaveToFile("q3.pdf", values);

What your users get

Pick the values, look at the report, then download it, print it or open its data in Excel.

Parameters panel

Every parameter of the report becomes a labelled field: text, number, date, a date range with From and To, a select of the Options and a checkbox. A Required parameter shows an asterisk and is checked in the browser before Apply and again on the server. Reset restores the default of every field.

PDF preview

The preview uses the embedded pdf.js of TsgcHTMLComponent_PDFViewer, with its toolbar, page navigation, zoom and search. A spinner with the text Generating report... covers it until the first page is drawn. With AutoGenerate the preview loads at once with the default values.

Download, Print and Excel

Download PDF and Print are the same PDF as the preview, and the download is named after FileName. Export to Excel writes the data of the report with ExportToXLSX. ShowDownload, ShowPrint and ShowExportXLSX show or hide each one.

Clear messages

A missing required value marks the field and moves the focus to it. When no row prints, the preview shows No data for the selected parameters instead of an empty PDF. A refused or failed generation shows its reason and disables the links. The texts come from the locale of the library.

Accessibility and keyboard

The viewer is a labelled region. Every field has a label, a date range is a fieldset with a legend, required fields carry aria-required and a missing value sets aria-invalid. Enter in a field applies the parameters, and a polite live region announces required fields, no data, refusals and errors.

Banded reports to PDF

The engine behind the viewer is a non visual component of its own. It writes the PDF with TsgcHTMLExportPDF, the PDF engine of sgcHTML, and the same report can also be written as an Excel sheet.

Bands

A report header, page headers, nested groups with headers and footers, detail rows, page footers and a report footer. Group headers can repeat on every new page, KeepTogether keeps a group on one page, NewPageBefore and NewPageAfter break pages, and a report header with NewPageAfter is a cover page.

Items

Bands hold text, images, lines, rectangles, charts, rich text, barcodes, QR codes and subreports. Text is clipped to its box, and items with AutoHeight grow the band to fit the wrapped text.

Expressions and PrintIf

Texts hold expressions between [ ]: fields with a mask such as [Amount:#,##0.00], [Sum(Field)], [Count], [Avg(Field)], [Min(Field)], [Max(Field)], [RunningSum(Field)], [Page] of [Pages], [Param.Name] and [GroupValue]. Bands and items print only when their PrintIf condition is true, such as Amount > 1000.

Data sources

The rows come from a DataSet, a Grid, a JSON array in RowsJSON or the OnGetRow event. LoadFromGrid builds a table report of the columns of a TsgcHTMLComponent_Grid, with the captions on every page, zebra rows, the totals of the numeric columns and page numbers.

Charts, barcodes and QR codes

A chart item draws the rows of its band as vector graphics: bar, horizontal bar, stacked bar, line, area, pie or doughnut, one chart per group in a group band. ChartSource prints a TsgcHTMLComponent_Chart as the web page shows it. Barcode items draw Code 128, and QR code items use error correction level M.

Subreports and rich text

A subreport item prints another report inside its band, such as the lines of an order, linked to the master row by LinkFields, up to 5 levels deep, and continues on the next pages. A rich text item prints HTML, and with AutoHeight it flows across pages after the page headers.

Fonts and languages

Items print with the Base-14 fonts by default, which hold the characters of Windows-1252. Register TrueType fonts in Fonts to print Cyrillic, Greek, Arabic, Hebrew, Chinese, Japanese, Korean or symbols. Only the glyphs printed are embedded, and FallbackFonts and AutoFallback cover the characters a font lacks.

Same output everywhere

Numbers and dates print with DecimalSeparator, ThousandSeparator, DateFormat and TimeFormat of the report, never with the regional settings of the machine, so a report prints the same on every computer and on .NET. With a fixed CreationDate the same input gives the same PDF bytes.

Definition as JSON

SaveToJSON writes the page setup, fonts, bands, items and parameters, and LoadFromJSON reads them back after it validates the whole definition, with the JSON path of any error. Users design reports in the browser with the Report Designer, and a double click on the report opens the same designer in the Delphi IDE.

One report, many requests

Generate, SaveToFile, SaveToStream, GetPDFBytes, ExportToXLSX and HasData each build their own copy of the rows and the layout. One report serves several requests of a web server at the same time, each one filtered with its own parameters, with no lock of your own.

Key properties, methods & events

The members of the viewer you reach for most often.

Report and OnGetReport

Report is the TsgcHTMLReport to show. One viewer serves every user: to show each user a different report, for instance per tenant or per role, return it in OnGetReport(Sender, aParams, aReport), which fires on the thread of the request where sgcHTMLRequestSession gives the session.

OnBeforeGenerate

OnBeforeGenerate(Sender, aParams, aAccept, aErrorMessage) accepts or refuses a generation, when the viewer renders, on every Apply and on every GET of a link, so a copied link is refused too. Use it for permissions and for rules across parameters, such as a period of at most one year.

Every file link carries an HMAC-SHA256 token over the component, the format, the parameter values, the session and the expiry, and works only in the session that rendered it. Links expire after TokenLifetime seconds (300 by default), and the script signs fresh ones for a page left open. Set the same TokenSecret on every server behind a load balancer.

No server state

The values travel in the link, and the report is generated on the GET, after OnGetReport and OnBeforeGenerate run again. Files are served with Cache-Control: private, no-store, and a bad request, a bad token or a refusal answer 400 or 403.

Preview options

ShowParameters, ShowToolbar, ShowPageNav, ShowZoomControls and ShowSearch set what the viewer shows, Zoom takes auto, page-width, fit or a percentage, and Theme and CSSHeight set the look of the preview.

Without an engine

With ActionURL and no HTMXEngine, your host routes the Apply post to DispatchComponentEvent and the file links to DispatchComponentFile. GetReportURL signs the same links for your own code, for instance to send a link to the PDF of a period in a message.

ASP.NET Core

In a Razor view the <sgc-report-viewer> Tag Helper renders the viewer. report takes a long-lived TsgcHTMLReport, or leave it out and use on-get-report. Apply posts to the component events endpoint and the PDF and Excel links are served by the component file route of UseSgcHtml, so nothing needs to be mapped.

The demo

Demos\60.HTML\01.RunTime\31.ReportViewer is sgc Sales Reports, a server on port 8133 with three reports: sales by region with a bar chart per region and a doughnut chart of the share of each region, an invoice with a logo, a QR code to pay and a Code 128 barcode, and a printout of a grid. The New order button adds an order, and every open preview, in every browser, applies its parameters again over the WebSocket of the page. The design time, Lazarus and .NET versions mirror it.

Keep exploring

Try It OnlineSee it in the Report Viewer demo, running live on the eSeGeCe demo server.
Online HelpFull API reference and usage guide for the viewer.
TsgcHTMLReport HelpBands, expressions, charts, subreports, fonts and the JSON definition of the report engine.
Report Designer ComponentDesign the bands, items and parameters of a report in the browser.
PDF Viewer ComponentThe pdf.js viewer that draws the preview of the report.
All sgcHTML ComponentsBrowse the full feature matrix of 80+ components.
Download Free TrialThe 30-day trial ships the 60.HTML demo projects.
PricingSingle, Team and Site licenses with full source code.
Best value: All-AccessEvery eSeGeCe product, Premium Support included, from €1,059/year.
See All-Access pricing

Ready to Get Started?

Download the free trial and start building web UIs in Delphi, C++ Builder and .NET.