关于c#:导出大量数据

Exporting Large Amounts of Data

这是我的问题……

我们的站点中有两种类型的报告,网格中显示的数据和作为报告即时下载的数据。

这些报告可以包含几年的数据(超过一百万行),我们允许客户根据日期范围下载数据,但我们开始限制他们查看数据的时间,以防止我们网站出现性能问题。然而,即使是在一个小的日期范围内,数据仍然变得相当大,因为它们正在扩展,如果下载太多,我们的内存就会超过几格,耗尽内存。

我的问题是,我不想限制他们的数据,所以我正试图找到一个好的解决方案,允许他们下载他们想要的。

我可以通过每页返回数据来限制他们看到的内容,这样就不会出现性能问题,但是下载始终是问题所在。

我已经研究过Async,但还没有成功地让它工作,因为它在加载数据时会增加内存。

思想?思想?建议?

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Get Data

SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
SqlDataAdapter da;
DataSet ds = new DataSet();

con.ConnectionString ="MyConnectionString";
con.Open();

cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText ="MyStoredProc";
da = new SqlDataAdapter(cmd);
da.Fill(ds);

con.Close();

StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
DataGrid dg = new DataGrid();
dg.DataSource = ds.Tables[0];
dg.DataBind();
dg.RenderControl(htw);

Response.ClearContent();
Response.ContentType ="application/vnd.ms-excel";
Response.AddHeader("Content-Disposition","attachment;filename=Report.xls");
Response.Write(sw.ToString());
Response.End();

当我用我的数据运行这个……大约有800K行,内存峰值,我会出现内存不足错误,使情况更糟。它总是在rendercontrol上猛冲直到完成


我假设数据来自后端数据库。如果是这样,则不应该让用户等待此操作完成。这是一个糟糕的用户界面设计,尤其是当内存可以达到4GB时。

我同意其他建议,即您应该考虑改进代码和设计,以帮助减少占地面积。但是无论如何,您应该有类似于计划的作业架构这样的东西。

您可以让用户点击搜索/文件上的"下载",然后将其添加到数据库表中的队列中。有一个db/.net进程来处理这些作业,并在服务器上以正确的格式生成文件。如果数据相同,并且使用适当的命名约定,那么可以跨多个用户重用该文件。然后,用户应该能够访问下载队列页面,查看他已安排的所有下载。一旦完成,他将能够下载文件。

如果你有一个不允许你这样做的要求,请发表评论解释。


好,我们走吧:

  • 不要用桌子
  • 不要使用数据集

完成了。

找一个数据阅读器,一边写HTML——你永远不会把所有的数据都保存在内存中。你的方法永远不会扩大。


解决了的!!!!

我在Excel中导出大量数据时也遇到了同样的问题。

解决方案:您可以使用开放式XML DLL来解决您的问题。使用此DLL,您可以在Excel中导出大量数据,并且内存消耗也会减少。

您可以从这里获得更多信息https://msdn.microsoft.com/en-us/library/office/hh180830(v=office.14).aspx


是否可以重写要分页的存储过程并在数据集中循环?然后重写输出部分以流式传输文件,而不是一次性全部输出(您当前的方法基本上只是写出一个HTML表)。

对数据进行分页可以防止下载过程将所有数据存储在内存中。