---
title: Render report
summary: Creates report XML if needed, resolves a platform-appropriate default printer, and calls the xPression preview service to produce cached report bytes.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Services.Printing
reference_type: package
operation_id: OP-PRT-04
trigger: Caller invokes ReportBase.Render, or Render is called internally by Print, Distribute, or Save
---

# Render report

`ReportBase.Render` is the shared production step behind the `IReport` workflow: it ensures report XML exists, resolves a default printer appropriate to the current execution platform, and calls the xPression preview service to obtain the rendered byte array that later print, distribute, and save operations reuse. Rendering is skipped when cached bytes already exist and the caller does not request a refresh.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PRT-04 |
| **Trigger** | Caller invokes `Render(overwrite)` on a `ReportBase`-derived report, or `Print`/`Distribute`/`Save` invoke it internally |
| **Inputs** | `overwrite` flag; the report's own `ReportPackage`, report XML (via `Create`), and `OutputProfile` |
| **Outputs** | Boolean success; cached rendered bytes (`ReportFile`) on success; an `ErrorDetail` entry in `Errors` on failure |
| **Primary components** | `Reporting.ReportBase.Render`, `Reporting.ReportBase.Create` (overridden by derived report classes), `SAIF.Framework.Security.clsSecurityPrincipal` |
| **Entry point** | `Services\SAIF.Services.Printing\Reporting\ReportBase.vb` |

## Steps

1. **Check the cache.** `Render` tests whether rendered bytes (`m_reportFile`) are missing or `overwrite` is `True` ([BR-004](../business-rules.md#br-004-rendered-bytes-are-reused-until-overwrite-is-requested)).
   - If bytes already exist and `overwrite` is `False`: skip rendering and return `True` immediately.
2. **Create or refresh report XML.** When rendering is needed, `Render` calls `Create(overwrite)`. The base `Create` implementation only clears `Errors` and returns the existing `m_reportXml`; derived report classes override `Create` to build the actual report XML tree.*
3. **Validate readiness.** `Render` checks that `m_reportXml` is not `Nothing` and that `m_ReportPackage` has a non-zero length.
   - If either condition fails: rendering is skipped and the method falls through without setting `result = True`, so `Render` returns `False`.
4. **Resolve the execution platform.** `Render` defaults the platform to `Windows`, then switches to `Web` when `_environmentService.IsWeb` is `True` ([BR-003](../business-rules.md#br-003-report-rendering-selects-the-default-printer-by-execution-platform)).
5. **Resolve the default printer.** `Render` constructs a `SAIF.Framework.Security.clsSecurityPrincipal` for the resolved platform and assigns `xPrint.Printer = x.GetDefaultPrinter()` ([BR-003](../business-rules.md#br-003-report-rendering-selects-the-default-printer-by-execution-platform)).
6. **Call the preview service.** `Render` calls `xPrint.previewDocument(m_ReportPackage, m_reportXml.ToXpression, OutputProfile)` — the profile-based preview path described in [Preview document via xPression](preview-document-via-xpression.md) — and stores the returned bytes in `m_reportFile`.
7. **Return success.** After a successful preview call, `result` is set to `True` and returned.
8. **On exception:** any exception raised during steps 2–6 is caught, wrapped in an `ErrorDetail("An error occurred while rendering the report.", ex)`, and appended to `Errors`; `Render` returns `False`.

## Process flow

The following diagram visualizes the render decision and preview call.

```mermaid
flowchart TD
	Start([Render called]) --> Cache{Bytes cached and<br>overwrite = False?}
	Cache -->|Yes| ReturnTrue([Return True, reuse cached bytes])
	Cache -->|No| Create[Call Create overwrite]
	Create --> Valid{XML present and<br>ReportPackage set?}
	Valid -->|No| ReturnFalse([Return False, no render attempted])
	Valid -->|Yes| Platform[Resolve Windows or Web platform]
	Platform --> Printer[Resolve default printer<br>via clsSecurityPrincipal]
	Printer --> Preview[Call xPrint.previewDocument]
	Preview --> Store[Store bytes in ReportFile]
	Store --> ReturnTrue
	Create -.->|Exception| Err[Add ErrorDetail, return False]
	Preview -.->|Exception| Err
```

## Failure and edge-case behavior

- If `Create(overwrite)` does not populate `m_reportXml` or leaves `m_ReportPackage` empty, `Render` silently returns `False` without adding an error to `Errors` — only exceptions add an `ErrorDetail`.*
- The base `Create` implementation performs no XML construction itself; its behavior depends entirely on the derived report class overriding it, so `Render` on an unmodified `ReportBase` instance always fails the readiness check in step 3.*
- Exceptions from printer resolution or the preview SOAP call are caught and converted into a generic `ErrorDetail` message that does not distinguish printer-resolution failures from xPression service failures.

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `Services\SAIF.Services.Printing\Reporting\ReportBase.vb`
- `Services\SAIF.Services.Printing\clsPrint.vb`
