# Save Rendered Output

## Content

The <span class="code" spellcheck="false" data-prosemirror-content-type="mark" data-prosemirror-mark-name="code">Render</span> extension method follows the same general rendering workflow across supported platforms. However, saving or downloading generated output depends on the application's execution environment.
Blazor FlexChart and FlexDiagram controls implement <span class="code" spellcheck="false" data-prosemirror-content-type="mark" data-prosemirror-mark-name="code">IChartBase</span> and can render into an <span class="code" spellcheck="false" data-prosemirror-content-type="mark" data-prosemirror-mark-name="code">IRendering</span> target.
Browser applications require a download workflow to transfer generated output to the client. The generated document can be saved to a <span class="code" spellcheck="false" data-prosemirror-content-type="mark" data-prosemirror-mark-name="code">MemoryStream</span> and downloaded using JavaScript interoperability.
The following example renders an existing Blazor FlexChart control to PDF and initiates a browser download.

```auto
using System.IO;
using C1.Chart;
using C1.Pdf;
using Microsoft.JSInterop;

// chart is an existing configured Blazor FlexChart.
// JS is an injected IJSRuntime instance.

async Task DownloadPdfAsync()
{
    using var doc = new C1PdfDocument();

    float margin = 72;
    float width = doc.PageSize.Width - 2 * margin;
    float height = 240;

    chart.Render(doc, margin, margin, width, height);

    using var stream = new MemoryStream();

    doc.Save(stream);
    stream.Position = 0;

    using var streamReference =
        new DotNetStreamReference(stream);

    await JS.InvokeVoidAsync(
        "downloadFileFromStream",
        "Chart.pdf",
        streamReference);
}
```

Add the following JavaScript function to the application to receive the generated document and initiate the download.

```javascript
window.downloadFileFromStream = async (
    fileName,
    contentStreamReference
) => {
    const arrayBuffer =
        await contentStreamReference.arrayBuffer();

    const blob = new Blob([arrayBuffer]);
    const url = URL.createObjectURL(blob);

    const anchor = document.createElement("a");
    anchor.href = url;
    anchor.download = fileName;
    anchor.click();
    anchor.remove();

    URL.revokeObjectURL(url);
};
```

>type=note
> **Note:** The JavaScript function must be available before invoking the download method.

The SVG rendering workflow can also generate markup for inclusion in a Blazor page. <span class="code" spellcheck="false" data-prosemirror-content-type="mark" data-prosemirror-mark-name="code">SvgRendering</span> is designed for resource-constrained environments, including Blazor.

>type=note
> **Note:** Blazor's existing <span class="code" spellcheck="false" data-prosemirror-content-type="mark" data-prosemirror-mark-name="code">SaveImage</span> method exports the chart's browser-rendered image. The <span class="code" spellcheck="false" data-prosemirror-content-type="mark" data-prosemirror-mark-name="code">Render(IRendering)</span> method renders directly into the specified rendering target.


