【问题标题】:Improving the performance of a DataTable to export a .CSV提高 DataTable 的性能以导出 .CSV
【发布时间】:2013-05-16 17:54:38
【问题描述】:

我的代码导出 .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?

谢谢你的帮助,我真的需要改进这个东西!

【问题讨论】:

  • 看看SSIS,它会比你通过C#代码执行这个操作更胖。但是,您可以直接从 DataReader 转到 CSV,而不是将 DataReader 转换为 DataTable,然后将 DataTable 转换为 CSV 文件。
  • 试试 Filehelpers filehelpers.sourceforge.net

标签: c# asp.net sql datatable export-to-excel


【解决方案1】:

我可以建议优化(并且不知道数据库的其余部分获取速度),直接写入输出流。

不要使用缓冲区和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 页面,错误处理程序来发送它们。

【讨论】:

    【解决方案2】:

    如果你去掉第一个 for 循环,并将 if 从那里移到最后一个 for 循环,你会看到一些改进。还;将 if 变成“if, else if”,以减少每次迭代必须评估的 if 数量。

    我无法真正理解用分号替换逗号的必要性 - 我认为将每个单元格括在引号中会更好:

    for(...)
        if (...)
        else if (...)
        else
            sb.AppendFormat("\"{0}\",", dt.Rows[i][k].ToString());   
    }
    //remove trailing comma:
    sb.length--
    //Append linebreak:
    sb.AppendLine();
    

    【讨论】:

      猜你喜欢
      • 2011-04-08
      • 2020-07-11
      • 1970-01-01
      • 2012-06-17
      • 2020-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      相关资源
      最近更新 更多