【发布时间】:2021-02-21 10:51:18
【问题描述】:
我正在尝试从我的 ASP.Net Core 3.1 Web API 导出简单的 CSV 文件。为此,我使用 CsvHelper 包,在其中使用以下方法生成 MemoryStream:
public async Task<MemoryStream> ExportAsync(IEnumerable records)
{
byte[] content = null;
using (var mem = new MemoryStream())
using (var writer = new StreamWriter(mem, Encoding.GetEncoding("windows-1250")))
{
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.TypeConverterOptionsCache.GetOptions<DateTime>().Formats = new[] { "yyyy-MM-dd HH:mm:ss" };
csvWriter.Configuration.Delimiter = "|";
csvWriter.WriteField("sep=|", false);
csvWriter.NextRecord();
await csvWriter.WriteRecordsAsync(records).ConfigureAwait(false);
await csvWriter.FlushAsync().ConfigureAwait(false);
await writer.FlushAsync().ConfigureAwait(false);
content = mem.ToArray();
}
}
var output = new MemoryStream(content);
return output;
}
这是通过以下方法从我的控制器中调用的:
[HttpGet("GetCountriesAsCSV")]
[SwaggerResponse(400, typeof(string))]
[SwaggerResponse(typeof(File))]
public async Task<IActionResult> GetCountriesAsCSV()
{
try
{
var allCountries = await countryManager.GetAllAsync();
var transformedCountries = mapper.Map<IEnumerable<CountryCsv>>(allCountries);
var stream = await csvExportService.ExportAsync(transformedCountries).ConfigureAwait(false);
return File(stream, "text/csv", $"AllCountries{DateTime.Now.Ticks}.csv");
}
catch (Exception ex)
{
return StatusCode((int)HttpStatusCode.BadRequest, ex.Message);
}
}
问题是,当我从 Excel 打开导出的 CSV 文件时,特殊字符无法正确显示(由于编码)。这是输出的样子:
我曾尝试使用完全相同的方法生成 CSV 文件,但我没有将其推回为 MemoryStream,而是将文件直接保存在当前文件夹中,如下所示:
private async Task WriteAll(IEnumerable records)
{
using (var writer = new StreamWriter("RobertFile.csv", true, Encoding.GetEncoding("windows-1250")))
{
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.TypeConverterOptionsCache.GetOptions<DateTime>().Formats = new[] { "yyyy-MM-dd HH:mm:ss" };
csvWriter.Configuration.Delimiter = "|";
csvWriter.WriteField("sep=|", false);
csvWriter.NextRecord();
await csvWriter.WriteRecordsAsync(records).ConfigureAwait(false);
await csvWriter.FlushAsync().ConfigureAwait(false);
await writer.FlushAsync().ConfigureAwait(false);
}
}
}
如您所见,ExportAsync 和 WriteAll 方法之间的唯一区别是 StreamWriter 参数(但编码规范完全相同)。
打开此文件后,它看起来非常好,如下所示:
我不太明白,为什么编码转换为MemoryStream然后导出为文件对象结果时会丢失。
我们将非常感谢您对此事的任何帮助。
【问题讨论】:
标签: c# encoding asp.net-core-webapi export-to-csv asp.net-core-3.1