【问题标题】:CSVHelper Dynamic number of columnsCSVHelper 动态列数
【发布时间】:2019-08-14 22:20:06
【问题描述】:

我今天刚开始研究 csvhelper 库,并获得了有关如何在下一列中添加条目的新帮助。假设我有三个数据集,由(ABC 办公室、莎拉办公室和布赖恩办公室)组成。这些是建筑物名称……对于每个建筑物,我都有 TaskName、PointName、DataName,然后是行的 Local 和 Value 数据。 每个建筑物将有 2 个柱子,可以有 10 或 20 个建筑物(动态) 每个建筑物可以是本地和价值行下方的 1000 条数据行。

我有以下代码

using (var writer = new StreamWriter(filePath))
                            using (var csv1 = new CsvWriter(writer))
                            {
    foreach (var point in this.Points)
                                    {
                                       csv1.WriteField(point.BuildingName);
                                       csv1.WriteField(" ");
                                        csv1.NextRecord();
                                        csv1.WriteField(point.TaskName);
                                        csv1.WriteField(" ");
                                        csv1.NextRecord();
                                        csv1.WriteField(point.PointName);
                                        csv1.WriteField(" ");
                                        csv1.NextRecord();
                                        csv1.WriteField(point.DataName);
                                        csv1.WriteField(" ");
                                        csv1.NextRecord();
                                    }
}

问题是它把所有的点信息放在第一列,然后' '放在第二个字段中。

我最终需要的是这样的东西。

添加点信息后,我希望能够在每个点下附加一个Local和Value列的数据集。

CSV 格式是否可以使用 CSVHelper?

更新:

到目前为止,我已经做到了这一点。使用 String builder 添加了前 5 行数据。 现在我需要能够在每个 Office 下附加一个包含 Local 和 Value 列的数据集。 CSVHeper 库中有没有一种方法可以指定附加数据集的位置。我得到的前 5 行是这样的。

var row1 = new StringBuilder();
 var row2 = new StringBuilder();
var row3 = new StringBuilder();
var row4 = new StringBuilder();


                                    foreach (var point in this.Points)
                                    {
                                        row1.Append($"{ point.BuildingName},,");
                                        row2.Append($"{point.TaskName},,");
                                        row3.Append($"{ point.PointName},,");
                                        row4.Append($"{ point.DataName},,");

                                    }
                                    //StreamWriter sw = new StreamWriter("filePath", true);
                                    using (StreamWriter sw = new StreamWriter(filePath1))
                                    {
                                        sw.Write(row1.ToString());
                                        sw.WriteLine();
                                        sw.Write(row2.ToString());
                                        sw.WriteLine();
                                        sw.Write(row3.ToString());
                                        sw.WriteLine();
                                        sw.Write(row4.ToString());
                                        sw.WriteLine();

                                        sw.Close();
                                    }

【问题讨论】:

  • 您预期的格式看起来不太适合作为 CSV 文件的开头。通常,CSV 文件是指组织成列的数据,由逗号等分隔符分隔。所以理想情况下,每一列应该有一种类型的数据,每条记录(行)应该代表一组数据。
  • @Sach,在第 6 行的本地行和值行之后会有数年的数据。每个 BuildingName、TaskName、Point 和数据名称(基本上是前 4 行)的信息为第 5 行之后的行中的数据提供信息。
  • 如果您有不同类型的数据,您可能应该考虑使用数据库。如果工作量太大,至少您应该考虑使用不同的 CSV 文件来保存该数据,然后使用一些逻辑将它们链接到您的程序中。就像现在一样,您的第一列似乎有一些办公室名称、温度读数和一些日期。秒列一些值,第三列是以前的数据等。还有 3 个 Local 和 3 个 Value 列背后的逻辑是什么,因为 CSV 文件被读取为行,所以一行中有 3 组数据.他们就该这样吗?
  • @Sach 是的,每个办公室都说 Sarah'Office 将有自己的本地和值列设置。这可能是三年的数据,而布赖恩的办公室可能只有两年的数据。
  • 好的,让我看看我是否理解正确,在您的代码中是否意味着BuildingName=ABCTaskName=Temperature 等,对吗?那么为什么不将BuildingNameTaskNameLocalValue 等作为您的列呢?当然,名称、任务等会重复,但这仍然比拥有像您这样的数据格式要好得多——这是一场等待发生的灾难。

