大数跨境
0
0

在 WebAPI 里生成 csv zip 文件

在 WebAPI 里生成 csv zip 文件 amazingdotnet
2024-01-18
0
导读:在 WebAPI 里生成 csv 压缩包

在 WebAPI 里生成 csv zip 文件

Intro

前段时间在写一个导出 csv 压缩包的 API,踩了一些坑,记录一下同时分享一下避免大家踩坑

Sample

API 是导出一个 zip 压缩包,这个压缩包里一些 csv 文件

csv 用的是 CsvHelper 来导出的,zip 是用的 .NET 里自带的 ZipArchive 来实现的,完整的导出代码如下:

[HttpPost("download")]
public async Task<IActionResult> DownloadCsv()
{
    var books = Get();
    
    var memoryStream = new MemoryStream();            
    using (var zip = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
    {
        foreach (var group in books
                    .GroupBy(t => new
                    {
                        t.Author
                    }))
        {
            var entryName = $"{group.Key.Author}.csv";
            var entry = zip.CreateEntry(entryName);

            await using var writer = new StreamWriter(entry.Open());
            await using var csv = new CsvWriter(writer, new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                HasHeaderRecord = false
            });

            // register class map if necessary
            // csv.Context.RegisterClassMap<ClassMap>();

            await csv.WriteRecordsAsync(group);
        }
    }
    memoryStream.Seek(0, SeekOrigin.Begin);
    return File(memoryStream, "application/zip""books.zip");
}

说一说可能会踩到坑:

  • memory stream 首先不能 using,因为要写入到 response 里
  • ZipArchive create 的时候需要指定 ZipArchiveMode.Create 并且,leaveOpen 需要指定为 true,原因同上,默认会 dispose stream
  • CsvHelper 要写入 entry 的时候可以直接用 ZipArchiveEntryOpen() 方法来获取对应的 stream,直接写入 entry 的 stream
  • ZipArchive 不要使用 using var zip = new ZipEntry(..); 这样的写法,这样写会有问题,会导致 ZipArchive 不会及时 dispose 导致 stream 数据是有问题的,使用 using {} 的形式,自己控制 using 的 scope
  • 最后导出之前需要把 memory stream 重置到开始的位置,可以使用 memoryStream.Seek(0, SeekOrigin.Begin),否则也会导致导出异常

导出效果:

References

  • https://github.com/WeihanLi/SamplesInPractice/blob/main/AspNetCoreSample/Controllers/BooksController.cs#L39
  • https://github.com/dotnet/runtime/blob/v8.0.0/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs
  • https://github.com/dotnet/runtime/blob/v8.0.0/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs


【声明】内容源于网络
0
0
amazingdotnet
dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
内容 539
粉丝 0
amazingdotnet dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
总阅读212
粉丝0
内容539