You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何从已排序的DataTable中按列拆分生成多个CSV文件

问题根因

  • 未在每个Sender的遍历周期开始时重置StringBuilder对象,上一个Sender的写入内容会持续残留,后续生成的文件内容会出现冗余错误
  • 内层行遍历遇到不匹配当前Sender的行时直接触发break,下一个Sender遍历时从第一行开始读取,第一行属于上一个Sender的取值范围,直接触发break退出内层循环,没有有效行写入也不会执行文件生成逻辑
  • 文件写入操作放在行遍历内部,每匹配到一行就执行一次写操作,产生大量不必要的IO开销,执行效率极低

修复代码

直接筛选匹配当前Sender的所有行,逻辑更简洁不容易出错:

foreach (string Sender in listSenders)
{
    // 每个Sender单独初始化StringBuilder,避免内容残留
    StringBuilder sb = new StringBuilder();
    // 写入CSV表头
    IEnumerable<string> columnNames = dtPHLIP251.Columns.Cast<DataColumn>()
        .Select(column => column.ColumnName);
    sb.AppendLine(string.Join(",", columnNames));

    // 筛选当前Sender对应的所有行
    var targetRows = dtPHLIP251.AsEnumerable()
        .Where(row => row[2].ToString() == Sender);

    foreach (DataRow row in targetRows)
    {
        IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
        sb.AppendLine(string.Join(",", fields));
    }

    // 所有行处理完成后统一写入文件,仅执行一次IO
    string filePath = $@"C:\Users\nkr7\Desktop\DMBErrors\PHLIP251ErrorsProd{strDate}{Sender}.csv";
    File.WriteAllText(filePath, sb.ToString());
}

可选优化(适配已排序的DataTable)

如果你已经确认DataTable严格按第3列(索引为2)排序,同一Sender的行完全连续,可以采用索引递进的方式避免每次遍历全表,进一步提升性能:

int rowIndex = 0;
int totalRows = dtPHLIP251.Rows.Count;
foreach (string Sender in listSenders)
{
    StringBuilder sb = new StringBuilder();
    IEnumerable<string> columnNames = dtPHLIP251.Columns.Cast<DataColumn>()
        .Select(column => column.ColumnName);
    sb.AppendLine(string.Join(",", columnNames));

    bool hasMatch = false;
    while (rowIndex < totalRows)
    {
        DataRow row = dtPHLIP251.Rows[rowIndex];
        string currentSender = row[2].ToString();
        if (currentSender == Sender)
        {
            IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
            sb.AppendLine(string.Join(",", fields));
            hasMatch = true;
            rowIndex++;
        }
        else if (hasMatch)
        {
            // 已遍历完当前Sender的所有行,直接退出处理下一个Sender
            break;
        }
        else
        {
            // 还未到当前Sender的行区间,继续向后遍历
            rowIndex++;
        }
    }

    string filePath = $@"C:\Users\nkr7\Desktop\DMBErrors\PHLIP251ErrorsProd{strDate}{Sender}.csv";
    File.WriteAllText(filePath, sb.ToString());
}

补充说明:如果你的字段内容包含逗号、双引号、换行符等特殊字符,建议先对字段内容做CSV标准转义处理,避免生成的CSV文件格式错乱。

内容的提问来源于stack exchange,提问作者user16188164

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:45:00