提高数据表导出csv文件的性能
本文关键字:文件 性能 csv 数据表 | 更新日期: 2023-09-27 18:13:52
我的代码花了很长时间来导出. cvs,我们说的是几分钟。在SQL中执行查询需要几秒钟。
这是我现在用来填充DT的内容:
using (SqlConnection myConnection = new SqlConnection(connString))
{
using (SqlCommand myCommand = new SqlCommand(sqlString, myConnectionString))
{
myCommand.Parameters.AddWithValue("@DATE1", Date1);
myCommand.Parameters.AddWithValue("@DATE2", Date2);
myCommand.CommandTimeout = 0;
myConnection.Open();
using (SqlDataReader myReader = myCommand.ExecuteReader())
{
DataTable myTable = new DataTable();
myTable.Load(myReader);
return myTable;
}
}
}
下面是我用来创建。cvs文件的代码:
protected void ExportToCSV(object sender, EventArgs e)
{
DataTable dt = ContactProvider.GetDataTable(Date1, Date2);
DataRow row;
foreach (System.Data.DataColumn col in dt.Columns) col.ReadOnly = false;
//I use this to change the value of the columns, because EXCEL changes the string to a date -.-
for (int i = 0; i < dt.Rows.Count; i++)
{
row = dt.Rows[i];
if (dt.Rows[i][5].ToString() == "MAR2")
{
row[5] = "='"MAR2'"";
}
if (dt.Rows[i][5].ToString() == "MAR1")
{
row[5] = "='"MAR1'"";
}
}
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition","attachment;filename=Report.csv");
Response.Charset = "";
Response.ContentType = "application/text";
StringBuilder sb = new StringBuilder();
for (int k = 0; k < dt.Columns.Count; k++)
{
sb.Append(dt.Columns[k].ColumnName + ',');
}
sb.Append("'r'n");
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int k = 0; k < dt.Columns.Count; k++)
{
sb.Append(dt.Rows[i][k].ToString().Replace(",", ";") + ',');
}
sb.Append("'r'n");
}
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.xls";
Response.Charset = "UTF-8";
Response.ContentEncoding = System.Text.Encoding.Unicode;
Response.Output.Write(sb.ToString());
Response.Flush();
Response.End();
}
是否有一种方法可以提高这些方法的性能,以便我可以尽可能快地填充DT并导出.CVS ?
谢谢你的帮助,我真的需要改进这个东西!
我可以建议优化(并且不知道数据库读取速度的其余部分),直接写入输出流。
不要使用buffer和StringBuilder首先在内存中创建它,然后再写入它,而是直接将它们发送到客户端:
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.xls";
Response.Charset = "UTF-8";
Response.ContentEncoding = System.Text.Encoding.Unicode;
// important !, send them as you make them.
Response.Buffer = false;
for (int k = 0; k < dt.Columns.Count; k++)
{
Response.Output.Write(dt.Columns[k].ColumnName);
Response.Output.Write(',');
}
Response.Output.Write("'r'n");
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int k = 0; k < dt.Columns.Count; k++)
{
Response.Output.Write(dt.Rows[i][k].ToString().Replace(",", ";"));
Response.Output.Write(',');
}
Response.Output.Write("'r'n");
}
这样你可以避免大量的内存消耗在服务器端,大量的处理速度,连接一个字符串与另一个字符串,用户/程序看到结果,因为你创建它们,而不是等待第一次制作,然后发送它们。
并且不要使用aspx页面,bug处理程序来发送它们
如果您去掉第一个for循环,并将If从那里移到最后一个for循环,您将看到一些改进。也;将if变为if,否则if,以减少每次迭代中必须计算的if的数量。
我真的不明白为什么要用分号来代替逗号——我认为如果你用引号把每个单元格都括起来会更好:
for(...)
if (...)
else if (...)
else
sb.AppendFormat("'"{0}'",", dt.Rows[i][k].ToString());
}
//remove trailing comma:
sb.length--
//Append linebreak:
sb.AppendLine();