Blazor导出CSV组件生成空文件问题求助
Blazor CSV导出为空问题修复
开发了一个Blazor组件,功能是接收对象集合并导出为CSV文件供用户下载,但下载后的CSV文件始终为空。组件代码基于Blazor文件下载和CsvHelper的示例编写,代码如下:
JavaScript 代码
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); }
Blazor 组件代码
@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>
问题分析
导出的CSV为空的核心原因是StreamWriter和CsvWriter的缓存未被写入MemoryStream:
- CsvWriter依赖StreamWriter处理IO操作,而StreamWriter默认会缓存数据,若不主动刷新或释放资源,数据会留在内存缓存中,不会写入到MemoryStream。
- 原代码中未正确释放StreamWriter,还可能导致MemoryStream被提前关闭,进一步引发读取空内容的问题。
解决方案
修改GetFileStream方法,确保缓存数据被写入MemoryStream,同时避免流被意外关闭:
private Stream GetFileStream() { // 校验输入数据,避免空集合导出空文件 if (objects == null || !objects.Any()) { return new MemoryStream(); } var memoryStream = new MemoryStream(); // 使用using包裹StreamWriter,设置leaveOpen: true防止关闭MemoryStream using var streamWriter = new StreamWriter(memoryStream, leaveOpen: true); using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture); csvWriter.WriteRecords(objects); // 显式刷新缓存,确保所有内容写入MemoryStream csvWriter.Flush(); streamWriter.Flush(); // 重置流位置到开头,供后续读取 memoryStream.Position = 0; return memoryStream; }
关键修复点
- 用
using语句包裹StreamWriter和CsvWriter,确保资源释放时自动Flush缓存 - 设置
StreamWriter的leaveOpen: true,防止StreamWriter在Dispose时关闭MemoryStream - 显式调用
Flush()方法,强制将缓存数据写入MemoryStream - 增加输入数据校验,避免空集合导出空文件(可选但建议)
内容的提问来源于stack exchange,提问作者Davide Dunne Sánche
相关产品推荐
相关产品推荐

