我一直在读:

https://www.aspsnippets.com/Articles/Export-data-from-SQL-Server-to-CSV-file-in-ASPNet-using-C-and-VBNet.aspx

而不仅仅是可以 Select 下载csv,如中所述:

                //Download the CSV file.
                Response.Clear();
                Response.Buffer = true;
                Response.AddHeader("content-disposition", "attachment;filename=SqlExport.csv");
                Response.Charset = "";
                Response.ContentType = "application/text";
                Response.Output.Write(csv);
                Response.Flush();
                Response.End();

有没有一种使用本机asp的方法.net首先压缩csv变量的csv输出作为响应.输出写(csv);以便用户下载SqlExport.zip而不是SqlExport.csv?

推荐答案

大致以this为基础,您可以创建一个zip文件,同时将其流式传输到客户端;

Response.ContentType = "application/octet-stream";
Response.Headers.Add("Content-Disposition", "attachment; filename=\"SqlExport.zip\"");

using var archive = new ZipArchive(Response.Body, ZipArchiveMode.Create);

var entry = archive.CreateEntry("SqlExport.csv");
using var entryStream = entry.Open();

entryStream.Write(csv); // write the actual content here

entryStream.Flush();

不过,您可能应该考虑使用StreamWriter将每个文本片段直接写入响应流,而不是附加到单个csv字符串中.从链接的csv示例中替换;

using var sw = new StreamWriter(entryStream);

// TODO write header

foreach (DataRow row in dt.Rows)
{
    foreach (DataColumn column in dt.Columns)
    {
        //Add the Data rows.
        await sw.WriteAsync(row[column.ColumnName].ToString().Replace(",", ";") + ',');
    }
    //Add new line.
    await sw.WriteLineAsync();
}

尽管这是一个可怕的csv文件示例.而不是替换';'个字符,字符串应该被引用&;所有的引语都漏掉了.

然而,Response.Body只在美国上市.净5/芯.直接写入中的http响应.NET4.8或更早版本,您必须编写自己的HttpContent.把所有东西放在一起,包括更好的csv格式化程序;

public class ZipContent : HttpContent
{
    private DataTable dt;
    private string name;

    public ZipContent(DataTable dt, string name = null)
    {
        this.dt = dt;
        this.name = name ?? dt.TableName;
        Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
        Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = $"{name}.zip"
        };
    }

    private string formatCsvValue(string value)
    {
        if (value == null)
            return "";
        if (value.Contains('"') || value.Contains(',') || value.Contains('\r') || value.Contains('\n'))
            return $"\"{value.Replace("\"", "\"\"")}\"";
        return value;
    }

    private IEnumerable<DataColumn> Columns()
    {
        // Why is this not already an IEnumerable<DataColumn>?
        foreach (DataColumn col in dt.Columns)
            yield return col;
    }

    protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
        using var archive = new ZipArchive(stream, ZipArchiveMode.Create);

        var entry = archive.CreateEntry($"{name}.csv");
        using var entryStream = entry.Open();
        using var sw = new StreamWriter(entryStream);

        await sw.WriteLineAsync(
            string.Join(",",
                Columns()
                .Select(c => formatCsvValue(c.ColumnName))
            ));

        foreach (DataRow row in dt.Rows)
        {
            await sw.WriteLineAsync(
                string.Join(",", 
                    row.ItemArray
                    .Select(o => formatCsvValue(o?.ToString()))
                ));
        }
    }

    protected override bool TryComputeLength(out long length)
    {
        length = 0;
        return false;
    }
}

Csharp相关问答推荐

从LED面板中提取文本

将多个enum值传递给MAUI中的转换器参数的XML语法是什么?

如何打印已添加到List的Linq值,而不是C#中的:System.Collections.Generic.List ' 1[System.Int32]?

当打印一行x个项目时,如何打印最后一行项目?

错误401未授权ASP.NET Core.使用JWT创建身份验证/授权

在. net毛伊岛窗口的深度链接已经创建""

需要澄清C#的Clean Architecture解决方案模板的AuditableEntityInterceptor类

当通过Google的Gmail Api发送邮件时,签名会产生dkim = neutral(正文散列未验证)'

可为空的泛型属性

查找表中的模式

使用泛型可空类实现接口

异步任务导致内存泄漏

Swagger没有显示int?可以为空

使用System.Text.Json进行序列化时发生StackOverflow异常

Azure Functions v4中的Serilog控制台主题

为什么Azure函数(独立工作进程)索引失败?使用Azure App配置的CosmosDbTrigger绑定失败,未解析为值

如何在特定环境中运行dotnet测试?

在.NET8中如何反序列化为私有字段?

在同一个捕获中可以有多种类型的异常吗?

在Unity C#中按键点击错误的参数