Table of Contents

Show reports in a browser

DocWright.Reporting.Viewer turns a paginated report into HTML with inline SVG for the browser, plus a region map: JSON describing every item's position, links, toggles and text, for your viewer to bind behaviour to. It reads the same page model as the PDF, so the preview and the export can't disagree.

dotnet add package DocWright.Reporting.Viewer

Render to HTML

Process the report as in the SSRS tutorial, then:

using DocWright.Reporting.Pagination;
using DocWright.Reporting.Viewer;

// Soft pages for the screen: the report's InteractiveHeight, no margins.
ReportPageModel pages = ReportPaginator.Paginate(instance, fonts,
    new ReportPaginationOptions { Mode = ReportPaginationMode.Interactive });

ReportHtmlProjection projection = ReportHtmlRenderer.Project(pages, new ReportHtmlOptions
{
    Output = ReportHtmlOutput.Document,   // a whole HTML page; Fragment to embed in yours
});

File.WriteAllText("regional-sales.html", projection.Html);
File.WriteAllText("regional-sales-regions.json", projection.RegionMap.ToJson());

ReportRegionPage first = projection.RegionMap.Pages[0];
Console.WriteLine($"{projection.RegionMap.Pages.Count} page(s); page 1 has {first.Regions.Count} regions");

Output

1 page(s); page 1 has 20 regions
regional-sales.html in Microsoft Edge
The Regional Sales report rendered as HTML and SVG in a browser, matching the PDF
The HTML projection in a browser. Compare it with the PDF: same positions, same text. Download: regional-sales.html.

How it is drawn

Part Markup Why
Item boxes and backgrounds Absolutely positioned <div>s, in points Exact positioning
Borders One <div> per edge, centred on the edge Matches the PDF, where CSS borders sit inside or outside the box
Text <svg><text> at the measured baseline Text lands where the PDF puts it, whatever fonts the browser has
Charts, gauges, barcodes One <svg> per item Drawn by the same shapes as the PDF
Images <img> with a data: URL, clipped

Output = ReportHtmlOutput.Fragment (the default) returns markup to embed in your own page. Include projection.StyleSheet once. projection.Pages gives the markup one page at a time, for streaming.

Pagination for the screen

ReportPaginationMode.Interactive uses the report's InteractiveHeight and InteractiveWidth, with no margins, and never cuts a page sideways. Page breaks, repeated headers and page numbers follow the same rules as print, from the same paginator.

Safe to show untrusted reports

A report's text, tooltips and URLs are evaluated expressions written by someone else, so the HTML:

  • escapes every value, and drops control characters;
  • contains no script and no event handlers, ever;
  • writes links only for http, https, mailto or relative URLs. javascript: and data: links are refused (DXP9501) and left out. They are still in the region map, marked IsNavigable = false, if your own policy wants them;
  • embeds only raster images, never SVG documents, which can carry script (DXP9503).

The region map

projection.RegionMap lists each page's regions with their position (integer twips from the page's top-left), text, Actions (hyperlinks, bookmark links, drill-throughs), Toggle and UserSort. ToJson() writes it deterministically. A viewer uses it for clicks and search instead of reading the markup back.

Viewer services

The viewer package also has the services behind an interactive viewer: hit-testing (what is at this point), action resolution (where this link goes), search across pages, and toggling and sorting with re-pagination of only the pages affected. Toggle state lives in ReportPaginationOptions.ToggledItems, so the server re-paginates the same processed report without running its queries again.