You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用WriteAllText将DataTable列名写入CSV文件表头?

解决DataTable写入CSV时添加表头的问题

嘿,我来帮你搞定这个CSV表头的问题!你的代码现在有几个小问题导致表头没正确生成,我一步步给你梳理并修正:

首先,你当前代码里的sb.AppendLine(string.Join(",", columnNames));其实是把分组后的匿名对象直接拼接了,这根本不是DataTable的列名;而且你把StringBuilder放在了内层循环里,每次循环都会新建一个,最后每个CSV文件只会保留最后一行数据;还有文件名里的row直接转字符串会输出类似<>f__AnonymousType0的内容,不是你想要的RE名称。

下面是修正后的完整代码,我加了注释说明关键改动:

private void GenerateRETest()
{
    DataTable rI = new DataTable();
    rI.Columns.Add("sID", typeof(int));
    rI.Columns.Add("sn", typeof(string));
    rI.Columns.Add("RE", typeof(string));
    rI.Rows.Add(25, "Apex 1", "RE 1");
    rI.Rows.Add(50, "Apex 2", "RE 1");
    rI.Rows.Add(10, "Apex 3", "RE 1");
    rI.Rows.Add(21, "Apex 4", "RE 1");
    rI.Rows.Add(251, "Apex 11", "RE 11");
    rI.Rows.Add(501, "Apex 21", "RE 11");
    rI.Rows.Add(101, "Apex 31", "RE 11");
    rI.Rows.Add(211, "Apex 41", "RE 11");
    rI.Rows.Add(215, "Apex 12", "RE 12");
    rI.Rows.Add(510, "Apex 22", "RE 12");
    rI.Rows.Add(110, "Apex 32", "RE 12");
    rI.Rows.Add(211, "Apex 42", "RE 12");

    // 按RE分组,修正原代码里的变量名错误(dt改成rI)
    var groupedData = rI.AsEnumerable()
                        .GroupBy(row => row.Field<string>("RE"))
                        .Select(group => new 
                        { 
                            RE = group.Key, 
                            Rows = group.OrderBy(row => row.Field<string>("sn")).ToList() 
                        })
                        .OrderBy(x => x.RE)
                        .ToList();

    // 获取DataTable的列名,处理引号转义,和数据字段保持一致格式
    var headerFields = rI.Columns.Cast<DataColumn>()
                                 .Select(col => $"\"{col.ColumnName.Replace("\"", "\"\"")}\"");
    string headerLine = string.Join(",", headerFields);

    foreach (var group in groupedData)
    {
        // 把StringBuilder放在分组循环外面,收集该分组的所有行
        StringBuilder sb = new StringBuilder();
        // 先写入表头
        sb.AppendLine(headerLine);

        foreach (var dataRow in group.Rows)
        {
            // 处理数据字段,转义引号并包裹双引号
            IEnumerable<string> dataFields = dataRow.ItemArray
                                                    .Select(field => $"\"{field.ToString().Replace("\"", "\"\"")}\"");
            sb.AppendLine(string.Join(",", dataFields));
        }

        // 用分组的RE值作为文件名的一部分,避免无效文件名
        string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        string fileName = Path.Combine(desktopPath, $"{group.RE}_display.csv");
        // 写入整个分组的内容到CSV
        File.WriteAllText(fileName, sb.ToString());
    }
}

关键改动点说明:

  • 修正了原代码里的变量名错误(dt改成rI
  • 提前生成表头行,用DataColumn.ColumnName获取真正的列名,同时处理引号转义
  • StringBuilder移到分组循环外层,确保每个CSV文件包含表头+所有对应行
  • 文件名使用group.RE来命名,避免生成奇怪的类名格式文件名
  • 统一表头和数据字段的格式(都用双引号包裹,转义内部的双引号)

这样每个生成的CSV文件都会以sID,sn,RE作为第一行表头,后面跟着对应分组的数据行啦!

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

火山引擎 最新活动