标签: c# export-to-csv csvhelper


【解决方案1】:

您尝试创建的不是 CsvHelper 旨在创建的标准 CSV 文件。 CSV 文件有一行标题,后面跟着一行数据。您似乎正在使用逗号分隔值创建 Excel 报告。 CsvHelper 可以帮助您编写字段,但您必须提供编写报告格式的逻辑。以下是您可以做到的一种方法。

public static void Main(string[] args)
{
    var points = new List<Point>
    {
        new Point
        {
            BuildingName = "ABC Office",
            TaskName = "Temperature",
            PointName = "14",
            DataName = "Temperature: Degrees F",
            Results = new List<Result> {
                new Result { Local = new DateTime(2019, 1,1), Value = 2},
                new Result { Local = new DateTime(2019, 1, 2), Value = 23}
            }
        },
        new Point
        {
            BuildingName = "Sarah's Office",
            TaskName = "Fan",
            PointName = "33",
            DataName = "0=Stop;1=Run",
            Results = new List<Result> {
                new Result { Local = new DateTime(2019, 1,1), Value = 2},
                new Result { Local = new DateTime(2019, 1, 2), Value = 23},
                new Result { Local = new DateTime(2019, 1, 3), Value = 45},
                new Result { Local = new DateTime(2019, 1, 4), Value = 34},
                new Result { Local = new DateTime(2019, 1, 5), Value = 36}
            }
        },
        new Point
        {
            BuildingName = "Brian's Office",
            TaskName = "Fan",
            PointName = "35",
            DataName = "Humidity",
            Results = new List<Result> {
                new Result { Local = new DateTime(2019, 1,1), Value = 2},
                new Result { Local = new DateTime(2019, 1, 2), Value = 23},
                new Result { Local = new DateTime(2019, 1, 3), Value = 45},
                new Result { Local = new DateTime(2019, 1, 4), Value = 34},
                new Result { Local = new DateTime(2019, 1, 5), Value = 36},
                new Result { Local = new DateTime(2019, 1, 6), Value = 56},
                new Result { Local = new DateTime(2019, 1, 7), Value = 92}
            }
        },
    };

    using (var writer = new StreamWriter(filePath))
    using (var csv = new CsvWriter(writer))
    {
        // Print buildings
        foreach (var point in points)
        {
            csv.WriteField(point.BuildingName);
            csv.WriteField("");
        }
        csv.NextRecord();

        // Print Tasks
        foreach (var point in points)
        {
            csv.WriteField(point.TaskName);
            csv.WriteField("");
        }
        csv.NextRecord();

        // Print Points
        foreach (var point in points)
        {
            csv.WriteField(point.PointName);
            csv.WriteField("");
        }
        csv.NextRecord();

        // Print DataNames
        foreach (var point in points)
        {
            csv.WriteField(point.DataName);
            csv.WriteField("");
        }
        csv.NextRecord();

        // Print value titles
        foreach (var point in points)
        {
            csv.WriteField("Local");
            csv.WriteField("Value");
        }
        csv.NextRecord();

        var endReached = false;
        var pointIndex = 0;

        // Print values
        while (!endReached)
        {
            endReached = true;
            foreach (var point in points)
            {
                if (point.Results.Count > pointIndex)
                {
                    csv.WriteField(point.Results[pointIndex].Local);
                    csv.WriteField(point.Results[pointIndex].Value);

                    if (point.Results.Count > pointIndex + 1)
                    {
                        endReached = false;
                    }
                }
                else
                {
                    csv.WriteField("");
                    csv.WriteField("");
                }
            }
            csv.NextRecord();

            pointIndex += 1;
        }
    }
}

public class Point
{
    public string BuildingName { get; set; }
    public string TaskName { get; set; }
    public string PointName { get; set; }
    public string DataName { get; set; }
    public List<Result> Results { get; set; }

}

public class Result
{
    public DateTime Local { get; set; }
    public int Value { get; set; }
}

【讨论】:

  • 嗨@David,非常感谢。我能够以与您提到的相同的方式完成此操作。我确实提供了编写报告格式的逻辑。非常感谢。
猜你喜欢
  • 2021-12-21
  • 2017-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 2020-02-03
  • 1970-01-01
  • 2018-08-15
相关资源
最近更新 更多