首页 > 解决方案 > 导出和压缩 CSV .Net Core

问题描述

我需要一个使用 .Net Core API 从我的数据库中将 CSV 文件导出为 ZIP 的 API,所以我遵循这种方式:-

  1. 使用CSV Helper Library将 CSV 文件导出到临时文件夹
  2. 压缩它
  3. 临时文件夹中删除此 CSV

这是我正在使用的代码

    [HttpGet("exportAsZip")]
    public FileResult DownloadZipFileasas()
    {
        //Create temp CSV file
        var cc = new CsvConfiguration(new System.Globalization.CultureInfo("en-US"));
        using (MemoryStream ms = new MemoryStream())
        {
            var query = _context.AbdaInaktivProtokoll.Take(50).ToList();
            using (var sw = new StreamWriter(stream: ms, encoding: new UTF8Encoding(true)))
            {
                using (var cw = new CsvWriter(sw, cc))
                {
                    cw.WriteRecordsAsync(query);
                }
                var tempData = File(ms.ToArray(), "text/csv", "data.csv");
                //System.IO.File.Copy(@"C:\Temp\data.csv", @"C:\Temp\data.csv");
                //string fileName = Path.Combine(@"C:\Temp\data.csv", "data.csv");
            }

            //Compressing CSV file
            using (ZipArchive arch = new ZipArchive(ms, ZipArchiveMode.Create, true))
            {
                arch.CreateEntryFromFile(@"C:\Temp\data.csv", "data.csv");
            }
            MemoryStream dolly = new MemoryStream(ms.ToArray());
            using (FileStream file = new FileStream(@"C:\Temp\data.csv", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                byte[] bytes = new byte[dolly.Length];
                dolly.ReadAsync(bytes, 0, (int)dolly.Length);
                file.WriteAsync(bytes, 0, bytes.Length);
                file.FlushAsync();
                dolly.Close();

                //Delete Csv temp file after it compressed
                file.DisposeAsync();
                System.IO.File.Delete(@"C:\Temp\data.csv");

                Response.Headers.Add("Content-Disposition", "attachment; filename=Dateien Exportieren_" + (DateTime.UtcNow.ToShortDateString()) + ".zip");
                return File(bytes, "application/zip");

            }

        }
    }

它一直告诉我这个错误

System.ObjectDisposedException: Cannot access a closed Stream.

标签: c#apicsv.net-corezip

解决方案


我试图按照您的代码实际执行的操作,并且与字节和流混淆太多了。

您要处理多少 csv 数据?您应该尝试直接从 csv 编写器写入 zip 文件。

您是否想在 ram 中创建整个 zip 文件,然后将其发送给客户端。主要是为了让您可以指定 http 内容长度标头。

var ms = new MemoryStream();

using (var zip = new ZipArchive(ms, ZipArchiveMode.Create, true)){
    var entry = zip.CreateEntry("data.csv");
    using var sw = new StreamWriter(entry.Open(), Encoding.UTF8);
    using var cw = new CsvWriter(sw, cc);
    await cw.WriteRecordsAsync(query);
}
ms.Seek(0, SeekOrigin.Begin);
return File(ms, "application/zip", $"Dateien Exportieren_{DateTime.UtcNow.ToShortDateString()}.zip" );

或者您想直接以 http 分块模式流式传输 zip 文件,而根本不需要服务器上的大缓冲区。


推荐阅读