导出和压缩CSV .Net Core

问题描述

我需要一个使用.Net Core API从数据库中将CSV文件导出为ZIP的API 所以我就这样:-

  1. 使用 CSV帮助器库
  2. 将CSV文件导出到临时文件
  3. 压缩它
  4. 临时文件
  5. 删除此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,(int)dolly.Length);
                file.WriteAsync(bytes,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.

解决方法

我试图跟踪您的代码实际在做什么,而字节和流的混乱实在太多了。

您要处理多少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文件,而根本不需要服务器上有很大的缓冲区。