【问题标题】:Download csv file from a query resultset as larg as a 50000 rows in Asp.net MVC从 Asp.net MVC 中 50000 行的查询结果集中下载 csv 文件
【发布时间】:2017-11-30 21:20:34
【问题描述】:

我的控制器中有一个函数,可以为 Linq 查询结果集下载 csv 文件。 linq 查询只是从数据库中获取用户提供的日期范围的数据。

var dataForDateRange = obj.table.Where(m => m.id== id && m.CreatedDateTime >= start && m.CreatedDateTime<= end);
string csv = string.Empty;
foreach(var csvData in dataForDateRange)
{
    csv = csvData.col1 + "," + csvData.col2 + "," + csvData.col3......;
    csv += "\r\n";
}
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename="+engineName+"_CSV.csv");
Response.Charset = "";
Response.ContentType = "application/text";
Response.Output.Write(csv);
Response.Flush();
Response.End();

上面的代码成功地适用于较少数量的数据行。如果记录超过 10000,则浏览器超时。调试显示代码在 foreach 循环处挂起。 为大约 500000 条记录完成这项工作的最佳方法是什么?

【问题讨论】:

  • 对于初学者,您可能希望在构建 csv 文件时切换到使用 StringBuilder。您的代码现在的方式可能会创建数千个临时字符串。
  • 我会将其转换为从那里使用数据表我会使用 lambda 语句使用数据表将其快速导出到 csv .. 这要快得多..
  • @pstrjds He has terabytes of memory clearly, efficiency is for chumps.
  • 对于这样的情况,我会推荐一种不同的方法。让用户触发请求,在后台处理它,监控完成,将文件保存在您的服务器中,并在文件准备好时提供一个链接,以便用户下载。
  • @Greg - 这不仅仅是内存压力,还有一个性能问题。虽然粗略计算,如果只有 4 列,每列 10 个字符的数据,在 500000 行中,我们正在查看大约 40 MB 的文件。因此,即使使用StringBuilder,也不确定这是一个好方法。

标签: c# asp.net linq csv


【解决方案1】:

您可以使用 StringBuilder 类和 FileStream 来生成 csv。 试试下面的代码。 您可以为 StringBuilder 和 System.IO 命名空间包含 System.Text 以使用 FileStream 类。

var dataForDateRange = obj.table.Where(m => m.id== id && m.CreatedDateTime >= start && m.CreatedDateTime<= end);
StringBuilder csvBuilder = new StringBuilder();

//Adding column header
csvBuilder.AppendLine("Col1","Col2", "Col3", ....);

//Adding row data
for(int i = 0; i < dataForDateRange.Rows.Count; i++)
{
    csvBuilder.Append(dataForDateRange.Rows[i] + ",");
    csvBuilder.Append("\n");
}

//Save your file
public void SaveFileReport()
{
    try
    {
        if(File.Exists("yourfilepath") == false) //eg @"c:\test.csv"
        {
            FileStream fstream = File.Create("yourfilepath"); 
            fstream.Close();
        }
        File.WriteAllText("yourfilepath", csvBuilder.ToString());
    }
    catch(Exception)
    {
        throw;
    }
}

//注意:我已经给出了实现的基本逻辑,请您添加您的代码 并调试以获得所需的结果。

【讨论】:

  • 即使你没有写下所有的细节,使用一些有效的语法可能会更好。就像标题的csvBuilder.AppendLine("Col1,Col2,Col3, ..."); 一样,而不是看起来好像接受许多参数的不存在的AppendLine。您也可以保留foreach(var csvData in dataForDateRange)csvData.col1, csvData.col2 ... 的问题符号用于列访问。可能使用Append("{0},{1},...", csvData.col1, ...).AppendLine() 或类似的东西以有效且符合字符串生成器的方式模仿问题行为。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2020-01-15
  • 1970-01-01
  • 2012-01-25
  • 2011-04-05
  • 1970-01-01
相关资源
最近更新 更多