从asp.net中的数据库表下载> 10,000行

时间:2009-09-01 01:08:32

标签: asp.net download

我应该如何在asp.net页面上提供下载功能,从数据库表中下载一系列行,这些行表示为linq2sql类,只有成员的原始类型(理想情况下是一种易于阅读的格式)的Excel)?

E.g。

public class Customer
{
public int CustomerID;
public string FirstName;
public string LastName;
}

到目前为止我尝试了什么。

最初我创建了一个DataTable,将所有Customer数据添加到此表并将其绑定到DataGrid,然后有一个下载按钮,将DataGrid1.RenderControl调用到HtmlTextWriter,然后将其写入响应(内容类型为“application”) /vnd.ms-excel“)并且对少数客户来说效果很好。

但是,现在此表格中的行数大于10,000,预计会达到100,000以上,因此在用户可以在页面上显示所有这些数据之前就越来越不容易单击下载按钮。

所以问题是,如何才能提供下载所有这些数据的功能,而无需先在DataGrid上显示所有数据?

8 个答案:

答案 0 :(得分:3)

用户请求下载后,您可以将数据写入服务器上的文件(.CSV,Excel,XML等),然后将重定向发送到文件URL。

答案 1 :(得分:1)

我在Matt Berseth博客上使用了以下方法来获取大型记录集。

Export GridView to Excel

如果您对请求超时有疑问,请尝试在web.config中增加http请求时间

答案 2 :(得分:1)

除了合理的建议首先将服务器上的数据保存到其中一个答案中的文件之外,我还想指出没有理由使用DataGrid(这也是你的一个问题)。 DataGrid几乎可以解决任何问题。您可以迭代记录,并使用HtmlTextWriter,TextWriter(或只是Response.Write或类似)直接将它们保存到服务器文件或客户端输出流。在我看来,这似乎是一个明显的答案,所以我必须遗漏一些东西。

考虑到记录的数量,您可能会遇到许多问题。如果直接写入客户端输出流,并首先缓冲服务器上的所有数据,则可能会对服务器造成压力。但也许不是;它取决于服务器上的内存量,实际数据大小以及人们下载数据的频率。此方法的优点是不会长时间阻塞数据库连接。或者,您可以在迭代时直接写入客户端输出流。这可能会阻止数据库连接太长时间,因为它取决于客户端的下载速度。但是又一次;你的应用程序是中小型(在观众中)然后一切都很好。

答案 3 :(得分:1)

您一定要查看FileHelpers库。它是一个免费软件,优秀的实用程序集来处理这种情况 - 从文本文件导入和导出数据;分隔(如CSV)或固定宽度。

它提供了大量的选项和工作方式,而且它是免费,它在我正在使用它的各种项目中运行得非常好。你可以导出一个DataSet,一个数组,一个对象列表 - 无论你有什么。

它甚至还有Excel文件的导入/导出 - 所以你真的得到了很多选择。

刚开始使用FileHelpers - 它会为你节省很多无聊的打字和东西,你不会相信它: - )

马克

答案 4 :(得分:1)

只需提醒一句,Excel对数据行数有限制 - 约65k。 CSV会很好,但如果您的客户将文件导入Excel,他们将遇到这种限制。

答案 5 :(得分:0)

为什么不允许他们翻阅数据,也许在分页之前对其进行排序,然后给他们一个按钮,将所有内容都作为cvs文件。

这似乎是DLinq做得很好的事情,包括分页和写出来,因为它一次只能获取一行,所以在处理它们之前你不会读取所有100k行。

因此,对于cvs,您只需要使用不同的LINQ查询来获取所有行,然后开始保存它们,通过分隔符(通常是逗号或制表符)分隔每个单元格。也许这可能是用户选择的东西。

答案 6 :(得分:0)

好的,我认为你说太多行来做DataReader,然后循环创建cvs文件。唯一可行的方法是运行:

SQLCMD -S MyInstance -E -d MyDB -i MySelect.sql -o MyOutput.csv -s

有关如何从ASP.Net代码运行此代码,请参阅here.然后,一旦完成,您的ASP.Net页面将继续:

    string fileName = "MyOutput.csv";
    string filePath = Server.MapPath("~/"+fileName);
    Response.Clear();        
    Response.AppendHeader("content-disposition", 
"attachment; filename=" + fileName);        
    Response.ContentType = "application/octet-stream";        
    Response.WriteFile(filePath);        
    Response.Flush();        
    Response.End();    

这将为用户提供保存文件的弹出窗口。如果您认为一次会发生多个这样的事情,您将不得不进行调整。

答案 7 :(得分:0)

经过一些研究后,我最后尝试的解决方案是使用http://www.asp.net/learn/videos/video-449.aspx的代码示例的略微修改版本,并使用以下代码格式化我的DataTable for CSV中的每一行值避免可能存在问题的文字:

private static string FormatForCsv(object value)
        {
            var stringValue = value == null ? string.Empty : value.ToString();
            if (stringValue.Contains("\"")) { stringValue = stringValue.Replace("\"", "\"\""); }
            return "\"" + stringValue + "\"";
        }

对于对上述内容感到好奇的人,我基本上围绕引号中的每个值,并通过将它们作为双引号来转义任何现有引号。即。

My Dog => "My Dog"
My "Happy" Dog => "My ""Happy"" Dog"

对于少量记录来说,这似乎正在诀窍。我将很快用> 10,000条记录试一试,看看它是怎么回事。

编辑:此解决方案在数千条记录的制作中运作良好。