Search code examples
blazorblazor-server-sidecsvhelper

Blazor component for exporting to csv leaves csv empty


I made a Blazor component which gets a collection of objects and then exports it to csv and download it to the user, the csv is getting downloaded however the output file is empty. I obtained the code from the two following documentation articles: https://learn.microsoft.com/en-us/aspnet/core/blazor/file-downloads?view=aspnetcore-6.0#download-from-a-stream https://joshclose.github.io/CsvHelper/getting-started/#writing-a-csv-file

window.downloadFileFromStream = async (fileName, contentStreamReference) => {
    const arrayBuffer = await contentStreamReference.arrayBuffer();
    const blob = new Blob([arrayBuffer]);
    const url = URL.createObjectURL(blob);
    const anchorElement = document.createElement('a');
    anchorElement.href = url;
    anchorElement.download = fileName ?? '';
    anchorElement.click();
    anchorElement.remove();
    URL.revokeObjectURL(url);
}
@using System.IO
@using CsvHelper
@using System.Globalization
@inject IJSRuntime JS
@code {
    [Parameter, EditorRequired]
    public IEnumerable<object>? objects { get; set; }
    [Parameter, EditorRequired]
    public string? FileName { get; set; }
    [Parameter, EditorRequired]
    public string? TextDisplay { get; set; }
    private Stream GetFileStream()
    {
        var memoryStream = new MemoryStream();
        var streamWriter = new StreamWriter(memoryStream);

        var csvWriter = new CsvWriter(streamWriter, culture: CultureInfo.InvariantCulture);
        csvWriter.WriteRecords(objects);
        // Reset memory stream
        memoryStream.Position = 0;

        return memoryStream;
    }
    private async Task DownloadFileFromStream()
    {
        using var fileStream = GetFileStream();
        using var streamRef = new DotNetStreamReference(stream: fileStream);
        await JS.InvokeVoidAsync("downloadFileFromStream", FileName, streamRef);
    }
}
<MudIconButton Icon="@Icons.Material.Filled.Download" Color="Color.Secondary" Size="Size.Small" aria-label="Export to CSV" OnClick="DownloadFileFromStream">@TextDisplay</MudIconButton>

Solution

  • Changed GetFileStream to disposise csvWriter.WriteRecords

    private Stream GetFileStream()
    {
        var memoryStream = new MemoryStream();
        using (var streamWriter = new StreamWriter(memoryStream, leaveOpen: true))
        using (var csvWriter = new CsvWriter(streamWriter, culture: CultureInfo.InvariantCulture))
        {
            csvWriter.WriteRecords(objects);
        }
    
        // Reset memory stream
        memoryStream.Position = 0;
    
        return memoryStream;
    }